diff --git a/CHANGELOG.md b/CHANGELOG.md index b242089..b4844cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +- make the maximum output coefficient configurable [#123](https://github.com/s-allius/tsun-gen3-proxy/issues/123) - cleanup shutdown - add preview build - MODBUS: the last digit of the inverter version is a hexadecimal number [#119](https://github.com/s-allius/tsun-gen3-proxy/issues/119) diff --git a/app/src/infos.py b/app/src/infos.py index a32e5b7..f644049 100644 --- a/app/src/infos.py +++ b/app/src/infos.py @@ -18,6 +18,7 @@ class Register(Enum): EQUIPMENT_MODEL = 24 NO_INPUTS = 25 MAX_DESIGNED_POWER = 26 + OUTPUT_COEFFICIENT = 27 INVERTER_CNT = 50 UNKNOWN_SNR = 51 UNKNOWN_MSG = 52 @@ -194,9 +195,9 @@ class Infos: Register.SERIAL_NUMBER: {'name': ['inverter', 'Serial_Number'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 Register.EQUIPMENT_MODEL: {'name': ['inverter', 'Equipment_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 Register.NO_INPUTS: {'name': ['inverter', 'No_Inputs'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 - Register.MAX_DESIGNED_POWER: {'name': ['inverter', 'Max_Designed_Power'], 'level': logging.INFO, 'unit': 'W', 'ha': {'dev': 'inverter', 'dev_cla': None, 'stat_cla': None, 'id': 'designed_power_', 'fmt': '| string + " W"', 'name': 'Max Designed Power', 'icon': 'mdi:lightning-bolt', 'ent_cat': 'diagnostic'}}, # noqa: E501 + Register.MAX_DESIGNED_POWER: {'name': ['inverter', 'Max_Designed_Power'], 'level': logging.INFO, 'unit': 'W', 'ha': {'dev': 'inverter', 'dev_cla': None, 'stat_cla': None, 'id': 'designed_power_', 'fmt': '| string + " W"', 'name': 'Max Designed Power', 'icon': 'mdi:lightning-bolt', 'ent_cat': 'diagnostic'}}, # noqa: E501 Register.RATED_POWER: {'name': ['inverter', 'Rated_Power'], 'level': logging.DEBUG, 'unit': 'W', 'ha': {'dev': 'inverter', 'dev_cla': None, 'stat_cla': None, 'id': 'rated_power_', 'fmt': '| string + " W"', 'name': 'Rated Power', 'icon': 'mdi:lightning-bolt', 'ent_cat': 'diagnostic'}}, # noqa: E501 - + Register.OUTPUT_COEFFICIENT: {'name': ['inverter', 'Output_Coefficient'], 'level': logging.INFO, 'unit': '%', 'ha': {'dev': 'inverter', 'dev_cla': None, 'stat_cla': 'measurement', 'id': 'output_coef_', 'fmt': '| int', 'name': 'Output Coefficient', 'icon': 'mdi:lightning-bolt', 'ent_cat': 'diagnostic'}}, # noqa: E501 Register.PV1_MANUFACTURER: {'name': ['inverter', 'PV1_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 Register.PV1_MODEL: {'name': ['inverter', 'PV1_Model'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 Register.PV2_MANUFACTURER: {'name': ['inverter', 'PV2_Manufacturer'], 'level': logging.DEBUG, 'unit': ''}, # noqa: E501 diff --git a/app/src/modbus.py b/app/src/modbus.py index 63c2d19..7a9039d 100644 --- a/app/src/modbus.py +++ b/app/src/modbus.py @@ -41,7 +41,8 @@ class Modbus(): __crc_tab = [] map = { 0x2007: {'reg': Register.MAX_DESIGNED_POWER, 'fmt': '!H', 'ratio': 1}, # noqa: E501 - 0x203e: {'reg': Register.NO_INPUTS, 'fmt': '!H', 'ratio': 1/256}, # noqa: E501 + 0x202c: {'reg': Register.OUTPUT_COEFFICIENT, 'fmt': '!H', 'ratio': 100/1024}, # noqa: E501 + 0x203e: {'reg': Register.NO_INPUTS, 'fmt': '!H', 'ratio': 1/256}, # noqa: E501 0x3000: {'reg': Register.INVERTER_STATUS, 'fmt': '!H'}, # noqa: E501 0x3008: {'reg': Register.VERSION, 'fmt': '!H', 'eval': "f'V{(result>>12)}.{(result>>8)&0xf}.{(result>>4)&0xf}{result&0xf:1X}'"}, # noqa: E501 diff --git a/app/src/mqtt.py b/app/src/mqtt.py index 2f55660..25f9408 100644 --- a/app/src/mqtt.py +++ b/app/src/mqtt.py @@ -60,6 +60,7 @@ class Mqtt(metaclass=Singleton): interval = 5 # Seconds ha_status_topic = f"{ha['auto_conf_prefix']}/status" mb_rated_topic = "tsun/+/rated_load" # fixme + mb_out_coeff_topic = "tsun/+/out_coeff" # fixme mb_reads_topic = "tsun/+/modbus_read_regs" # fixme mb_inputs_topic = "tsun/+/modbus_read_inputs" # fixme mb_at_cmd_topic = "tsun/+/at_cmd" # fixme @@ -75,6 +76,7 @@ class Mqtt(metaclass=Singleton): # async with self.__client.messages() as messages: await self.__client.subscribe(ha_status_topic) await self.__client.subscribe(mb_rated_topic) + await self.__client.subscribe(mb_out_coeff_topic) await self.__client.subscribe(mb_reads_topic) await self.__client.subscribe(mb_inputs_topic) await self.__client.subscribe(mb_at_cmd_topic) @@ -93,6 +95,19 @@ class Mqtt(metaclass=Singleton): Modbus.WRITE_SINGLE_REG, 1, 0x2008) + if message.topic.matches(mb_out_coeff_topic): + payload = message.payload.decode("UTF-8") + val = round(float(payload) * 1024/100) + + if val < 0 or val > 1024: + logger_mqtt.error('out_coeff: value must be in' + 'the range 0..100,' + f' got: {payload}') + else: + await self.modbus_cmd(message, + Modbus.WRITE_SINGLE_REG, + 0, 0x202c, val) + if message.topic.matches(mb_reads_topic): await self.modbus_cmd(message, Modbus.READ_REGS, 2) @@ -154,7 +169,7 @@ class Mqtt(metaclass=Singleton): logger_mqtt.debug(f'Found: {node_id}') fnc = getattr(m, "send_modbus_cmd", None) res = payload.split(',') - if params != len(res): + if params > 0 and params != len(res): logger_mqtt.error(f'Parameter expected: {params}, ' f'got: {len(res)}') return