Summary
The Savings/Insights table's current-hour battery SOC display can jump straight to the configured Min SOC floor instead of showing the live sensor reading, when the live/initial SOE is below the configured minimum. This happens legitimately in demo mode (or with any external controller) since BESS's own Min SOC floor doesn't constrain hardware it isn't writing to.
Reported in
#126, first at 65% (Min SOC setting) vs a live 24%/31% reading in 9.9.0b1/b4, then again at 45%/50% after the user changed Min SOC, confirming the display tracks whatever Min SOC is configured rather than the sensor. A maintainer reply acknowledged it as "a known display issue... I'll track it separately" but no follow-up issue was ever filed.
Reproduced again independently in a fresh 9.9.0b5 debug export (4 Jul 2026): initial_soe=2.4 (16% of 15 kWh, matching the live sensor), but the very first period of the optimization run jumps straight to battery_soe_end=6.8 (45.3%, exactly the configured Min SOC of 45%) under a plain IDLE intent with zero battery action:
| Per | Time | Intent | BattAct | SOE kWh | ... |
| 25 | 06:15 | IDLE | +0.000 | 2.4→6.8 | ... |
min_soe_kwh for this run: 6.75 kWh (45% of 15 kWh battery) — matches the jump target exactly.
Root cause
core/bess/dp_battery_algorithm.py, _state_transition, final safety clamp (lines 241-244):
# Ensure SOE stays within physical bounds
next_soe = min(
battery_settings.max_soe_kwh, max(battery_settings.min_soe_kwh, next_soe)
)
When the optimizer's starting SOE (from the live sensor) is below min_soe_kwh, this clamp forces the reported next_soe up to the floor in a single period, with no physical charging having occurred — the number is fabricated, not measured or simulated from real energy flow.
This is a partially-fixed issue: commit 6eb4d3587c9d1b275537fe902d9dd6689a75d815 ("Fix SOLAR_STORAGE phantom when initial SOE starts below minimum floor", closes #161) patched _idle_battery_flows so the strategic-intent label is now correctly IDLE instead of a phantom SOLAR_STORAGE in this situation. But it only touched intent classification — the underlying next_soe/battery_soe_end value (which feeds the Savings-table SOC display) still goes through the unconditional clamp above and jumps to the floor. The label is fixed; the number the user is actually complaining about is not.
Suggested fix direction
Either: (a) don't clamp next_soe up to min_soe_kwh when the starting SOE was already below the floor with zero energy actually stored that period (only clamp when real charging pushes it there), or (b) have the Savings-table display read the live sensor value directly for the current-hour row instead of the DP's internal (floor-clamped) SOE state, clearly labeling the DP's internal target separately if it needs to be shown at all.
Related
Summary
The Savings/Insights table's current-hour battery SOC display can jump straight to the configured Min SOC floor instead of showing the live sensor reading, when the live/initial SOE is below the configured minimum. This happens legitimately in demo mode (or with any external controller) since BESS's own Min SOC floor doesn't constrain hardware it isn't writing to.
Reported in
#126, first at 65% (Min SOC setting) vs a live 24%/31% reading in 9.9.0b1/b4, then again at 45%/50% after the user changed Min SOC, confirming the display tracks whatever Min SOC is configured rather than the sensor. A maintainer reply acknowledged it as "a known display issue... I'll track it separately" but no follow-up issue was ever filed.
Reproduced again independently in a fresh 9.9.0b5 debug export (4 Jul 2026):
initial_soe=2.4(16% of 15 kWh, matching the live sensor), but the very first period of the optimization run jumps straight tobattery_soe_end=6.8(45.3%, exactly the configured Min SOC of 45%) under a plainIDLEintent with zero battery action:min_soe_kwhfor this run:6.75kWh (45% of 15 kWh battery) — matches the jump target exactly.Root cause
core/bess/dp_battery_algorithm.py,_state_transition, final safety clamp (lines 241-244):When the optimizer's starting SOE (from the live sensor) is below
min_soe_kwh, this clamp forces the reportednext_soeup to the floor in a single period, with no physical charging having occurred — the number is fabricated, not measured or simulated from real energy flow.This is a partially-fixed issue: commit
6eb4d3587c9d1b275537fe902d9dd6689a75d815("Fix SOLAR_STORAGE phantom when initial SOE starts below minimum floor", closes #161) patched_idle_battery_flowsso the strategic-intent label is now correctlyIDLEinstead of a phantomSOLAR_STORAGEin this situation. But it only touched intent classification — the underlyingnext_soe/battery_soe_endvalue (which feeds the Savings-table SOC display) still goes through the unconditional clamp above and jumps to the floor. The label is fixed; the number the user is actually complaining about is not.Suggested fix direction
Either: (a) don't clamp
next_soeup tomin_soe_kwhwhen the starting SOE was already below the floor with zero energy actually stored that period (only clamp when real charging pushes it there), or (b) have the Savings-table display read the live sensor value directly for the current-hour row instead of the DP's internal (floor-clamped) SOE state, clearly labeling the DP's internal target separately if it needs to be shown at all.Related
6eb4d35— prior partial fix (intent label only)