Skip to content

Decode a lifetime energy of 0 as not accumulated#11

Merged
frenck merged 3 commits into
mainfrom
frenck/inverter-energy-acc32
Jul 15, 2026
Merged

Decode a lifetime energy of 0 as not accumulated#11
frenck merged 3 commits into
mainfrom
frenck/inverter-energy-acc32

Conversation

@frenck

@frenck frenck commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Breaking change

A factory-new inverter that has not produced yet reads ac_energy as None instead of 0 until its first watt-hour accumulates. Every producing inverter reads exactly as before.

Proposed change

SunSpec types the inverter's lifetime energy (register 40093) as acc32, where 0 means "not accumulated", and some firmware transiently reports 0 there around the sleep/wake transition. The field was modelled as uint32, so that transient 0 posed as a genuine reading of zero, which is poison for anything tracking a monotonic counter. Both long-standing community integrations reject 0 on this register (solaredge-modbus-multi via its SunSpecAccum.NA32 check, home-assistant-solaredge-modbus via a > 0 validation).

The meter accumulators deliberately stay uint32: a freshly commissioned meter's 0 is a genuine reading, and their helper documents that tradeoff (now with a pointer to this contrast). No community dump snapshot changed: none of the captured devices reported 0.

Type of change

  • Dependency or tooling upgrade
  • Bugfix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Deprecation (replaces or removes a feature, with a migration path)
  • Breaking change (a fix or feature that changes existing behavior)
  • Code quality, refactor, or test-only change
  • Documentation only

Additional information

  • This PR is related to: the accumulator guards in solaredge-modbus-multi and home-assistant-solaredge-modbus linked above

Checklist

  • I fully understand the code in this pull request and can explain every line, including any AI-assisted changes.
  • The change is covered by tests, and poetry run pytest passes locally. A pull request cannot be merged unless CI is green.
  • poetry run prek run --all-files passes (lint, format, and type checks).
  • No commented-out or dead code is left in the pull request.

SunSpec types the inverter's lifetime energy as acc32, where 0 means "not accumulated", and some firmware transiently reports 0 there around the sleep/wake transition. It was modelled as uint32, so that transient 0 posed as a genuine reading; both long-standing community integrations reject 0 on this register. A producing inverter's lifetime counter is never genuinely 0, unlike a meter's, so the meter accumulators deliberately stay uint32 (their helper documents that tradeoff).

No community dump snapshot changed: none of the captured devices reported 0.
Copilot AI review requested due to automatic review settings July 15, 2026 07:14
@frenck frenck added the bugfix Inconsistencies or issues which will cause a problem for users or implementers. label Jul 15, 2026
@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (1542d9d) to head (a61c883).

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #11   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            7         7           
  Lines          824       824           
  Branches        50        50           
=========================================
  Hits           824       824           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This pull request updates the inverter lifetime energy decoding to follow SunSpec acc32 semantics so a reported value of 0 is treated as “not accumulated” and decodes to None, preventing transient firmware zeros from looking like a real monotonic counter reset.

Changes:

  • Model Inverter.ac_energy as acc32 (instead of uint32) so 0 decodes to None.
  • Add a test covering the “0 lifetime energy decodes to None” case.
  • Update README wording to mention this decoding behavior.

Reviewed changes

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

File Description
tests/test_solaredged.py Adds coverage for the lifetime energy 0 sentinel decoding to None.
src/solaredged/components.py Switches inverter lifetime energy field to acc32 and clarifies the meter accumulator contrast.
README.md Documents the None decoding behavior for the inverter lifetime energy sentinel.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/test_solaredged.py
Comment on lines +425 to +430
"""A lifetime energy of 0 decodes to None per acc32 semantics.

SunSpec defines 0 on an accumulator as "not accumulated", and some firmware
transiently reports it around the sleep/wake transition; a producing
inverter's lifetime counter is never genuinely 0.
"""
Comment thread README.md Outdated
Comment on lines +115 to +119
`async_probe` validates the SunSpec header and detects which meters, batteries
and control blocks are present. `async_update` refreshes every component in as
few Modbus reads as possible. Values decode to `None` when the device reports a
point as not implemented.
point as not implemented, including a lifetime energy of 0 (SunSpec's "not
accumulated", transiently reported by some firmware around sleep/wake).
Copilot AI review requested due to automatic review settings July 15, 2026 07:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread tests/test_solaredged.py
Comment on lines +426 to +431
"""A lifetime energy of 0 decodes to None per acc32 semantics.

SunSpec defines 0 on an accumulator as "not accumulated", and some firmware
transiently reports it around the sleep/wake transition; a producing
inverter's lifetime counter is never genuinely 0.
"""
Comment thread README.md Outdated
Comment on lines +118 to +121
component in as few Modbus reads as possible. Values decode to `None` when the
device reports a point as not implemented, and `on_grid` is `None` on firmware
without the extension.
device reports a point as not implemented, including a lifetime energy of 0
(SunSpec's "not accumulated", transiently reported by some firmware around
sleep/wake), and `on_grid` is `None` on firmware without the extension.
Copilot AI review requested due to automatic review settings July 15, 2026 07:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread tests/test_solaredged.py
Comment on lines +469 to +474
"""A lifetime energy of 0 decodes to None per acc32 semantics.

SunSpec defines 0 on an accumulator as "not accumulated", and some firmware
transiently reports it around the sleep/wake transition; a producing
inverter's lifetime counter is never genuinely 0.
"""
Comment thread README.md
Comment on lines 118 to +122
component in as few Modbus reads as possible. Values decode to `None` when the
device reports a point as not implemented, `on_grid` is `None` on firmware
without the extension, and a battery state of energy or health outside 0-100
(reported by initializing batteries) decodes to `None` as well.
device reports a point as not implemented, including a lifetime energy of 0
(SunSpec's "not accumulated", transiently reported by some firmware around
sleep/wake). `on_grid` is `None` on firmware without the extension, and a
battery state of energy or health outside 0-100 (reported by initializing
@frenck
frenck merged commit aa8ce46 into main Jul 15, 2026
31 checks passed
@frenck
frenck deleted the frenck/inverter-energy-acc32 branch July 15, 2026 07:23
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bugfix Inconsistencies or issues which will cause a problem for users or implementers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants