Skip to content

fix(energy): preserve counter continuity across device identity refinement - #1513

Closed
segran2 wants to merge 4 commits into
srcfl:masterfrom
segran2:fix/energy-identity-counter-continuity
Closed

segran2 wants to merge 4 commits into
srcfl:masterfrom
segran2:fix/energy-identity-counter-continuity

Conversation

@segran2

@segran2 segran2 commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Problem

When a device is first known by MAC and later reports a hardware serial, ResolveDeviceID upgrades mac:... to make:serial. Energy ledger cursors are keyed by asset/device ID, so the stronger identity starts with counter_baseline and loses counter-gap recovery across an outage.

This was reproduced on Pixii: the same MAC/endpoint changed from mac:b827ebf83119 to pixii:235101100376; the old counters stopped on Sep 8 and the serial asset received a fresh baseline on Sep 25. SMA/Easee, whose identities stayed stable, recovered the same outage via counter_gap.

Fix

  • Detect a weaker MAC alias when a live serial is a verified refinement of the same hardware.
  • Seed the new serial asset's ledger cursors from that alias before the first serial-based energy observation.
  • Never overwrite existing target cursors; the operation is idempotent.
  • Do not inherit counters when a different prior serial exists on the same MAC.
  • Keep historical ledger rows on their original asset IDs; only cursor continuity is transferred.

Test

Adds a regression test that seeds a MAC counter, refines identity to Pixii serial, and verifies the serial asset recovers the 600 Wh gap instead of creating a zero baseline.

Regression area introduced/hardened around #1186 (fix(core): confirm live device identity before recording energy counters).

segran2 commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Ready for maintainer review/merge.

Current status:

  • PR is mergeable with no base-branch conflict.
  • All applicable GitHub checks pass, including Go test + vet, Core, full stack, changeset validation, and Linux ARM64/AMD64 builds.
  • No review submissions or unresolved review threads are present.
  • Scope remains focused on preserving energy-counter cursor continuity when a verified device identity is refined from MAC to serial.
  • Regression coverage verifies that the refined serial identity recovers the counter gap instead of creating a new zero baseline, while avoiding inheritance from a different prior serial.

@frahlg Could you please review/merge when ready?

@segran2

segran2 commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Problem found I my database by ChatGPT during a clean-up. I believe that this problem was caused by a combination of a less successful migration back from duck base to sqlite and that the pixii identifier changed from the Mac-address during the time duck base was in use. Not likely to happen to anyone else, not anymore!

@frahlg

frahlg commented Oct 4, 2026

Copy link
Copy Markdown
Member

Thanks @segran2, and thanks for tracing it down. Closing this one: as you say, the cause was the DuckDB→SQLite migration in your own database, and that path is gone.

A general fix would also need a different shape. Here the cursor seed runs inside buildEnergyObservations, so every tick opens a write transaction on the history database for each device that still has a MAC-only row, and it would re-seed a weeks-old MAC cursor if the serial cursor were ever cleared. If the MAC→serial case shows up again on a clean install, the seed should run once, when the identity changes. Please open an issue then and we can take it from there.

🤖 Generated with Claude Code

@frahlg frahlg closed this Oct 4, 2026
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