-
-
Notifications
You must be signed in to change notification settings - Fork 108
Fix current load glitching to 0.0 kWh when load_power_fill_enable is active #3524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -743,6 +743,11 @@ def fetch_sensor_data(self, save=True): | |
| self.log("Using load_power data to fill gaps in load_today data") | ||
| load_power_data, _ = self.minute_data_load(self.now_utc, "load_power", self.max_days_previous, required_unit="W", load_scaling=1.0, interpolate=True) | ||
| self.load_minutes = self.fill_load_from_power(self.load_minutes, load_power_data) | ||
| # Recalculate load_minutes_now and load_last_period using the improved data from fill_load_from_power | ||
| # This ensures that if the original load_today data had a transient zero or gap at minute 0, | ||
| # the power-based fill is reflected in the current load estimate instead of leaving it at 0 | ||
| self.load_minutes_now = get_now_from_cumulative(self.load_minutes, self.minutes_now, backwards=True) | ||
| self.load_last_period = (self.load_minutes.get(0, 0) - self.load_minutes.get(PREDICT_STEP, 0)) * 60 / PREDICT_STEP | ||
|
Comment on lines
+746
to
+750
|
||
| else: | ||
| if self.load_forecast: | ||
| self.log("Using load forecast from load_forecast sensor") | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -305,6 +305,56 @@ def test_fill_load_from_power_backwards_time(): | |
| print("Test 6 PASSED") | ||
|
|
||
|
|
||
| def test_fill_load_from_power_zero_glitch_at_minute_0(): | ||
| """ | ||
| Test the specific bug scenario where load_today briefly glitches to 0 at minute 0. | ||
| The sensor reading resets to 0 for one cycle, but load_power data is still valid. | ||
| fill_load_from_power should detect the zero period at minute 0 and fill it with | ||
| power-integrated data, restoring the correct current load estimate. | ||
|
|
||
| This is the scenario described in the bug report where current load glitches to 0 | ||
| a few times a day. The fix is to recalculate load_minutes_now after fill_load_from_power. | ||
| """ | ||
| print("\n=== Test 7: Zero glitch at minute 0 (bug fix verification) ===") | ||
|
|
||
| fetch = TestFetch() | ||
|
|
||
| # Simulate: sensor was accumulating fine (17.61 kWh by yesterday) | ||
| # At minute 0 (now), the load_today sensor glitched to 0 | ||
| # Minutes 1-4 are also 0 (filled from the glitched reading) | ||
| # Minutes 5+ have the correct cumulative data | ||
| load_minutes = {} | ||
| load_minutes[0] = 0.0 # Glitch: should be ~17.61 kWh | ||
| load_minutes[1] = 0.0 | ||
| load_minutes[2] = 0.0 | ||
| load_minutes[3] = 0.0 | ||
| load_minutes[4] = 0.0 | ||
| # From minute 5 onwards, data is correct (10.0 kWh for testing) | ||
| for minute in range(5, 35): | ||
| load_minutes[minute] = 10.0 - (minute - 5) * (1.0 / 30.0) # Slowly decreasing from 10.0 | ||
| load_minutes[35] = 9.0 | ||
|
|
||
| # Power data is still valid (sensor didn't glitch, ~3kW load) | ||
| load_power_data = {} | ||
| for minute in range(0, 35): | ||
| load_power_data[minute] = 3000.0 # 3 kW = 0.05 kWh/minute | ||
|
|
||
| result = fetch.fill_load_from_power(load_minutes, load_power_data) | ||
|
|
||
| # After fill_load_from_power, minute 0 should be non-zero | ||
| # (the power data filled the zero gap) | ||
| assert result[0] > 0.0, f"Minute 0 should be non-zero after power fill, got {result[0]}" | ||
|
|
||
| # Minute 0 should reflect the accumulated power consumption for the zero period | ||
| # 5 minutes at 3kW = 5 * 3/60 = 0.25 kWh | ||
| # So minute 0 should be approximately 0.25 kWh (power-integrated) | ||
| assert result[0] >= 0.1, f"Minute 0 should be at least 0.1 kWh from power fill, got {result[0]}" | ||
|
Comment on lines
+326
to
+351
|
||
|
|
||
| print(f"✓ Zero glitch at minute 0 fixed: result[0] = {dp4(result[0])} kWh") | ||
| print(f" (was 0.0 kWh, now restored from power data)") | ||
| print("Test 7 PASSED") | ||
|
|
||
|
|
||
| def run_all_tests(my_predbat=None): | ||
| """Run all tests""" | ||
| print("\n" + "=" * 60) | ||
|
|
@@ -318,6 +368,7 @@ def run_all_tests(my_predbat=None): | |
| test_fill_load_from_power_single_minute_period() | ||
| test_fill_load_from_power_zero_load() | ||
| test_fill_load_from_power_backwards_time() | ||
| test_fill_load_from_power_zero_glitch_at_minute_0() | ||
|
|
||
| print("\n" + "=" * 60) | ||
| print("✅ ALL TESTS PASSED") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
load_last_periodcan become negative if the cumulative series has a transient reset/glitch (e.g.,load_minutes[0] < load_minutes[PREDICT_STEP]). That negative kW then feeds intodynamic_load()logic. Consider clamping this computed value to >= 0 (and potentially logging when a negative delta is observed) to avoid impossible negative load rates influencing planning.