From 794112639d7a5ee9de65baf18a93c0d6b5238fa5 Mon Sep 17 00:00:00 2001 From: Etienne Goossens Date: Sun, 12 Jan 2025 12:46:35 +0100 Subject: [PATCH 1/3] Growatt serial-no buffer overrun + manifest pymodbus - Solved issue where the serial number read count is to large for the actual registers in function async_read_serialnr. - Updated pymodbus to allign with home assistants 25.1 version (thanks @Luflosi for the comment on the PR) - Updated version so version could be released if needed. --- custom_components/solax_modbus/manifest.json | 4 ++-- custom_components/solax_modbus/plugin_growatt.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/solax_modbus/manifest.json b/custom_components/solax_modbus/manifest.json index c0679d1b..97f52190 100644 --- a/custom_components/solax_modbus/manifest.json +++ b/custom_components/solax_modbus/manifest.json @@ -9,6 +9,6 @@ "integration_type": "hub", "iot_class": "local_polling", "issue_tracker": "https://github.com/wills106/homsassistant-solax-modbus/issues", - "requirements": ["pymodbus==3.7.4"], - "version": "2025.01.6" + "requirements": ["pymodbus==3.8.3"], + "version": "2025.01.7" } diff --git a/custom_components/solax_modbus/plugin_growatt.py b/custom_components/solax_modbus/plugin_growatt.py index 5bb80486..2b227a12 100644 --- a/custom_components/solax_modbus/plugin_growatt.py +++ b/custom_components/solax_modbus/plugin_growatt.py @@ -61,7 +61,7 @@ async def async_read_serialnr(hub, address): res = None try: - inverter_data = await hub.async_read_holding_registers(unit=hub._modbus_addr, address=address, count=6) + inverter_data = await hub.async_read_holding_registers(unit=hub._modbus_addr, address=address, count=5) if not inverter_data.isError(): decoder = BinaryPayloadDecoder.fromRegisters(inverter_data.registers, byteorder=Endian.BIG) res = decoder.decode_string(12).decode("ascii") From cf79b127f0e1169ba66ffcde46605896ca195799 Mon Sep 17 00:00:00 2001 From: Etienne Goossens Date: Sun, 12 Jan 2025 12:48:53 +0100 Subject: [PATCH 2/3] Decrease string size as byte size is also smaller --- custom_components/solax_modbus/plugin_growatt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/solax_modbus/plugin_growatt.py b/custom_components/solax_modbus/plugin_growatt.py index 2b227a12..21278232 100644 --- a/custom_components/solax_modbus/plugin_growatt.py +++ b/custom_components/solax_modbus/plugin_growatt.py @@ -64,7 +64,7 @@ async def async_read_serialnr(hub, address): inverter_data = await hub.async_read_holding_registers(unit=hub._modbus_addr, address=address, count=5) if not inverter_data.isError(): decoder = BinaryPayloadDecoder.fromRegisters(inverter_data.registers, byteorder=Endian.BIG) - res = decoder.decode_string(12).decode("ascii") + res = decoder.decode_string(10).decode("ascii") hub.seriesnumber = res except Exception as ex: _LOGGER.warning(f"{hub.name}: attempt to read firmware failed at 0x{address:x}", exc_info=True) if not res: _LOGGER.warning(f"{hub.name}: reading firmware number from address 0x{address:x} failed; other address may succeed") From 2d99211455ee102fec35a0901581223e657be636 Mon Sep 17 00:00:00 2001 From: Etienne Goossens Date: Sun, 12 Jan 2025 14:12:24 +0100 Subject: [PATCH 3/3] Fixed rounding issue datetime conversion Rounding issue when expected a year of 2 digits but receiving one of 4 digits in functions: - value_function_rtc - value_function_rtc_ymd --- custom_components/solax_modbus/const.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/solax_modbus/const.py b/custom_components/solax_modbus/const.py index efa0be01..c282e87a 100644 --- a/custom_components/solax_modbus/const.py +++ b/custom_components/solax_modbus/const.py @@ -407,7 +407,7 @@ def value_function_rtc(initval, descr, datadict): rtc_months, rtc_years, ) = initval - val = f"{rtc_days:02}/{rtc_months:02}/{rtc_years:02} {rtc_hours:02}:{rtc_minutes:02}:{rtc_seconds:02}" + val = f"{rtc_days:02}/{rtc_months:02}/{rtc_years%100:02} {rtc_hours:02}:{rtc_minutes:02}:{rtc_seconds:02}" return datetime.strptime(val, "%d/%m/%y %H:%M:%S") # ok since sensor.py has been adapted except: pass @@ -423,7 +423,7 @@ def value_function_rtc_ymd(initval, descr, datadict): rtc_minutes, rtc_seconds, ) = initval - val = f"{rtc_days:02}/{rtc_months:02}/{rtc_years:02} {rtc_hours:02}:{rtc_minutes:02}:{rtc_seconds:02}" + val = f"{rtc_days:02}/{rtc_months:02}/{rtc_years%100:02} {rtc_hours:02}:{rtc_minutes:02}:{rtc_seconds:02}" return datetime.strptime(val, "%d/%m/%y %H:%M:%S") # ok since sensor.py has been adapted except: pass