Skip to content

Fix: Solakon One: power values - #4316

Open
seaspotter wants to merge 4 commits into
openWB:masterfrom
seaspotter:fix-solakon-one-battery-register
Open

seaspotter wants to merge 4 commits into
openWB:masterfrom
seaspotter:fix-solakon-one-battery-register

Conversation

@seaspotter

@seaspotter seaspotter commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

UI: openWB/openwb-ui-settings#1170

Fixes #3852: seit #3497 liest bat.py Register 39237 ("Battery Combined Power") für die Batterieleistung. Dieses Register existiert laut der offiziellen Solakon-Dokumentation (https://github.com/solakon-de/solakon-one-homeassistant/blob/main/custom_components/solakon_one/const.py) überhaupt nicht - das echte, dort dokumentierte Batterieleistungsregister ist 39230 ("battery_power").

Zusätzlich: neuer counter-Baustein (Reg 39134, "Grid Information") für Nutzer ohne separaten Zähler, inverter.py zurück auf reine PV-Register (39118/39601).

Summary by Sourcery

Correct Solakon One power measurements and add integrated grid-meter support for installations without a separate counter.

New Features:

  • Add support for Solakon One installations that use the inverter’s integrated grid meter as a counter.
  • Expose Solakon One counter configuration and component handling.

Bug Fixes:

  • Read battery power from the documented Solakon One battery-power register.
  • Prevent inverter power and energy values from being sourced from grid measurements by using the PV registers instead.

Enhancements:

  • Use simulated counting for inverter-imported energy when only PV measurements are available.

@sourcery-ai

sourcery-ai Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Linked issues

Checked at commit fe7d80f

#3852 [BUG] Solakon ONE: statt Netz- nun Batterieleistung ausgewertet / Werte verfälscht · 1 of 1 met

# Requirement Status Notes
1 Use grid-connection power, not battery power, for grid readings. ✅ Met The counter reads documented Grid Information register 39134 for power; the battery component now reads battery register 39230.

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="packages/modules/devices/solakon/solakon_one/bat.py" line_range="36" />
<code_context>
-        # Reg 39237 Battery Combined Power
-        power = self.client.read_holding_registers(39237, ModbusDataType.INT_32, unit=unit)
+        # Reg 39230 Battery Power, laut Hersteller-Doku positiv beim Laden, negativ beim Entladen
+        power = self.client.read_holding_registers(39230, ModbusDataType.INT_32, unit=unit)
         # SoC Ladezustand der Batterie in %
         soc = self.client.read_holding_registers(39424, ModbusDataType.INT_16, unit=unit)
</code_context>
<issue_to_address>
**Still reads battery power**

The issue asks for power at the grid connection, as before, because battery-power readings distort the values. This change reads register 39230 for battery power instead.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@seaspotter seaspotter changed the title Fix: Solakon One: bat power Fix: Solakon One: power values Nov 12, 2026
@seaspotter

Copy link
Copy Markdown
Collaborator Author

@sourcery-ai review

@seaspotter
seaspotter requested a review from ndrsnhs November 12, 2026 23:47

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 5 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="packages/modules/devices/solakon/solakon_one/counter.py" line_range="35" />
<code_context>
+
+        # Reg 39134 AC Leistung am Stecker (Grid Information laut Hersteller-Doku), Bezug hat positive Werte,
+        # Einspeisung hat negative Werte
+        power = self.client.read_holding_registers(39134, ModbusDataType.INT_32, unit=unit) * -1
+
+        # Gesamte Netzeinspeisung/-bezug in Wh
</code_context>
<issue_to_address>
**Grid power direction is reversed**

When the grid register reports its documented positive-import or negative-export value, `power` negates register 39134 before storing it in `CounterState`, so imports are reported as exports and exports as imports; `CounterAll` then uses the reversed power for consumption calculations, and callers see incorrect grid direction and consumption.

Store register 39134 without reversing its documented sign.
</issue_to_address>

### Comment 2
<location path="packages/modules/devices/solakon/solakon_one/inverter.py" line_range="41" />
<code_context>
+        power = self.client.read_holding_registers(39118, ModbusDataType.INT_32, unit=unit) * -1
+        # Gesamte DC PV Produktion in Wh
+        exported = self.client.read_holding_registers(39601, ModbusDataType.UINT_32, unit=unit) * 10
+        imported, _ = self.sim_counter.sim_count(power)

         imported, exported = self.peak_filter.check_values(power, imported, exported)
</code_context>
<issue_to_address>
**AC imports are not accumulated**

When the inverter consumes or charges from AC while PV output is absent or generating, `power` comes from the DC PV register and is negated before `sim_counter.sim_count()`, which counts generation as export; assigning only its imported result leaves `InverterState.imported` unchanged, so AC consumption is not reported.

Derive simulated imported energy from an AC-import measurement rather than the DC PV power register.

Also at `packages/modules/devices/solakon/solakon_one/inverter.py:42`.
</issue_to_address>

### Comment 3
<location path="packages/modules/devices/solakon/solakon_one/inverter.py" line_range="38" />
<code_context>
-        exported = self.client.read_holding_registers(39621, ModbusDataType.UINT_32, unit=unit) * 10
-        imported = self.client.read_holding_registers(39625, ModbusDataType.UINT_32, unit=unit) * 10
+        # Gesamte DC PV Leistung aller vier MPPT in W
+        power = self.client.read_holding_registers(39118, ModbusDataType.INT_32, unit=unit) * -1
+        # Gesamte DC PV Produktion in Wh
+        exported = self.client.read_holding_registers(39601, ModbusDataType.UINT_32, unit=unit) * 10
</code_context>
<issue_to_address>
**Valid PV readings are rejected**

When DC PV power exceeds twice the configured AC output maximum, `PeakFilter.check_values()` compares the DC PV reading with the AC output maximum and rejects the update, so valid inverter data is omitted and the inverter state is not refreshed.

Validate the DC PV reading against an appropriate DC limit instead of the configured AC output maximum.

Also at `packages/modules/devices/solakon/solakon_one/inverter.py:39`.
</issue_to_address>

### Comment 4
<location path="packages/modules/devices/solakon/solakon_one/inverter.py" line_range="41" />
<code_context>
+        power = self.client.read_holding_registers(39118, ModbusDataType.INT_32, unit=unit) * -1
+        # Gesamte DC PV Produktion in Wh
+        exported = self.client.read_holding_registers(39601, ModbusDataType.UINT_32, unit=unit) * 10
+        imported, _ = self.sim_counter.sim_count(power)

         imported, exported = self.peak_filter.check_values(power, imported, exported)
</code_context>
<issue_to_address>
**Rejected samples still change energy**

When a power reading exceeds twice the configured inverter maximum, `sim_counter.sim_count()` persists the sample and accumulated energy before `peak_filter.check_values()` rejects it, so the failed update still advances the simulated total and callers see incorrect inverter energy.

Reject the sample before updating the simulated counter state.
</issue_to_address>

### Comment 5
<location path="packages/modules/devices/solakon/solakon_one/inverter.py" line_range="41" />
<code_context>
+        power = self.client.read_holding_registers(39118, ModbusDataType.INT_32, unit=unit) * -1
+        # Gesamte DC PV Produktion in Wh
+        exported = self.client.read_holding_registers(39601, ModbusDataType.UINT_32, unit=unit) * 10
+        imported, _ = self.sim_counter.sim_count(power)

         imported, exported = self.peak_filter.check_values(power, imported, exported)
</code_context>
<issue_to_address>
**Simulated import resets on restart**

When the service restarts after the inverter has accumulated simulated import energy, `sim_counter.sim_count(power)` restores the inverter’s simulated state through `SimCounterStoreBroker.initialize`, which explicitly initializes inverter `imported` energy to 0 instead of restoring its last value. After a service restart, the inverter’s accumulated simulated import therefore starts over and callers see the energy total drop.

Restore the inverter’s last imported total during SimCounter initialization now that inverter imports are simulated.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

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.

[BUG] Solakon ONE: statt Netz- nun Batterieleistung ausgewertet / Werte verfälscht

1 participant