app/drivers.py holds one Driver per roster entry (configured, actuator_id, limits, read, write, release, probe, link_stale_s, batt_bound, settle_s, brand, words). GoodWeEsphomeDriver makes the calls the code it replaced made, in the same order. Inverter gets driver; has_writer, is_live and link_note read it. The SoC/power read, the write, the device range (run_control, amain, the settings panel), rule 2 per unit and the SAFETY-28 census go through it. setpoint_entity is optional per entry beside driver, host, port, unit_id and maintenance; only goodwe_esphome is selectable, the rest are checked and unused. Co-Authored-By: Claude <noreply@anthropic.com>
2.3 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 driver binds its Home
Assistant on first use by the Controller, so a unit added later is wired too.
Schema. setpoint_entity is optional per entry (rule 9(d) still requires
it for GoodWe, with the same sentence), 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.