From e027f59ae06b9dccff84db34873aa3cc4e35e31e Mon Sep 17 00:00:00 2001 From: Jesse Kleemann Date: Fri, 9 Aug 2024 03:35:33 +0200 Subject: [PATCH] v1.0.19: support uint64 and int64 --- README.md | 4 ++-- modbus_handler.py | 13 +++++++++++++ sungrowmodbus2mqtt.py | 27 ++++++++++++--------------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8eb2384..6dc9b12 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,12 @@ Tested: SH10RT services: sungrowmodbus2mqtt: container_name: sungrowmodbus2mqtt - image: ghcr.io/jesseklm/sungrowmodbus2mqtt:v1.0.18 + image: ghcr.io/jesseklm/sungrowmodbus2mqtt:v1.0.19 restart: unless-stopped volumes: - ./config.sh10rt.yaml:/config/config.yaml:ro ``` -- `wget -O config.sh10rt.yaml https://raw.githubusercontent.com/jesseklm/sungrowmodbus2mqtt/v1.0.18/config.sh10rt.example.yaml` +- `wget -O config.sh10rt.yaml https://raw.githubusercontent.com/jesseklm/sungrowmodbus2mqtt/v1.0.19/config.sh10rt.example.yaml` - adjust your config yaml - `docker compose up -d` diff --git a/modbus_handler.py b/modbus_handler.py index e948147..34883c9 100644 --- a/modbus_handler.py +++ b/modbus_handler.py @@ -9,6 +9,15 @@ class ModbusHandler: + WORD_COUNT = { + 'uint16': 1, + 'int16': 1, + 'uint32': 2, + 'int32': 2, + 'uint64': 4, + 'int64': 4, + } + def __init__(self, config: dict): self.host: str = config['ip'] self.port: int = config.get('port', 502) @@ -66,4 +75,8 @@ def decode(self, registers: list[int], datatype: str) -> int: return decoder.decode_32bit_uint() elif datatype == 'int32': return decoder.decode_32bit_int() + elif datatype == 'uint64': + return decoder.decode_64bit_uint() + elif datatype == 'int64': + return decoder.decode_64bit_int() logging.warning(f'unknown datatype %s %s.', datatype, registers) diff --git a/sungrowmodbus2mqtt.py b/sungrowmodbus2mqtt.py index 20f2115..8bc6604 100644 --- a/sungrowmodbus2mqtt.py +++ b/sungrowmodbus2mqtt.py @@ -7,7 +7,7 @@ from modbus_handler import ModbusHandler from mqtt_handler import MqttHandler -__version__ = '1.0.18' +__version__ = '1.0.19' class SungrowModbus2Mqtt: @@ -50,6 +50,9 @@ def exit_handler(self, signum, frame): self.modbus_handler.close() sys.exit(0) + def add_dummy_register(self, register_table: str, address: int): + self.registers[register_table][address] = {'type': 'dummy'} + def create_register(self, register_table: str, config_register: dict) -> dict: register = {'topic': config_register['pub_topic']} if 'type' in config_register: @@ -69,9 +72,9 @@ def create_register(self, register_table: str, config_register: dict) -> dict: register['shift'] = config_register['shift'] if 'retain' in config_register: register['retain'] = config_register['retain'] - if register['type'].endswith('32'): - self.registers[register_table][ - config_register['address'] + self.address_offset + 1] = {'type': f'{register["type"]}_2'} + word_count = ModbusHandler.WORD_COUNT.get(register['type'], 1) + for i in range(1, word_count): + self.add_dummy_register(register_table, config_register['address'] + self.address_offset + i) return register def init_register(self, register_table: str, register: dict): @@ -143,20 +146,14 @@ def publish(self): for address in self.registers[table]: register: dict = self.registers[table][address] register_type: str = register['type'] - if register_type in ['int32_2', 'uint32_2']: + if register_type == 'dummy': continue - if register_type in ['int32', 'uint32']: - new: bool = register.get('new', False) or self.registers[table][address + 1].get('new', False) - else: - new: bool = register.get('new', False) + word_count = ModbusHandler.WORD_COUNT.get(register_type, 1) + new = any(self.registers[table][address + i].get('new', False) for i in range(word_count)) if not new: continue - value: int = register['value'] - if register_type in ['int32', 'uint32']: - value_2: int = self.registers[table][address + 1]['value'] - value = self.modbus_handler.decode([value, value_2], register_type) - else: - value = self.modbus_handler.decode([value], register_type) + values: list[int] = [self.registers[table][address + i]['value'] for i in range(word_count)] + value = self.modbus_handler.decode(values, register_type) for subregister in register.get('multi', []): self.mqtt_handler.publish(subregister['topic'], self.prepare_value(subregister, value), subregister.get('retain', False))