From fb1830e16a43c887ed1f1ec813bce1fd028d9433 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 3 Nov 2025 12:37:32 +0100 Subject: [PATCH] fix modbus bulk reader: some sdm allow only 50 read regs --- packages/modules/common/sdm.py | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/modules/common/sdm.py b/packages/modules/common/sdm.py index f6af11163d..2bf8f07f64 100644 --- a/packages/modules/common/sdm.py +++ b/packages/modules/common/sdm.py @@ -35,11 +35,13 @@ class SdmRegister(IntEnum): class Sdm630_72(Sdm): - REG_MAPPING = ( + REG_MAPPING_BULK_1 = ( (SdmRegister.VOLTAGE_L1, [ModbusDataType.FLOAT_32]*3), (SdmRegister.CURRENT_L1, [ModbusDataType.FLOAT_32]*3), (SdmRegister.POWER_L1, [ModbusDataType.FLOAT_32]*3), - (SdmRegister.POWER_FACTOR_L1, [ModbusDataType.FLOAT_32]*3), + (SdmRegister.POWER_FACTOR_L1, [ModbusDataType.FLOAT_32]*3) + ) + REG_MAPPING_BULK_2 = ( (SdmRegister.FREQUENCY, ModbusDataType.FLOAT_32), (SdmRegister.IMPORTED, ModbusDataType.FLOAT_32), (SdmRegister.EXPORTED, ModbusDataType.FLOAT_32), @@ -57,8 +59,14 @@ def get_power(self) -> Tuple[List[float], float]: return powers, power def get_counter_state(self) -> CounterState: - resp = self.client.read_input_registers_bulk( - SdmRegister.VOLTAGE_L1, 76, mapping=self.REG_MAPPING, unit=self.id) + # entgegen der Doku können nicht bei allen SDM72 80 Register auf einmal gelesen werden, + # manche können auch nur 50 + bulk_1 = self.client.read_input_registers_bulk( + SdmRegister.VOLTAGE_L1, 38, mapping=self.REG_MAPPING_BULK_1, unit=self.id) + time.sleep(0.1) + bulk_2 = self.client.read_input_registers_bulk( + SdmRegister.FREQUENCY, 8, mapping=self.REG_MAPPING_BULK_2, unit=self.id) + resp = {**bulk_1, **bulk_2} frequency = resp[SdmRegister.FREQUENCY] if frequency > 100: frequency = frequency / 10 @@ -78,11 +86,13 @@ def get_counter_state(self) -> CounterState: class Sdm120(Sdm): - REG_MAPPING = ( + REG_MAPPING_BULK_1 = ( (SdmRegister.VOLTAGE_L1, ModbusDataType.FLOAT_32), (SdmRegister.CURRENT_L1, ModbusDataType.FLOAT_32), (SdmRegister.POWER_L1, ModbusDataType.FLOAT_32), - (SdmRegister.POWER_FACTOR_L1, ModbusDataType.FLOAT_32), + (SdmRegister.POWER_FACTOR_L1, ModbusDataType.FLOAT_32) + ) + REG_MAPPING_BULK_2 = ( (SdmRegister.FREQUENCY, ModbusDataType.FLOAT_32), (SdmRegister.IMPORTED, ModbusDataType.FLOAT_32), (SdmRegister.EXPORTED, ModbusDataType.FLOAT_32), @@ -99,8 +109,13 @@ def get_power(self) -> Tuple[List[float], float]: return [power, 0, 0], power def get_counter_state(self) -> CounterState: - resp = self.client.read_input_registers_bulk( - SdmRegister.VOLTAGE_L1, 76, mapping=self.REG_MAPPING, unit=self.id) + # beim SDM120 steht nichts von Bulk-Reads in der Doku, daher auch auf 50 Register limitiert + bulk_1 = self.client.read_input_registers_bulk( + SdmRegister.VOLTAGE_L1, 32, mapping=self.REG_MAPPING_BULK_1, unit=self.id) + time.sleep(0.1) + bulk_2 = self.client.read_input_registers_bulk( + SdmRegister.FREQUENCY, 8, mapping=self.REG_MAPPING_BULK_2, unit=self.id) + resp = {**bulk_1, **bulk_2} frequency = resp[SdmRegister.FREQUENCY] if frequency > 100: frequency = frequency / 10