Skip to content

fix: prevent race condition causing dashboard SOC to show wrong value during plan calculation#3909

Merged
springfall2008 merged 4 commits into
mainfrom
copilot/fix-dashboard-soc-reporting
May 14, 2026
Merged

fix: prevent race condition causing dashboard SOC to show wrong value during plan calculation#3909
springfall2008 merged 4 commits into
mainfrom
copilot/fix-dashboard-soc-reporting

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 12, 2026

The dashboard battery SOC header showed a stale/incorrect value (e.g. 50% instead of actual 98%) transiently after a plan calculation cycle. The plan rows themselves showed the correct SOC, only the header percentage was wrong.

Root cause

calculate_yesterday() temporarily mutated self.soc_kw and self.soc_max on the base PredBat object to bootstrap historical simulations:

self.soc_kw = soc_yesterday   # e.g. 14.28 kWh → shows as 50%
self.prediction = Prediction(self, ...)
...
self.soc_kw = 0               # no-battery sim → shows as 0%
self.soc_max = 0
self.prediction = Prediction(self, ...)
...
self.soc_kw = soc_kw          # restored — but too late

The web server polls self.base.soc_kw every 5 seconds to render the battery icon. Any request landing during the several-second window of calculate_yesterday() would read the temporary value. soc_yesterday is typically the battery's end-of-day level (often ~50%), which matches what users were seeing.

Fix

  • prediction.py — added optional soc_kw and soc_max override parameters to Prediction.__init__. When provided, these override the values copied from base.
  • output.py — removed the direct mutations of self.soc_kw/self.soc_max in calculate_yesterday(). The desired starting SOC is now passed directly to each Prediction constructor:
# Historical baseline simulation
self.prediction = Prediction(self, ..., soc_kw=soc_yesterday)

# No-battery/PV simulation
self.prediction = Prediction(self, ..., soc_kw=0, soc_max=0)

The base object's soc_kw/soc_max are never modified during calculate_yesterday(), eliminating the race window entirely.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.octopus.energy
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick git conf�� --global ame it (dns block)
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick git conf�� unset --global /home/REDACTED/.config/composer/vendor/bin/git user.email (dns block)
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick git conf�� get --local /usr/bin/git credential.helpe/home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/bin/rustc (dns block)
  • gitlab.com
    • Triggering command: /usr/lib/git-core/git-remote-https /usr/lib/git-core/git-remote-https origin REDACTED (dns block)
    • Triggering command: /usr/lib/git-core/git-remote-https /usr/lib/git-core/git-remote-https origin REDACTED bash -c mkcert --CAROOT (dns block)
  • https://api.github.com/repos/springfall2008/batpred/contents/apps/predbat
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick git conf�� --global ame it (http block)
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick git conf�� unset --global /home/REDACTED/.config/composer/vendor/bin/git user.email (http block)
    • Triggering command: /home/REDACTED/work/batpred/batpred/coverage/venv/bin/python3 python3 ../apps/predbat/unit_test.py --quick git conf�� get --local /usr/bin/git credential.helpe/home/REDACTED/.rustup/toolchains/stable-x86_64-REDACTED-linux-gnu/bin/rustc (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI linked an issue May 12, 2026 that may be closed by this pull request
…o prevent race condition with web UI

The web server polls self.base.soc_kw every 5 seconds to display the
battery percentage. During calculate_yesterday(), soc_kw and soc_max
were temporarily modified to run historical simulations, causing the
web UI to transiently display wrong SOC values (e.g. yesterday's final
SOC of ~50% instead of the real current 98%).

Fix: Add optional soc_kw and soc_max override parameters to
Prediction.__init__ so the simulations can use the correct starting
values without needing to modify the base object's attributes.

Agent-Logs-Url: https://github.com/springfall2008/batpred/sessions/63349b86-5d73-4473-97e2-3249c796dd33

Co-authored-by: springfall2008 <48591903+springfall2008@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix incorrect SOC reporting on dashboard fix: prevent race condition causing dashboard SOC to show wrong value during plan calculation May 12, 2026
Copilot AI requested a review from springfall2008 May 12, 2026 08:08
@springfall2008 springfall2008 marked this pull request as ready for review May 13, 2026 20:01
Copilot AI review requested due to automatic review settings May 13, 2026 20:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a dashboard SOC race during calculate_yesterday() by moving temporary simulation SOC values into Prediction construction instead of mutating the shared PredBat state.

Changes:

  • Added optional soc_kw and soc_max overrides to Prediction.__init__.
  • Updated yesterday and no-battery simulations to pass SOC overrides directly.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
apps/predbat/prediction.py Adds SOC override parameters when copying state from the base object.
apps/predbat/output.py Removes direct SOC mutations during yesterday/no-battery simulations and passes overrides to Prediction.

Comment thread apps/predbat/output.py

# Simulate yesterday
self.prediction = Prediction(self, yesterday_pv_step, yesterday_pv_step, yesterday_load_step, yesterday_load_step)
self.prediction = Prediction(self, yesterday_pv_step, yesterday_pv_step, yesterday_load_step, yesterday_load_step, soc_kw=soc_yesterday)
Comment on lines +103 to +104
self.soc_kw = soc_kw if soc_kw is not None else base.soc_kw
self.soc_max = soc_max if soc_max is not None else base.soc_max
@springfall2008 springfall2008 merged commit cc303a3 into main May 14, 2026
1 check passed
@springfall2008 springfall2008 deleted the copilot/fix-dashboard-soc-reporting branch May 14, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard SOC incorrectly reporting

3 participants