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 -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