MAINT-13 round 2: gate open when nothing holds the charge back; safety93 scenario restored
- gate_open is true with no price gate set up, in a cheap window, or while the pack is taking charge; the stall rule and timeout now work on a no-tariff site. - reset the save timer on a phase change; exact 5 min gap-cap test. - test_safety93: original timeout scenario kept (B finished) plus a case where a due B takes the slot after A's failure. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
28eff568b5
commit
6f05b2e4be
@@ -3875,6 +3875,22 @@ class Controller:
|
||||
inv.refusal_note())]
|
||||
if n]
|
||||
|
||||
def _charge_gate_open(self, inv) -> bool:
|
||||
"""MAINT-13: may this pack charge now, for the maintenance timeout?
|
||||
|
||||
True when no price gate is set up (no price entities, no fixed tariff:
|
||||
nothing holds the charge back), in a cheap window, or while the pack is
|
||||
really taking charge (sun outside cheap hours). Closed only when a gate
|
||||
exists, it is shut, and the pack is not charging.
|
||||
"""
|
||||
o = self.o
|
||||
gated = bool((o.get("price_now_entity") and o.get("price_avg_entity"))
|
||||
or o.get("static_profile"))
|
||||
if not gated or self.cheap:
|
||||
return True
|
||||
batt = inv.batt
|
||||
return batt is not None and float(batt) <= -MAINT_CHARGING_W
|
||||
|
||||
async def cycle(self) -> None:
|
||||
"""Gather claims, resolve precedence, write the winner.
|
||||
|
||||
@@ -3923,10 +3939,10 @@ class Controller:
|
||||
if blocked is None:
|
||||
maint_results.append(MaintResult(IDLE, False, None, False, []))
|
||||
continue
|
||||
# MAINT-13: the charge timeout counts only the minutes the price
|
||||
# gate (`self.cheap`) let the pack charge.
|
||||
# MAINT-13: the charge timeout counts only the minutes the pack was
|
||||
# allowed to charge (see `_charge_gate_open`).
|
||||
res = machine.tick(now, inv.soc, blocked_by=blocked,
|
||||
gate_open=bool(self.cheap))
|
||||
gate_open=self._charge_gate_open(inv))
|
||||
for msg in res.events:
|
||||
self.log_event(msg, hint=messages.hint(
|
||||
"maint_failed" if res.failed else "maintenance",
|
||||
@@ -7387,6 +7403,10 @@ class Controller:
|
||||
return None
|
||||
|
||||
|
||||
# MAINT-13: a battery power reading at or below minus this many W is a pack
|
||||
# that is taking charge.
|
||||
MAINT_CHARGING_W = 50.0
|
||||
|
||||
# SAFETY-61. Exit status when the control task dies; 70 is sysexits(3)
|
||||
# EX_SOFTWARE. See DECISIONS/SAFETY-61-control-task-death.md.
|
||||
EXIT_CONTROL_DIED = 70
|
||||
|
||||
Reference in New Issue
Block a user