MAINT-11: start or stop the maintenance cycle per battery
checks / unit (pull_request) Successful in 38m46s
infra-pin / fresh (pull_request) Successful in 1s

maint_start and maint_abort take an optional unit. With two or more batteries
each Batteries card has Start cycle and Stop cycle buttons. One slot per site
stays: a start while a battery cycles is refused and names it (no queue). A
battery that is switched off, an unknown unit, and a stop on a battery that is
not cycling are refused with a plain message. A request with no unit is the
old call. The scheduler and the phase machine are unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
This commit is contained in:
glenn schrooyen
2026-10-13 21:37:36 +02:00
co-authored by Claude
parent 79dd0770f9
commit 21d8a944bc
9 changed files with 521 additions and 1 deletions
+10
View File
@@ -60,6 +60,8 @@ _LOG = logging.getLogger("goodwe.web")
# OPT-11: the per-battery actions, which name a battery and a value.
PACK_ACTIONS = ("pack_use", "pack_mode", "pack_sell")
# MAINT-11: start or stop one battery's maintenance cycle (the unit is optional).
MAINT_ACTIONS = ("maint_start", "maint_abort")
# UX-13 P1: the page lives in app/static/ as three files - index.html,
# app.css, app.js - plus the page words from app/ui_text/<lang>.json (English
@@ -163,6 +165,14 @@ def build_app(controller, selfcfg=None) -> web.Application:
return web.json_response({"ok": False,
"error": result["error"]},
status=400)
elif what in MAINT_ACTIONS and body.get("unit") is not None:
# MAINT-11: one battery's cycle. No unit = the old bare call below.
result = await controller.handle_action(what, unit=body["unit"])
if isinstance(result, dict) and "error" in result:
return web.json_response(
{"ok": False, "error": result["error"],
"code": result["code"], "unit": result["unit"]},
status=409 if result["code"] != "unit" else 400)
else:
result = await controller.handle_action(what)
if result is None: