From 7b4ed406a1a937e9141248b272090d16b113298a Mon Sep 17 00:00:00 2001 From: Stefan Allius <122395479+s-allius@users.noreply.github.com> Date: Tue, 23 Apr 2024 22:26:01 +0200 Subject: [PATCH 1/4] Update README.md Exchange logger fw version with the real inverter fw version in the compatibility table --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a26179..b3ef585 100644 --- a/README.md +++ b/README.md @@ -215,7 +215,7 @@ In the following table you will find an overview of which inverter model has bee A combination with a red question mark should work, but I have not checked it in detail. - + From 0a1891832672f7f57208a648273027feec58c494 Mon Sep 17 00:00:00 2001 From: Stefan Allius <122395479+s-allius@users.noreply.github.com> Date: Sat, 8 Jun 2024 23:23:56 +0200 Subject: [PATCH 2/4] Update python-app.yml run also on pushes to issue branches --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 2c7031b..9a5f624 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -5,7 +5,7 @@ name: Python application on: push: - branches: [ "main", "dev-*" ] + branches: [ "main", "dev-*", "issue*" ] paths-ignore: - '**.md' # Do no build on *.md changes - '**.yml' # Do no build on *.yml changes From c34b33ed5f2d26ee6dde1e017a0587042ef52823 Mon Sep 17 00:00:00 2001 From: Stefan Allius <122395479+s-allius@users.noreply.github.com> Date: Sat, 8 Jun 2024 23:39:28 +0200 Subject: [PATCH 3/4] Update python-app.yml fix name for issues branches --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 9a5f624..f51ae3d 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -5,7 +5,7 @@ name: Python application on: push: - branches: [ "main", "dev-*", "issue*" ] + branches: [ "main", "dev-*", "*/issue*" ] paths-ignore: - '**.md' # Do no build on *.md changes - '**.yml' # Do no build on *.yml changes From a3c054d2b10508162ef32ff5ce486cb62f00368c Mon Sep 17 00:00:00 2001 From: Stefan Allius <122395479+s-allius@users.noreply.github.com> Date: Fri, 21 Jun 2024 18:12:48 +0200 Subject: [PATCH 4/4] Dev 0.8 (#106) * S allius/issue102 (#103) * hotfix: don't send two MODBUS commands together * Update README.md Exchange logger fw version with the real inverter fw version in the compatibility table * Update python-app.yml run also on pushes to issue branches fix name for issues branches * S allius/issue104 (#105) * Update README.md Exchange logger fw version with the real inverter fw version in the compatibility table * Update python-app.yml run also on pushes to issue branches fix name for issues branches * fix forwarding of MODBUS responses * fix unit tests * update changelog --- CHANGELOG.md | 5 +++++ app/src/gen3/talent.py | 3 ++- app/src/gen3plus/solarman_v5.py | 3 ++- app/src/scheduler.py | 6 +++--- app/tests/test_solarman.py | 24 +++++++++++++++++++++--- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4eeed..c869069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Fix MODBUS responses are dropped and not forwarded to the TSUN cloud [#104](https://github.com/s-allius/tsun-gen3-proxy/issues/104) +- GEN3 Fix connections losts due MODBUS requests [#102](https://github.com/s-allius/tsun-gen3-proxy/issues/102) + +[0.8.0] - 2024-06-07 + - improve logging: add protocol or node_id to connection logs - improve logging: log ignored AT+ or MODBUS commands - improve tracelog: log level depends on message type and source diff --git a/app/src/gen3/talent.py b/app/src/gen3/talent.py index ad37337..18a336f 100644 --- a/app/src/gen3/talent.py +++ b/app/src/gen3/talent.py @@ -426,7 +426,8 @@ class Talent(Message): if self.ctrl.is_req(): if self.remoteStream.mb.recv_req(data[hdr_len:], - self.msg_forward): + self.remoteStream. + msg_forward): self.inc_counter('Modbus_Command') else: self.inc_counter('Invalid_Msg_Format') diff --git a/app/src/gen3plus/solarman_v5.py b/app/src/gen3plus/solarman_v5.py index 64e4536..a498a2b 100644 --- a/app/src/gen3plus/solarman_v5.py +++ b/app/src/gen3plus/solarman_v5.py @@ -495,7 +495,8 @@ class SolarmanV5(Message): elif ftype == self.MB_RTU_CMD: if self.remoteStream.mb.recv_req(data[15:], - self.__forward_msg()): + self.remoteStream. + __forward_msg): self.inc_counter('Modbus_Command') else: self.inc_counter('Invalid_Msg_Format') diff --git a/app/src/scheduler.py b/app/src/scheduler.py index 785bbcd..6f54b6d 100644 --- a/app/src/scheduler.py +++ b/app/src/scheduler.py @@ -41,7 +41,7 @@ class Schedule: fnc = getattr(m, "send_modbus_cmd", None) if callable(fnc): await fnc(Modbus.READ_REGS, 0x3008, 21, logging.DEBUG) - if 0 == (cls.count % 30): - # logging.info("Regular Modbus Status request") - await fnc(Modbus.READ_REGS, 0x2007, 2, logging.DEBUG) + # if 0 == (cls.count % 30): + # # logging.info("Regular Modbus Status request") + # await fnc(Modbus.READ_REGS, 0x2007, 2, logging.DEBUG) cls.count += 1 diff --git a/app/tests/test_solarman.py b/app/tests/test_solarman.py index 9deae56..fca2b41 100644 --- a/app/tests/test_solarman.py +++ b/app/tests/test_solarman.py @@ -91,6 +91,9 @@ class MemoryStream(SolarmanV5): def get_sn() -> bytes: return b'\x21\x43\x65\x7b' +def get_sn_int() -> int: + return 2070233889 + def get_inv_no() -> bytes: return b'T170000000000001' @@ -531,6 +534,15 @@ def MsgModbusCmd(): msg += b'\x15' return msg +@pytest.fixture +def MsgModbusCmdFwd(): + msg = b'\xa5\x17\x00\x10\x45\x01\x00' +get_sn() +b'\x02\xb0\x02' + msg += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x06\x20\x08' + msg += b'\x00\x00\x03\xc8' + msg += correct_checksum(msg) + msg += b'\x15' + return msg + @pytest.fixture def MsgModbusCmdCrcErr(): msg = b'\xa5\x17\x00\x10\x45\x03\x02' +get_sn() +b'\x02\xb0\x02' @@ -1412,9 +1424,11 @@ def test_msg_at_command_rsp2(ConfigTsunInv1, AtCommandRspMsg): assert m.db.stat['proxy']['Modbus_Command'] == 0 m.close() -def test_msg_modbus_req(ConfigTsunInv1, MsgModbusCmd): +def test_msg_modbus_req(ConfigTsunInv1, MsgModbusCmd, MsgModbusCmdFwd): ConfigTsunInv1 m = MemoryStream(b'') + m.snr = get_sn_int() + m.state = m.STATE_UP c = m.createClientStream(MsgModbusCmd) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -1428,8 +1442,9 @@ def test_msg_modbus_req(ConfigTsunInv1, MsgModbusCmd): assert str(c.seq) == '03:02' assert c.header_len==11 assert c.data_len==23 - assert c._forward_buffer==MsgModbusCmd + assert c._forward_buffer==b'' assert c._send_buffer==b'' + assert m.writer.sent_pdu == MsgModbusCmdFwd assert m.db.stat['proxy']['Unknown_Ctrl'] == 0 assert m.db.stat['proxy']['AT_Command'] == 0 assert m.db.stat['proxy']['Modbus_Command'] == 1 @@ -1439,6 +1454,8 @@ def test_msg_modbus_req(ConfigTsunInv1, MsgModbusCmd): def test_msg_modbus_req2(ConfigTsunInv1, MsgModbusCmdCrcErr): ConfigTsunInv1 m = MemoryStream(b'') + m.snr = get_sn_int() + m.state = m.STATE_UP c = m.createClientStream(MsgModbusCmdCrcErr) m.db.stat['proxy']['Unknown_Ctrl'] = 0 @@ -1452,8 +1469,9 @@ def test_msg_modbus_req2(ConfigTsunInv1, MsgModbusCmdCrcErr): assert str(c.seq) == '03:02' assert c.header_len==11 assert c.data_len==23 - assert c._forward_buffer==MsgModbusCmdCrcErr + assert c._forward_buffer==b'' assert c._send_buffer==b'' + assert m.writer.sent_pdu==b'' assert m.db.stat['proxy']['Unknown_Ctrl'] == 0 assert m.db.stat['proxy']['AT_Command'] == 0 assert m.db.stat['proxy']['Modbus_Command'] == 0
Micro Inverter ModelFw. 1.00.06Fw. 1.00.17Fw. 1.00.20Fw. 1.1.00.0B
Micro Inverter ModelFw. 1.00.06Fw. 1.00.17Fw. 1.00.20Fw. 4.0.10
GEN3 micro inverters (single MPPT):
MS300, MS350, MS400
MS400-D
GEN3 micro inverters (dual MPPT):
MS600, MS700, MS800
MS600-D, MS800-D
✔️✔️✔️
GEN3 PLUS micro inverters:
MS1600, MS1800, MS2000
MS2000-D
✔️