MAINT-20 part 1 review: restore three lost lines, rewrap ragged comments
Comment, docstring and DECISIONS only (same-code script OK; python -OO bytecode now identical for all six files). - peakguard.charge_room_w: one-line docstring + SAFETY-125 pointer (cut whole). - peakguard.shaping_suspended: keep 'the one place this conjunction is written; do not inline it'. - price_forecast module note: an hour with no price and no yesterday is left out, never filled (test_price.py 14d cites the module note for it). - Refill comment blocks the cut left ragged; DECISIONS pointers on one line. - FCST-04 note: _yesterday_of(), not _previous_day(); FCST-03 note: the 49 stronger cases are why the rule is a real change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bdqr7PiaHcBnzPituu2yTC
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6e2fde63ff
commit
63dda4b0d3
@@ -29,8 +29,7 @@ FLOOR_AT_SOC_FLOOR = "the battery level is at or below the peak reserve"
|
||||
SOURCE = "peak"
|
||||
|
||||
# Mirror of config.yaml's peak options, pinned to the file by
|
||||
# test_peakguard.py.
|
||||
# Not a read: `decide()` takes them as arguments.
|
||||
# test_peakguard.py. Not a read: `decide()` takes them as arguments.
|
||||
PEAK_OPTION_DEFAULTS = {
|
||||
# Percent a forced discharge may not go below. 20 is derived from the
|
||||
# reference pack, 300 Ah at 51.2 V with DoD 90 - 13.8 kWh usable (a test
|
||||
@@ -42,8 +41,7 @@ PEAK_OPTION_DEFAULTS = {
|
||||
# SAFETY-79. Watts the guard aims under `peak_cap_w`.
|
||||
"peak_margin_w": 50,
|
||||
}
|
||||
# SAFETY-79. Range of `peak_margin_w` in config.yaml, pinned by
|
||||
# test_peakguard.py.
|
||||
# SAFETY-79. Range of `peak_margin_w` in config.yaml; test_peakguard.py pins it.
|
||||
PEAK_MARGIN_RANGE_W = (0, 500)
|
||||
|
||||
|
||||
@@ -75,8 +73,8 @@ class PeakDecision:
|
||||
held: tuple = ()
|
||||
able_w: float | None = None
|
||||
# SAFETY-126: power is wanted but the quarter still ends within
|
||||
# ALARM_MISS_W
|
||||
# of the aim with the batteries at 0 W (`misses_aim()`). Set by main.py.
|
||||
# ALARM_MISS_W of the aim with the batteries at 0 W (`misses_aim()`). Set
|
||||
# by main.py.
|
||||
within_aim: bool = False
|
||||
|
||||
def explain(self) -> str:
|
||||
@@ -422,6 +420,9 @@ def charge_headroom_w(decision) -> float | None:
|
||||
|
||||
|
||||
def charge_room_w(decision, projection) -> float | None:
|
||||
"""SAFETY-125: `charge_headroom_w()` less the unread seconds counted at the
|
||||
last reading, so a late reading is not room for a grid charge.
|
||||
DECISIONS/SAFETY-125-grid-charge-under-the-month-peak.md."""
|
||||
room = charge_headroom_w(decision)
|
||||
if not room or projection is None or projection.block_start is None:
|
||||
return room
|
||||
@@ -437,7 +438,9 @@ def shaping_suspended(decision, peak_forecast_w, cap_w) -> bool:
|
||||
Crossing limits resolve to 0 W, so the rule is suppression, not priority.
|
||||
Both terms are needed: the forecast entity is empty on a default install,
|
||||
where the measured guard fires. Dropping either parks the battery in the
|
||||
billed quarter (test_peakguard.py part 7). DECISIONS/SAFETY-07-peak-guard.md."""
|
||||
billed quarter (test_peakguard.py part 7). The one place this conjunction is
|
||||
written, public so the test grades the shipped expression: do not inline it.
|
||||
DECISIONS/SAFETY-07-peak-guard.md."""
|
||||
if peak_at_risk(peak_forecast_w, float(cap_w)):
|
||||
return True
|
||||
return decision is not None and decision.engaged
|
||||
|
||||
Reference in New Issue
Block a user