diff --git a/goodwe_controller/app/main.py b/goodwe_controller/app/main.py index 2b569aa..cb71db6 100644 --- a/goodwe_controller/app/main.py +++ b/goodwe_controller/app/main.py @@ -7564,10 +7564,8 @@ class Controller: # picked on its own. At N=1 both branches are `maints[0]` and this # is the shipped call, byte for byte. # - # A PER-PACK BUTTON IS A UI CARD, NOT THIS ONE. `web.py` posts a - # bare `maint_start` with no unit, and inventing a unit parameter - # here would ship half a surface: the page would still have one - # button and the API would have two meanings. + # This is the bare request (no unit). A request naming a battery + # was handled above by `_maint_unit_action()` (MAINT-11). _m = self._maint_button(now) for msg in _m.force_start(now): self.log_event(msg, hint=messages.hint("maintenance", diff --git a/goodwe_controller/test_maint11.py b/goodwe_controller/test_maint11.py index 726ed70..102c420 100644 --- a/goodwe_controller/test_maint11.py +++ b/goodwe_controller/test_maint11.py @@ -306,6 +306,7 @@ rs = asyncio.run(serve(c, [ {"action": "maint_abort", "unit": "inverter-b"}, {"action": "maint_start", "unit": None}, {"action": "maint_abort"}, + {"action": "maint_start", "unit": ""}, ])) check("start with a unit: 200 and the unit's answer", rs[0] == (200, {"ok": True, "result": {"unit": "inverter-b", @@ -326,6 +327,9 @@ check("a null unit is the bare call: 200 and the old answer", rs[5] == (200, {"ok": True, "result": {"phase": DRAIN}})) check("a request with no unit: 200 and the old answer", rs[6] == ( 200, {"ok": True, "result": {"phase": IDLE}})) +check("an empty unit is refused (400), not taken as the bare call", + rs[7][0] == 400 and rs[7][1]["code"] == "unit" + and phases(c) == [IDLE, IDLE]) # --- the words -------------------------------------------------------------- print("\nthe words") @@ -358,6 +362,9 @@ check("the buttons are drawn only with two or more batteries", check("both buttons post the battery's name and ask first", 'JSON.stringify({ action: what, unit: b.name }) });' in JS and 'ask1("start_dialog", "maint_start")' in JS and 'ask1("abort_dialog", "maint_abort")' in JS) +check("a refusal is shown in the page's language, by its code", + 'const own = j.code && t("batteries.cycle." + j.code);' in JS + and 'toast(own ? say(own.description' in JS) check("the old header buttons still post a bare request", 'ask("maint_start", () => simple("maint_start"))' in JS and "body: JSON.stringify({ action: what }) });" in JS)