Files
goodwe-addon/goodwe_controller/DECISIONS/SMA-2-driver-seam.md
T

49 lines
3.0 KiB
Markdown

# 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.** The brief says "`setpoint_entity` becomes optional" (SMA-2, "Schema per
inverter entry"; SMA-9 section 1.1): it is the GoodWe driver's own key, so a
driver reached by host and port has none. `setpoint_entity` is optional per entry
in config.yaml; rule 9(d) still refuses a GoodWe entry without it, with the same
sentence (`test_sma2_driver.py` part 6), beside `driver` (only `goodwe_esphome`),
`host`, `port`, `unit_id`, `maintenance`. The last four are checked for shape
and not read. The Supervisor shape probe was re-run (section K).
**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.
**Per-entry keys the page does not draw** are listed in `uilayout.ROSTER_HIDDEN`;
test_uilayout and test_sma2_driver fail for a key that is neither a card field
nor hidden, and a save through the page keeps them (a test).