Owner decision 2026-11-07: clients see nothing new until SMA-4. config.yaml, translations, labels and the page layout are back to 23ff9d0's. The validation of the keys stays for callers that skip the schema. Co-Authored-By: Claude <noreply@anthropic.com>
3.4 KiB
SMA-2 - each inverter is reached through a driver
Status: for review. Tests: test_sma2_driver.py. Source: SMA-9 report
section 1.1. A pure refactor: no behaviour change for GoodWe, no change to a
command, a log line or a sentence the add-on shows.
Every place that read or steered an inverter used the GoodWe ESPHome entities
directly, so a second make meant touching all of them. app/drivers.py now
holds one Driver per roster entry (Inverter.driver): configured(),
actuator_id(), limits(), read(), write(), release(), probe(), and
link_stale_s, batt_bound, settle_s, brand, words. GoodWeEsphomeDriver
makes the same calls in the same order as the code it replaced; its
release() is write(0).
Moved to the driver: the SoC and power read (_read_unit), the write
(_write_unit, still under the SAFETY-28 gate, the clamp, shadow mode and the
write budget), the device range (run_control, amain, the settings panel),
liveness and its window (has_writer, is_live, link_note), the freshness
bound, the status rows' "is a source set" test, rule 2's per-unit range check
and SAFETY-28's census. Not moved: the clamp, the gate, the heartbeat and
command_site_zero(); stop is still 0 W for every unit, and nothing calls
release() yet (SMA-10). settle_s and the control constants are not read
from the driver yet either: with only GoodWe they would change nothing.
The seam is not TCP-shaped. The census asks each entry's driver for its
actuator id: the setpoint entity for GoodWe, host:port:unit_id for a driver
reached over a socket, so two units behind one gateway are two actuators and
one unit named twice is the SAFETY-28 refusal. The census still counts every
setpoint_entity key as before and adds the driver's own actuator to it (parity
with 23ff9d0 on 349 option shapes is a test). The driver binds its Home
Assistant on first use by the Controller, so a unit added later is wired too.
Schema, and why the new keys are not in it. The brief asks for
driver, host, port, unit_id, maintenance per entry and for
setpoint_entity to become optional. Owner decision 2026-11-07: clients see
nothing new until SMA-4/SMA-7 use the keys. The Supervisor form shows every
schema key (and marks required ones), and a nested entry with a key the schema
lacks has that key silently dropped (measured, shape probe section K), so the
only way to hide them is to keep them out of config.yaml. So for now config.yaml, the
translations and the labels are exactly 23ff9d0's, and setpoint_entity stays
required there: until a driver without one is selectable, no entry can lack it.
The code underneath is the brief's: the driver defaults to goodwe_esphome,
rule 9(d) is per driver (a GoodWe entry without a setpoint entity is refused,
same sentence), and rule 9(h) checks driver, host, port, unit_id,
maintenance when a caller that skips the schema (the panel's save path,
sim/inject, the checks) supplies them; those sentences name the key, having no
label. When SMA-4 needs them: add them to the schema as optional with
translations, make setpoint_entity str?, and add them to uilayout as card
fields or a hidden list.
Checked against 23ff9d0: replay digests and a log of every Home Assistant
call are byte-identical at N=1 and N=2; the TEL-07 announce diff is 0/0/0; a
fake driver beside a GoodWe unit allocates, grades, drops and publishes per
unit; a call site that goes round the seam is caught.