Fix SolarEdge module statistics sum resetting after a gap by tronikos · Pull Request #186753 · home-assistant/core · GitHub
Skip to content

Fix SolarEdge module statistics sum resetting after a gap - #186753

Merged
balloob merged 3 commits into
home-assistant:devfrom
tronikos:fix-solaredge-statistics-sum-reset
Oct 16, 2026
Merged

balloob merged 3 commits into
home-assistant:devfrom
tronikos:fix-solaredge-statistics-sum-reset

Conversation

@tronikos

@tronikos tronikos commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Proposed change

Fix the SolarEdge module statistics sum resetting to 0 after the integration
has not updated for more than a week.

The module statistics are cumulative, so a newly fetched window must continue
from the last sum before that window. _async_get_last_sums looked for the
statistic one hour before the window and, if it was missing, fell back to the
absolute last statistic for the statistic ID.

That fallback is wrong when statistics already exist inside the window. After
the first update following a gap, the same window can be fetched again (for
example when the integration is reloaded the same day). The absolute last
statistic is then one written by the previous update inside the window, so the
fallback used 0.0 and the whole window was rewritten starting from zero,
producing a large negative jump in the statistics graph.

The fix derives the sum before the window from the change of the first
statistic in the window. The recorder computes that change relative to the last
sum strictly before the window, so it is correct no matter how old the previous
statistics are, and it never resolves to a statistic written inside the window.
If the first statistic has no usable sum or change, it falls back to the last
statistic before the window, and then to 0. This also repairs windows already
corrupted by the bug on the next update.

The recorder query now returns the first statistic in the window instead of a
single row, so it fetches roughly the window's hourly rows per statistic ID
(about 168 rows per statistic per 12h refresh). This is deliberate: a bounded
query could miss the first row if it is not exactly at the window start and
fall back to a reset.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running: python3 -m script.gen_requirements_all.
  • For the updated dependencies a diff between library versions and ideally a link to the changelog/release notes is added to the PR description.

To help with the load of incoming pull requests:

The module statistics are cumulative, so a newly fetched window must continue from the last sum before that window. When the integration had not updated for more than a week, and the same window was fetched again before a statistic existed right before it, the fallback used the absolute last statistic. That statistic can be one written by an earlier update inside the window, which reset the sum to zero and created a large negative jump in the statistics graph.

Derive the sum before the window from the change of the first statistic in the window instead. The recorder computes that change relative to the last sum strictly before the window, so it is correct no matter how old the previous statistics are, and never resolves to a statistic inside the window. Fall back to the last statistic before the window, and then to 0, when the first statistic has no usable sum or change.
@home-assistant

Copy link
Copy Markdown
Contributor

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.

🟡 Changes recommended

A null leading statistic can still cause an existing cumulative baseline to reset to zero.

1 open finding
What changed in this PR

Fixes SolarEdge module statistics resetting after long gaps when the same data window is refreshed again, addressing #186653.

Changes:

  • Derives the cumulative baseline from recorded sum and change values.
  • Adds regression tests for repeated refreshes and newly added equipment.
File Description
tests/​components/​solaredge/​test_coordinator.py Tests repeated windows after gaps and new equipment.
homeassistant/​components/​solaredge/​coordinator.py Updates pre-window cumulative sum recovery.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread homeassistant/components/solaredge/coordinator.py
The baseline is derived from the change of the first statistic in the window.
The recorder computes that change relative to the last sum before the window
regardless of how many leading statistics have no sum, so scan for the first
statistic that has both a sum and a change instead of only looking at the
first one.

Add a regression test with a statistic without a sum ahead of one with a sum.
Copilot AI balanced review requested due to automatic review settings October 16, 2026 01:40

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.

🔵 Needs a closer look

The fallback still loses a valid pre-window total when every in-window sum is null.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

…missing

When every statistic in the window is missing a sum, the fallback returned the
last statistic, which is inside the window and rejected as not before the
window, so the baseline was lost. Fetch one more statistic than the number in
the window and use the newest one before the window that has a sum.

Add a regression test where no in-window statistic has a sum.
Copilot AI balanced review requested due to automatic review settings October 16, 2026 01:55

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.

🟢 Approval recommended

Recorder behavior supports the recovery logic, regression tests cover the key cases, and no blocking issues remain.

0 open findings

🧠 Review effort: Balanced

@balloob
balloob merged commit 6c81847 into home-assistant:dev Oct 16, 2026
36 checks passed
@frenck frenck mentioned this pull request Oct 16, 2026
gabrielcosi pushed a commit to gabrielcosi/home-ops that referenced this pull request Oct 17, 2026
…2026.10.1 ➔ 2026.10.2) (#1247)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/home-operations/home-assistant](https://ghcr.io/home-operations/home-assistant) ([source](https://github.com/home-assistant/core)) | patch | `2026.10.1` → `2026.10.2` |

---

### Release Notes

<details>
<summary>home-assistant/core (ghcr.io/home-operations/home-assistant)</summary>

### [`v2026.10.2`](https://github.com/home-assistant/core/releases/tag/2026.10.2)

[Compare Source](home-assistant/core@2026.10.1...2026.10.2)

- Fix IndexError on out-of-range heater levels in Tesla Fleet ([@&#8203;sebr] - [#&#8203;178049]) ([tesla_fleet docs])
- Deduplicate sleepers within a single SleepIQ bed ([@&#8203;derekcentrico] - [#&#8203;181461]) ([sleepiq docs])
- Handle Enphase envoy Session is Closed in background tasks ([@&#8203;catsmanac] - [#&#8203;183172]) ([enphase_envoy docs])
- Treat MPD protocol errors as a connection failure ([@&#8203;mattias-arrelid] - [#&#8203;184481]) ([mpd docs])
- Bump py-opendisplay to 7.18.1 ([@&#8203;g4bri3lDev] - [#&#8203;184911]) ([opendisplay docs]) (dependency)
- Bump aiotankerkoenig to 0.5.5 ([@&#8203;mib1185] - [#&#8203;185714]) ([tankerkoenig docs]) (dependency)
- Tankerkoenig handle api errors config flow ([@&#8203;mib1185] - [#&#8203;185719]) ([tankerkoenig docs])
- Handle Gemini generation parameters and complete WAV TTS responses ([@&#8203;oohhddaanngg] - [#&#8203;185723]) ([google_generative_ai_conversation docs])
- Fix SmartTub error sensor reporting stale historical errors ([@&#8203;mdz] - [#&#8203;185726]) ([smarttub docs])
- Bump aiohttp to 3.14.5 ([@&#8203;bdraco] - [#&#8203;185746]) (dependency)
- Mark Aquacell sensors unavailable when data is stale ([@&#8203;alexborro] - [#&#8203;185762]) ([aquacell docs])
- Bump aionanoleaf2 to 1.0.5 ([@&#8203;feixm1] - [#&#8203;185777]) ([nanoleaf docs]) (dependency)
- Bump my-pv to 0.0.13 ([@&#8203;rrooggiieerr] - [#&#8203;185797]) ([my_pv docs]) (dependency)
- Catch TimeoutError in the Nettigo Air Monitor integration ([@&#8203;bieniu] - [#&#8203;185812]) ([nam docs])
- Ignore devices without TR-064 support during FRITZ!Box Tools SSDP discovery ([@&#8203;mib1185] - [#&#8203;185816]) ([fritz docs])
- Bump arcam-fmj to 3.0.1 ([@&#8203;elupus] - [#&#8203;185887]) ([arcam_fmj docs]) (dependency)
- Handle Alexa RequireRelink on cloud entity registry updates ([@&#8203;balloob] - [#&#8203;185894]) ([cloud docs])
- Redact schedule coordinates in Teslemetry and Tesla Fleet diagnostics ([@&#8203;Bre77] - [#&#8203;185905]) ([teslemetry docs]) ([tesla_fleet docs])
- Report a dedicated error when the Tedee bridge has no locks ([@&#8203;zweckj] - [#&#8203;185907]) ([tedee docs])
- Prevent WiiM browse failures from marking devices unavailable ([@&#8203;Linkplay2020] - [#&#8203;185926]) ([wiim docs])
- Fix group sensor crash when the group has no members ([@&#8203;joostlek] - [#&#8203;185931]) ([group docs])
- Do not cut off KNX SQLite telegram store initialization with a timeout ([@&#8203;farmio] - [#&#8203;185940]) ([knx docs])
- Bump nyt_games to 1.0.1 ([@&#8203;joostlek] - [#&#8203;185968]) ([nyt_games docs]) (dependency)
- Gate Nanoleaf event listener on supports_events ([@&#8203;loebi-ch] - [#&#8203;185977]) ([nanoleaf docs])
- Fix MQTT device triggers and tags firing twice after reload ([@&#8203;klejejs] - [#&#8203;185998]) ([mqtt docs])
- Fix FRITZ!SmartHome SSDP host selection ([@&#8203;mib1185] - [#&#8203;186029]) ([fritzbox docs])
- switch Broadlink to broadlink-async (fixes [#&#8203;184800](home-assistant/core#184800), replaces [#&#8203;184806](home-assistant/core#184806)) ([@&#8203;DAB-LABS] - [#&#8203;186053]) ([broadlink docs])
- Fix weatherflow last_reset updating on every device report ([@&#8203;jeeftor] - [#&#8203;186141]) ([weatherflow docs])
- Bump weatherflow4py to 1.5.12 ([@&#8203;jeeftor] - [#&#8203;186142]) ([weatherflow_cloud docs]) (dependency)
- Bump intellifire4py to 4.5.6 ([@&#8203;jeeftor] - [#&#8203;186143]) ([intellifire docs]) (dependency)
- Fix scrape subentry reconfigure flow not finishing ([@&#8203;joostlek] - [#&#8203;186144]) ([scrape docs])
- pin pycares to 5.0.1 ([@&#8203;aclerici38] - [#&#8203;186164])
- Allow a list of states for state conditions with a duration ([@&#8203;emontnemery] - [#&#8203;186165])
- Bump airthings-ble to 1.3.1 ([@&#8203;LaStrada] - [#&#8203;186387]) ([airthings_ble docs]) (dependency)
- Guard owner and existing credentials in auth provider create command ([@&#8203;zweckj] - [#&#8203;186398]) ([config docs])
- Fetch missing Renault vehicle details ([@&#8203;epenet] - [#&#8203;186402]) ([renault docs])
- Fix Discogs random record sensor when release has no format description ([@&#8203;cerealkiller57540] - [#&#8203;186405]) ([discogs docs])
- Fix permissions validation for ProxmoxVE ([@&#8203;CoMPaTech] - [#&#8203;186420]) ([proxmoxve docs])
- Hide MELCloud Home swing modes on units without vanes ([@&#8203;erwindouna] - [#&#8203;186468]) ([melcloud_home docs])
- Fix modbus reload without YAML config ([@&#8203;joyjit] - [#&#8203;186554]) ([modbus docs])
- Revoke refresh tokens when removing a user ([@&#8203;frenck] - [#&#8203;186558])
- Redact credentials and host in SFR Box diagnostics ([@&#8203;epenet] - [#&#8203;186668]) ([sfr_box docs])
- Fix SolarEdge module statistics sum resetting after a gap ([@&#8203;tronikos] - [#&#8203;186753]) ([solaredge docs])
- Bump deebot-client to 18.7.0 ([@&#8203;edenhaus] - [#&#8203;186779]) ([ecovacs docs]) (dependency)
- Redact identifying data in NRGkick diagnostics ([@&#8203;andijakl] - [#&#8203;186781]) ([nrgkick docs])
- Persist Ecovacs account credentials to avoid device verification ([@&#8203;erwindouna] - [#&#8203;186796]) ([ecovacs docs])
- Update frontend to [`2026093`](https://github.com/home-assistant/core/commit/20260930).4 ([@&#8203;bramkragten] - [#&#8203;186813]) ([frontend docs]) (dependency)
- Fix Fritz setup failing when UPnP info lacks NewEnable key ([@&#8203;mib1185] - [#&#8203;186896]) ([fritz docs])
- Bump aiomelcloudhome to 0.3.0 ([@&#8203;erwindouna] - [#&#8203;185769]) ([melcloud_home docs]) (dependency)
- Pin pypasser below 1.0.0 ([@&#8203;erwindouna] - [#&#8203;186527])

[#&#8203;178049]: home-assistant/core#178049

[#&#8203;181461]: home-assistant/core#181461

[#&#8203;183172]: home-assistant/core#183172

[#&#8203;184481]: home-assistant/core#184481

[#&#8203;184707]: home-assistant/core#184707

[#&#8203;184911]: home-assistant/core#184911

[#&#8203;185554]: home-assistant/core#185554

[#&#8203;185714]: home-assistant/core#185714

[#&#8203;185719]: home-assistant/core#185719

[#&#8203;185723]: home-assistant/core#185723

[#&#8203;185726]: home-assistant/core#185726

[#&#8203;185746]: home-assistant/core#185746

[#&#8203;185762]: home-assistant/core#185762

[#&#8203;185769]: home-assistant/core#185769

[#&#8203;185777]: home-assistant/core#185777

[#&#8203;185797]: home-assistant/core#185797

[#&#8203;185812]: home-assistant/core#185812

[#&#8203;185816]: home-assistant/core#185816

[#&#8203;185887]: home-assistant/core#185887

[#&#8203;185894]: home-assistant/core#185894

[#&#8203;185905]: home-assistant/core#185905

[#&#8203;185907]: home-assistant/core#185907

[#&#8203;185926]: home-assistant/core#185926

[#&#8203;185931]: home-assistant/core#185931

[#&#8203;185940]: home-assistant/core#185940

[#&#8203;185968]: home-assistant/core#185968

[#&#8203;185977]: home-assistant/core#185977

[#&#8203;185998]: home-assistant/core#185998

[#&#8203;186029]: home-assistant/core#186029

[#&#8203;186053]: home-assistant/core#186053

[#&#8203;186141]: home-assistant/core#186141

[#&#8203;186142]: home-assistant/core#186142

[#&#8203;186143]: home-assistant/core#186143

[#&#8203;186144]: home-assistant/core#186144

[#&#8203;186164]: home-assistant/core#186164

[#&#8203;186165]: home-assistant/core#186165

[#&#8203;186387]: home-assistant/core#186387

[#&#8203;186398]: home-assistant/core#186398

[#&#8203;186402]: home-assistant/core#186402

[#&#8203;186405]: home-assistant/core#186405

[#&#8203;186420]: home-assistant/core#186420

[#&#8203;186468]: home-assistant/core#186468

[#&#8203;186527]: home-assistant/core#186527

[#&#8203;186554]: home-assistant/core#186554

[#&#8203;186558]: home-assistant/core#186558

[#&#8203;186668]: home-assistant/core#186668

[#&#8203;186753]: home-assistant/core#186753

[#&#8203;186779]: home-assistant/core#186779

[#&#8203;186781]: home-assistant/core#186781

[#&#8203;186796]: home-assistant/core#186796

[#&#8203;186813]: home-assistant/core#186813

[#&#8203;186896]: home-assistant/core#186896

[@&#8203;Bre77]: https://github.com/Bre77

[@&#8203;CoMPaTech]: https://github.com/CoMPaTech

[@&#8203;DAB-LABS]: https://github.com/DAB-LABS

[@&#8203;LaStrada]: https://github.com/LaStrada

[@&#8203;Linkplay2020]: https://github.com/Linkplay2020

[@&#8203;aclerici38]: https://github.com/aclerici38

[@&#8203;alexborro]: https://github.com/alexborro

[@&#8203;andijakl]: https://github.com/andijakl

[@&#8203;balloob]: https://github.com/balloob

[@&#8203;bdraco]: https://github.com/bdraco

[@&#8203;bieniu]: https://github.com/bieniu

[@&#8203;bramkragten]: https://github.com/bramkragten

[@&#8203;catsmanac]: https://github.com/catsmanac

[@&#8203;cerealkiller57540]: https://github.com/cerealkiller57540

[@&#8203;derekcentrico]: https://github.com/derekcentrico

[@&#8203;edenhaus]: https://github.com/edenhaus

[@&#8203;elupus]: https://github.com/elupus

[@&#8203;emontnemery]: https://github.com/emontnemery

[@&#8203;epenet]: https://github.com/epenet

[@&#8203;erwindouna]: https://github.com/erwindouna

[@&#8203;farmio]: https://github.com/farmio

[@&#8203;feixm1]: https://github.com/feixm1

[@&#8203;frenck]: https://github.com/frenck

[@&#8203;g4bri3lDev]: https://github.com/g4bri3lDev

[@&#8203;jeeftor]: https://github.com/jeeftor

[@&#8203;joostlek]: https://github.com/joostlek

[@&#8203;joyjit]: https://github.com/joyjit

[@&#8203;klejejs]: https://github.com/klejejs

[@&#8203;loebi-ch]: https://github.com/loebi-ch

[@&#8203;mattias-arrelid]: https://github.com/mattias-arrelid

[@&#8203;mdz]: https://github.com/mdz

[@&#8203;mib1185]: https://github.com/mib1185

[@&#8203;oohhddaanngg]: https://github.com/oohhddaanngg

[@&#8203;rrooggiieerr]: https://github.com/rrooggiieerr

[@&#8203;sebr]: https://github.com/sebr

[@&#8203;tronikos]: https://github.com/tronikos

[@&#8203;zweckj]: https://github.com/zweckj

[airthings_ble docs]: https://www.home-assistant.io/integrations/airthings_ble/

[aquacell docs]: https://www.home-assistant.io/integrations/aquacell/

[arcam_fmj docs]: https://www.home-assistant.io/integrations/arcam_fmj/

[broadlink docs]: https://www.home-assistant.io/integrations/broadlink/

[cloud docs]: https://www.home-assistant.io/integrations/cloud/

[config docs]: https://www.home-assistant.io/integrations/config/

[discogs docs]: https://www.home-assistant.io/integrations/discogs/

[ecovacs docs]: https://www.home-assistant.io/integrations/ecovacs/

[enphase_envoy docs]: https://www.home-assistant.io/integrations/enphase_envoy/

[fritz docs]: https://www.home-assistant.io/integrations/fritz/

[fritzbox docs]: https://www.home-assistant.io/integrations/fritzbox/

[frontend docs]: https://www.home-assistant.io/integrations/frontend/

[google_generative_ai_conversation docs]: https://www.home-assistant.io/integrations/google_generative_ai_conversation/

[group docs]: https://www.home-assistant.io/integrations/group/

[intellifire docs]: https://www.home-assistant.io/integrations/intellifire/

[knx docs]: https://www.home-assistant.io/integrations/knx/

[melcloud_home docs]: https://www.home-assistant.io/integrations/melcloud_home/

[modbus docs]: https://www.home-assistant.io/integrations/modbus/

[mpd docs]: https://www.home-assistant.io/integrations/mpd/

[mqtt docs]: https://www.home-assistant.io/integrations/mqtt/

[my_pv docs]: https://www.home-assistant.io/integrations/my_pv/

[nam docs]: https://www.home-assistant.io/integrations/nam/

[nanoleaf docs]: https://www.home-assistant.io/integrations/nanoleaf/

[nrgkick docs]: https://www.home-assistant.io/integrations/nrgkick/

[nyt_games docs]: https://www.home-assistant.io/integrations/nyt_games/

[opendisplay docs]: https://www.home-assistant.io/integrations/opendisplay/

[proxmoxve docs]: https://www.home-assistant.io/integrations/proxmoxve/

[renault docs]: https://www.home-assistant.io/integrations/renault/

[scrape docs]: https://www.home-assistant.io/integrations/scrape/

[sfr_box docs]: https://www.home-assistant.io/integrations/sfr_box/

[sleepiq docs]: https://www.home-assistant.io/integrations/sleepiq/

[smarttub docs]: https://www.home-assistant.io/integrations/smarttub/

[solaredge docs]: https://www.home-assistant.io/integrations/solaredge/

[tankerkoenig docs]: https://www.home-assistant.io/integrations/tankerkoenig/

[tedee docs]: https://www.home-assistant.io/integrations/tedee/

[tesla_fleet docs]: https://www.home-assistant.io/integrations/tesla_fleet/

[teslemetry docs]: https://www.home-assistant.io/integrations/teslemetry/

[weatherflow docs]: https://www.home-assistant.io/integrations/weatherflow/

[weatherflow_cloud docs]: https://www.home-assistant.io/integrations/weatherflow_cloud/

[wiim docs]: https://www.home-assistant.io/integrations/wiim/

</details>

---

### Configuration

📅 **Schedule**: (in timezone Europe/Berlin)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNjUuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjE2NS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.xcd.dev/gabrielcosi/home-ops/pulls/1247
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SolarEdge module statistics: sum resets to 0 after a gap longer than one week

5 participants