Skip to content

fix(deye): source energy counters from the Daily registers - #4391

Merged
springfall2008 merged 2 commits into
mainfrom
fix/deye-daily-energy-registers
Jul 30, 2026
Merged

fix(deye): source energy counters from the Daily registers#4391
springfall2008 merged 2 commits into
mainfrom
fix/deye-daily-energy-registers

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

Problem

load_today was climbing slower than the house actually consumed, which made Predbat's learned load too low and under-sized every charge window.

DEYE_ENERGY_KEYS mapped Predbat's *_today args onto the lifetime Total* accumulators. Those are firmware-derived and drift. On a live capture (productId 0_5411_1, 3-phase hybrid):

TotalConsumption                                                = 14332.40 kWh
buy 13579.20 + PV 2208.30 - sell 11.80 + discharge 5255.90
                                       - charge 5556.60        = 15475.00 kWh

A 7.4% shortfall, and it lands directly on the load history Predbat learns from.

Fix

The Daily* registers balance exactly on that same payload:

DailyActiveProduction 4.50 + DailyEnergyPurchased 7.00 - DailyGridFeedIn 0.00
                     + DailyDischargingEnergy 4.10 - DailyChargingEnergy 2.80 = 12.80
DailyConsumption                                                              = 12.80  ✓

So all four counters now read from them:

arg was now
import_today TotalEnergyBuy DailyEnergyPurchased
export_today TotalEnergySell DailyGridFeedIn
pv_today TotalActiveProduction DailyActiveProduction
load_today TotalConsumption DailyConsumption

On the midnight reset

The previous comment justified the lifetime choice by claiming Predbat needs an incrementing series and a daily reset "would read as a large negative delta every night". That is not the case, and the comment is corrected rather than left to mislead:

  • minute_data() smooths the near-midnight drop (the near_midnight branch in utils.py)
  • clean_incrementing_reverse() re-bases on any reset to <= 0, so the nightly return to 0.00 is absorbed regardless of whether the inverter's day boundary aligns with local midnight

Tests

  • energy_counters_daily_registers — asserts all four resolve to the Daily values on the captured live payload (replaces the test that pinned the lifetime values)
  • daily_energy_balance — new; pins the daily energy balance so a drifted key spelling breaks the sum. That is the same failure mode that hid the original bug

./run_all -k deye and ./run_all --quick pass; ./run_pre_commit clean.

Version bumped to v8.47.1.

🤖 Generated with Claude Code

DEYE_ENERGY_KEYS mapped Predbat's *_today args onto the lifetime "Total*"
accumulators. Those are firmware-derived and drift: on a live capture
TotalConsumption read 14332.40 kWh where the other lifetime counters implied
15475.00 (buy 13579.20 + PV 2208.30 - sell 11.80 + discharge 5255.90 -
charge 5556.60), a 7.4% shortfall. That fed straight into Predbat's learned
load, so load_today climbed slower than the house actually consumed and every
charge window came out under-sized.

The Daily registers balance exactly on the same payload
(DailyConsumption 12.80 = DailyActiveProduction 4.50 + DailyEnergyPurchased
7.00 - DailyGridFeedIn 0.00 + DailyDischargingEnergy 4.10 -
DailyChargingEnergy 2.80), so all four counters now read from them.

The old comment claimed daily counters were unusable because Predbat needs an
incrementing series and a midnight reset would read as a large negative delta.
That is not the case: minute_data() smooths the near-midnight drop and
clean_incrementing_reverse() re-bases on any reset to <= 0, so the nightly
return to 0.00 is absorbed. Comment corrected rather than left to mislead.

Tests: energy counters now assert the Daily values, plus a new test pinning
the daily energy balance so a drifted key spelling breaks the sum - the same
failure that hid the original bug.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 DEYE inverter energy counter sourcing so Predbat’s *_today history inputs come from DEYE’s Daily* registers (which balance correctly) rather than the drifting lifetime Total* accumulators, improving learned load accuracy and downstream charge-window sizing.

Changes:

  • Remap DEYE_ENERGY_KEYS to DailyEnergyPurchased, DailyGridFeedIn, DailyActiveProduction, and DailyConsumption, and update related in-code comments.
  • Update DEYE tests to assert the daily-register mapping and add a balance-guard test for the daily register set.
  • Bump Predbat version to v8.47.1.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
apps/predbat/deye_const.py Switches energy counter key mapping from Total* to Daily* and updates rationale comments.
apps/predbat/deye.py Updates published-sensor comment to reflect daily counters and reset handling.
apps/predbat/tests/test_deye_api.py Replaces lifetime-counter assertion with daily-register assertions; adds a daily energy balance guard test and updates registry entries.
apps/predbat/tests/test_deye_publish.py Updates publish/config mapping test expectations to daily-register magnitudes.
apps/predbat/predbat.py Version bump to v8.47.1.

Comment thread apps/predbat/deye_const.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@springfall2008
springfall2008 merged commit e9e3782 into main Jul 30, 2026
2 checks passed
@springfall2008
springfall2008 deleted the fix/deye-daily-energy-registers branch July 30, 2026 15:13
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.

2 participants