SMA-10: two idle states, hold 0 W or hand the inverter back
A driver now says whether its release() hands the inverter back (Driver.hands_back; GoodWe is False, so release() stays write(0) and the Controller never calls it). command_site_release() sits next to command_site_zero(): the Stop button and shutdown() (so SIGTERM, restart, control task death and a late config refusal) hand a hand-back unit back, once, and zero every other unit as before. Safety stops and refusals still hold 0 W for every unit. Shadow mode releases a hand-back unit. After a release nothing is written to the unit (heartbeat and cycle included) until control starts again. release() is bounded by RELEASE_BUDGET_S (= the write budget), runs concurrently per unit, and a raising or hanging release on one unit does not stop the others. The "set to 0 W" sentences for Stop, restart, shadow mode and the stopped banner are built from the roster (app/handback.py, EN and NL, words from the driver); a GoodWe-only roster keeps every old literal. A handed-back unit shows "Back under <its control>" on Home. Existing test edited: test_messages.py (two classification entries for the CRITICAL line that moved into a roster builder, and the new release bound). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
57c8d1b912
commit
a1be9c48b3
@@ -77,7 +77,13 @@ class Driver:
|
||||
writer_key = ""
|
||||
#: the brand word the per-driver sentences and device names use
|
||||
brand = ""
|
||||
#: per-driver sentences (SMA-10 and later). Empty until a caller needs one.
|
||||
#: SMA-10. Does `release()` give the inverter BACK to something that steers
|
||||
#: it by itself (SMA energy management)? False: `release()` is `write(0)`,
|
||||
#: the add-on goes on holding 0 W, and the Controller never calls it.
|
||||
hands_back = False
|
||||
#: per-driver sentences. A driver that hands back says whose control the
|
||||
#: unit returns to: `{"back": "SMA control", "back_nl": "de sturing van SMA"}`
|
||||
#: ("goes back to SMA control"). Missing words fall back to a plain phrase.
|
||||
words: dict = {}
|
||||
#: how long all-rejected writes last before the unit stops being live
|
||||
link_stale_s = GOODWE_LINK_STALE_S
|
||||
@@ -145,7 +151,13 @@ class Driver:
|
||||
raise NotImplementedError
|
||||
|
||||
async def release(self) -> bool:
|
||||
"""Stop steering this inverter. For a driver with nothing better, 0 W."""
|
||||
"""Stop steering this inverter. For a driver with nothing better, 0 W.
|
||||
|
||||
SMA-10. Only a driver with `hands_back = True` has this called by the
|
||||
Controller, and only when the add-on goes away (Stop, shutdown, restart,
|
||||
task death) or sits in shadow mode. After it the Controller writes
|
||||
nothing more to the unit until control starts again. A safety stop is
|
||||
never a release: that is `write(0)`."""
|
||||
return await self.write(0.0)
|
||||
|
||||
async def probe(self) -> Probe:
|
||||
@@ -159,7 +171,8 @@ class GoodWeEsphomeDriver(Driver):
|
||||
A transcription of what `main.py` and `selfconfig.py` did inline: `limits()`
|
||||
is `hass.limits(setpoint)`, `read()` is `hass.number(soc)` then
|
||||
`hass.number(batt, invert)`, `write()` is `hass.set_number(setpoint, w)`.
|
||||
`release()` is `write(0)`: the board's own watchdog is what hands back.
|
||||
`release()` is `write(0)` and `hands_back` is False: the board's own watchdog
|
||||
is what hands back, so after Stop the unit keeps its 0 W write and heartbeat.
|
||||
"""
|
||||
|
||||
name = DEFAULT_DRIVER
|
||||
|
||||
Reference in New Issue
Block a user