diff --git a/goodwe_controller/test_safety126.py b/goodwe_controller/test_safety126.py index 03301f1..a76f152 100644 --- a/goodwe_controller/test_safety126.py +++ b/goodwe_controller/test_safety126.py @@ -22,6 +22,8 @@ quarter's edge as on the rig. before, and names both batteries. 3. `misses_aim()` on its own. 4. The page and the "Why" on a decision within the aim. + +Mutations (MUTATION.md, purged copies) are listed in the pull request. """ import asyncio @@ -39,6 +41,7 @@ sys.path.insert(0, HERE) sys.path.insert(0, os.path.join(HERE, "tools")) import opt11p3_replay as rp # noqa: E402 +from named_absence import first, nth, present # noqa: E402 import app.main as m # noqa: E402 import app.p1 as p1mod # noqa: E402 from app import homeview, messages, peakguard, tariff # noqa: E402 @@ -335,8 +338,9 @@ for tag, onset, kw in ( print(f" notifications at {_th} s; with the fix reverted {_tb} s") check(f"{tag}: the first at the same cycle as before the fix " f"({first_h} s, {first_b} s), and none that was not raised before", - first_h is not None and first_h == first_b and _th - and _th[0] == _tb[0] and set(_th) <= set(_tb)) + first_h is not None and first_h == first_b + and present(nth(_th, 0)) and nth(_th, 0) == nth(_tb, 0) + and set(_th) <= set(_tb)) check(f"{tag}: the red peak row and its banner while it stands", any(s[4] for s in head["seen"])) @@ -392,8 +396,10 @@ _dec = peakguard.PeakDecision( def page(d): """(the peak row is red, the "Why" says peak) for decision `d`.""" _c.peak_guard, _c._peak_floor_limited = d, False - row = next(r for r in _c.checks(datetime.now(timezone.utc)) - if r["id"] == "peak_guard") + row = first((r for r in _c.checks(datetime.now(timezone.utc)) + if r["id"] == "peak_guard"), "peak row") + if not present(row): + return {"red": None}, None return dict(row, red=row["ok"] is False and not row.get("warn")), \ homeview.peak_engaged(_c) @@ -402,7 +408,7 @@ _r1, _w1 = page(_dec) _r2, _w2 = page(dataclasses.replace(_dec, within_aim=True)) check("a saturated decision: red 'Load too high' row and the 'Why' peak, " "as before", _r1["red"] and _w1) -check("...within the aim: neither", not _r2["red"] and not _w2) +check("...within the aim: neither", _r2["red"] is False and _w2 is False) _lim = dataclasses.replace(_dec, floor_w=0.0, saturated=False, floor_limited=True, soc=10.0, soc_floor_reason=peakguard.FLOOR_AT_SOC_FLOOR) @@ -410,7 +416,8 @@ _r3, _w3 = page(_lim) _r4, _w4 = page(dataclasses.replace(_lim, within_aim=True)) check("floor-limited at 0 W: the red reserve row with its banner, as " "before", _r3["red"] and "banner" in _r3 and not _w3) -check("...within the aim: no red row", not _r4["red"] and not _w4) +check("...within the aim: no red row", + _r4["red"] is False and _w4 is False) # ============================================================================ #