Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 53 additions & 36 deletions packages/modules/devices/sungrow/sungrow/bat.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from modules.common.simcount import SimCounter
from modules.common.store import get_bat_value_store
from modules.devices.sungrow.sungrow.config import SungrowBatSetup, Sungrow
from modules.devices.sungrow.sungrow.version import Version
from modules.devices.sungrow.sungrow.firmware import Firmware
from modules.devices.sungrow.sungrow.registers import RegMode

log = logging.getLogger(__name__)

Expand All @@ -33,52 +32,70 @@ def initialize(self) -> None:
self.store = get_bat_value_store(self.component_config.id)
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.last_mode = 'Undefined'
self.firmware_check = self.check_firmware_register()
self.register_check = self.detect_register_check()

def check_firmware_register(self) -> bool:
if Firmware(self.device_config.configuration.firmware) == Firmware.v1:
return False
def detect_register_check(self) -> RegMode:
# Battery register availability test
unit = self.device_config.configuration.modbus_id

try:
self.__tcp_client.read_input_registers(5213, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=unit)
log.debug("Wechselrichter Firmware ist größer gleich 95.09")
return True
self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, unit=unit)
log.debug("Battery register check: using new_registers (5213/5630).")
return RegMode.NEW_REGISTERS
except Exception:
pass

try:
self.__tcp_client.read_input_registers(13000, ModbusDataType.UINT_16, unit=unit)
log.debug("Battery register check: using old_registers (13021 + 13000 bits for sign).")
return RegMode.OLD_REGISTERS
except Exception:
log.debug("Wechselrichter Firmware ist kleiner als 95.09")
return False
pass

log.debug("Battery register check: using fallback (13021 + total vs PV power).")
return RegMode.FALLBACK

def update(self) -> None:
unit = self.device_config.configuration.modbus_id

soc = int(self.__tcp_client.read_input_registers(13022, ModbusDataType.UINT_16, unit=unit) / 10)
version = Version(self.device_config.configuration.version)

if Firmware(self.device_config.configuration.firmware) == Firmware.v2:
if self.firmware_check: # Firmware >= 95.09
bat_current = self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, unit=unit) * -0.1
bat_power = self.__tcp_client.read_input_registers(5213, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=unit) * -1
else: # Firmware between 95.03 and 95.09
bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, unit=unit) * -0.1
if version == Version.SH:
bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.INT_16, unit=unit)
elif version == Version.SH_winet_dongle:
bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, unit=unit)
total_power = self.__tcp_client.read_input_registers(13033, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=unit)
pv_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
wordorder=Endian.Little, unit=unit)
if total_power > pv_power:
bat_power = bat_power * -1
else: # Firmware.v1 (Firmware < 95.03)

# === Mode 1: new_registers ===
if self.register_check == RegMode.NEW_REGISTERS:
bat_current = self.__tcp_client.read_input_registers(5630, ModbusDataType.INT_16, unit=unit) * -0.1
bat_power = self.__tcp_client.read_input_registers(5213, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=unit) * -1

# === Mode 2: old_registers ===
elif self.register_check == RegMode.OLD_REGISTERS:
bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, unit=unit) * -0.1
bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, unit=unit)
if version in (Version.SH, Version.SH_winet_dongle):
resp = self.__tcp_client._delegate.read_input_registers(13000, 1, unit=unit)
binary = bin(resp.registers[0])[2:].zfill(8)
if binary[5] == "1":
bat_power = bat_power * -1

resp = self.__tcp_client._delegate.read_input_registers(13000, 1, unit=unit)
running_state = resp.registers[0]
is_charging = (running_state & 0x02) != 0
is_discharging = (running_state & 0x04) != 0

if is_discharging:
bat_power = -abs(bat_power)
elif is_charging:
bat_power = abs(bat_power)

# === Mode 3: fallback ===
else:
bat_current = self.__tcp_client.read_input_registers(13020, ModbusDataType.INT_16, unit=unit) * -0.1
bat_power = self.__tcp_client.read_input_registers(13021, ModbusDataType.UINT_16, unit=unit)

total_power = self.__tcp_client.read_input_registers(13033, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=unit)
pv_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
wordorder=Endian.Little, unit=unit)

if total_power > pv_power:
bat_power = -abs(bat_power)
else:
bat_power = abs(bat_power)

currents = [bat_current / 3] * 3

Expand Down
5 changes: 1 addition & 4 deletions packages/modules/devices/sungrow/sungrow/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from modules.common.component_setup import ComponentSetup
from modules.devices.sungrow.sungrow.version import Version
from modules.devices.sungrow.sungrow.firmware import Firmware
from ..vendor import vendor_descriptor


Expand All @@ -11,13 +10,11 @@ def __init__(self,
ip_address: Optional[str] = None,
port: int = 502,
modbus_id: int = 1,
version: Version = Version.SG,
firmware: Firmware = Firmware.v1):
version: Version = Version.SG):
self.ip_address = ip_address
self.port = port
self.modbus_id = modbus_id
self.version = version
self.firmware = firmware


class Sungrow:
Expand Down
6 changes: 0 additions & 6 deletions packages/modules/devices/sungrow/sungrow/firmware.py

This file was deleted.

15 changes: 6 additions & 9 deletions packages/modules/devices/sungrow/sungrow/inverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,17 @@ def update(self) -> float:
dc_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
wordorder=Endian.Little, unit=unit) * -1

current_L1 = self.__tcp_client.read_input_registers(13030, ModbusDataType.INT_16, unit=unit) * -0.1
current_L2 = self.__tcp_client.read_input_registers(13031, ModbusDataType.INT_16, unit=unit) * -0.1
current_L3 = self.__tcp_client.read_input_registers(13032, ModbusDataType.INT_16, unit=unit) * -0.1
currents = [current_L1, current_L2, current_L3]
else:
currents = self.__tcp_client.read_input_registers(13030, [ModbusDataType.INT_16]*3, unit=unit)
currents = [value * -0.1 for value in currents]

elif self.device_config.configuration.version in (Version.SG, Version.SG_winet_dongle):
power = self.__tcp_client.read_input_registers(5030, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=unit) * -1
dc_power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32,
wordorder=Endian.Little, unit=unit) * -1

current_L1 = self.__tcp_client.read_input_registers(5021, ModbusDataType.UINT_16, unit=unit) * -0.1
current_L2 = self.__tcp_client.read_input_registers(5022, ModbusDataType.UINT_16, unit=unit) * -0.1
current_L3 = self.__tcp_client.read_input_registers(5023, ModbusDataType.UINT_16, unit=unit) * -0.1
currents = [current_L1, current_L2, current_L3]
currents = self.__tcp_client.read_input_registers(5021, [ModbusDataType.INT_16]*3, unit=unit)
currents = [value * -0.1 for value in currents]

imported, exported = self.sim_counter.sim_count(power)

Expand Down
7 changes: 7 additions & 0 deletions packages/modules/devices/sungrow/sungrow/registers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from enum import Enum


class RegMode(Enum):
NEW_REGISTERS = "new_registers"
OLD_REGISTERS = "old_registers"
FALLBACK = "fallback"