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
27 changes: 11 additions & 16 deletions packages/modules/devices/sofar/sofar/bat.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,22 @@ def __init__(self,
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))

def update(self, client: ModbusTcpClient_) -> None:
# 0x0606 Power_bat1 Int16 in kW accuracy 0,01
# 0x060D Power_bat2, 0x0614 Power_bat3, 0x061B Power_bat4, 0x0622 Power_bat5,
# 0x0629 Power_bat6, 0x0630 Power_bat7, 0x0637 Power_bat8
# 0x0646 Power_bat9, 0x064D Power_bat10, 0x0654 Power_bat11, 0x065B Power_bat12
power = sum(client.read_input_registers(reg, ModbusDataType.INT_16, unit=self.__modbus_id)
for reg in [0x0606, 0x060D, 0x0614, 0x061B, 0x0622, 0x0629, 0x0630,
0x0637, 0x0646, 0x064D, 0x0654, 0x065B])
# 0x0608 SOC_Bat1 UInt16 in % accuracy 1
# 0x060F SOC_bat2, 0x0616 SOC_bat3, 0x061D SOC_bat4, 0x0624 SOC_bat5,
# 0x062B SOC_bat6, 0x0632 SOC_bat7, 0x0639 SOC_bat_8
# 0x0648 SOC_bat9, 0x064F SOC_bat10, 0x0656 SOC_bat11, 0x065D SOC_bat12
soc = sum(client.read_input_registers(0x0608, ModbusDataType.UINT_16, unit=self.__modbus_id)
for reg in [0x0608, 0x060F, 0x0616, 0x061D, 0x0624, 0x062B, 0x0632,
0x0639, 0x0648, 0x064F, 0x0656, 0x065D])
# 0x900D High 8 bits: the number of battery packs in parallel
# Lower 8 bits: the number of battery strings in the battery pack
battery_packs = client.read_holding_registers(0x900D, ModbusDataType.UINT_16, unit=self.__modbus_id) >> 8
# Power bat1 - bat12: INT_16 in kW accuracy 0,01
power_regs = [0x0606, 0x060D, 0x0614, 0x061B, 0x0622, 0x0629, 0x0630, 0x0637, 0x0646, 0x064D, 0x0654, 0x065B]

power = sum(client.read_holding_registers(power_regs[idx], ModbusDataType.INT_16, unit=self.__modbus_id)
for idx in range(battery_packs)) * 10
soc = client.read_holding_registers(0x9012, ModbusDataType.UINT_16, unit=self.__modbus_id)
# 0x0696 Bat_charge_total LSB UInt32 0,1 kWh
# 0x0697 Bat_charge_total UInt32 0,1 kWh
imported = client.read_input_registers(
imported = client.read_holding_registers(
0x0696, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
# 0x069A Bat_discharge_total LSB UInt32 0,1 kWh
# 0x069B Bat:discharge_total UInt32 0,1 kWh
exported = client.read_input_registers(
exported = client.read_holding_registers(
0x069A, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100

bat_state = BatState(
Expand Down
55 changes: 13 additions & 42 deletions packages/modules/devices/sofar/sofar/counter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
from typing import Dict, Union
from pymodbus.constants import Endian

from dataclass_utils import dataclass_from_dict
from modules.common.abstract_device import AbstractCounter
Expand All @@ -24,58 +23,30 @@ def __init__(self,
def update(self, client: ModbusTcpClient_):
# 0x0485 ActivePower_output_total Int16 in kW accuracy 0,01 discharge + charge -
# 0x0488 ActivePower_PCC_total Int16 0,01 kW
power = client.read_input_registers(0x0488, ModbusDataType.INT_16, wordorder=Endian.Little,
unit=self.__modbus_id) * -1
power = client.read_holding_registers(0x0488, ModbusDataType.INT_16, unit=self.__modbus_id) * -10
# 0x0484 Frequency_Grid UInt16 in Hz accuracy 0,01
frequency = client.read_input_registers(
frequency = client.read_holding_registers(
0x0484, ModbusDataType.UINT_16, unit=self.__modbus_id) / 100
try:
# 0x048F ActivePower_Output_R UInt16 in V accuracy 0,1
# 0x0493 ActivePower_PCC_R Int16 in kW accuracy 0,01
powers = [-value for value in client.read_input_registers(
0x0493, [ModbusDataType.INT_16] * 1, wordorder=Endian.Little, unit=self.__modbus_id
)]
powers = [
client.read_holding_registers(0x0493, ModbusDataType.INT_16, unit=self.__modbus_id) * -10,
client.read_holding_registers(0x049E, ModbusDataType.INT_16, unit=self.__modbus_id) * -10,
client.read_holding_registers(0x04A9, ModbusDataType.INT_16, unit=self.__modbus_id) * -10]
except Exception:
powers = None
try:
voltages = [client.read_input_registers(
# 048D Voltage_Phase_R UInt16 in V accuracy 0,1
0x048D, ModbusDataType.UINT_16, unit=self.__modbus_id
) / 10, client.read_input_registers(
# 0498 Voltage_Phase_S UInt16 in V accuracy 0,1
0x0498, ModbusDataType.UINT_16, unit=self.__modbus_id
) / 10, client.read_input_registers(
# 04A3 Voltage_Phase_T UInt16 in V accuracy 0,1
0x04A3, ModbusDataType.UINT_16, unit=self.__modbus_id
) / 10]
if voltages[0] < 1:
voltages[0] = 230
if voltages[1] < 1:
voltages[1] = 230
if voltages[2] < 1:
voltages[2] = 230
except Exception:
voltages = [230, 230, 230]
exported = [value * 10
for value in client.read_input_registers(
# 0x0692 Energy_Selling_Total UInt32 in kwH accuracy 0,01 LSB
# 0x0693 Energy_Selling_Total UInt32 in kwH accuracy 0,01
0x0692, [ModbusDataType.UINT_32] * 10,
wordorder=Endian.Little, unit=self.__modbus_id)]
imported = [value * 10
for value in client.read_input_registers(
# 0x068E Energy_Purchase_Total UInt32 in kwH accuracy 0,01 LSB
# 0x068F Energy_Purchase_Total UInt32 in kwH accuracy 0,01
0x068E, [ModbusDataType.UINT_32] * 10,
wordorder=Endian.Little, unit=self.__modbus_id)]
# 0x0692 Energy_Selling_Total UInt32 in kwH accuracy 0,01 LSB
# 0x0693 Energy_Selling_Total UInt32 in kwH accuracy 0,01
exported = client.read_holding_registers(0x0692, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100
# 0x068E Energy_Purchase_Total UInt32 in kwH accuracy 0,01 LSB
# 0x068F Energy_Purchase_Total UInt32 in kwH accuracy 0,01
imported = client.read_holding_registers(0x068E, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100

counter_state = CounterState(
imported=imported,
exported=exported,
power=power,
powers=powers,
frequency=frequency,
voltages=voltages,
frequency=frequency
)
self.store.set(counter_state)

Expand Down
18 changes: 3 additions & 15 deletions packages/modules/devices/sofar/sofar/inverter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
from typing import Dict, Union
from pymodbus.constants import Endian

from dataclass_utils import dataclass_from_dict
from modules.common.abstract_device import AbstractInverter
Expand All @@ -22,20 +21,9 @@ def __init__(self,
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))

def update(self, client: ModbusTcpClient_) -> None:
# 0x0586 Power_PV1 UInt16 in kW accuracy 0,01
# 0x0589 Power_PV2, 0x058C Power_PV3, 0x058F Power_PV4, 0x0592 Power_PV5,
# 0x0595 Power_PV6, 0x0598 Power_PV7, 0x059B Power_PV8, 0x059E Power_PV9, 0x05A1 Power_PV10,
# 0x05A4 Power_PV11, 0x05A7 Power_PV12, 0x05AA Power_PV13,
# 0x05AD Power_PV14, 0x05B0 Power_PV15, 0x05B3 Power_PV16
power = sum([client.read_input_registers(reg, ModbusDataType.UINT_16,
unit=self.__modbus_id) for reg in [0x0586, 0x0589, 0x058C, 0x058F, 0x0592,
0x0595, 0x0598, 0x059B, 0x059E, 0x05A1, 0x05A4,
0x05A7, 0x05AA, 0x05AD, 0x05B0, 0x05B3]]) * -1
# 0x05C4 Power_PV_Total UInt16 in kW accuracy 0,1
# 0x0686 PV_Generation_Total UInt32 0,1 kW LSB
# 0x0687 PV_Generation_Total UInt32 0,1 kW
exported = client.read_input_registers(0x0686, ModbusDataType.UINT_32, wordorder=Endian.Little,
unit=self.__modbus_id) * 100
# 0x05C4 Power_PV_Total UINT16 in kW accuracy 0,1
power = client.read_holding_registers(0x05C4, ModbusDataType.UINT_16, unit=self.__modbus_id) * -100
exported = client.read_holding_registers(0x0686, ModbusDataType.UINT_32, unit=self.__modbus_id) * 100

inverter_state = InverterState(
power=power,
Expand Down