Skip to content

v1.0.15

Choose a tag to compare

@github-actions github-actions released this 09 May 04:53
v1.0.15
8fac04e

Fixed

  • Entity-mode force-charge / force-discharge / export-limit writes now respect the target entity's unit_of_measurement (D-056). When running in entity mode (typically against foxess_modbus), the integration writes power commands via number.set_value to user-configured target entities. Every power entity published by foxess_modbus declares unit_of_measurement: "kW" with min: 0, max: 15 (values 0–15 kW). Previous releases wrote raw watts (e.g. 10500 for 10.5 kW) into these targets; foxess_modbus clamped every such write to its declared max of 15, so force-charge / force-discharge / export-limit all ran at the clamp ceiling (15 kW) regardless of what the pacing algorithm requested — the user had no effective control. Fix: FoxESSEntityAdapter now routes every power write through a new _convert_and_clamp_power_for_write helper, which reads the target's unit_of_measurement + min + max attributes, converts watts via HA's PowerConverter, and clamps to the declared range. Missing or unrecognised units pass through unchanged with a visible warning (so a 1000× misconfiguration can't be silent); over-max requests are clamped with a warning so the user sees when pacing is capped by the target's declared max. Non-power writes (SoC percent, work-mode select) are untouched. Cloud mode — which writes fdPwr in watts natively via the FoxESS Open API — is unaffected. Nine-test regression suite in tests/test_entity_mode_write_units.py drives the real FoxESSEntityAdapter against a foxess_modbus-shaped number entity (kW/W/missing-unit) covering charge, discharge, export-limit, and a guard that the min_soc percent write is never re-scaled. Restores pacing control for every entity-mode user — the algorithm's decisions now actually take effect on the inverter.

Reverted

  • Attempted "no-solar dashboard fallback" feature withdrawn. Three pre-release iterations (beta.1 Gen Load swap → beta.2 20-min timeout → beta.3 hide-by-default) tried to replace the stuck-zero solar reading on AC-coupled / unwired-PV installs with something more useful. Each iteration exposed a fresh way the dashboard surface fell short — the Gen Load swap duplicated what the House box already shows, the timeout kept the display honest overnight but didn't fix duplication, and hide-by-default added nothing beyond what boxes: config already offered. Reverted to v1.0.14 behaviour: the four-box overview card renders unconditionally; users who want to hide the solar box on a non-solar install can use the existing boxes: config. The full solar-seen plumbing was removed as dead code; D-052 is marked [RETIRED] in the knowledge tree with the three-pivot story preserved in docs/knowledge/META.md (2026-05-08).

Test infrastructure

  • Page-fixture predicate hardened against the entity-mode init race (C-031). tests/e2e/conftest.py::_wait_for_lovelace_panel previously gated the final-stage settled signal on main.hass.connected === true (a live JS property) alongside the hui-root DOM check. Under entity-mode CI, the heavier state-change burst from input-helper polling could transiently flap connected=true→false→true across multiple Playwright polls and exhaust the 75 s budget. hui-root's presence is strictly stronger: once mounted, the Lit render that produced it required both panel.hass and main.hass.connected to be true at render time, and the DOM fact survives runtime flaps of either property. Final-stage predicate now settles on hui-root alone. Four new unit tests in tests/test_e2e_page_fixture.py::TestWaitForLovelacePanelEntityModeInitRace extract the predicate string from conftest, evaluate it in real Node.js against an adversarial entity-mode DOM snapshot (panel mounted, hui-root present, connected=false), and assert it returns truthy.