1010from modules .common .simcount import SimCounter
1111from modules .common .store import get_bat_value_store
1212from modules .devices .sungrow .sungrow .config import SungrowBatSetup , Sungrow
13- from modules .devices .sungrow .sungrow .version import Version
14- from modules .devices .sungrow .sungrow .firmware import Firmware
13+ from modules .devices .sungrow .sungrow .registers import RegMode
1514
1615log = logging .getLogger (__name__ )
1716
@@ -33,52 +32,70 @@ def initialize(self) -> None:
3332 self .store = get_bat_value_store (self .component_config .id )
3433 self .fault_state = FaultState (ComponentInfo .from_component_config (self .component_config ))
3534 self .last_mode = 'Undefined'
36- self .firmware_check = self .check_firmware_register ()
35+ self .register_check = self .detect_register_check ()
3736
38- def check_firmware_register (self ) -> bool :
39- if Firmware (self .device_config .configuration .firmware ) == Firmware .v1 :
40- return False
37+ def detect_register_check (self ) -> RegMode :
38+ # Battery register availability test
4139 unit = self .device_config .configuration .modbus_id
40+
4241 try :
4342 self .__tcp_client .read_input_registers (5213 , ModbusDataType .INT_32 ,
4443 wordorder = Endian .Little , unit = unit )
45- log .debug ("Wechselrichter Firmware ist größer gleich 95.09" )
46- return True
44+ self .__tcp_client .read_input_registers (5630 , ModbusDataType .INT_16 , unit = unit )
45+ log .debug ("Battery register check: using new_registers (5213/5630)." )
46+ return RegMode .NEW_REGISTERS
47+ except Exception :
48+ pass
49+
50+ try :
51+ self .__tcp_client .read_input_registers (13000 , ModbusDataType .UINT_16 , unit = unit )
52+ log .debug ("Battery register check: using old_registers (13021 + 13000 bits for sign)." )
53+ return RegMode .OLD_REGISTERS
4754 except Exception :
48- log .debug ("Wechselrichter Firmware ist kleiner als 95.09" )
49- return False
55+ pass
56+
57+ log .debug ("Battery register check: using fallback (13021 + total vs PV power)." )
58+ return RegMode .FALLBACK
5059
5160 def update (self ) -> None :
5261 unit = self .device_config .configuration .modbus_id
53-
5462 soc = int (self .__tcp_client .read_input_registers (13022 , ModbusDataType .UINT_16 , unit = unit ) / 10 )
55- version = Version (self .device_config .configuration .version )
56-
57- if Firmware (self .device_config .configuration .firmware ) == Firmware .v2 :
58- if self .firmware_check : # Firmware >= 95.09
59- bat_current = self .__tcp_client .read_input_registers (5630 , ModbusDataType .INT_16 , unit = unit ) * - 0.1
60- bat_power = self .__tcp_client .read_input_registers (5213 , ModbusDataType .INT_32 ,
61- wordorder = Endian .Little , unit = unit ) * - 1
62- else : # Firmware between 95.03 and 95.09
63- bat_current = self .__tcp_client .read_input_registers (13020 , ModbusDataType .INT_16 , unit = unit ) * - 0.1
64- if version == Version .SH :
65- bat_power = self .__tcp_client .read_input_registers (13021 , ModbusDataType .INT_16 , unit = unit )
66- elif version == Version .SH_winet_dongle :
67- bat_power = self .__tcp_client .read_input_registers (13021 , ModbusDataType .UINT_16 , unit = unit )
68- total_power = self .__tcp_client .read_input_registers (13033 , ModbusDataType .INT_32 ,
69- wordorder = Endian .Little , unit = unit )
70- pv_power = self .__tcp_client .read_input_registers (5016 , ModbusDataType .UINT_32 ,
71- wordorder = Endian .Little , unit = unit )
72- if total_power > pv_power :
73- bat_power = bat_power * - 1
74- else : # Firmware.v1 (Firmware < 95.03)
63+
64+ # === Mode 1: new_registers ===
65+ if self .register_check == RegMode .NEW_REGISTERS :
66+ bat_current = self .__tcp_client .read_input_registers (5630 , ModbusDataType .INT_16 , unit = unit ) * - 0.1
67+ bat_power = self .__tcp_client .read_input_registers (5213 , ModbusDataType .INT_32 ,
68+ wordorder = Endian .Little , unit = unit ) * - 1
69+
70+ # === Mode 2: old_registers ===
71+ elif self .register_check == RegMode .OLD_REGISTERS :
7572 bat_current = self .__tcp_client .read_input_registers (13020 , ModbusDataType .INT_16 , unit = unit ) * - 0.1
7673 bat_power = self .__tcp_client .read_input_registers (13021 , ModbusDataType .UINT_16 , unit = unit )
77- if version in (Version .SH , Version .SH_winet_dongle ):
78- resp = self .__tcp_client ._delegate .read_input_registers (13000 , 1 , unit = unit )
79- binary = bin (resp .registers [0 ])[2 :].zfill (8 )
80- if binary [5 ] == "1" :
81- bat_power = bat_power * - 1
74+
75+ resp = self .__tcp_client ._delegate .read_input_registers (13000 , 1 , unit = unit )
76+ running_state = resp .registers [0 ]
77+ is_charging = (running_state & 0x02 ) != 0
78+ is_discharging = (running_state & 0x04 ) != 0
79+
80+ if is_discharging :
81+ bat_power = - abs (bat_power )
82+ elif is_charging :
83+ bat_power = abs (bat_power )
84+
85+ # === Mode 3: fallback ===
86+ else :
87+ bat_current = self .__tcp_client .read_input_registers (13020 , ModbusDataType .INT_16 , unit = unit ) * - 0.1
88+ bat_power = self .__tcp_client .read_input_registers (13021 , ModbusDataType .UINT_16 , unit = unit )
89+
90+ total_power = self .__tcp_client .read_input_registers (13033 , ModbusDataType .INT_32 ,
91+ wordorder = Endian .Little , unit = unit )
92+ pv_power = self .__tcp_client .read_input_registers (5016 , ModbusDataType .UINT_32 ,
93+ wordorder = Endian .Little , unit = unit )
94+
95+ if total_power > pv_power :
96+ bat_power = - abs (bat_power )
97+ else :
98+ bat_power = abs (bat_power )
8299
83100 currents = [bat_current / 3 ] * 3
84101
0 commit comments