Releases: xchillxx/surplus-load-switch
Release list
v1.13.0
Fixed
- The base_load calculation now accounts for house-load sensor lag right after a managed device's on/off state changes. Cloud-polled load sensors (e.g. FusionSolarPlus) can keep reporting the pre-transition total for several minutes -- since managed_power_kw already reflects the device being off, subtracting it from that still-stale total misattributed the device's own lingering reading to "base load", spiking it and tanking available surplus until the sensor caught up. Confirmed against real data: this caused a device to be shed for ~9 minutes right after a windowed device's (e.g. pool pump) daily schedule cutoff -- not an occasional glitch, this happened every evening. For a fixed 6 minutes after any managed device's composition changes, the pre-transition power figure is now used for this calculation instead of the fresh one.
v1.12.0
Changed
- Power-measurement averaging now uses a window of 24 hours of active (ON) runtime instead of 3 calendar days. A weather-dependent device (e.g. a pool heat pump) that sits idle for several rainy days no longer has its entire sample history age out and fall back to the configured static estimate right when it starts running again -- idle periods simply don't touch the buffer, so real historical samples stay valid until the device runs again and fresh ones replace them.
v1.11.1
Fixed
- The battery projection (
_project_energy_kwh/_hours_until_depleted, used by both the switching decisions and the Akku-reicht display) was double-counting the household's deficit whenever available surplus was negative (base load alone exceeding solar -- common at dusk/night).available_surplusis now floored at 0 before subtracting, matching the pattern already used formanaged_discharge_kw. Verified against a live scenario with 0 committed devices and negative surplus: projection went from ~7.8h to the correct ~16.3h.
v1.11.0
Fixed
- The discharge-rate smoothing used to compute base_discharge_kw (feeding both the switching decisions and the Akku-reicht/Modus display) now resets whenever the set of currently-on managed devices changes, instead of carrying up to 20 minutes of pre-transition history across the change. A managed device turning on/off is a real, immediate, known composition change, not the kind of external noise (stove, kettle) the 20-minute median is meant to filter -- previously it could take up to 20 minutes after e.g. a windowed device's cutoff before the freed-up battery margin was reflected.
v1.10.1
Fixed
- "Akku reicht" and the Modus sensor now use the same time-window-aware projection the actual switching decisions are based on, instead of a flat avail_kwh / current-discharge-rate division. Previously this diagnostic could look like a battery shortfall right up until a windowed device's (schedule/time window) cutoff, even though the real per-device logic already accounted for that device dropping out of the load.
- Corrected the "gemessen (7 Tage)" power-measurement data-source label to "3 Tage", stale since the averaging window was shortened in v1.10.0.
v1.10.0
Fixed
- Entities no longer flash "unavailable" when a core sensor (solar/load/SOC/battery) briefly blips.
availablenow depends only on the coordinator having data at all, not on the last cycle having succeeded -- the last-known values (including should_be_on) stay visible the whole time, as originally intended by the v1.7.1 sensor-outage safety mechanism.
Changed
- Devices that cross their off-threshold in the same cycle (e.g. a sudden drop in solar) no longer switch off simultaneously. The off-hold wait time is now staggered by priority rank -- 1 minute shorter per rank below the highest, down to a 1-minute floor -- so the lowest-priority device sheds first.
- The power-measurement averaging window is now 3 days instead of 7, so devices with weather-dependent draw (e.g. a heat pump) reflect current conditions faster.
v1.9.2 — Critical fix: coordinator crash with schedule.* devices
Critical fix: v1.9.0's time-window-aware battery projection crashed the coordinator on every update cycle for any install using a schedule.* helper on a device — all integration sensors went unavailable while the real controlled devices kept running untouched (no switching happened at all, since the coordinator never produced fresh data).
Root cause: the schedule helper's next_event attribute is a native datetime object on the in-memory state (only the REST/websocket APIs serialize it to a string, which is what made it look like a plain string during testing). Calling dt_util.parse_datetime() directly on that datetime raised TypeError: argument must be str every cycle.
Fixed by accepting either a datetime or a string. Same defensive handling applied to sun.sun's next_rising attribute, which had the identical latent risk.
If you're on v1.9.0 or v1.9.1 and your dashboard shows "unavailable"/"nicht verfügbar" for the surplus/battery sensors, update to this version and restart.
v1.9.1 — Expose real should-be-on decision for dashboards
New attributes on each device's power-tracking sensor: sollte_an_sein (the cascade's current on/off target for that device) and korrekt_geschaltet (whether the real device state matches it).
Dashboards previously had no choice but to reimplement an approximation of the switching logic to show "is this device correctly on/off" — which drifts out of sync as the real logic grows more sophisticated (per-device forward-looking battery check, dependencies, time windows, minimum runtime). Confirmed this actually happened on a real install: a hand-written dashboard formula said a device "should be on" for 3 hours overnight while the real coordinator had correctly kept it off, because the dashboard's simplified formula didn't know about the newer per-device projection logic.
These attributes are computed directly from the same should_on/should_off values the coordinator actually acts on, so a dashboard status card can read the real verdict instead of guessing.
v1.9.0 — Time-window-aware battery projection
The overnight battery projection is now time-window-aware. Previously every committed device was assumed to keep drawing its predicted power all the way to solar start, even one with a known schedule/window cutoff (e.g. a pool pump that stops at a fixed time regardless of battery state) — making lower-priority devices' projections needlessly pessimistic after that cutoff.
The projection is now piecewise: each committed device carries its own effective cutoff — a schedule.* helper's next_event while it's on, a window_end time, or inherited from a prerequisite device it depends on (the earliest of these wins) — and drops out of the projected load at that point instead of being assumed to run the full remaining horizon.
With no time windows/schedules configured at all, this reduces to exactly the previous constant-rate calculation — no behavior change for simple setups. Verified against the old formula plus three cutoff scenarios (single cutoff, dependency-inherited cutoff, cutoff beyond the projection horizon) before release.
Each device's power-tracking sensor also gains a naechster_cutoff attribute showing the cutoff time used in its own projection, if any.
v1.8.3 — Fix hassfest validation (recorder dependency)
Declares 'recorder' as an after_dependency in manifest.json, fixing a hassfest validation failure. The solar-offset calibrator already handled recorder being unavailable gracefully (falls back to configured/default offsets) — this just makes the dependency relationship explicit so Home Assistant loads recorder first when present. No behavior change.