Local-polling Home Assistant integration for Eveus EV chargers — full entity set and native statistics, for both v1 and v2 hardware generations.
Originally based in part on shlafik/eveuspro2ha, then rewritten around a single polling coordinator and HA-native quality requirements.
Tip
Документація також доступна українською мовою 🇺🇦
Eveus (formerly the Energy Star trademark) is a Ukrainian manufacturer of portable EV chargers. This integration connects an Eveus charger to Home Assistant over the local network — no cloud and no account required.
Once configured, it lets you:
- monitor the charging state, current, voltage, power, energy and temperatures;
- start / stop charging and set the charging current;
- switch the charger's AI / adaptive power mode;
- track per-session and daily energy and charging time, ready for the Energy Dashboard.
The charger comes in two hardware generations — v1 and v2 — which expose different on-device HTTP APIs. You pick the matching model when adding the integration (see Supported devices).
Several Home Assistant projects exist for Eveus chargers. This one focuses on:
- Both hardware generations in one integration — the v1 and v2 chargers expose different HTTP APIs; you pick the model in the config flow and the differences (state model, polarity, scaling, extra sensors) are handled internally.
- First-class HA statistics — correct
state_class/device_classon energy, power, current and voltage, so long-term statistics and the Energy Dashboard work out of the box. Daily energy and charging-time sensors reset at local midnight and survive restarts. - HACS-grade plumbing — diagnostics (IP, credentials and serial numbers redacted), Repairs issues for real errors only, re-auth and reconfigure flows, config-entry migration, and CI (hassfest + HACS validation + unit tests) on every commit.
- Single polling coordinator — one source of truth for device state with dynamic polling (30 s while charging, 60 s otherwise) instead of per-entity requests.
- Robust safety signals — ground sensors use debounce to suppress transient glitches, while firmware fault states bypass debounce and trigger immediately.
- Ukrainian-first localization — UI strings in Ukrainian, English and Russian, with a bundled brand icon.
| Model | Min current | JSON fields |
|---|---|---|
| v1 | 7 A | 41 |
| v2 | 6 A | 97 |
| Feature | v1 | v2 |
|---|---|---|
evseEnabled polarity |
1 = charging active |
0 = charging active |
| State model | 14 states — errors encoded in the single state field (0, 6, 9, 12–22) |
8 top-level states in state + subState for limit / error detail |
| AI modes | Off, Voltage | Off, Voltage, Tesla (auto), Power |
systemTime format |
"HH:MM:SS" string |
Unix timestamp (integer) |
| Measurement values | Raw integers — curMeas1 and energy fields scaled ×0.1 |
Real floats in native units |
powerMeas |
Not in response — calculated from V × I | Reported directly by device |
| Extra sensors | — | subState, vBat, RSSI, IEM1, IEM2 |
| Stopping a session | Not possible over HTTP — no charging switch is created |
charging switch stops and starts |
| Firmware version | Read from the page the charger serves (no field in /main) |
verFWMain in /main |
| Write acknowledgement | None — empty body for both applied and rejected writes | Body OK on success |
| Time sync | sync_time button (writes local wall-clock seconds) |
sync_time button (writes Unix timestamp to device) |
Full HTTP API reference. The complete endpoint and field documentation — all endpoints, the
/mainfield reference, command list, enums, and an OpenAPI 3.1 spec — is maintained in a separate community repository: Soundistor/eveus-api-doc.
- Copy
custom_components/eveus/to/config/custom_components/eveus/on your HA instance. - Restart Home Assistant.
- Settings → Integrations → Add → Eveus Charger.
The quickest way — click the button below to open the custom-repository dialog pre-filled:
Or add it manually:
- Open HACS → Integrations.
- Click the three-dot menu (⋮) in the top-right corner → Custom repositories.
- Enter
https://github.com/Soundistor/ha-eveusand select category Integration → Add. - Find Eveus Charger in the list and click Download.
- Restart Home Assistant.
- Settings → Integrations → Add → Eveus Charger.
| Field | Description |
|---|---|
| IP address | Charger IP (e.g. 192.168.x.x) |
| Model | v1 or v2 |
| Username | Optional (leave blank if not set) |
| Password | Optional (leave blank if not set) |
| Device prefix | Prefix for entity IDs, e.g. eveus_1 or eveus_home |
The device prefix determines entity IDs: a prefix of eveus_1 produces sensor.eveus_1_state, sensor.eveus_1_currentset, etc. Set it to match your existing automations. The prefix must be unique across your Eveus entries — the config flow enforces this. The prefix also defines the device name shown in HA: eveus_home → Eveus Home (with an empty prefix the device is named Eveus <ip>).
Changing settings later: open the integration entry menu (⋮) → Reconfigure to change the IP address, API version or credentials without re-adding the integration. The device record is keyed by the config entry, not the IP, so an IP change does not duplicate the device. The prefix cannot be changed after setup.
| Entity | Unit | Notes |
|---|---|---|
state |
— | Human-readable charger state |
currentset |
A | Configured charging current |
curmeas1 |
A | Measured charging current |
voltmeas1 |
V | Measured voltage |
powermeas |
W | Charging power |
temperature1 |
°C | Sensor 1 |
temperature2 |
°C | Sensor 2 |
aistatus |
— | Active AI mode |
aivoltage |
V | AI voltage setpoint |
aimodecurrent |
A | Current the adaptive algorithm is allowing right now; empty while adaptive mode is off |
curdesign |
A | Design max current |
sessiontime |
s | Session duration (raw seconds) |
session_time_daily |
h | Charging time since local midnight (resets daily, survives restart) |
sessionenergy |
kWh | Energy this session |
totalenergy |
kWh | Total energy (cumulative) |
energy_daily |
kWh | Charging energy since local midnight (resets daily, survives restart) |
last_session_energy |
kWh | Energy of the previous completed session, frozen at session end (survives restart) |
last_session_duration |
s | Duration of the previous completed session, frozen at session end (survives restart) |
systemtime |
— | Charger clock (diagnostic; disabled by default — enable manually if needed) |
time_drift |
s | Charger clock offset vs HA time, 0 = in sync (diagnostic) |
leakvalue |
— | Raw earth-leakage channel (diagnostic). Deliberately unitless: the scale is unconfirmed, and the vendor's "mA" label does not match the firmware's own trip thresholds. |
| Entity | Unit | Notes |
|---|---|---|
substate |
— | Detailed sub-state (limit or error) |
vbat |
V | Battery voltage (diagnostic) |
rssi |
dBm | Wi-Fi signal (diagnostic) |
iem1 |
kWh | Energy meter 1 (cumulative) |
iem2 |
kWh | Energy meter 2 (cumulative) |
| Platform | Entity | Notes |
|---|---|---|
switch |
charging |
Start / stop charging — V2 only, see the note below |
number |
current_set |
Charging current setpoint |
select |
ai_mode |
AI mode selector |
binary_sensor |
ground |
Ground connection OK |
binary_sensor |
groundctrl |
Ground protection active |
button |
force_refresh |
Force data update |
button |
sync_time |
Sync charger clock to HA time |
Besides the entities above, two services are available for automations and scripts:
| Service | Description |
|---|---|
eveus.set_current |
Set the charging current, in amperes (6–32 A depending on model). |
eveus.set_ai_mode |
Set the AI / adaptive power mode. Values: off, voltage, tesla_auto, power (V1 supports only off and voltage). |
set_current targets the charger's number entity, set_ai_mode — its select entity.
The integration fires events on the Home Assistant bus at charging-session transitions, so automations can trigger without polling. Filter by entry_id or device_name when you run more than one charger.
| Event | Fired when | Data |
|---|---|---|
eveus_charging_started |
The charger enters the charging state (including resume from pause), or a new session is detected while the reported state never left charging | entry_id, device_name |
eveus_session_ended |
A session finishes: the charger leaves the charging/paused states, or its session counter drops back to zero while the state is still active | entry_id, device_name, energy_kwh, duration_s, ended_state, ended_at |
The energy and duration in eveus_session_ended are the final session values captured just before the charger resets its counters for the next session — the same figures the last_session_* sensors keep.
Sessions cut short by a power cut. A charger that loses power mid-session boots straight back into charging, so its reported state never changes and there is no transition to detect. The integration treats the session counter returning to zero as the session boundary instead, and reports the interrupted session rather than losing it. Two things to know when you filter on this event:
ended_statethen carries the state the charger is in at the moment of detection, which may be an active state such ascharging— this field never carried an active state before;ended_atis the moment of detection, not the moment the session actually died. After a long outage the two differ by hours.
This covers the charger losing power. An outage that also takes Home Assistant down restarts the integration, and the interrupted session cannot be recovered.
UI strings are available in Ukrainian (uk), English (en), and Russian (ru).
Standard HA diagnostics are supported: Settings → Integrations → Eveus → Download diagnostics. IP address, username, password and device serial numbers are redacted in the output — safe to attach to GitHub issues.
- Polling interval is dynamic: 30 s while charging, 60 s otherwise.
- When the charger is powered off or unplugged, its entities simply become unavailable — this is normal and does not raise a repair issue. A repair issue is only created when the charger is reachable but returns an error (e.g. a malformed response, or the configured API version not matching the firmware).
- A charger that is offline when Home Assistant starts does not block setup. The integration loads anyway, its entities appear as unavailable, and they come back on the first successful poll — within about a minute of the charger rejoining the network. Daily counters keep their value across such a restart instead of starting the day again from zero.
- A reading that steps backwards is held back for one poll. A station that has just rebooted serves
totalEnergyas0for about a minute, until the counter is read back from flash, and can report a charging current below the minimum it accepts. A single such frame is dropped instead of published: the entity keeps its previous value and the reading returns on the next poll. A value that is still low on the following poll is accepted — a genuine counter reset, or energy the station really did lose, is not hidden forever. total_energyis atotalstatistic, nottotal_increasing. The station loses the kWh it has not yet flushed to flash when it reboots, so the counter is not strictly increasing, and Home Assistant was logging a warning that pointed users at this repository. The trip meters (iem1,iem2) staytotal_increasing: those are reset on purpose, andtotal_increasingis what preserves their accumulated sum across a reset.- A device row left behind by an upgrade can be deleted. Before 0.4.0 the device was keyed by IP address; upgrading created a new row and left the old one in place with no entities. That row can now be removed from its own device page. The row the configuration entry currently owns is not deletable — remove the entry instead.
groundandgroundctrluse debounce (3 consecutive polls) to suppress transient glitches; firmware fault states bypass debounce and trigger immediately.groundctrluses value2for active (not1) — handled correctly.- The charging switch updates optimistically in the UI; the next poll confirms the actual device state.
- V1 chargers get no charging switch. That firmware has no remote-stop command at all — its own web interface has none either, and a stop written directly to the device is ignored. Whether a session is running is shown by the
statesensor. Ending a session means unplugging the car or letting a limit expire. - After a write the charger keeps serving cached values for a few seconds, so the confirming poll is deliberately delayed rather than issued immediately.
- Credentials are validated when you add or reconfigure the charger. On V2 this needs a separate request: the
/mainendpoint the integration polls answers successfully whatever the password is, so a wrong password cannot be detected on the polling path at all — only when adding or reconfiguring. V1 credentials are not verified by the integration. - All entity names are lowercase to match legacy YAML-based unique IDs and preserve automations.
- The integration ships its own icon (
brand/), shown automatically on Home Assistant 2026.3+ via the local brands proxy. On older versions the icon requires a submission to home-assistant/brands.
