Decode a lifetime energy of 0 as not accumulated#11
Merged
Conversation
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.
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
…y-acc32 # Conflicts: # README.md
There was a problem hiding this comment.
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_energyasacc32(instead ofuint32) so0decodes toNone. - 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 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 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). |
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 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. |
…y-acc32 # Conflicts: # README.md
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 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Breaking change
A factory-new inverter that has not produced yet reads
ac_energyasNoneinstead of0until 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 asuint32, 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 itsSunSpecAccum.NA32check, home-assistant-solaredge-modbus via a> 0validation).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
Additional information
Checklist
poetry run pytestpasses locally. A pull request cannot be merged unless CI is green.poetry run prek run --all-filespasses (lint, format, and type checks).