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>
56 lines
3.4 KiB
Markdown
56 lines
3.4 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, 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.
|
|
|