Skip to content

Repository files navigation

EVSE Hub for Home Assistant

EVSE Hub for Home Assistant

Language: English · 中文

A vendor-agnostic Home Assistant integration for EV chargers. One HA integration, a pluggable Provider SPI, support for many brands. Currently bundled: Geely Galaxy / Direct Wallbox (吉利银河 / 浩瀚能源).

HACS Release License Python Tests

✨ Features

  • Start / stop charging remotely (switch, Siri-controllable via HomeKit)
  • 📊 Live status: idle / charging / plugged / online / offline / fault
  • 🔋 Live telemetry during charge: current, voltage, power, kWh, elapsed time
  • 🩺 Health checks: voltage / grounding / network / faults
  • 🔧 Diagnostics: firmware version, OTA availability, active charging user
  • 🔑 Token lifecycle monitoring: access / refresh token remaining time + state-change events (thresholds tunable via UI)
  • 🍎 HomeKit / Siri / Mijia / XiaoAi bridge-friendly via HA's built-in HomeKit Bridge

🏭 Supported providers

Provider key Brand / hardware Login methods Status
geely Geely Galaxy / 浩瀚能源 (DIRECT_WDZ, etc.) SMS / Token file / paste JWT ✅ Author-tested
PRs welcome TELD / Star Charge / YKC / Zhida / NIO / XPeng / … 🤝 Recruiting

See docs/PROVIDER-GUIDE.md for how to add a new vendor.

📦 Installation

Option 1: HACS (recommended, not yet in default store)

Using custom repositories:

  1. HACS → three-dot menu → Custom repositories
  2. Repository: https://github.com/jiusanzhou/evse-hub-ha
  3. Type: Integration
  4. Save, then search for EVSE Hub in HACS and install
  5. Restart Home Assistant

Option 2: Manual

cd /path/to/evse-hub-ha
./install-ha.sh

# Remote HAOS:
HA_SSH=ha HA_PATH=/mnt/data/supervisor/homeassistant ./install-ha.sh
ssh ha "docker exec hassio_cli ha core restart"

🚀 Setup

When adding the integration you pick a provider first, then follow that provider's login flow.

🔑 Provider: geely (Geely Galaxy / 浩瀚能源)

No prerequisite setup — the integration ships with the current Geely Galaxy app client parameters baked in, so you can install and log in right away.

Overriding the built-in AppSecrets

The GEELY_RECHARGE_SECRET / GEELY_GALAXY_SECRET values that sign gateway requests are client-fixed parameters — the same for every Geely Galaxy app install, not per-user credentials. They're comparable to the client_id / base_url that many other HA integrations hard-code.

If the vendor ever rotates them, override with either:

# Option 1: environment variables (highest priority)
export GEELY_RECHARGE_SECRET=<new value>
export GEELY_GALAXY_SECRET=<new value>

# Option 2: /config/.evse_hub_secrets.json
{
  "geely_recharge_secret": "<new value>",
  "geely_galaxy_secret":   "<new value>"
}

Extract fresh values from the app following docs/capture-guide.md.

Login methods

Method One-time cost Ongoing maintenance Status
A. SMS login Phone number + slider + one SMS Auto-refresh every 7 days; re-login after 30 days ✅ Recommended
B. Token file Android emulator + capture login once Daemon auto-refreshes
C. Paste JWT manually Capture / obtain token once Re-paste every 7 days ✅ Emergency

New users should just use A — no extra tooling required.

Method A: SMS login (recommended, zero setup)
  1. HA → Settings → Devices & services → Add integration → search EVSE Hub
  2. Pick provider Geely Galaxy / 浩瀚能源
  3. Pick auth method "SMS login (recommended, one-click)"
  4. HA gives you a URL (/api/evse_hub/auth?session=...) — open it in a phone browser on the same network
  5. On the page: enter phone number → complete slider CAPTCHA → enter 6-digit SMS code → submit
  6. Page shows "🎉 login successful", then submit the HA form → integration persists the token

Technical note: SMS login is a 6-step chain (galaxy security config → geeTestV4/validate → sendSms → mobileCodeLogin → oauth2/code → api-recharge getTokenByCode). All signing (including Alibaba API Gateway's alphabetical query-arg rules) is implemented in provider/geely/sms_auth.py.

Method B: Android emulator + token daemon (unattended, long-term)

See docs/capture-guide.md:

  1. Set up an Android emulator (Google APIs image, needs root), install the Geely Galaxy app, log in
  2. Capture the login response with mitmproxy — or after rooting, read /data/data/com.geelygalaxy.customer/files/mmkv/ directly

Write the token to ~/.geely_jwt.json:

{
  "accessToken": "eyJ...",
  "refreshToken": "eyJ...",
  "sub": "your userId",
  "expiresAt": 1234567890,
  "refreshExpiresAt": 1234567890
}
python3 tools/geely_jwt_daemon.py &

Every 30 minutes the daemon:

  • pulls the latest JWT from the emulator's MMKV storage
  • checks expiry and auto-refreshes when close
  • optionally syncs to HA over SSH (HA_TOKEN_DEST)

When adding the integration, pick "Token file" and enter the token path (default /config/geely_jwt.json).

Method C: Paste JWT manually (emergency, 5-minute setup)
  1. Use mitmproxy / Charles on your phone to capture the login response from api.geely.com
  2. Pull out accessToken, refreshToken, sub (your userId)
  3. In the HA add-integration flow, pick "Paste JWT manually (emergency)" and paste the three values
  4. The integration writes /config/geely_jwt.json and runs in Token-file mode
  5. After 7 days, if the daemon isn't running, you'll need to re-paste

⚙️ Token warning thresholds (Options UI)

After install, Settings → Integrations → EVSE Hub → CONFIGURE:

Field Unit Default Meaning
Poll interval seconds 30 Coordinator poll frequency
Access-token warning threshold hours 24 Fire warning event below this
Access-token critical threshold hours 2 Fire critical event below this
Refresh-token warning threshold days 3 Fire needs_relogin event below this

Event name: evse_hub_token_state.

🍎 HomeKit / Siri / Mijia / XiaoAi (optional)

📊 Entities

Entity Kind Description
switch.charger_charging switch Start / stop charging
sensor.charger_status sensor idle / charging / fault / offline
sensor.charger_power sensor (kW) Live power
sensor.charger_current / _voltage sensor (A/V) Live current / voltage
sensor.charger_session_energy sensor (kWh) Energy delivered this session
sensor.charger_duration sensor (min) Duration of this session
sensor.charger_firmware / _active_user sensor Diagnostics
binary_sensor.charger_plugged / _charging / _online binary State
binary_sensor.charger_health / _fault / _update_available problem/update Diagnostics
sensor.access_token_remaining / refresh_token_remaining / token_status sensor/enum Token lifecycle

(Actual entity names follow the charger's Chinese display name in Geely's app; you can rename them in HA.)

🔔 Automation examples

Token about to expire → Telegram notification:

automation:
  - alias: "Charger token needs relogin"
    trigger:
      - platform: event
        event_type: evse_hub_token_state
    condition:
      - condition: template
        value_template: >
          {{ trigger.event.data.new_state in ['warning','critical','needs_relogin','expired'] }}
    action:
      - service: notify.telegram
        data:
          message: >
            🔌 Charger token state: {{ trigger.event.data.new_state }}
            Access left: {{ trigger.event.data.access_remaining_hours }} h;
            Refresh left: {{ trigger.event.data.refresh_remaining_days }} d.

More examples (off-peak auto-charge, session-end notifications, fault alerts, Lovelace cards) in examples/.

🏗️ Architecture

                    ┌────────────────────────────────────────────┐
                    │  Home Assistant                            │
                    │                                            │
                    │  ┌── coordinator (30s poll) ──┐            │
                    │  │        ↓                   │            │
                    │  │  Equipment / ChargeStatus  │  ← unified │
                    │  │        ↑                   │    models  │
                    │  │   Provider SPI             │            │
                    │  │        ↑                   │            │
                    │  │  ┌─────┴──────┐            │            │
                    │  │  │            │            │            │
                    │  ▼  ▼            ▼            │            │
                    │ geely  starcharge (future) …  │            │
                    │  │        │                   │            │
                    └──┼────────┼───────────────────┘
                       │        │
                       ▼        ▼
         api-recharge.geely.com   …vendor cloud

Design pillars:

  • Provider SPI: vendor adapters implement the Provider ABC (list_equipments, get_status, start_charge, stop_charge, …)
  • Unified data model: Equipment, ChargeStatus, TokenBundle, Health, Versions — entity layer never sees vendor-specific fields
  • Pluggable: adding a vendor = writing one provider/<key>/ package and @register_provider. See docs/PROVIDER-GUIDE.md

🧑‍💻 Writing a provider for another vendor

# custom_components/evse_hub/provider/starcharge/__init__.py
from ...models import Equipment, ChargeStatus, TokenBundle
from .. import Provider, register_provider

@register_provider
class StarChargeProvider(Provider):
    key = "starcharge"
    display_name = "Star Charge"
    supports_sms_login = True

    async def load_token(self, token_path): ...
    async def list_equipments(self, bundle): ...
    async def get_status(self, bundle, eq): ...
    async def start_charge(self, bundle, eq): ...
    async def stop_charge(self, bundle, eq, order_id=None): ...

Full guide: docs/PROVIDER-GUIDE.md Requesting a new provider? Use the 📦 New Provider Request issue template.

⚠️ Known limitations

  1. Auth lifetime varies by provider. Geely refresh tokens last 30 days; the evse_hub_token_state event warns you in time.
  2. SMS slider SDK needs public network. GeeTest v4 (captcha4.geely.com) must be reachable — pure-offline setups can't SMS-login.
  3. Field names may differ across chargers. The Geely provider is currently only verified on Galaxy E5 + DIRECT_WDZ. Please open issues with captures for other models.
  4. Signing is vendor-private. Support comes from interoperability research; if the vendor changes its algorithm, this integration may break temporarily.
  5. HomeKit Bridge is capped at 150 accessories. If your household has lots of Mijia devices, run a dedicated bridge for the charger to avoid the cap.

🤝 Contributing

  • 🐛 Issues — bugs, model coverage, feature requests
  • 🔧 PRs welcome, especially:
    • New provider adapters (TELD / Star Charge / YKC / NIO / XPeng / …)
    • Field-adapter tweaks for additional charger models
    • Getting the integration into the HACS default store
    • MQTT Discovery variant

📚 Docs

⚖️ Disclaimer

  • This project is a personal interoperability research effort, intended for learning and to let users connect their own chargers to their own smart home.
  • It does not provide any capability to bypass paywalls, defraud billing, perform mass access, or operate on other people's accounts. Users must own or have permission to control the charger they connect.
  • The compatibility layer uses publicly reachable HTTPS endpoints with the user's own credentials; it does not redistribute proprietary software or circumvent commercial licensing.
  • Official APIs may change without notice; the author makes no availability guarantee.
  • Any loss (vehicle, appliance, account ban, …) resulting from use of this project is the user's responsibility.
  • If a vendor takes issue with this project's positioning, please open an issue — the author will cooperate on adjustments.

📄 License

MIT

About

Multi-provider Home Assistant integration for EV chargers. Bundled providers: Geely Galaxy (吉利银河/浩瀚能源). Extensible via a Provider SPI — PRs welcome.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages