SMA-2 round 2: keep the driver keys out of the schema, translations and labels
checks / unit (pull_request) Successful in 23m13s
infra-pin / fresh (pull_request) Successful in 1s

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>
This commit is contained in:
glenn schrooyen
2026-11-07 13:09:31 +01:00
co-authored by Claude
parent 0b20f53cf8
commit c015230452
13 changed files with 79 additions and 154 deletions
-10
View File
@@ -1683,11 +1683,6 @@ LABELS = {
"capacity_kwh": "Usable battery capacity",
"inverters": "Inverter list",
"name": "Name",
"driver": "Inverter type",
"host": "Inverter address",
"port": "Inverter port",
"unit_id": "Inverter unit number",
"maintenance": "Battery maintenance",
"meter_source": "Where the meter reading comes from",
"meter_phases": "Number of phases",
"p1_host": "HomeWizard P1 address",
@@ -1769,11 +1764,6 @@ LABELS_NL = {
"capacity_kwh": "Bruikbare capaciteit",
"inverters": "Lijst met omvormers",
"name": "Naam",
"driver": "Type omvormer",
"host": "Adres van de omvormer",
"port": "Poort van de omvormer",
"unit_id": "Eenheidsnummer van de omvormer",
"maintenance": "Onderhoud van de batterij",
"meter_source": "Waar de meterstand vandaan komt",
"meter_phases": "Aantal fasen",
"p1_host": "Adres van de HomeWizard P1",
-13
View File
@@ -302,19 +302,6 @@ DERIVED = {
HIDDEN: dict = {"price_service_token": "a secret, set on the Configuration tab"}
# SMA-2. Per-entry keys of the inverter list the page never shows. They pick and
# address an inverter driver, only `goodwe_esphome` is selectable, and nothing
# reads the other four yet. An entry's keys the page does not draw travel
# through a save as stored (uimodel._roster_decode keeps the whole entry).
ROSTER_HIDDEN: dict = {
"driver": "only goodwe_esphome for now; empty means that",
"host": "not read yet",
"port": "not read yet",
"unit_id": "not read yet",
"maintenance": "not read yet",
}
def fields():
"""Every field once, in page order, roster fields after `inverters`."""
for group in GROUPS:
+10 -4
View File
@@ -814,6 +814,12 @@ def _whole(raw, lo: int, hi: int):
def _driver_problems(entry: dict, who: str) -> list[str]:
"""Rule 9(h) (SMA-2): the keys that choose and address an inverter driver.
NOT IN config.yaml's SCHEMA, so the Supervisor form and its validator never
see them (owner decision 2026-11-07: clients see nothing new until SMA-4).
They can still reach this rule from callers that skip the schema (the
panel's save path, sim/inject, the checks), so they are graded here, and
named by key because they have no label.
Only `goodwe_esphome` is selectable for now. `host`, `port`, `unit_id` and
`maintenance` are accepted and checked for shape, and nothing reads them
yet: a later driver's entry must not be refused for carrying them.
@@ -822,21 +828,21 @@ def _driver_problems(entry: dict, who: str) -> list[str]:
raw = entry.get("driver")
if raw not in (None, "") and str(raw).strip() not in drivers.SELECTABLE:
out.append(
f"{who} has {S('driver')} {messages.shown(raw)}. Use "
f"{who} has `inverters.driver` {messages.shown(raw)}. Use "
f"{', '.join(drivers.SELECTABLE)}, or leave it empty.")
host = entry.get("host")
if host not in (None, "") and (not isinstance(host, str)
or re.search(r"\s", host.strip())):
out.append(f"{who} has {S('host')} {messages.shown(host)}, which is "
out.append(f"{who} has `inverters.host` {messages.shown(host)}, which is "
"not an address. Use a name or an IP address.")
for key, lo, hi in (("port", 1, 65535), ("unit_id", 0, 247)):
val = entry.get(key)
if val not in (None, "") and _whole(val, lo, hi) is None:
out.append(f"{who} has {S(key)} {messages.shown(val)}. Use a "
out.append(f"{who} has `inverters.{key}` {messages.shown(val)}. Use a "
f"whole number from {lo} to {hi}.")
maint = entry.get("maintenance")
if maint is not None and not isinstance(maint, bool):
out.append(f"{who} has {S('maintenance')} {messages.shown(maint)}. "
out.append(f"{who} has `inverters.maintenance` {messages.shown(maint)}. "
"Use on or off.")
return out