diff --git a/haos-addon/config.yaml b/haos-addon/config.yaml index 97ac4cf..0eb132e 100644 --- a/haos-addon/config.yaml +++ b/haos-addon/config.yaml @@ -1,5 +1,5 @@ name: ShineBridge -version: "1.1.4" +version: "1.1.5" slug: shinebridge description: Growatt Wechselrichter lokal in Home Assistant — Modbus TCP via ShineLAN-X, MQTT Discovery, Web UI url: https://gitea.bitfire.work/retr0/Growatt-Wechselrichter-HAOS diff --git a/haos-addon/src/inverters.py b/haos-addon/src/inverters.py index dde608a..952f4b9 100644 --- a/haos-addon/src/inverters.py +++ b/haos-addon/src/inverters.py @@ -7,12 +7,13 @@ class Sensor: id: str name: str reg: int - count: int # 1 = uint16, 2 = uint32 (high word first) + count: int # number of 16-bit registers (1 or 2) scale: float unit: str device_class: Optional[str] state_class: str icon: str + data_type: str = "uint16" # "uint16", "uint32", "float32" @dataclass @@ -95,6 +96,28 @@ def _mod_sensors() -> List[Sensor]: ] +def _sdm630_sensors() -> List[Sensor]: + f = "float32" + return [ + Sensor("voltage_l1", "Spannung L1", 0, 2, 1.0, "V", "voltage", "measurement", "mdi:flash", f), + Sensor("voltage_l2", "Spannung L2", 2, 2, 1.0, "V", "voltage", "measurement", "mdi:flash", f), + Sensor("voltage_l3", "Spannung L3", 4, 2, 1.0, "V", "voltage", "measurement", "mdi:flash", f), + Sensor("current_l1", "Strom L1", 6, 2, 1.0, "A", "current", "measurement", "mdi:flash", f), + Sensor("current_l2", "Strom L2", 8, 2, 1.0, "A", "current", "measurement", "mdi:flash", f), + Sensor("current_l3", "Strom L3", 10, 2, 1.0, "A", "current", "measurement", "mdi:flash", f), + Sensor("power_l1", "Wirkleistung L1", 12, 2, 1.0, "W", "power", "measurement", "mdi:flash", f), + Sensor("power_l2", "Wirkleistung L2", 14, 2, 1.0, "W", "power", "measurement", "mdi:flash", f), + Sensor("power_l3", "Wirkleistung L3", 16, 2, 1.0, "W", "power", "measurement", "mdi:flash", f), + Sensor("power_factor_l1", "Leistungsfaktor L1", 30, 2, 1.0, "", None, "measurement", "mdi:sine-wave", f), + Sensor("power_factor_l2", "Leistungsfaktor L2", 32, 2, 1.0, "", None, "measurement", "mdi:sine-wave", f), + Sensor("power_factor_l3", "Leistungsfaktor L3", 34, 2, 1.0, "", None, "measurement", "mdi:sine-wave", f), + Sensor("total_power", "Gesamtwirkleistung", 48, 2, 1.0, "W", "power", "measurement", "mdi:transmission-tower", f), + Sensor("frequency", "Frequenz", 70, 2, 1.0, "Hz", "frequency", "measurement", "mdi:sine-wave", f), + Sensor("import_kwh", "Bezug Gesamt", 72, 2, 1.0, "kWh", "energy", "total_increasing", "mdi:transmission-tower-import", f), + Sensor("export_kwh", "Einspeisung Gesamt", 74, 2, 1.0, "kWh", "energy", "total_increasing", "mdi:transmission-tower-export", f), + ] + + INVERTERS = { "MIC_1500_TL_X": Inverter( id="MIC_1500_TL_X", @@ -124,4 +147,11 @@ INVERTERS = { sensors=_mod_sensors(), read_ranges=[(3, 91), (93, 1)], ), + "SDM_630": Inverter( + id="SDM_630", + name="Eastron SDM-630", + manufacturer="Eastron", + sensors=_sdm630_sensors(), + read_ranges=[(0, 76)], # regs 0-75, alle 16 Sensoren + ), } diff --git a/haos-addon/src/modbus_client.py b/haos-addon/src/modbus_client.py index 857c1cf..974080d 100644 --- a/haos-addon/src/modbus_client.py +++ b/haos-addon/src/modbus_client.py @@ -1,4 +1,5 @@ import logging +import struct import time from typing import Dict, Optional @@ -66,12 +67,18 @@ def _extract_sensors(sensors: list, regs: Dict[int, int]) -> Dict[str, float]: if s.reg not in regs: log.warning("Register %d fehlt in Antwort (%s)", s.reg, s.id) continue - if s.count == 2: + data_type = getattr(s, "data_type", "uint16") + if data_type == "float32": if s.reg + 1 not in regs: - log.warning("Register %d (high word) fehlt (%s)", s.reg + 1, s.id) + log.warning("Register %d+1 fehlt (%s)", s.reg, s.id) continue - raw = (regs[s.reg] << 16) | regs[s.reg + 1] + raw_val = struct.unpack(">f", struct.pack(">HH", regs[s.reg], regs[s.reg + 1]))[0] + elif s.count == 2: + if s.reg + 1 not in regs: + log.warning("Register %d+1 fehlt (%s)", s.reg, s.id) + continue + raw_val = ((regs[s.reg] << 16) | regs[s.reg + 1]) * s.scale else: - raw = regs[s.reg] - values[s.id] = round(raw * s.scale, 3) + raw_val = regs[s.reg] * s.scale + values[s.id] = round(raw_val, 3) return values diff --git a/haos-addon/src/web/index.html b/haos-addon/src/web/index.html index 370f08b..a778b65 100644 --- a/haos-addon/src/web/index.html +++ b/haos-addon/src/web/index.html @@ -161,7 +161,7 @@
Live-Daten
-
Wechselrichter
+
Geräte
Einstellungen
@@ -195,11 +195,11 @@