Skip to content

Releases: Soundistor/ha-eveus

v0.4.5

Choose a tag to compare

@Soundistor Soundistor released this 15 Sep 06:14

A maintenance release. Everything here comes from measurements on live stations: a reboot makes the charger serve a frame of readings it does not mean, and those readings were reaching Home Assistant's long-term statistics.

Fixed

  • A lifetime counter that steps backwards is no longer believed on the first frame. For about a minute after a reboot the station reports totalEnergy as 0, before the counter is read back from flash. A single poll landing in that window used to reset the daily energy baseline and make the day report the whole lifetime counter — 134 kWh in one day on a 4.2 kW station, measured. Such a frame is now held back; a value still low on the next poll is accepted, so a genuine reset, or energy the station really lost, is not hidden forever. totalEnergy, IEM1 and IEM2 are guarded.
  • A charging current below what the station accepts is no longer published. The same reboot frame can carry a currentSet the station cannot legally have been set to. It is dropped until a second poll, a full poll interval later, confirms it — and a confirmed low value is then taken as the new normal, so a station genuinely running below the minimum is reported rather than hidden.
  • The daily energy sensor no longer rolls over on a frame that carries no reading. Crossing midnight on such a frame opened the new day already holding the previous day's total.
  • A charger that is offline when Home Assistant starts no longer erases the stored firmware version. The device page kept showing the version before this; now it does again.

Changed

  • total_energy is now reported as a total statistic instead of total_increasing. The station loses the kWh it has not yet flushed to flash when it reboots, so the counter is not strictly increasing — Home Assistant was logging a state class total_increasing, but its state is not strictly increasing warning and pointing users at this repository for a bug that is not one. The trip meters iem1 and iem2 deliberately stay total_increasing: those are reset on purpose, and total_increasing is what preserves their accumulated sum across a reset.

    Note for existing installations: historical data for total_energy is not rewritten by this release, and the change is not expected to raise a repair issue — Home Assistant raises those when a state class is removed or a unit changes, neither of which happens here. Measured on the maintainer's own instance after upgrading: none appeared.

Added

  • A device row left behind by an upgrade can now 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 and no way to remove it from the UI. Such a row can now be deleted from its own device page. The row the configuration entry currently owns stays undeletable — remove the entry itself for that.

v0.4.4

Choose a tag to compare

@Soundistor Soundistor released this 01 Sep 19:24

The first stable release since 0.4.3. Most of it comes from reading the station's own firmware and from live measurements on both generations, which is why several long-standing values turned out to be wrong rather than merely imprecise.

If you have automations or dashboards referring to this integration, read the breaking changes — several of them fail silently: the trigger simply stops matching and nothing appears in the log.

⚠️ Breaking changes

V1: sensor.*_state reports different values. The state table inherited from the project this was forked from came from a V2-generation station and agreed with V1 only on two codes. Two everyday states were reported wrongly: a plugged car that is waiting (code 9) read as no_ground, and an unplugged one (code 12) read as overcurrent. Any automation written against the observed behaviour triggers on exactly those two values and stops firing after the update.

code was is now
9 no_ground waiting
12 overcurrent ready
13 overvoltage delayed_start
14 undervoltage overcurrent
15 limited_by_time overvoltage
16 limited_by_energy current_leak
17 limited_by_money station_error
18 limited_by_schedule1 overheat
19 limited_by_schedule2 locked
20 disabled_by_user no_ground
21 relay_stuck overheat_plug
22 limited_by_ai_mode undervoltage

0 (no_data) and 6 (charging) are unchanged. Codes 15, 7, 8, 10 and 11 do not exist on V1 at all, so the values the old table produced for them never arrived.

V1: the charging switch is gone. This firmware has no remote stop: sending evseEnabled=0 mid-session was tested on a live station and the charger kept charging while still reporting itself enabled. The switch could not be honoured, so it is no longer created. End a session by unplugging, or let a time/energy limit expire.

binary_sensor.*_ground is unknown while the station's protective-earth monitoring is off (groundCtrl != 1). The ground field reads 1 whether monitoring is on or off, so reporting "safe" on a SAFETY sensor was a claim we cannot make. On V1 this is a permanent state, not a window at startup — the fix is to enable ground monitoring on the station itself. Automations testing state: 'off' on this sensor stop matching; test explicitly for what you mean.

switch.*_charging reports unknown when the frame carries no evseEnabled instead of claiming "off".

eveus_session_ended now also fires for a session cut short by a power cut. A charger that loses power boots straight back into charging, so its state never changes and the interrupted session used to vanish. Two consequences if you filter on this event: ended_state may now carry an active state such as charging, which it never did before; and ended_at is the moment of detection, not of the session's death — after a long outage the two differ by hours. eveus_charging_started fires for the new session in the same case, so started/ended stay paired. This covers the charger losing power, not an outage that also takes Home Assistant down.

Renamed and re-typed sensors. leak_current is now leak_channel_raw and has lost its mA unit and its state_class: the channel's scale is unknown, and long-term statistics over a guess only lent it authority. aiVoltage lost its state_class too — it is stored configuration, not a measurement. On V2, substate 9 is now external_limit instead of waiting_for_activation.

Long-term statistics. Because of those metadata changes, Home Assistant will raise Repairs (state_class_removed, units_changed) on installations that already collected statistics. This is the recorder reacting to a deliberate change, not a fault. Home Assistant offers to drop the collected statistics or keep the old metadata — that choice is yours.

Added

  • V1: firmware version on the device page, and a Sync time button.
  • Adaptive current sensor, reported only while adaptive mode is actually on — with it off the station keeps serving a stale figure.
  • Diagnostics download, with device identifiers and credentials redacted.

Fixed

Reliability

  • The entry now loads even when the charger is unreachable; setup no longer waits for a station that is powered only while a car is plugged in.
  • Every request to the station is serialised. The firmware accepts one connection at a time and closes the existing one to make room, which was behind a long tail of timeouts and dropped connections — including whenever anyone had the station's own web page open.
  • Writes are read back correctly: the station's acknowledgement was being misread, so accepted writes on V1 looked like failures, and the post-write refresh is now deferred instead of reading stale cached values.
  • Daily energy and session-time accumulators survive restarts and unavailability.
  • A garbage value in a single field no longer fails the whole poll with a repair issue; that sensor reads unknown instead.
  • V1: numeric fields with an absent or unparseable value now read unknown rather than a confident 0.

Correctness

  • systemTime on V2 is the station's local clock, not a UTC epoch, and timeMsg == 1 means the clock is invalid rather than a real reading; on V1 it is localised to Home Assistant's timezone, not the host's.
  • A temperature below −50 is the firmware's "no sensor" sentinel, not a reading.
  • number.current_set takes its minimum from the station rather than a hardcoded constant, and is capped at 12 A on a 110 V grid.
  • Ground-fault confirmation is now truthful in both directions: a fault the station declares is reported immediately, and one inferred from the field alone needs three consecutive polls, so a missed poll no longer confirms a fault on stale data.
  • Adaptive mode is set by posting the mode alone instead of a junk parameter pair.
  • V1: a failed firmware-version read is no longer silent — it logs once when its retries run out, and its cause appears in diagnostics.

Configuration

  • Credentials are validated against a handler that actually checks them; a wrong password used to be accepted silently and simply left the firmware version blank.
  • Choosing the wrong generation (V1/V2) is rejected instead of producing a half-working entry.
  • Reconfigure no longer fails, and no longer wipes the stored password.

v0.4.4-rc6

v0.4.4-rc6 Pre-release
Pre-release

Choose a tag to compare

@Soundistor Soundistor released this 15 Aug 05:59

Pre-release for live testing on production. Not the final 0.4.4.

Fixed

  • binary_sensor.*_ground no longer claims "safe" without grounds. While the charger's PE
    monitoring is disabled (groundCtrl != 1), the sensor reports unknown instead of off. On
    V1/EnergyStar chargers PE monitoring is off in every frame observed so far, so the sensor stays
    unknown there until ground control is enabled on the charger itself. Breaking for
    automations
    matching state: 'off' on this sensor — replace with an explicit check.
  • Ground-fault confirmation is now truthful in both directions. A fault reported by the charger
    (state/subState = no ground / grounding error) raises the sensor immediately, where before it
    could never raise while ground = 1. A fault inferred only from the ground field now needs
    three consecutive polls — a missed poll restarts the counter, so the debounce no longer fires
    on a stale frame.
  • switch.*_charging reports unknown instead of "off" when a poll carries no evseEnabled
    field. No trigger for this has been observed live; this is a contract change, not a fix for a
    seen failure.
  • A garbage (non-numeric) value in state, subState or aiStatus now yields unknown for
    that one sensor instead of failing the entire poll and raising a repair issue.
  • Firmware version now reaches the device page after Home Assistant starts while the charger is
    offline, without reloading the integration.

v0.4.4-rc5 (pre-release)

Pre-release

Choose a tag to compare

@Soundistor Soundistor released this 13 Aug 14:47

Release candidate. Closes 22 findings from the 2026-08-13 code review, plus the first live measurements of the station's write behaviour.

Fixed

  • Reconfigure no longer fails, and no longer wipes the stored password. Changing the charger's IP after a DHCP change submitted an empty password field, which failed the credential check with invalid_auth — and on success would have cleared the saved password. An empty password field now means "keep the one I already have". Regression introduced by the credential check in the rc series.
  • Last Session Energy / Duration survive a restart while the charger is offline. They were restored from the entity's last state, which is unavailable whenever HA shuts down with the charger unreachable — the normal case for this device. They now persist independently of availability, like the daily counters already did.
  • Daily Energy no longer freezes at zero. Two ways in, both fixed: resetting the lifetime counter from the station's own web UI (which also zeroes totalEnergy) used to clamp the daily figure to 0 until midnight, and a missed baseline left the sensor dead for the rest of the day. The accumulated day is preserved across both.
  • A ground fault now trips the safety sensor immediately. grounding_error (V2) and no_ground (V1) were missing from the set of firmware faults that bypass debounce, so the one fault the ground sensor exists for was the slowest to confirm — up to three polls, about three minutes.
  • Clock drift over 12 hours is reported truthfully on V2. The midnight wrap-around, which is correct for V1's HH:MM:SS clock, was also applied to V2's absolute timestamp and folded a genuine 13-hour drift into "11 hours behind".
  • Firmware version on V1 is retried. A single failed read left the device page with no firmware version until the next reload — and that read fails exactly when the station has only just come back up.
  • Entities that do not need the charger stay available while it is offline. Daily Energy, Daily Session Time, Last Session Energy/Duration and the Force Refresh button serve their own values or act locally; going unavailable with the station also wiped their attributes.
  • The charging switch no longer springs back. It now holds the state you set until a poll actually agrees with it, instead of dropping it on the first poll that follows.
  • A corrupted stored value no longer stops the Daily Session Time sensor from loading.
  • eveus.set_ai_mode rejects a mode the connected generation does not have (V1 has two, V2 four) instead of sending it to the station.

Changed — please read before updating

  • The leak sensor loses its unit and its long-term statistics, and is renamed to "Leak channel (raw)". The value is the station's raw earth-leakage channel; the "mA" label came from the vendor's UI and does not match the firmware's own trip thresholds, so it was most likely wrong. State history is kept, but long-term statistics for this sensor stop. New installations get the entity id sensor.<prefix>_leak_channel_raw; existing installations keep their current entity id.
  • A password can no longer be cleared through Reconfigure. An empty field means "keep the stored password". Remove and re-add the charger if you need to drop credentials entirely.
  • Some entities no longer become unavailable when the charger is offline (see above). Automations that trigger on those entities becoming unavailable will need adjusting.

Internal

  • Test suite grown from 148 to 229 tests: new coverage for the switch, select and button platforms, all five deferred-write paths, diagnostics redaction (a missing password redaction used to leave every test green), the V2 state maps, and the device registry.
  • Firmware knowledge base updated with the first live measurements of /main key stability and the post-write settle window. Two constants that had been derived from a comment in the vendor's JavaScript are now backed by measurement.

v0.4.4-rc4 (pre-release)

Pre-release

Choose a tag to compare

@Soundistor Soundistor released this 13 Aug 09:42

Pre-release for prod verification of the 2026-08-13 offline-recovery batch.

The charger coming back online is picked up on its own

Setup no longer waits for the first poll to succeed. Previously an HA restart while the charger was offline left the config entry in SETUP_RETRY with no entities at all, and the core's retry backoff doubles to a 600 s ceiling — so a charger that rejoined the network could stay invisible for up to 10 minutes, which looked like the integration being permanently dead until it was reloaded by hand. The entry now loads regardless: entities register as unavailable and become available on the next poll, within about a minute.

Daily counters survive an offline restart

Daily Energy could restart the day at zero after an HA restart. HA writes no attributes for an unavailable entity, so the stored state carried neither the date nor the baseline, and the sensor re-anchored itself to the station's current total. The three restore-based sensors now persist their values independently of availability, with a one-time migration so no baseline is lost on upgrade.

A wrong password is now detected when adding a charger (V2)

The /main endpoint answers successfully whatever the password is — POST handlers on this firmware check no credentials at all — so the config flow accepted any password. V2 credentials are now probed against the one handler that does check them. V1 is deliberately left unverified: its auth path has never been measured, and a probe that rejected a valid password would make the station impossible to add.

Smaller fixes

  • The current-setting entity used a deprecated Home Assistant method and only worked through a fallback path; HA logged a warning about it on every setup.
  • Removed the coordinator's unreachable 401 → re-auth branch. Had it ever fired, polling would have stopped for good.
  • Stale repair issues from older versions (cannot_connect, unsuffixed device_error) are deleted at setup — one of them had been sitting in storage since June.

v0.4.4-rc3 (pre-release)

Pre-release

Choose a tag to compare

@Soundistor Soundistor released this 30 Jul 17:09

Pre-release for live testing. Everything here concerns V1 (EnergyStar) chargers; V2 behaviour is unchanged except for two shared improvements at the end.

This round is based on the V1 charger's own web interface plus live probes of a real station, so the claims below are measured rather than inferred.

Breaking

  • V1 chargers no longer get a charging switch. That firmware has no remote-stop command at all: its own web interface offers none, and a stop written straight to the device is ignored. Its evseEnabled flag also reads "enabled" at all times, so the toggle was misleading in both directions. Whether a session is running is shown by the state sensor; ending one means unplugging the car or letting a limit expire. Automations referencing the switch on a V1 charger will need updating.
  • V1 state names changed. The previous mapping was inherited from an older project whose configuration had been written against a V2-generation station. It matched a real V1 only for "no data" and "charging" — a plugged-in car was reported as No Ground and an unplugged one as Overcurrent. The state sensor now uses the enum the charger itself renders (verified live: unplugged = Ready, plugged and idle = Waiting). Codes that do not exist on V1 report Unknown instead of an invented meaning. Historical states recorded under the old names stay in the database; those readings were wrong, not the new mapping.

Fixed

  • Every write to a V1 charger failed with an error since 0.4.4-rc1, even though the charger had applied the command. V1 answers writes with an empty body, which the new response check read as a rejection. The expected acknowledgement is now per firmware generation.
  • Turning charging off on V1 silently did nothing. It now reports the limitation instead of pretending to succeed.
  • The AI mode selector sent a junk parameter (pageevent=evseEnabled&aiMode=…). It now sends aiMode alone, as the charger's own interface does.
  • Out-of-range charging currents were truncated by the charger rather than refused — a request for 999 A was stored as 231 A. Values outside 0–255 are now rejected before they are sent.
  • A value could jump back after being changed. The charger keeps serving cached data for a few seconds after a write, so the confirming poll is now deliberately delayed instead of issued immediately. Affects both generations.

Added

  • Sync Time works on V1. The write format differs from V2: this firmware stores exactly the timestamp it is given and applies no timezone of its own, so local wall-clock time is sent.
  • Firmware version for V1 chargers. V1 reports no version over the API, so it is read once at setup from the page the charger serves.
  • Adaptive Current sensor (both generations) — the current the adaptive algorithm is actually allowing, next to the requested setpoint. Reports nothing while adaptive mode is off, where the underlying field keeps a stale figure.

v0.4.4-rc2 (pre-release)

Pre-release

Choose a tag to compare

@Soundistor Soundistor released this 27 Jul 13:25

Pre-release for live verification only — not a general update. Builds on v0.4.4-rc1 (already smoke-tested: write path, request serialization, V2 clock offset) and adds the remaining ten fixes from the 2026-07-27 API analysis.

New in this rc

  • timeMsg == 1 (station clock invalid, typically a dead RTC backup battery) now blanks systemTime instead of publishing a garbage reading.
  • number.current_set minimum now comes from the station's minCurrent instead of a hardcoded constant that no longer matched the device after a firmware update.
  • Absent temperature sensor (< -50 °C sentinel) now reads unknown instead of a permanent -60 °C.
  • V2 substate 9 renamed waiting_for_activationexternal_limit — it actually means the current is under external/OCPP control, the opposite of what the old name implied.
  • aiVoltage (a stored threshold, not a live measurement) moved to Diagnostics and no longer collects statistics.
  • Diagnostics now redacts stationId and STA_IP_Addres in addition to the serial numbers already redacted.
  • sw_version no longer carries the firmware's trailing space.
  • Debounce now applies only to safety sensors — groundCtrl (a config flag) reacts on the first poll instead of being delayed by up to three.
  • Config flow now rejects a mismatched V1/V2 model choice instead of silently corrupting every measurement.
  • Current ceiling capped at 12 A when the station reports a 110 V grid (gridRange == 1) — latent on our own 230 V hardware, added for correctness.

Rollback

HACS → Eveus Charger → ⋮ → Redownload → v0.4.3.

v0.4.4-rc1 (pre-release)

Pre-release

Choose a tag to compare

@Soundistor Soundistor released this 27 Jul 11:45

Pre-release for live verification only — not a general update. It carries the three critical fixes from the 2026-07-27 API analysis so they can be confirmed on real hardware before 0.4.4 ships.

Fixes

Every write raised an error after the charger had already applied it. /pageEvent never answers JSON — a successful write returns the plain text OK, and a refusal returns plain text too, always with HTTP 200. The response was parsed as JSON, so setting the current, toggling charging, changing the AI mode and syncing the clock all showed "Failed to perform the action" with a traceback even though the charger had accepted the command. The exception also aborted the follow-up refresh, so the new value only appeared with the next scheduled poll. Present since v0.2.0.

(Note: this tag replaces an earlier v0.4.4-rc1 that checked for the wrong success body — static firmware analysis suggested mainPost successfully, but a live test on real hardware showed the station actually replies OK. If you installed the previous rc1, please update again — it still raised on every write.)

Requests to the charger are now serialized. The station serves exactly one connection: a second one is not queued or refused, it closes the session already in use. A poll overlapping a write therefore broke both, and any other client (the charger's own web UI polls once a second) could kill a pooled socket and take the next request down with it. All reads and writes now pass through a single lock.

V2 clock offset. systemTime is the station's local wall clock encoded as an epoch (UTC + timeZone*3600), not an absolute UTC epoch. Decoding it as UTC made the time-drift sensor report a permanent offset equal to the configured timezone on a perfectly healthy clock. The write direction was already correct and is unchanged. Confirmed live: Time Drift reads 0.00s.

Rollback

HACS → Eveus Charger → ⋮ → Redownload → v0.4.3.

v0.4.3

Choose a tag to compare

@Soundistor Soundistor released this 17 Jul 17:54

Fixed

  • Repair issues are now per-charger and name the device — in a multi-charger setup, one charger recovering no longer clears another charger's error notification.
  • Re-authentication now distinguishes a wrong username/password (prompts you to re-enter credentials) from a charger that is simply unreachable.
  • The "session ended" event and the Last Session sensors are no longer lost when a charging session ends during a brief network hiccup, and a stale event is no longer replayed after a long offline period.

Changed

  • The charging-current control's maximum now follows the charger's reported hardware limit instead of a fixed 32 A.
  • Session Energy statistics keep their reset point across Home Assistant restarts.
  • Logs and the update coordinator now carry the device name, making multi-charger setups easier to read.

Under the hood

  • The integration now uses Home Assistant's shared HTTP session, shares a single entity base class across all platforms, and stores its runtime data on the config entry (modern typed pattern).
  • Added a full automated test suite (coordinator, config flow, sensors, golden/snapshot) and ruff linting to CI.

v0.4.2

Choose a tag to compare

@Soundistor Soundistor released this 17 Jul 14:17

Added

  • Session lifecycle events — the integration now fires eveus_charging_started and eveus_session_ended on the Home Assistant event bus, so automations (notifications, energy logging, etc.) can trigger on charging start/finish without polling. eveus_session_ended carries the session's final energy_kwh, duration_s, ended_state, and ended_at. Filter by entry_id / device_name if you run more than one charger.
  • Last Session sensorslast_session_energy (kWh) and last_session_duration (s) freeze the previous completed session's final figures and keep them until the next session ends. They survive Home Assistant restarts. The charger clears its live session counters the moment the next session begins, so these sensors preserve numbers that would otherwise disappear.

Fixed

  • Dynamic polling now actually speeds up while charging — a state-string case mismatch meant the coordinator always polled at 60 s; it now correctly polls every 30 s during an active charging session and 60 s otherwise.

Documentation

  • README now links the external HTTP API reference, Soundistor/eveus-api-doc.
  • README (English + Ukrainian) documents the new events and Last Session sensors.