Skip to content

Commit 7017ebb

Browse files
fix(output): recognise "X, Warn - ..." behind a state, and drop the test-only helper
split_status_warning() knew Predheat's bare "Warn - ..." form but not the same warning behind a state, so "Exporting, Warn - ..." would have been read as one state and lost its flag. The marker list now matches the bare list. yesterday_status_core() had no production caller once calculate_yesterday() moved to split_status_warning(); the test now calls split_status_warning() directly and checks the warning half too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent a681386 commit 7017ebb

2 files changed

Lines changed: 24 additions & 13 deletions

File tree

‎apps/predbat/output.py‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,17 @@ def split_status_warning(status):
101101
component_suffix = COMPONENT_ERROR_STATUS_SUFFIX.lower()
102102
if lowered.startswith(component_prefix) and component_suffix in lowered:
103103
return status[len(component_prefix) : lowered.index(component_suffix)].strip(), status
104+
# Predheat words its warnings "Warn - ..." rather than "Warn: ...", so both forms are
105+
# recognised, bare and behind a state alike.
104106
if lowered.startswith("warn:") or lowered.startswith("warn -") or lowered.startswith("error:"):
105107
return "", status
106-
for marker in (", warn:", ", error:"):
108+
for marker in (", warn:", ", warn -", ", error:"):
107109
index = lowered.find(marker)
108110
if index >= 0:
109111
return status[:index].strip(), status[index + 2 :].strip()
110112
return status, ""
111113

112114

113-
def yesterday_status_core(status):
114-
"""The charge/export state a historical ``predbat.status`` string records - see split_status_warning()."""
115-
return split_status_warning(status)[0]
116-
117-
118115
def more_active_slot_status(current, candidate, precedence):
119116
"""Pick the more significant of two ``predbat.status`` strings, used to break a tie in
120117
``dominant_slot_status()`` below.

‎apps/predbat/tests/test_calculate_yesterday.py‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
from const import PREDICT_STEP, EXPORT_MODE_FREEZE, CHARGE_STATE_PRECEDENCE, EXPORT_STATE_PRECEDENCE
3131
from utils import export_mode_of
32-
from output import yesterday_slot_is_exporting, yesterday_status_core, more_active_slot_status
32+
from output import yesterday_slot_is_exporting, split_status_warning, more_active_slot_status
3333
from tests.test_infra import reset_rates, reset_inverter
3434

3535
UTC = pytz.UTC
@@ -2224,13 +2224,13 @@ def _test_yesterday_slot_is_exporting(my_predbat, failed):
22242224
return failed
22252225

22262226

2227-
def _test_yesterday_status_core(my_predbat, failed):
2228-
"""Test: yesterday_status_core() keeps real states and blanks out warnings and errors.
2227+
def _test_split_status_warning(my_predbat, failed):
2228+
"""Test: split_status_warning() keeps real states and blanks out warnings and errors.
22292229
22302230
A warning pinned on the status sensor was read by substring: "car_charging_soc" contains
22312231
"charging", so a day of force exports was rebuilt as charge holds.
22322232
"""
2233-
print("calculate_yesterday: Test - yesterday_status_core drops warnings and errors, keeps real states")
2233+
print("calculate_yesterday: Test - split_status_warning drops warnings and errors, keeps real states")
22342234

22352235
cases = [
22362236
("Exporting", "Exporting"),
@@ -2245,11 +2245,25 @@ def _test_yesterday_status_core(my_predbat, failed):
22452245
("Exporting, Warn: Return bad float value unavailable from car_charging_soc", "Exporting"),
22462246
("Freeze exporting, Hold for car, Error: Inverter 0 unable to read Export window", "Freeze exporting, Hold for car"),
22472247
("Warn - Unable to fetch data from sensor.outdoor_temperature", ""),
2248+
("Exporting, Warn - Unable to fetch data from sensor.outdoor_temperature", "Exporting"),
22482249
]
22492250
for status, expected in cases:
2250-
result = yesterday_status_core(status)
2251+
result = split_status_warning(status)[0]
22512252
if result != expected:
2252-
print("ERROR: yesterday_status_core({!r}) should be {!r}, got {!r}".format(status, expected, result))
2253+
print("ERROR: split_status_warning({!r}) state should be {!r}, got {!r}".format(status, expected, result))
2254+
failed = True
2255+
2256+
# The warning half is what flags the History slot, so every form must hand one back
2257+
warning_cases = [
2258+
("Exporting", ""),
2259+
("Warn - Unable to fetch data from sensor.outdoor_temperature", "Warn - Unable to fetch data from sensor.outdoor_temperature"),
2260+
("Exporting, Warn - Unable to fetch data from sensor.outdoor_temperature", "Warn - Unable to fetch data from sensor.outdoor_temperature"),
2261+
("Exporting, Warn: Return bad float value unavailable from car_charging_soc", "Warn: Return bad float value unavailable from car_charging_soc"),
2262+
]
2263+
for status, expected in warning_cases:
2264+
result = split_status_warning(status)[1]
2265+
if result != expected:
2266+
print("ERROR: split_status_warning({!r}) warning should be {!r}, got {!r}".format(status, expected, result))
22532267
failed = True
22542268

22552269
return failed
@@ -2439,7 +2453,7 @@ def test_calculate_yesterday(my_predbat):
24392453
failed = _test_brief_edge_blip_is_not_counted(my_predbat, failed)
24402454
failed = _test_edge_only_state_still_gets_real_window_bounds(my_predbat, failed)
24412455
failed = _test_cross_charging_export_window_covers_the_slot(my_predbat, failed)
2442-
failed = _test_yesterday_status_core(my_predbat, failed)
2456+
failed = _test_split_status_warning(my_predbat, failed)
24432457
failed = _test_warning_status_is_not_a_charge_state(my_predbat, failed)
24442458

24452459
return failed

0 commit comments

Comments
 (0)