Skip to content

fix(sunsynk,deye): own the power sign flags instead of inheriting them - #4618

Merged
springfall2008 merged 1 commit into
mainfrom
fix/sunsynk-deye-sign-flags
Aug 20, 2026
Merged

fix(sunsynk,deye): own the power sign flags instead of inheriting them#4618
springfall2008 merged 1 commit into
mainfrom
fix/sunsynk-deye-sign-flags

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

The bug

base.args is a single shared dict and is not namespaced per inverter type, so whichever component sets grid_power_invert sets it for every inverter index on the install.

teslemetry.py:646 and fox.py:2235 both set it True for their own hardware — quite correctly. Sunsynk and Deye never claimed the key at all, so on an install running either of those alongside them, they inherited the flip:

sensor.predbat_sunsynk_<sn>_grid_power  = +506  (exporting, correct)
  → inverter.grid_power                 = +506
  → grid_power_invert, left True by another component → −506
  → Predbat reads negative as importing → power-flow arrow reversed

Verified live that the component itself publishes the correct sign — raw pac −506 with the day's counters at 0.0 kWh imported against 10.7 kWh exported, published as +506, which is Predbat's documented convention (negative import, positive export). So the sensor was right and the flag was flipping it afterwards.

The fix

Both components now set grid_power_invert, battery_power_invert and load_power_invert explicitly to False in automatic_config.

Setting them rather than relying on the default is the whole point: a default only applies when nothing else has written the key, which is exactly the case that was failing.

False is right for all three because publish_data already emits Predbat's conventions — grid negative on import (SUNSYNK_TELEMETRY_NEGATE / DEYE_TELEMETRY_NEGATE), battery positive on discharge, load positive — each confirmed against live hardware.

Testing

A regression test per component asserting all three flags are claimed with one entry per inverter, so neither can silently go back to inheriting. Full --quick suite green, pre-commit clean.

🤖 Generated with Claude Code

base.args is a single shared dict and is NOT namespaced per inverter type, so
whichever component sets grid_power_invert sets it for every inverter index on
the install. teslemetry and fox both set it True for their own hardware, quite
correctly - and a Sunsynk or DEYE inverter that never claimed the key inherited
that flip.

The effect on an install running Sunsynk alongside either of them: the component
publishes a correct grid sensor (+506 W while exporting, verified live), then
inverter.py negates it again on the inherited flag, so the export reads as an
import and the power-flow arrow points the wrong way.

All three flags are now set explicitly to False, because publish_data already
emits Predbat's conventions - grid negative on import (SUNSYNK_TELEMETRY_NEGATE /
DEYE_TELEMETRY_NEGATE), battery positive on discharge, load positive - each
confirmed live. Setting them rather than relying on the default is the point: a
default only applies when nothing else has written the key, which is exactly the
case that was failing.

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

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 a cross-component configuration leak where grid_power_invert/battery_power_invert/load_power_invert could be unintentionally inherited via the shared base.args dict, causing Sunsynk and Deye power-flow signs to be flipped after publishing already-correct sensor values.

Changes:

  • Explicitly sets grid_power_invert, battery_power_invert, and load_power_invert to False in automatic_config() for Sunsynk and Deye so they always “own” these flags.
  • Adds regression tests for both components to ensure all three flags are always set and are per-inverter lists (one entry per inverter index).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
apps/predbat/sunsynk.py Sets all three invert flags explicitly to False during Sunsynk auto-discovery to prevent inherited sign flips.
apps/predbat/deye.py Sets all three invert flags explicitly to False during Deye auto-discovery to prevent inherited sign flips.
apps/predbat/tests/test_sunsynk_config.py Adds a regression test asserting the invert flags are claimed and correctly sized per inverter.
apps/predbat/tests/test_deye_publish.py Adds a regression test asserting the invert flags are claimed and correctly sized per inverter.

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

@springfall2008
springfall2008 merged commit d805d81 into main Aug 20, 2026
3 checks passed
@springfall2008
springfall2008 deleted the fix/sunsynk-deye-sign-flags branch August 20, 2026 16:35
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