From c54748ac315b6d3fa8fd2189c8fc38f773233485 Mon Sep 17 00:00:00 2001 From: Oleh Horbachov Date: Thu, 8 Aug 2024 14:04:21 +0300 Subject: [PATCH 01/25] base support for SRNE inverters 2021+ --- README.md | 1 + .../srne_2021_v1.96.holding_registry_map.csv | 47 +++++++++++++++++++ protocols/srne_2021_v1.96.json | 5 ++ 3 files changed, 53 insertions(+) create mode 100644 protocols/srne_2021_v1.96.holding_registry_map.csv create mode 100644 protocols/srne_2021_v1.96.json diff --git a/README.md b/README.md index b007997..4753df7 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ srne_v3.9 = SRNE inverters - Untested victron_gx_3.3 = Victron GX Devices - Untested solark_v1.1 = SolarArk 8/12K Inverters - Untested hdhk_16ch_ac_module = some chinese current monitoring device :P +srne_2021_v1.96 = SRNE inverters 2021+ (tested at ASF48100S200-H) eg4_v58 = eg4 inverters ( EG4-6000XP ) - confirmed working eg4_3000ehv_v1 = eg4 inverters ( EG4_3000EHV ) diff --git a/protocols/srne_2021_v1.96.holding_registry_map.csv b/protocols/srne_2021_v1.96.holding_registry_map.csv new file mode 100644 index 0000000..f994780 --- /dev/null +++ b/protocols/srne_2021_v1.96.holding_registry_map.csv @@ -0,0 +1,47 @@ +variable name,data type,register,documented name,description,writable,values,unit,note +,BYTE,0x000B,Product type,,R,"{""0"": ""domestic controller"", ""1"": ""controller for street light"", ""3"": ""grid-connected inverter"", ""4"": ""all-in-one solar charger inverter"", ""5"": ""power frequency off-grid""}",, +,,0x0014,Software version,,R,,0.01, +,,0x0016,Hardware version,,R,,0.01, +,BYTE,0x001A,RS485 address,,R,1~247,, +,,0x001C,RS485 version,,R,,0.01, +,ASCII,0x0035~0x0048,Product SN,,R,,, +,,0x0100,Battery capacity SOC,,R,0~100,%, +,,0x0101,Battery voltage,,R,,0.1V, +,SHORT,0x0102,Battery current,,R,,0.1A, +,SHORT,0x0103,Battery temperature,,R,,0.1C, +,,0x0107,PV1 voltage,,R,,0.1V, +,,0x0108,PV1 current,,R,,0.1A, +,,0x0109,PV1 power,,R,,W, +,,0x010F,PV2 voltage,,R,,0.1V, +,,0x0110,PV2 current,,R,,0.1A, +,,0x0111,PV2 power,,R,,W, +,BYTE,0x010B,Charge state,,R,"{""0"": ""Charge off"", ""1"": ""Quick charge"", ""2"": ""Const voltage charge"", ""4"": ""Float charge"", ""6"": ""Li battery activate"", ""8"": ""Full""}",, +,,0x010E,Total charging power,,R,,W, +,BYTE,0x0210,Device state,,R,"{""0"": ""Initialization"", ""1"": ""Standby"", ""2"": ""AC power operation"", ""3"": ""Inverter operation""}",, +,,0x0212,Bus Voltage Sum,,R,,0.1V, +,,0x0213,Grid power phase-A voltage,,R,,0.1V, +,,0x0214,Grid power phase-A current,,R,,0.1A, +,,0x022A,Grid power phase-B voltage,,R,,0.1V, +,,0x0238,Grid power phase-B current,,R,,0.1A, +,,0x022B,Grid power phase-C voltage,,R,,0.1V, +,,0x0239,Grid power phase-C current,,R,,0.1A, +,,0x0216,Inverter phase-A output voltage,,R,,0.1V, +,,0x0217,Inverter phase-A inductive current,,R,,0.1A, +,,0x022C,Inverter phase-B output voltage,,R,,0.1V, +,,0x022E,Inverter phase-B inductive current,,R,,0.1A, +,,0x022D,Inverter phase-C output voltage,,R,,0.1V, +,,0x022F,Inverter phase-C inductive current,,R,,0.1A, +,,0x0215,Grid power frequency,,R,,0.01Hz, +,,0x0218,Inverter frequency,,R,,0.01Hz, +,,0x0219,Load Phase-A current,,R,,0.1A, +,,0x021B,Load Phase-A active power,,R,,W, +,,0x021C,Load Phase-A apparent power,,R,,VA, +,,0x021F,Load Phase-A ratio,,R,0~100,%, +,,0x0230,Load Phase-B current,,R,,0.1A, +,,0x0232,Load Phase-B active power,,R,,W, +,,0x0234,Load Phase-B apparent power,,R,,VA, +,,0x0236,Load Phase-B ratio,,R,0~100,%, +,,0x0231,Load Phase-C current,,R,,0.1A, +,,0x0233,Load Phase-C active power,,R,,W, +,,0x0235,Load Phase-C apparent power,,R,,VA, +,,0x0237,Load Phase-C ratio,,R,0~100,%, \ No newline at end of file diff --git a/protocols/srne_2021_v1.96.json b/protocols/srne_2021_v1.96.json new file mode 100644 index 0000000..ee874b1 --- /dev/null +++ b/protocols/srne_2021_v1.96.json @@ -0,0 +1,5 @@ +{ + "transport" : "modbus_rtu", + "send_holding_register": true, + "send_input_register" : false +} \ No newline at end of file From 37cd3e21de70167e573cc2a4d2c78c48bb856b85 Mon Sep 17 00:00:00 2001 From: Oleh Horbachov Date: Thu, 15 Aug 2024 10:16:36 +0300 Subject: [PATCH 02/25] updated naming of vars --- protocols/srne_2021_v1.96.holding_registry_map.csv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/protocols/srne_2021_v1.96.holding_registry_map.csv b/protocols/srne_2021_v1.96.holding_registry_map.csv index f994780..e201e48 100644 --- a/protocols/srne_2021_v1.96.holding_registry_map.csv +++ b/protocols/srne_2021_v1.96.holding_registry_map.csv @@ -19,19 +19,19 @@ variable name,data type,register,documented name,description,writable,values,uni ,,0x010E,Total charging power,,R,,W, ,BYTE,0x0210,Device state,,R,"{""0"": ""Initialization"", ""1"": ""Standby"", ""2"": ""AC power operation"", ""3"": ""Inverter operation""}",, ,,0x0212,Bus Voltage Sum,,R,,0.1V, -,,0x0213,Grid power phase-A voltage,,R,,0.1V, -,,0x0214,Grid power phase-A current,,R,,0.1A, -,,0x022A,Grid power phase-B voltage,,R,,0.1V, -,,0x0238,Grid power phase-B current,,R,,0.1A, -,,0x022B,Grid power phase-C voltage,,R,,0.1V, -,,0x0239,Grid power phase-C current,,R,,0.1A, +,,0x0213,Grid phase-A voltage,,R,,0.1V, +,,0x0214,Grid phase-A current,,R,,0.1A, +,,0x022A,Grid phase-B voltage,,R,,0.1V, +,,0x0238,Grid phase-B current,,R,,0.1A, +,,0x022B,Grid phase-C voltage,,R,,0.1V, +,,0x0239,Grid phase-C current,,R,,0.1A, +,,0x0215,Grid frequency,,R,,0.01Hz, ,,0x0216,Inverter phase-A output voltage,,R,,0.1V, ,,0x0217,Inverter phase-A inductive current,,R,,0.1A, ,,0x022C,Inverter phase-B output voltage,,R,,0.1V, ,,0x022E,Inverter phase-B inductive current,,R,,0.1A, ,,0x022D,Inverter phase-C output voltage,,R,,0.1V, ,,0x022F,Inverter phase-C inductive current,,R,,0.1A, -,,0x0215,Grid power frequency,,R,,0.01Hz, ,,0x0218,Inverter frequency,,R,,0.01Hz, ,,0x0219,Load Phase-A current,,R,,0.1A, ,,0x021B,Load Phase-A active power,,R,,W, From cf52dca4d41aa483745fa69e872e2fc88587980d Mon Sep 17 00:00:00 2001 From: Oleh Horbachov Date: Thu, 15 Aug 2024 11:39:56 +0300 Subject: [PATCH 03/25] srne2021 - add some statistics --- .../srne_2021_v1.96.holding_registry_map.csv | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/protocols/srne_2021_v1.96.holding_registry_map.csv b/protocols/srne_2021_v1.96.holding_registry_map.csv index e201e48..a904f7a 100644 --- a/protocols/srne_2021_v1.96.holding_registry_map.csv +++ b/protocols/srne_2021_v1.96.holding_registry_map.csv @@ -15,10 +15,10 @@ variable name,data type,register,documented name,description,writable,values,uni ,,0x010F,PV2 voltage,,R,,0.1V, ,,0x0110,PV2 current,,R,,0.1A, ,,0x0111,PV2 power,,R,,W, -,BYTE,0x010B,Charge state,,R,"{""0"": ""Charge off"", ""1"": ""Quick charge"", ""2"": ""Const voltage charge"", ""4"": ""Float charge"", ""6"": ""Li battery activate"", ""8"": ""Full""}",, -,,0x010E,Total charging power,,R,,W, +,BYTE,0x010B,Device Charge state,,R,"{""0"": ""Charge off"", ""1"": ""Quick charge"", ""2"": ""Const voltage charge"", ""4"": ""Float charge"", ""6"": ""Li battery activate"", ""8"": ""Full""}",, +,,0x010E,Device Total charging power,,R,,W, ,BYTE,0x0210,Device state,,R,"{""0"": ""Initialization"", ""1"": ""Standby"", ""2"": ""AC power operation"", ""3"": ""Inverter operation""}",, -,,0x0212,Bus Voltage Sum,,R,,0.1V, +,,0x0212,Device Bus Voltage Sum,,R,,0.1V, ,,0x0213,Grid phase-A voltage,,R,,0.1V, ,,0x0214,Grid phase-A current,,R,,0.1A, ,,0x022A,Grid phase-B voltage,,R,,0.1V, @@ -44,4 +44,16 @@ variable name,data type,register,documented name,description,writable,values,uni ,,0x0231,Load Phase-C current,,R,,0.1A, ,,0x0233,Load Phase-C active power,,R,,W, ,,0x0235,Load Phase-C apparent power,,R,,VA, -,,0x0237,Load Phase-C ratio,,R,0~100,%, \ No newline at end of file +,,0x0237,Load Phase-C ratio,,R,0~100,%, +,BYTE,0xF02C,Stats GenerateEnergyToGridTday,,R,0.1,kWh, +,BYTE,0xF02D,Stats BatChgTday,,R,1,AH, +,BYTE,0xF02E,Stats BatDischgTday,,R,1,AH, +,BYTE,0xF02F,Stats GenerateEnergyTday,,R,0.1,kWh, +,BYTE,0xF030,Stats UsedEnergyTday,,R,0.1,kWh, +,BYTE,0xF031,Stats WorkDaysTotal,,R,1,d, +,BYTE,0xF03C,Stats GridChgEnergyTday,,R,1,AH, +,BYTE,0xF03D,Stats LoadConsumLineTday,,R,0.1,kWh, +,BYTE,0xF03E,Stats InvWorkTimeTday,,R,1,min, +,BYTE,0xF03F,Stats GridWorkTimeTday,,R,1,min, +,BYTE,0xF04A,Stats InvWorkTimeTotal,,R,1,h, +,BYTE,0xF04B,Stats GridWorkTimeTotal,,R,1,h, \ No newline at end of file From 12e9dd3e4647a62cf5775acb92f64785452ab11c Mon Sep 17 00:00:00 2001 From: Oleh Horbachov Date: Sat, 17 Aug 2024 09:02:46 +0300 Subject: [PATCH 04/25] srne2021 - fix syntax errors --- .../srne_2021_v1.96.holding_registry_map.csv | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/protocols/srne_2021_v1.96.holding_registry_map.csv b/protocols/srne_2021_v1.96.holding_registry_map.csv index a904f7a..ce9db32 100644 --- a/protocols/srne_2021_v1.96.holding_registry_map.csv +++ b/protocols/srne_2021_v1.96.holding_registry_map.csv @@ -45,15 +45,15 @@ variable name,data type,register,documented name,description,writable,values,uni ,,0x0233,Load Phase-C active power,,R,,W, ,,0x0235,Load Phase-C apparent power,,R,,VA, ,,0x0237,Load Phase-C ratio,,R,0~100,%, -,BYTE,0xF02C,Stats GenerateEnergyToGridTday,,R,0.1,kWh, -,BYTE,0xF02D,Stats BatChgTday,,R,1,AH, -,BYTE,0xF02E,Stats BatDischgTday,,R,1,AH, -,BYTE,0xF02F,Stats GenerateEnergyTday,,R,0.1,kWh, -,BYTE,0xF030,Stats UsedEnergyTday,,R,0.1,kWh, -,BYTE,0xF031,Stats WorkDaysTotal,,R,1,d, -,BYTE,0xF03C,Stats GridChgEnergyTday,,R,1,AH, -,BYTE,0xF03D,Stats LoadConsumLineTday,,R,0.1,kWh, -,BYTE,0xF03E,Stats InvWorkTimeTday,,R,1,min, -,BYTE,0xF03F,Stats GridWorkTimeTday,,R,1,min, -,BYTE,0xF04A,Stats InvWorkTimeTotal,,R,1,h, -,BYTE,0xF04B,Stats GridWorkTimeTotal,,R,1,h, \ No newline at end of file +,BYTE,0xF02C,Stats GenerateEnergyToGridTday,,R,,0.1kWh, +,BYTE,0xF02D,Stats BatChgTday,,R,,1AH, +,BYTE,0xF02E,Stats BatDischgTday,,R,,1AH, +,BYTE,0xF02F,Stats GenerateEnergyTday,,R,,0.1kWh, +,BYTE,0xF030,Stats UsedEnergyTday,,R,,0.1kWh, +,BYTE,0xF031,Stats WorkDaysTotal,,R,,1d, +,BYTE,0xF03C,Stats GridChgEnergyTday,,R,,1AH, +,BYTE,0xF03D,Stats LoadConsumLineTday,,R,,0.1kWh, +,BYTE,0xF03E,Stats InvWorkTimeTday,,R,,1min, +,BYTE,0xF03F,Stats GridWorkTimeTday,,R,,1min, +,BYTE,0xF04A,Stats InvWorkTimeTotal,,R,,1h, +,BYTE,0xF04B,Stats GridWorkTimeTotal,,R,,1h, \ No newline at end of file From f3ea551184a74aee050f5592143257511cd88684 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 11:57:37 -0500 Subject: [PATCH 05/25] wiki to repo --- ...otocol-PYLON-low-voltage-V1.2-20180408.pdf | Bin ...00-EHV - MODBUS Communication Protocol.pdf | Bin ...4-6000XP-MODBUS-Communication-Protocol.pdf | Bin .../Growatt Modbus Protocol v1.24.pdf | Bin ...verter Modbus RS485 RTU Protocol V3.04.pdf | Bin ...verter Modbus RS485 RTU Protocol V3.15.pdf | Bin .../MAX Series Modbus RTU Protocol.pdf | Bin ...RS485RS232-RTU-Protocol-V0.14-20210420.pdf | Bin ...odbus-Protocol-for-RS485-V1.3-20170627.pdf | Bin ...-RS485-communication-protocol-20180615.pdf | Bin ...\210PACE-CAN-TY\357\274\211-20161216-.pdf" | Bin ...ication protocol - RS485 V2.8 20161216.pdf | Bin .../3rdparty/protocols}/README.md | 0 ...otocol-pylon-low-voltage-V3.3-20180821.pdf | Bin .../3rdparty/protocols}/SRNE_MODBUS_v3.9.pdf | Bin ...ort-Modbus-RTU-Protocol-v0.11-20200302.pdf | Bin .../protocols}/Sol-Ark ModBus V1.1.pdf | Bin ...tron VE-Bus-products-MK2-Protocol-3-14.pdf | Bin ...on-CCGX-Modbus-TCP-register-list-3.30.xlsx | Bin .../3rdparty/protocols}/converter.txt | 0 .../hdhk_16ch_ac_module_modbus_rtu.jpeg | Bin ...hdhk_16ch_ac_module_modbus_rtu_chinese.pdf | Bin ...c_module_modbus_rtu_translated_english.pdf | Bin documentation/dashboards/grafana.md | 0 documentation/dashboards/homeassistant.md | 0 documentation/dashboards/nodered.md | 82 +++++++ documentation/devices/EG4.md | 32 +++ documentation/devices/Growatt.md | 120 ++++++++++ documentation/devices/SOK.md | 16 ++ documentation/devices/Sigineer.md | 45 ++++ documentation/devices/SolArk.md | 17 ++ .../modbus_rtu_to_modbus_tcp.md | 44 ++++ .../modbus_rtu_to_mqtt.md | 49 ++++ .../usage/creating_and_editing_protocols.md | 72 ++++++ documentation/usage/protocols.md | 48 ++++ documentation/usage/transports.md | 217 ++++++++++++++++++ 36 files changed, 742 insertions(+) rename {docs => documentation/3rdparty/protocols}/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf (100%) rename {docs => documentation/3rdparty/protocols}/EG4-3000-EHV - MODBUS Communication Protocol.pdf (100%) rename {docs => documentation/3rdparty/protocols}/EG4-6000XP-MODBUS-Communication-Protocol.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Growatt Modbus Protocol v1.24.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf (100%) rename {docs => documentation/3rdparty/protocols}/MAX Series Modbus RTU Protocol.pdf (100%) rename {docs => documentation/3rdparty/protocols}/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf (100%) rename {docs => documentation/3rdparty/protocols}/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf (100%) rename {docs => documentation/3rdparty/protocols}/PACE-BMS-RS485-communication-protocol-20180615.pdf (100%) rename "docs/PACE-CAN-communication-protocal\357\274\210PACE-CAN-TY\357\274\211-20161216-.pdf" => "documentation/3rdparty/protocols/PACE-CAN-communication-protocal\357\274\210PACE-CAN-TY\357\274\211-20161216-.pdf" (100%) rename {docs => documentation/3rdparty/protocols}/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf (100%) rename {docs => documentation/3rdparty/protocols}/README.md (100%) rename {docs => documentation/3rdparty/protocols}/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf (100%) rename {docs => documentation/3rdparty/protocols}/SRNE_MODBUS_v3.9.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Sol-Ark ModBus V1.1.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Victron VE-Bus-products-MK2-Protocol-3-14.pdf (100%) rename {docs => documentation/3rdparty/protocols}/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx (100%) rename {docs => documentation/3rdparty/protocols}/converter.txt (100%) rename {docs => documentation/3rdparty/protocols}/hdhk_16ch_ac_module_modbus_rtu.jpeg (100%) rename {docs => documentation/3rdparty/protocols}/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf (100%) rename {docs => documentation/3rdparty/protocols}/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf (100%) create mode 100644 documentation/dashboards/grafana.md create mode 100644 documentation/dashboards/homeassistant.md create mode 100644 documentation/dashboards/nodered.md create mode 100644 documentation/devices/EG4.md create mode 100644 documentation/devices/Growatt.md create mode 100644 documentation/devices/SOK.md create mode 100644 documentation/devices/Sigineer.md create mode 100644 documentation/devices/SolArk.md create mode 100644 documentation/usage/configuration_examples/modbus_rtu_to_modbus_tcp.md create mode 100644 documentation/usage/configuration_examples/modbus_rtu_to_mqtt.md create mode 100644 documentation/usage/creating_and_editing_protocols.md create mode 100644 documentation/usage/protocols.md create mode 100644 documentation/usage/transports.md diff --git a/docs/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf b/documentation/3rdparty/protocols/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf similarity index 100% rename from docs/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf rename to documentation/3rdparty/protocols/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf diff --git a/docs/EG4-3000-EHV - MODBUS Communication Protocol.pdf b/documentation/3rdparty/protocols/EG4-3000-EHV - MODBUS Communication Protocol.pdf similarity index 100% rename from docs/EG4-3000-EHV - MODBUS Communication Protocol.pdf rename to documentation/3rdparty/protocols/EG4-3000-EHV - MODBUS Communication Protocol.pdf diff --git a/docs/EG4-6000XP-MODBUS-Communication-Protocol.pdf b/documentation/3rdparty/protocols/EG4-6000XP-MODBUS-Communication-Protocol.pdf similarity index 100% rename from docs/EG4-6000XP-MODBUS-Communication-Protocol.pdf rename to documentation/3rdparty/protocols/EG4-6000XP-MODBUS-Communication-Protocol.pdf diff --git a/docs/Growatt Modbus Protocol v1.24.pdf b/documentation/3rdparty/protocols/Growatt Modbus Protocol v1.24.pdf similarity index 100% rename from docs/Growatt Modbus Protocol v1.24.pdf rename to documentation/3rdparty/protocols/Growatt Modbus Protocol v1.24.pdf diff --git a/docs/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf b/documentation/3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf similarity index 100% rename from docs/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf rename to documentation/3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf diff --git a/docs/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf b/documentation/3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf similarity index 100% rename from docs/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf rename to documentation/3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf diff --git a/docs/MAX Series Modbus RTU Protocol.pdf b/documentation/3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf similarity index 100% rename from docs/MAX Series Modbus RTU Protocol.pdf rename to documentation/3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf diff --git a/docs/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf b/documentation/3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf similarity index 100% rename from docs/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf rename to documentation/3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf diff --git a/docs/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf b/documentation/3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf similarity index 100% rename from docs/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf rename to documentation/3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf diff --git a/docs/PACE-BMS-RS485-communication-protocol-20180615.pdf b/documentation/3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf similarity index 100% rename from docs/PACE-BMS-RS485-communication-protocol-20180615.pdf rename to documentation/3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf diff --git "a/docs/PACE-CAN-communication-protocal\357\274\210PACE-CAN-TY\357\274\211-20161216-.pdf" "b/documentation/3rdparty/protocols/PACE-CAN-communication-protocal\357\274\210PACE-CAN-TY\357\274\211-20161216-.pdf" similarity index 100% rename from "docs/PACE-CAN-communication-protocal\357\274\210PACE-CAN-TY\357\274\211-20161216-.pdf" rename to "documentation/3rdparty/protocols/PACE-CAN-communication-protocal\357\274\210PACE-CAN-TY\357\274\211-20161216-.pdf" diff --git a/docs/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf b/documentation/3rdparty/protocols/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf similarity index 100% rename from docs/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf rename to documentation/3rdparty/protocols/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf diff --git a/docs/README.md b/documentation/3rdparty/protocols/README.md similarity index 100% rename from docs/README.md rename to documentation/3rdparty/protocols/README.md diff --git a/docs/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf b/documentation/3rdparty/protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf similarity index 100% rename from docs/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf rename to documentation/3rdparty/protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf diff --git a/docs/SRNE_MODBUS_v3.9.pdf b/documentation/3rdparty/protocols/SRNE_MODBUS_v3.9.pdf similarity index 100% rename from docs/SRNE_MODBUS_v3.9.pdf rename to documentation/3rdparty/protocols/SRNE_MODBUS_v3.9.pdf diff --git a/docs/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf b/documentation/3rdparty/protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf similarity index 100% rename from docs/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf rename to documentation/3rdparty/protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf diff --git a/docs/Sol-Ark ModBus V1.1.pdf b/documentation/3rdparty/protocols/Sol-Ark ModBus V1.1.pdf similarity index 100% rename from docs/Sol-Ark ModBus V1.1.pdf rename to documentation/3rdparty/protocols/Sol-Ark ModBus V1.1.pdf diff --git a/docs/Victron VE-Bus-products-MK2-Protocol-3-14.pdf b/documentation/3rdparty/protocols/Victron VE-Bus-products-MK2-Protocol-3-14.pdf similarity index 100% rename from docs/Victron VE-Bus-products-MK2-Protocol-3-14.pdf rename to documentation/3rdparty/protocols/Victron VE-Bus-products-MK2-Protocol-3-14.pdf diff --git a/docs/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx b/documentation/3rdparty/protocols/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx similarity index 100% rename from docs/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx rename to documentation/3rdparty/protocols/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx diff --git a/docs/converter.txt b/documentation/3rdparty/protocols/converter.txt similarity index 100% rename from docs/converter.txt rename to documentation/3rdparty/protocols/converter.txt diff --git a/docs/hdhk_16ch_ac_module_modbus_rtu.jpeg b/documentation/3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg similarity index 100% rename from docs/hdhk_16ch_ac_module_modbus_rtu.jpeg rename to documentation/3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg diff --git a/docs/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf b/documentation/3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf similarity index 100% rename from docs/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf rename to documentation/3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf diff --git a/docs/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf b/documentation/3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf similarity index 100% rename from docs/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf rename to documentation/3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf diff --git a/documentation/dashboards/grafana.md b/documentation/dashboards/grafana.md new file mode 100644 index 0000000..e69de29 diff --git a/documentation/dashboards/homeassistant.md b/documentation/dashboards/homeassistant.md new file mode 100644 index 0000000..e69de29 diff --git a/documentation/dashboards/nodered.md b/documentation/dashboards/nodered.md new file mode 100644 index 0000000..32ae6c4 --- /dev/null +++ b/documentation/dashboards/nodered.md @@ -0,0 +1,82 @@ +# Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 +This is a simple how-to on setting up a Rasperry Pi node, attempting to be as copy/pastable as possible. As we stand on the shoulders of giants, I will refer to external how-tos for some of the steps. They did it better than I could anyway. + +## Requirements +- a multicore raspberry pi. Though you can run it on a classic raspi 2/pi zero w, a pi zero 2 is the minimum for stablility. +- a recent version of raspberry pi os. + +## Install Raspberry Pi OS +[Just like it says on the tin](https://www.raspberrypi.com/documentation/computers/getting-started.html#install-an-operating-system). Throughout this, I will use some conventions assuming you used the hostname Solar, the username is Solar, and the password is SolarPowered. The rest of this doc assumes you are SSHed in using PuTTY (for windows users) or a terminal of your choice (for the rest of us heathens). The hostname will be `solar.local`, username `solar`, and password `SolarPowered` + +## install dependencies +`sudo apt update && sudo apt upgrade && sudo apt install tmux git mosquitto nginx` + +## Configure Mosquitto MQTT server +Using your favorite text editor, add these lines to `/etc/mosquitto/mosquitto.conf` + +``` +listener 1883 + +allow_anonymous false +password_file /etc/mosquitto/passwd + +``` +Create a new `mosquitto` password file while adding an mqtt user `sudo mosquitto_passwd -c /etc/mosquitto/passwd solar` - to add another user later, drop the `-c`. Start the service with `sudo systemctl start mosquitto`, set the service to start on boot with `sudo systemctl enable mosquitto`. + +## Download/configure PythonProtocolGateway +### Download +`mkdir ~/src/ && cd ~/src && git clone https://github.com/HotNoob/PythonProtocolGateway.git` +### Configure +[Follow the wiki](https://github.com/HotNoob/PythonProtocolGateway/wiki) + +## Install/configure NodeRed service +### Install +[Install how-to](https://nodered.org/docs/getting-started/raspberrypi) - As of the 6 August 2024, you can just paste in `bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)` + +## install NodeRed Nodes +1. [Log in.](http://solar.local:1880/) +2. Click the hambuger menu. +3. Go to `Manage palette`. +4. Under the `Install` tab, search for `@flowfuse/node-red-dashboard`. Click `Install`. +5. Optional: Under the `Install` tab, search for `node-red-contrib-influxdb`, click `Install`. + +## Optional: Install/Enable InfluxDB +If you want to do some historical logging, InfluxDB is a better solution than the node-red internal db. +1. Install influx `sudo apt install influxdb influxdb-client && sudo systemctl enable influxdb && sudo systemctl start ` +2. Create the `solar` db in influx `echo "CREATE DATABASE solar" | influx` +3. Drag an `InfluxDB Out Node` out into the workspace, connect a wire from the `mqtt in` node to the `InfluxDB Out` node. Double click the node, click the `+`, give it a name and the name of the database from above (solar). Click add. It will return you to the node setup, where you will give it a name and a measurement (`solar` in my setup), click `save` or `done`. + +### TODO: create some nodes that consume the DB info. + +## Create your flow or import the example flow (for EG4 users) +### Import example +Go to the hamburger, down to `Import`, click `select a file to import`, find `nodered-example-flow.json` in the repo. You should be left with something like this. +![example flow](https://github.com/user-attachments/assets/c2c284f8-e40f-4e05-bcb7-e054e32dad4c) + +### Create your own flow +1. Drag a `debug` node out - we will be using this throughout to see how the data flows. You can see the debug output by dragging a wire from an output to the debug's input and turning it on. +2. Drag an `mqtt in` node out to the workspace. click the pencil to create a new mqtt-broker-node. Give it a name, enter the hostname in the server field (`solar.local` in our example), click security, add the username and password, click `add` orf `update`. Under `Topic`, enter `home/inverter`. Click done. +3. Drag a json node out onto the workspace, connect the input (left) side of the `json` node to the output of the `mqtt in` node. +4. For each of the things you want on the dashboard, add in a `function` node. This is to filter out the thing you want displayed, in this example, battery percentage. Drag a wire from the `json` node to the function you just created. +``` +msg.payload = parseInt(msg.payload.battery_percentage); +return msg; +``` +click done. +4. From here on out, you will be setting up the wigets you want to see. Checkout the [flowfuse dashboard wiki](https://dashboard.flowfuse.com/getting-started.html) for more info. For each of the functions you just created, create a `chart`, `gauge`, or `text` node to display the things the way you want them displayed. You will need to create a group and page node on the first, the ui will help you throuhg that. + +## Edit the nginx config file to point at the dashboard +Use sudo and your favorite editor to edit `/etc/nginx/sites-enabled/default`. jump down to the `server_name _` section and replace everything between the `{` and `}` so it's like below. + +``` server_name _; + location / { + include proxy_params; + rewrite ^/(.*) /dashboard/$1 break; + proxy_pass http://127.0.0.1:1880; + } +``` + +You should now be able to browse to [Solar.local/Home](http://solar.local/Home/) + +--- +source: https://github.com/yNosGR/PythonProtocolGateway/blob/NodeRed_howto/NodeRed.MD \ No newline at end of file diff --git a/documentation/devices/EG4.md b/documentation/devices/EG4.md new file mode 100644 index 0000000..177b5b6 --- /dev/null +++ b/documentation/devices/EG4.md @@ -0,0 +1,32 @@ +## Hardware +1. USB to RS485 Adapter (RJ45) from EG4 **or** USB to RS485 Adapter & RJ45 Ethernet cable ( or 3 wires ) +2. Connect RJ45 ethernet cable to an avaiable RS485/Modbus port: + +![image](https://github.com/HotNoob/PythonProtocolGateway/assets/2180145/c387d8af-5864-4795-9958-3161d23501f1) + +
+ Example Image + +![327825986-94315fea-abad-4c9c-942d-aa5ad4b47802](https://github.com/HotNoob/PythonProtocolGateway/assets/2180145/f8bee2f2-4f7c-4fd8-a437-2f03af1ba2b0) + +
+ +3. Connect appropriate wires to USB RS485 Adapter + +## Configuration +Follow configuration example for ModBus RTU to MQTT +https://github.com/HotNoob/PythonProtocolGateway/wiki/Configuration-Examples#modbus-rtu-to-mqtt + +#### EG4 6000XP, EG4 18Kpv +``` +protocol_version = eg4_v58 +baud = 19200 +``` + +#### EG4 3000EHV inverters +``` +protocol_version = eg4_3000ehv_v1 +``` + +protocols may not be limited to the models listed. + diff --git a/documentation/devices/Growatt.md b/documentation/devices/Growatt.md new file mode 100644 index 0000000..ce8c666 --- /dev/null +++ b/documentation/devices/Growatt.md @@ -0,0 +1,120 @@ +## Hardware +1. USB-B or USB-A cable +2. for models with a DB9 port a DB9 RS232 adapter is required. "Before use RS232 communication, you should make sure the follow PIN1 and PIN2 are OFF" +3. Connect cable to wifi dongle port; if a alternative usb port exists, try connecting to that one first. + +## Configuration +Follow configuration example for ModBus RTU to MQTT +https://github.com/HotNoob/PythonProtocolGateway/wiki/Configuration-Examples#modbus-rtu-to-mqtt + +``` +protocol_version = v0.14 +``` + +## HomeAssistant Cards +Here are some example cards. If you want to use them, you will have to change the variable names and others to reflect your configs. + +## PV1 & PV2 Card +![pv watts](https://github.com/HotNoob/PythonProtocolGateway/assets/2180145/372980f9-f2d6-48e5-9acd-ee519badb61f) +
+ code + +``` +type: horizontal-stack +cards: + - type: gauge + needle: false + name: PV1 Voltage + entity: sensor.growatt_inverter_pv1_voltage + severity: + green: 150 + yellow: 50 + red: 0 + - type: gauge + entity: sensor.growatt_inverter_pv2_voltage + name: PV2 Voltage + severity: + green: 125 + yellow: 50 + red: 0 + - type: gauge + needle: false + entity: sensor.growatt_inverter_pv1_watts + name: PV1 Watts + severity: + green: 750 + yellow: 250 + red: 0 + - type: gauge + entity: sensor.growatt_inverter_pv2_watts + name: PV2 Watts + severity: + green: 750 + yellow: 250 + red: 0 +``` +
+ +## Output Card +![output](https://github.com/HotNoob/PythonProtocolGateway/assets/2180145/9a129dad-73bc-4401-9746-d7a0dd22cf0a) +
+ code + +``` +type: horizontal-stack +cards: + - type: gauge + needle: true + entity: sensor.growatt_inverter_output_voltage + name: Output Voltage + max: 270 + min: 210 + segments: + - from: 0 + color: '#db4437' + - from: 220 + color: '#ffa600' + - from: 235 + color: '#43a047' + - from: 245 + color: '#ffa600' + - from: 250 + color: '#db4437' + - type: gauge + entity: sensor.growatt_inverter_output_hz + name: Output Hertz + unit: hz + needle: true + max: 62 + min: 58 + segments: + - from: 0 + color: '#db4437' + - from: 59 + color: '#ffa600' + - from: 59.5 + color: '#43a047' + - from: 60.5 + color: '#ffa600' + - from: 61 + color: '#db4437' + - type: gauge + needle: false + entity: sensor.growatt_inverter_output_wattage + name: Output Watts + severity: + green: 0 + yellow: 1200 + red: 8000 + max: 12000 + - type: gauge + entity: sensor.growatt_inverter_output_current + name: Output Current + severity: + green: 0 + yellow: 10 + red: 40 + max: 50 + +``` +
\ No newline at end of file diff --git a/documentation/devices/SOK.md b/documentation/devices/SOK.md new file mode 100644 index 0000000..affee77 --- /dev/null +++ b/documentation/devices/SOK.md @@ -0,0 +1,16 @@ +``` +transport=modbus_rtu +protocol_version=pace_bms_v1.3 +``` +The Battery's RS485 Protocol must be set to: `PACE_MODBUS` + +Plugs into the RS485A port + +This protocol is only able to read the battery that is directly connected to it; a modbus hub can be used to help fix this limitation. + +SOK, jakiper 48v100AH battery and other PACE BMS batteries. + +![pace-bms](https://github.com/HotNoob/InverterModBusToMQTT/assets/2180145/1ea28956-5d74-4bdb-9732-341d492d15c3) + +### rs485a pinout ### +Pin 1,2,3 or Pin 8,7,6 \ No newline at end of file diff --git a/documentation/devices/Sigineer.md b/documentation/devices/Sigineer.md new file mode 100644 index 0000000..6a618dd --- /dev/null +++ b/documentation/devices/Sigineer.md @@ -0,0 +1,45 @@ +## Hardware +1. USB-B or USB-A cable +2. Connect usb cable. + +## Configuration +Follow configuration example for ModBus RTU to MQTT +https://github.com/HotNoob/PythonProtocolGateway/wiki/Configuration-Examples#modbus-rtu-to-mqtt + +``` +protocol_version = sigineer_v0.11 +``` + + +## Home Assistant Cards + +### Voltage Card +![sigineer output](https://github.com/HotNoob/PythonProtocolGateway/assets/2180145/55900744-6aaf-4b44-bf3e-46976fdffce2) + +
+code + +``` +type: horizontal-stack +cards: + - type: gauge + needle: false + name: Battery + entity: sensor.sigineer_battery_voltage + - type: gauge + entity: sensor.sigineer_output_voltage + name: Output + - type: gauge + needle: false + entity: sensor.sigineer_bus_voltage + name: Bus + - type: gauge + entity: sensor.sigineer_grid_voltage + name: Grid + severity: + green: 750 + yellow: 250 + red: 0 + +``` +
\ No newline at end of file diff --git a/documentation/devices/SolArk.md b/documentation/devices/SolArk.md new file mode 100644 index 0000000..75035b4 --- /dev/null +++ b/documentation/devices/SolArk.md @@ -0,0 +1,17 @@ +Currently untested / unconfirmed. ppg version 1.1.3 and higher + +## Hardware +1. USB to RS485 Adapter & RJ45 Ethernet cable ( or 3 wires ) +2. Connect RJ45 ethernet cable to an available RS485/Modbus port: +3. Connect appropriate wires to USB RS485 Adapter. see sol ark documentation + +![image](https://github.com/HotNoob/PythonProtocolGateway/assets/2180145/1d14a542-25ab-4233-917b-304c5bfe2ef2) + + +## Configuration +Follow configuration example for ModBus RTU to MQTT +https://github.com/HotNoob/PythonProtocolGateway/wiki/Configuration-Examples#modbus-rtu-to-mqtt + +``` +protocol_version = solark_v1.1 +``` \ No newline at end of file diff --git a/documentation/usage/configuration_examples/modbus_rtu_to_modbus_tcp.md b/documentation/usage/configuration_examples/modbus_rtu_to_modbus_tcp.md new file mode 100644 index 0000000..0f564ce --- /dev/null +++ b/documentation/usage/configuration_examples/modbus_rtu_to_modbus_tcp.md @@ -0,0 +1,44 @@ +### ModBus RTU to ModBus TCP +untested; in dev +``` +[general] +log_level = DEBUG + +[transport.0] #name must be unique, ie: transport.modbus +#rs485 / modbus device +#protocol config files are located in protocols/ +protocol_version = v0.14 +analyze_protocol = false +write = false + +#modbus address +address = 1 +port = {{serial port, likely /dev/ttyUSB0}} +baudrate = 9600 + +#modbus tcp/tls/udp example +#host = 192.168.0.7 +#port = 502 +#override protocol reader +#transport = modbus_tcp + +#the 'transport' that we want to share this with +bridge = transport.1 + +manufacturer = {{Your device's manufacturer here}} +model = {{Your device's model number here}} +#optional; leave blank to autofetch serial from device +serial_number = + +read_interval = 10 +error_interval = 60 + + +[transport.1] +#modbus tcp +protocol_version = v0.14 +transport=modbus_tcp +write = true +host = 127.0.0.1 +port = 502 +``` \ No newline at end of file diff --git a/documentation/usage/configuration_examples/modbus_rtu_to_mqtt.md b/documentation/usage/configuration_examples/modbus_rtu_to_mqtt.md new file mode 100644 index 0000000..1dc4fba --- /dev/null +++ b/documentation/usage/configuration_examples/modbus_rtu_to_mqtt.md @@ -0,0 +1,49 @@ +### ModBus RTU to MQTT +``` +[general] +log_level = DEBUG + +[transport.0] #name must be unique, ie: transport.modbus +#rs485 / modbus device +#protocol config files are located in protocols/ +protocol_version = v0.14 +analyze_protocol = false +write = false + +#modbus address +address = 1 +port = {{serial port, likely /dev/ttyUSB0}} +baudrate = 9600 + +#modbus tcp/tls/udp example +#host = 192.168.0.7 +#port = 502 +#override protocol reader +#transport = modbus_tcp + +#the 'transport' that we want to share this with +bridge = transport.1 + +manufacturer = {{Your device's manufacturer here}} +model = {{Your device's model number here}} +#optional; leave blank to autofetch serial from device +serial_number = + +read_interval = 10 +error_interval = 60 + + +[transport.1] +#connect mqtt +transport=mqtt +host = {{mqtt ip / host}} +port = 1883 +user = {{mqtt username here}} +pass = {{mqtt password}} +base_topic = home/inverter/ +error_topic = /error +json = false +discovery_enabled = true +discovery_topic = homeassistant +``` + diff --git a/documentation/usage/creating_and_editing_protocols.md b/documentation/usage/creating_and_editing_protocols.md new file mode 100644 index 0000000..92b0a2d --- /dev/null +++ b/documentation/usage/creating_and_editing_protocols.md @@ -0,0 +1,72 @@ +"Protocols" are defined through 2 file types. + +The first is .json, which contains the default settings and optionally codes. + +The .csv files hold the registry or address definitions. + +# CSV + +CSV = comma seperated values... spreadsheets. +delimeter for csv can be , or ; ( not both ) + +| variable name | data type | register|documented name|description|writable|values | +| -- | -- | -- | -- | -- | -- | -- | + + +### variable name +provides a user-friendly name to work with, while retaining the original documented name; since a lot of variable names are up to interpretation. + +### documented name +Original variable name provided from protocol documention; when variable name is not specified, this name is used. + +### data type +Defines the expected data type for the register / map entry + +| Type | Description | +| -- | -- | +| USHORT | A two byte ( 16 bit ) positive number. For protocols that return 2 byte values, this is the default type. +| BYTE | A single byte ( 8 bit ) positive number. +| UINT | A four byte ( 32 bit ) positive number. +| INT | A four byte ( 32 bit ) signed number (positive or negative) +| 16BIT_FLAGS | two bytes split into 16 bits, each bit represents on/off flag which is defined as b#. this will translate into 16x 0/1s if no "codes" are defined. +| 8BIT_FLAGS | A single byte split into 8 bit flags. see 16BIT_FLAGS +| 32BIT_FLAGS | four bytes split into 32 bit flags. see 16BIT_FLAGS +| #bit | A unsigned number comprised of # of bits. for example, 3bit is a 3 bit positive number (0 to 7). +| ASCII | ascii text representation of data. +| ASCII.# | for protocols with an undefined "registry" size, the length can be specified. ie: ASCII.7 will return a 7 character long string. + +### register +Register defines the location or for other protocols the main command / id. +The registers are defined in decimal form. a prefix of "x" is acceptable for hexadecimal. + +For **ASCII** or other MultiRegister Data Types, register ranges can be defined: +``` +7~14 +``` +a prefix of "r" will specify that the registers be "read" in backwards order. + +#### register bit +bit offsets are specified with .b#, # being the bit offset + +``` +#.b# +``` + +#### register byte +byte offsets are specified with .#, # being the byte offset + +``` +#.# +``` + +#### writable +mainly for registers / entries that support writing, such as the holding register for modbus + +``` +R = Read Only +RD = Read Disabled +W = Write +``` + + + diff --git a/documentation/usage/protocols.md b/documentation/usage/protocols.md new file mode 100644 index 0000000..9068598 --- /dev/null +++ b/documentation/usage/protocols.md @@ -0,0 +1,48 @@ +## Custom / Editing Protocols +Custom protocols can be created by naming them with name.custom. this will ensure that they do not get overwritten when updating. + +for example, say that you want to modify the eg4_v58 protocol without having to worry about updates overwritting it: + +``` +copy eg4_v58.json eg4_v58.custom.json +copy eg4_v58.input_registry_map.csv eg4_v58.input_registry_map.custom.csv +copy eg4_v58.holding_registry_map.csv eg4_v58.holding_registry_map.custom.csv +``` + +in the configuration for your transport: +``` +protocol_version = eg4_v58.custom +``` + +## Protocol Configuration - CSV / JSON +{protocol_name}.json contains default settings, releated to the transport. +{protocol_name}.{registry_type}_registry_map.csv contains configuration for specific registry "type". +{protocol_name}.registry_map.csv contains configuration for generic "registers". + +### csv format: +https://github.com/HotNoob/PythonProtocolGateway/wiki/Creating-and-Editing-Protocols-%E2%80%90-JSON-%E2%80%90-CSV#csv + +## egv_v58 +``` +protocol_version = eg4_v58 +``` +[Devices\EG4 to MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CEG4-to-MQTT) + +## v0.14 +``` +protocol_version = v0.14 +``` +[Devices\Growatt To MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CGrowatt-To-MQTT) + +## sigineer_v0.11 + +``` +protocol_version = sigineer_v0.11 +``` +[Devices\Sigineer to MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CSigineer-to-MQTT) + +## pace_bms_v1.3 +``` +protocol_version = pace_bms_v1.3 +``` +[Devices\SOK to MQTT](https://github.com/HotNoob/PythonProtocolGateway/wiki/Devices%5CSOK-to-MQTT) \ No newline at end of file diff --git a/documentation/usage/transports.md b/documentation/usage/transports.md new file mode 100644 index 0000000..aec5ab7 --- /dev/null +++ b/documentation/usage/transports.md @@ -0,0 +1,217 @@ +A transport is configured by creating a configuration section, starting with "transport." +``` +[transport.0] +{transport config here} +``` +or +``` +[transport.growatt] +{transport config here} +``` + +the section header is dual purpose and acts as naming mechanism for parameters like "bridge" + +## Protocol +Transports using ambigious open ended protocols, such as ModBus, Canbus, or register / address based protocols require a map to be defined. this is done so in the /protocols/ folder through csv tables. + +``` +protocol = v0.14 +``` + +see [Protocol Wiki](https://github.com/HotNoob/PythonProtocolGateway/wiki/Protocols) for more on this. + +Other transport protocols such as MQTT, do not require this configuration, as the variable names are provided during transmision and therefore do not need interpretation. + +### Reading +Some transports are Event based, such as MQTT, while others are require active reading. +for protocols that require active reading such as ModBus, the scan interval is set via "read_interval" + +``` +read_interval = 10 +``` + +### Writing +For ambigious sensitive protocols/transports such as ModBus, a safety mechanism is in place to help prevent "bricking" your devices or causing potentially catostrophic damages. + +In order to write, the configuration csv file must be at least 90% verifiable. Alternatively a manual verification method will be implemented in the future. This mainly entails that the current values in the writeable register ( probably holding ), be within the value range specified in the csv. + +Finally, to enable writing for a transport: +``` +write_enabled = true +``` + +Finally, to write, "read" data on any bridged transport. In most cases this will likely be MQTT. + +### Custom Transport +custom transports can be created by naming them name.custom and creating the appropriate .py file. +for example a custom mqtt transport: +copy classes/transports/mqtt.py to classes/transports/mqtt.custom.py + +to use this custom transport: +``` +transport=mqtt.custom +``` + +naming your transport with .custom will ensure that it won't be overwritten when updating. + +# Base +These are parameters that apply to all transports +``` +transport = +device_name = +manufacturer = +model = +serial_number = +bridge = +write_enabled = False +Interval = 10 +Error_Interval = 60 +``` +### transport +Transport is the type or method of reading and writing data +``` +transport = modbus_rtu +``` + + +### device_name +device_name is used as an identifier and is passed on where applicable. +if left blank, device_name will be set to manufacturer + model +``` +device_name = My Solar Inverter 1 +``` + +### manufacturer +manufacturer is used as an identifier and is passed on where applicable. +``` +manufacturer = Growatt +``` + +### model +model is used as an identifier and is passed on where applicable. +``` +model = SPF 12000T +``` + +### serial_number +serial_number is used as an identifier and is passed on where applicable. +If left empty, serial number may be automatically fetched if protocol supports it. +``` +serial_number = +``` + +### bridge +bridge determines which transports to translate data to +this value can be a csv to specify multiple transports +if bridge is set to "broadcast", data will be broadcasted / sent over all configured transports +``` +bridge = transport.mqtt +``` + +### write_enabled +write_enabled allows writting to this transport if enabled. +many protocols have this disabled by default and require accurate registry maps to enable writing, as misconfiguration can have fatal unintended consequences. +by default mqtt allows writing. +``` +write_enabled = True +``` + +#Interval +Interval ( seconds ), sets the frequency of how often data is actively read from a transport. +If interval is not set, data is only sent passively as events occur. +``` +Interval = 10 +``` + +# MQTT +``` +###required +Transport = MQTT +Host +Port +User +Pass +Base_Topic = +discovery_enabled = True +discovery_topic = homeassistant +``` + +``` +###optional +Json = False +Error_Topic = /error +holding_register_prefix = +input_register_prefix = +``` + +## MQTT Read +mqtt "reads" data via the "write" topic. +data that is "read" on the mqtt transport is "written" on any bridged transports. +i know... confusing :P + +during the initialization process, MQTT subscribes to "write enabled" variables / topics, based on the bridged transport's protocol. +the writable topics are given a prefix of "/write/" +``` +{base topic}/write/{variable name} +``` + +## MQTT Write +by default mqtt writes data from the bridged transport. + +# ModBus_RTU +``` +###required +transport = modbus_rtu +protocol_version = +Port = +BaudRate = +Address = +``` +### port +Port is the path to the communications port. on Windows this would be COM#, for Linux /dev/ttyUSB# + +these port numbers can change upon restarting, therefore alternatively, the port can be specified via hardware ids (v1.1.2+): +``` +port = [0x1a86:0x7523::1-4] +``` + +The hardware ids format is: +``` +[vendor id:product id:serial number:location] +``` + +for convience the hardware ids are outputted during script startup. +``` +Serial Port : COM11 = [0x1a86:0x7523::1-4] +``` + +### analyze_protocol +needs a lot of work. on the todo to improve. low priority +``` +analyze_protocol = true +``` + +when this mode runs, it attempt to read all of the registers of your inverter and attempt to determine which protocol best fits. +the higher the value, the more likely that the protocol matches. + +``` +=== growatt_2020_v1.24 - 710 === +input register : 405 of 695 +holding register : 305 of 561 +=== sigineer_v0.11 - 62 === +input register : 31 of 150 +holding register : 31 of 63 +=== v0.14 - 60 === +input register : 19 of 63 +holding register : 41 of 101 +``` + +the results above suggests that "growatt_2020_v1.24" is the most likely protocol for the inverter. + +### analyze_protocol_save_load +``` +analyze_protocol = true +analyze_protocol_save_load = true +``` +When enabled, the analyzer will save dump files containing the raw data found while scanning + From 9a1dc5a2c9b4d0262250c07180de8553d44169ea Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 11:59:13 -0500 Subject: [PATCH 06/25] Create index.md --- documentation/index.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 documentation/index.md diff --git a/documentation/index.md b/documentation/index.md new file mode 100644 index 0000000..e69de29 From 354cfa3bcbf8edb52e488842cdf62ed86f84e331 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 11:59:41 -0500 Subject: [PATCH 07/25] rename --- documentation/{index.md => readme.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename documentation/{index.md => readme.md} (100%) diff --git a/documentation/index.md b/documentation/readme.md similarity index 100% rename from documentation/index.md rename to documentation/readme.md From dfacca8b027b1b452827dc1fa0751004094abb0a Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:00:49 -0500 Subject: [PATCH 08/25] Delete readme.md --- documentation/readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 documentation/readme.md diff --git a/documentation/readme.md b/documentation/readme.md deleted file mode 100644 index e69de29..0000000 From 757c73075e7083f03e3f83ea196ccca6b30f1999 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:32:24 -0500 Subject: [PATCH 09/25] documentation index script --- documentation/.scripts/README.md | 1 + documentation/.scripts/generate_indexes.py | 80 ++++++++++++++++++++++ documentation/README.md | 65 ++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 documentation/.scripts/README.md create mode 100644 documentation/.scripts/generate_indexes.py create mode 100644 documentation/README.md diff --git a/documentation/.scripts/README.md b/documentation/.scripts/README.md new file mode 100644 index 0000000..b5e9fc2 --- /dev/null +++ b/documentation/.scripts/README.md @@ -0,0 +1 @@ +folder for scripts releated to documentation \ No newline at end of file diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py new file mode 100644 index 0000000..5f73410 --- /dev/null +++ b/documentation/.scripts/generate_indexes.py @@ -0,0 +1,80 @@ + + +import os + +def extract_first_header(file_path): + """Extract the first header from a markdown file.""" + with open(file_path, "r", encoding="utf-8") as file: + for line in file: + line = line.strip() + if line.startswith("#"): + return line + return None + + +def generate_readme(directory : str, folder_order : str = [], output_file : str ="README.md"): + with open(directory+output_file, "w", encoding="utf-8") as readme: + readme.write("# README Index\n\n") + readme.write("This README file contains an index of all files in the documentation directory.\n\n") + readme.write("## File List\n\n") + + previous_folder = "" + + folder_lines : dict[str, list[str]] = {} + + for root, dirs, files in os.walk(directory): + relative_folder = os.path.relpath(root, directory).replace("\\", "/") #use linux path structre + + #exclude . folders + if relative_folder[0] == '.': + continue + + if relative_folder != previous_folder: + # Create a bold header for each new folder + folder_lines[relative_folder] = [] + folder_lines[relative_folder].append(f"**{relative_folder}**\n\n") + + previous_folder = relative_folder + + for file in files: + file_path = os.path.relpath(os.path.join(root, file), directory) + + if file.endswith(".md"): + first_header = extract_first_header(os.path.join(root, file)) + if first_header: + folder_lines[relative_folder].append(f"- [{file}]({file_path}) - {first_header}") + else: + folder_lines[relative_folder].append(f"- [{file}]({file_path})") + else: + folder_lines[relative_folder].append(f"- [{file}]({file_path})") + + # Add an extra line break between different folders + if files: + folder_lines[relative_folder].append("") + + #write output + for folder in folder_lines: + if folder in folder_order: #skip ordered folders for the end + continue + + for line in folder_lines[folder]: + readme.write(line + "\n") + + #write ordered output + for folder in folder_order: + if folder not in folder_lines: #not found + continue + + for line in folder_lines[folder]: + readme.write(line + "\n") + + + +if __name__ == "__main__": + # Change the working directory to the location of the script + script_dir = os.path.dirname(os.path.abspath(__file__)) + os.chdir(script_dir) + + # Specify the directory you want to index + directory_to_index = "../" + generate_readme(directory_to_index, ["3rdparty", "3rdparty/protocols"]) \ No newline at end of file diff --git a/documentation/README.md b/documentation/README.md new file mode 100644 index 0000000..b76ee8d --- /dev/null +++ b/documentation/README.md @@ -0,0 +1,65 @@ +# Project Files Index + +This README file contains an index of all files in the project directory. + +## File List + +**dashboards** + + +- [grafana.md](dashboards\grafana.md) +- [homeassistant.md](dashboards\homeassistant.md) +- [nodered.md](dashboards\nodered.md) - # Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 + +**devices** + + +- [EG4.md](devices\EG4.md) - ## Hardware +- [Growatt.md](devices\Growatt.md) - ## Hardware +- [Sigineer.md](devices\Sigineer.md) - ## Hardware +- [SOK.md](devices\SOK.md) - ### rs485a pinout ### +- [SolArk.md](devices\SolArk.md) - ## Hardware + +**usage** + + +- [creating_and_editing_protocols.md](usage\creating_and_editing_protocols.md) - # CSV +- [protocols.md](usage\protocols.md) - ## Custom / Editing Protocols +- [transports.md](usage\transports.md) - ## Protocol + +**usage/configuration_examples** + + +- [modbus_rtu_to_modbus_tcp.md](usage\configuration_examples\modbus_rtu_to_modbus_tcp.md) - ### ModBus RTU to ModBus TCP +- [modbus_rtu_to_mqtt.md](usage\configuration_examples\modbus_rtu_to_mqtt.md) - ### ModBus RTU to MQTT + +**3rdparty** + + +**3rdparty/protocols** + + +- [CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf](3rdparty\protocols\CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf) +- [converter.txt](3rdparty\protocols\converter.txt) +- [EG4-3000-EHV - MODBUS Communication Protocol.pdf](3rdparty\protocols\EG4-3000-EHV - MODBUS Communication Protocol.pdf) +- [EG4-6000XP-MODBUS-Communication-Protocol.pdf](3rdparty\protocols\EG4-6000XP-MODBUS-Communication-Protocol.pdf) +- [Growatt Modbus Protocol v1.24.pdf](3rdparty\protocols\Growatt Modbus Protocol v1.24.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf](3rdparty\protocols\Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf](3rdparty\protocols\Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf) +- [hdhk_16ch_ac_module_modbus_rtu.jpeg](3rdparty\protocols\hdhk_16ch_ac_module_modbus_rtu.jpeg) +- [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty\protocols\hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) +- [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty\protocols\hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) +- [MAX Series Modbus RTU Protocol.pdf](3rdparty\protocols\MAX Series Modbus RTU Protocol.pdf) +- [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty\protocols\OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) +- [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty\protocols\PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) +- [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty\protocols\PACE-BMS-RS485-communication-protocol-20180615.pdf) +- [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty\protocols\PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf) +- [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty\protocols\PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf) +- [README.md](3rdparty\protocols\README.md) +- [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](3rdparty\protocols\RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) +- [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](3rdparty\protocols\Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) +- [Sol-Ark ModBus V1.1.pdf](3rdparty\protocols\Sol-Ark ModBus V1.1.pdf) +- [SRNE_MODBUS_v3.9.pdf](3rdparty\protocols\SRNE_MODBUS_v3.9.pdf) +- [Victron VE-Bus-products-MK2-Protocol-3-14.pdf](3rdparty\protocols\Victron VE-Bus-products-MK2-Protocol-3-14.pdf) +- [Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx](3rdparty\protocols\Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx) + From 2801fe25ba733dbd774286394446400ded920528 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:33:41 -0500 Subject: [PATCH 10/25] fix paths --- documentation/.scripts/generate_indexes.py | 4 +- documentation/README.md | 76 +++++++++++----------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index 5f73410..25bae3c 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -23,7 +23,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str folder_lines : dict[str, list[str]] = {} for root, dirs, files in os.walk(directory): - relative_folder = os.path.relpath(root, directory).replace("\\", "/") #use linux path structre + relative_folder = os.path.relpath(root, directory).replace("\\", "/") #use linux path structure #exclude . folders if relative_folder[0] == '.': @@ -37,7 +37,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str previous_folder = relative_folder for file in files: - file_path = os.path.relpath(os.path.join(root, file), directory) + file_path = os.path.relpath(os.path.join(root, file), directory).replace("\\", "/") #use linux path structure if file.endswith(".md"): first_header = extract_first_header(os.path.join(root, file)) diff --git a/documentation/README.md b/documentation/README.md index b76ee8d..0086d7f 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -1,37 +1,37 @@ -# Project Files Index +# README Index -This README file contains an index of all files in the project directory. +This README file contains an index of all files in the documentation directory. ## File List **dashboards** -- [grafana.md](dashboards\grafana.md) -- [homeassistant.md](dashboards\homeassistant.md) -- [nodered.md](dashboards\nodered.md) - # Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 +- [grafana.md](dashboards/grafana.md) +- [homeassistant.md](dashboards/homeassistant.md) +- [nodered.md](dashboards/nodered.md) - # Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 **devices** -- [EG4.md](devices\EG4.md) - ## Hardware -- [Growatt.md](devices\Growatt.md) - ## Hardware -- [Sigineer.md](devices\Sigineer.md) - ## Hardware -- [SOK.md](devices\SOK.md) - ### rs485a pinout ### -- [SolArk.md](devices\SolArk.md) - ## Hardware +- [EG4.md](devices/EG4.md) - ## Hardware +- [Growatt.md](devices/Growatt.md) - ## Hardware +- [Sigineer.md](devices/Sigineer.md) - ## Hardware +- [SOK.md](devices/SOK.md) - ### rs485a pinout ### +- [SolArk.md](devices/SolArk.md) - ## Hardware **usage** -- [creating_and_editing_protocols.md](usage\creating_and_editing_protocols.md) - # CSV -- [protocols.md](usage\protocols.md) - ## Custom / Editing Protocols -- [transports.md](usage\transports.md) - ## Protocol +- [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - # CSV +- [protocols.md](usage/protocols.md) - ## Custom / Editing Protocols +- [transports.md](usage/transports.md) - ## Protocol **usage/configuration_examples** -- [modbus_rtu_to_modbus_tcp.md](usage\configuration_examples\modbus_rtu_to_modbus_tcp.md) - ### ModBus RTU to ModBus TCP -- [modbus_rtu_to_mqtt.md](usage\configuration_examples\modbus_rtu_to_mqtt.md) - ### ModBus RTU to MQTT +- [modbus_rtu_to_modbus_tcp.md](usage/configuration_examples/modbus_rtu_to_modbus_tcp.md) - ### ModBus RTU to ModBus TCP +- [modbus_rtu_to_mqtt.md](usage/configuration_examples/modbus_rtu_to_mqtt.md) - ### ModBus RTU to MQTT **3rdparty** @@ -39,27 +39,27 @@ This README file contains an index of all files in the project directory. **3rdparty/protocols** -- [CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf](3rdparty\protocols\CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf) -- [converter.txt](3rdparty\protocols\converter.txt) -- [EG4-3000-EHV - MODBUS Communication Protocol.pdf](3rdparty\protocols\EG4-3000-EHV - MODBUS Communication Protocol.pdf) -- [EG4-6000XP-MODBUS-Communication-Protocol.pdf](3rdparty\protocols\EG4-6000XP-MODBUS-Communication-Protocol.pdf) -- [Growatt Modbus Protocol v1.24.pdf](3rdparty\protocols\Growatt Modbus Protocol v1.24.pdf) -- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf](3rdparty\protocols\Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf) -- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf](3rdparty\protocols\Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf) -- [hdhk_16ch_ac_module_modbus_rtu.jpeg](3rdparty\protocols\hdhk_16ch_ac_module_modbus_rtu.jpeg) -- [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty\protocols\hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) -- [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty\protocols\hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) -- [MAX Series Modbus RTU Protocol.pdf](3rdparty\protocols\MAX Series Modbus RTU Protocol.pdf) -- [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty\protocols\OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) -- [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty\protocols\PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) -- [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty\protocols\PACE-BMS-RS485-communication-protocol-20180615.pdf) -- [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty\protocols\PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf) -- [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty\protocols\PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf) -- [README.md](3rdparty\protocols\README.md) -- [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](3rdparty\protocols\RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) -- [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](3rdparty\protocols\Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) -- [Sol-Ark ModBus V1.1.pdf](3rdparty\protocols\Sol-Ark ModBus V1.1.pdf) -- [SRNE_MODBUS_v3.9.pdf](3rdparty\protocols\SRNE_MODBUS_v3.9.pdf) -- [Victron VE-Bus-products-MK2-Protocol-3-14.pdf](3rdparty\protocols\Victron VE-Bus-products-MK2-Protocol-3-14.pdf) -- [Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx](3rdparty\protocols\Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx) +- [CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf](3rdparty/protocols/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf) +- [converter.txt](3rdparty/protocols/converter.txt) +- [EG4-3000-EHV - MODBUS Communication Protocol.pdf](3rdparty/protocols/EG4-3000-EHV - MODBUS Communication Protocol.pdf) +- [EG4-6000XP-MODBUS-Communication-Protocol.pdf](3rdparty/protocols/EG4-6000XP-MODBUS-Communication-Protocol.pdf) +- [Growatt Modbus Protocol v1.24.pdf](3rdparty/protocols/Growatt Modbus Protocol v1.24.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf](3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf](3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf) +- [hdhk_16ch_ac_module_modbus_rtu.jpeg](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg) +- [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) +- [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) +- [MAX Series Modbus RTU Protocol.pdf](3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf) +- [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) +- [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) +- [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) +- [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty/protocols/PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf) +- [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty/protocols/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf) +- [README.md](3rdparty/protocols/README.md) +- [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](3rdparty/protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) +- [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](3rdparty/protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) +- [Sol-Ark ModBus V1.1.pdf](3rdparty/protocols/Sol-Ark ModBus V1.1.pdf) +- [SRNE_MODBUS_v3.9.pdf](3rdparty/protocols/SRNE_MODBUS_v3.9.pdf) +- [Victron VE-Bus-products-MK2-Protocol-3-14.pdf](3rdparty/protocols/Victron VE-Bus-products-MK2-Protocol-3-14.pdf) +- [Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx](3rdparty/protocols/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx) From fc88974458cde2f6fac5baead27f2661fc5696b2 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:34:35 -0500 Subject: [PATCH 11/25] Update README.md --- documentation/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/README.md b/documentation/README.md index 0086d7f..927b6ba 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -49,7 +49,7 @@ This README file contains an index of all files in the documentation directory. - [hdhk_16ch_ac_module_modbus_rtu.jpeg](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg) - [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) - [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) -- [MAX Series Modbus RTU Protocol.pdf](3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf) +- [MAX Series Modbus RTU Protocol.pdf]("3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf") - [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) - [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) - [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) From df2be7526e39027e2c21ddd6663a633361ac1eef Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:36:41 -0500 Subject: [PATCH 12/25] header fix --- documentation/.scripts/generate_indexes.py | 2 +- documentation/README.md | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index 25bae3c..7a85f8a 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -8,7 +8,7 @@ def extract_first_header(file_path): for line in file: line = line.strip() if line.startswith("#"): - return line + return line.replace('#', '') return None diff --git a/documentation/README.md b/documentation/README.md index 0086d7f..3e6a236 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -9,29 +9,29 @@ This README file contains an index of all files in the documentation directory. - [grafana.md](dashboards/grafana.md) - [homeassistant.md](dashboards/homeassistant.md) -- [nodered.md](dashboards/nodered.md) - # Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 +- [nodered.md](dashboards/nodered.md) - Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 **devices** -- [EG4.md](devices/EG4.md) - ## Hardware -- [Growatt.md](devices/Growatt.md) - ## Hardware -- [Sigineer.md](devices/Sigineer.md) - ## Hardware -- [SOK.md](devices/SOK.md) - ### rs485a pinout ### -- [SolArk.md](devices/SolArk.md) - ## Hardware +- [EG4.md](devices/EG4.md) - Hardware +- [Growatt.md](devices/Growatt.md) - Hardware +- [Sigineer.md](devices/Sigineer.md) - Hardware +- [SOK.md](devices/SOK.md) - rs485a pinout +- [SolArk.md](devices/SolArk.md) - Hardware **usage** -- [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - # CSV -- [protocols.md](usage/protocols.md) - ## Custom / Editing Protocols -- [transports.md](usage/transports.md) - ## Protocol +- [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - CSV +- [protocols.md](usage/protocols.md) - Custom / Editing Protocols +- [transports.md](usage/transports.md) - Protocol **usage/configuration_examples** -- [modbus_rtu_to_modbus_tcp.md](usage/configuration_examples/modbus_rtu_to_modbus_tcp.md) - ### ModBus RTU to ModBus TCP -- [modbus_rtu_to_mqtt.md](usage/configuration_examples/modbus_rtu_to_mqtt.md) - ### ModBus RTU to MQTT +- [modbus_rtu_to_modbus_tcp.md](usage/configuration_examples/modbus_rtu_to_modbus_tcp.md) - ModBus RTU to ModBus TCP +- [modbus_rtu_to_mqtt.md](usage/configuration_examples/modbus_rtu_to_mqtt.md) - ModBus RTU to MQTT **3rdparty** From 798f7e5772fa431d0c85f669f9c4ca8576e5ad70 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:39:03 -0500 Subject: [PATCH 13/25] Update EG4.md --- documentation/devices/EG4.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/devices/EG4.md b/documentation/devices/EG4.md index 177b5b6..de39be6 100644 --- a/documentation/devices/EG4.md +++ b/documentation/devices/EG4.md @@ -1,3 +1,5 @@ +# EG4 to MQTT + ## Hardware 1. USB to RS485 Adapter (RJ45) from EG4 **or** USB to RS485 Adapter & RJ45 Ethernet cable ( or 3 wires ) 2. Connect RJ45 ethernet cable to an avaiable RS485/Modbus port: From 39456f0638decd4491eb1a31000066fe364f2e71 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:40:57 -0500 Subject: [PATCH 14/25] fix titles --- documentation/README.md | 12 ++++++------ documentation/devices/Growatt.md | 2 ++ documentation/devices/SOK.md | 2 ++ documentation/devices/Sigineer.md | 2 ++ documentation/devices/SolArk.md | 2 ++ 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/documentation/README.md b/documentation/README.md index 78b8f0c..5e8c6bc 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -14,11 +14,11 @@ This README file contains an index of all files in the documentation directory. **devices** -- [EG4.md](devices/EG4.md) - Hardware -- [Growatt.md](devices/Growatt.md) - Hardware -- [Sigineer.md](devices/Sigineer.md) - Hardware -- [SOK.md](devices/SOK.md) - rs485a pinout -- [SolArk.md](devices/SolArk.md) - Hardware +- [EG4.md](devices/EG4.md) - EG4 to MQTT +- [Growatt.md](devices/Growatt.md) - Growatt To MQTT +- [Sigineer.md](devices/Sigineer.md) - Sigineer to MQTT +- [SOK.md](devices/SOK.md) - SOK to MQTT +- [SolArk.md](devices/SolArk.md) - SolArk to MQTT **usage** @@ -49,7 +49,7 @@ This README file contains an index of all files in the documentation directory. - [hdhk_16ch_ac_module_modbus_rtu.jpeg](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg) - [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) - [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) -- [MAX Series Modbus RTU Protocol.pdf]("3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf") +- [MAX Series Modbus RTU Protocol.pdf](3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf) - [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) - [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) - [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) diff --git a/documentation/devices/Growatt.md b/documentation/devices/Growatt.md index ce8c666..1b2d4f0 100644 --- a/documentation/devices/Growatt.md +++ b/documentation/devices/Growatt.md @@ -1,3 +1,5 @@ +# Growatt To MQTT + ## Hardware 1. USB-B or USB-A cable 2. for models with a DB9 port a DB9 RS232 adapter is required. "Before use RS232 communication, you should make sure the follow PIN1 and PIN2 are OFF" diff --git a/documentation/devices/SOK.md b/documentation/devices/SOK.md index affee77..5414453 100644 --- a/documentation/devices/SOK.md +++ b/documentation/devices/SOK.md @@ -1,3 +1,5 @@ +# SOK to MQTT + ``` transport=modbus_rtu protocol_version=pace_bms_v1.3 diff --git a/documentation/devices/Sigineer.md b/documentation/devices/Sigineer.md index 6a618dd..62cecd8 100644 --- a/documentation/devices/Sigineer.md +++ b/documentation/devices/Sigineer.md @@ -1,3 +1,5 @@ +# Sigineer to MQTT + ## Hardware 1. USB-B or USB-A cable 2. Connect usb cable. diff --git a/documentation/devices/SolArk.md b/documentation/devices/SolArk.md index 75035b4..3b889a7 100644 --- a/documentation/devices/SolArk.md +++ b/documentation/devices/SolArk.md @@ -1,3 +1,5 @@ +# SolArk to MQTT + Currently untested / unconfirmed. ppg version 1.1.3 and higher ## Hardware From 9e30e24e30e4320e5aac28acc9bc36a33aa3fca7 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:44:49 -0500 Subject: [PATCH 15/25] fix links --- documentation/.scripts/generate_indexes.py | 5 +++-- documentation/README.md | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index 7a85f8a..447a25a 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -1,6 +1,6 @@ - - import os +import urllib + def extract_first_header(file_path): """Extract the first header from a markdown file.""" @@ -38,6 +38,7 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str for file in files: file_path = os.path.relpath(os.path.join(root, file), directory).replace("\\", "/") #use linux path structure + file_path = urllib.parse.quote(file_path) if file.endswith(".md"): first_header = extract_first_header(os.path.join(root, file)) diff --git a/documentation/README.md b/documentation/README.md index 5e8c6bc..114fbde 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -41,25 +41,25 @@ This README file contains an index of all files in the documentation directory. - [CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf](3rdparty/protocols/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf) - [converter.txt](3rdparty/protocols/converter.txt) -- [EG4-3000-EHV - MODBUS Communication Protocol.pdf](3rdparty/protocols/EG4-3000-EHV - MODBUS Communication Protocol.pdf) +- [EG4-3000-EHV - MODBUS Communication Protocol.pdf](3rdparty/protocols/EG4-3000-EHV%20-%20MODBUS%20Communication%20Protocol.pdf) - [EG4-6000XP-MODBUS-Communication-Protocol.pdf](3rdparty/protocols/EG4-6000XP-MODBUS-Communication-Protocol.pdf) -- [Growatt Modbus Protocol v1.24.pdf](3rdparty/protocols/Growatt Modbus Protocol v1.24.pdf) -- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf](3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf) -- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf](3rdparty/protocols/Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf) +- [Growatt Modbus Protocol v1.24.pdf](3rdparty/protocols/Growatt%20Modbus%20Protocol%20v1.24.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf](3rdparty/protocols/Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.04.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf](3rdparty/protocols/Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.15.pdf) - [hdhk_16ch_ac_module_modbus_rtu.jpeg](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg) - [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) - [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) -- [MAX Series Modbus RTU Protocol.pdf](3rdparty/protocols/MAX Series Modbus RTU Protocol.pdf) +- [MAX Series Modbus RTU Protocol.pdf](3rdparty/protocols/MAX%20Series%20Modbus%20RTU%20Protocol.pdf) - [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) - [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) - [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) -- [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty/protocols/PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf) -- [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty/protocols/PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf) +- [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty/protocols/PACE-CAN-communication-protocal%EF%BC%88PACE-CAN-TY%EF%BC%89-20161216-.pdf) +- [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty/protocols/PYLON%20LFP%20Battery%20communication%20protocol%20-%20RS485%20V2.8%2020161216.pdf) - [README.md](3rdparty/protocols/README.md) - [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](3rdparty/protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) - [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](3rdparty/protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) -- [Sol-Ark ModBus V1.1.pdf](3rdparty/protocols/Sol-Ark ModBus V1.1.pdf) +- [Sol-Ark ModBus V1.1.pdf](3rdparty/protocols/Sol-Ark%20ModBus%20V1.1.pdf) - [SRNE_MODBUS_v3.9.pdf](3rdparty/protocols/SRNE_MODBUS_v3.9.pdf) -- [Victron VE-Bus-products-MK2-Protocol-3-14.pdf](3rdparty/protocols/Victron VE-Bus-products-MK2-Protocol-3-14.pdf) +- [Victron VE-Bus-products-MK2-Protocol-3-14.pdf](3rdparty/protocols/Victron%20VE-Bus-products-MK2-Protocol-3-14.pdf) - [Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx](3rdparty/protocols/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx) From 75e2fea1ef5a31eb9338e63347ccfd49842254ba Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 12:51:40 -0500 Subject: [PATCH 16/25] subfolder indexes --- documentation/.scripts/generate_indexes.py | 12 ++++++- documentation/3rdparty/README.md | 33 +++++++++++++++++++ documentation/3rdparty/protocols/README.md | 9 +++++ documentation/3rdparty/protocols/note.md | 14 ++++++++ documentation/README.md | 9 ++++- documentation/dashboards/README.md | 6 ++++ documentation/devices/README.md | 6 ++++ documentation/usage/README.md | 13 ++++++++ .../usage/configuration_examples/README.md | 6 ++++ 9 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 documentation/3rdparty/README.md create mode 100644 documentation/3rdparty/protocols/note.md create mode 100644 documentation/dashboards/README.md create mode 100644 documentation/devices/README.md create mode 100644 documentation/usage/README.md create mode 100644 documentation/usage/configuration_examples/README.md diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index 447a25a..7e14415 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -13,10 +13,17 @@ def extract_first_header(file_path): def generate_readme(directory : str, folder_order : str = [], output_file : str ="README.md"): - with open(directory+output_file, "w", encoding="utf-8") as readme: + with open(directory+'/'+output_file, "w", encoding="utf-8") as readme: readme.write("# README Index\n\n") readme.write("This README file contains an index of all files in the documentation directory.\n\n") readme.write("## File List\n\n") + + note_file : str = directory+'/note.md' + if os.path.exists(note_file): + readme.write("\n## Additional Notes\n\n") + with open(note_file, "r", encoding="utf-8") as note: + readme.write(note.read()) + previous_folder = "" @@ -36,6 +43,9 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str previous_folder = relative_folder + #generate index in folder + generate_readme(directory+"/"+relative_folder) + for file in files: file_path = os.path.relpath(os.path.join(root, file), directory).replace("\\", "/") #use linux path structure file_path = urllib.parse.quote(file_path) diff --git a/documentation/3rdparty/README.md b/documentation/3rdparty/README.md new file mode 100644 index 0000000..f38d852 --- /dev/null +++ b/documentation/3rdparty/README.md @@ -0,0 +1,33 @@ +# README Index + +This README file contains an index of all files in the documentation directory. + +## File List + +**protocols** + + +- [CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf](protocols/CAN-Bus-protocol-PYLON-low-voltage-V1.2-20180408.pdf) +- [converter.txt](protocols/converter.txt) +- [EG4-3000-EHV - MODBUS Communication Protocol.pdf](protocols/EG4-3000-EHV%20-%20MODBUS%20Communication%20Protocol.pdf) +- [EG4-6000XP-MODBUS-Communication-Protocol.pdf](protocols/EG4-6000XP-MODBUS-Communication-Protocol.pdf) +- [Growatt Modbus Protocol v1.24.pdf](protocols/Growatt%20Modbus%20Protocol%20v1.24.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.04.pdf](protocols/Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.04.pdf) +- [Growatt PV Inverter Modbus RS485 RTU Protocol V3.15.pdf](protocols/Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.15.pdf) +- [hdhk_16ch_ac_module_modbus_rtu.jpeg](protocols/hdhk_16ch_ac_module_modbus_rtu.jpeg) +- [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) +- [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) +- [MAX Series Modbus RTU Protocol.pdf](protocols/MAX%20Series%20Modbus%20RTU%20Protocol.pdf) +- [note.md](protocols/note.md) +- [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) +- [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) +- [PACE-BMS-RS485-communication-protocol-20180615.pdf](protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) +- [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](protocols/PACE-CAN-communication-protocal%EF%BC%88PACE-CAN-TY%EF%BC%89-20161216-.pdf) +- [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](protocols/PYLON%20LFP%20Battery%20communication%20protocol%20-%20RS485%20V2.8%2020161216.pdf) +- [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) +- [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) +- [Sol-Ark ModBus V1.1.pdf](protocols/Sol-Ark%20ModBus%20V1.1.pdf) +- [SRNE_MODBUS_v3.9.pdf](protocols/SRNE_MODBUS_v3.9.pdf) +- [Victron VE-Bus-products-MK2-Protocol-3-14.pdf](protocols/Victron%20VE-Bus-products-MK2-Protocol-3-14.pdf) +- [Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx](protocols/Victron-CCGX-Modbus-TCP-register-list-3.30.xlsx) + diff --git a/documentation/3rdparty/protocols/README.md b/documentation/3rdparty/protocols/README.md index 63eaf98..733053a 100644 --- a/documentation/3rdparty/protocols/README.md +++ b/documentation/3rdparty/protocols/README.md @@ -1,3 +1,12 @@ +# README Index + +This README file contains an index of all files in the documentation directory. + +## File List + + +## Additional Notes + Protocol Documentation --- diff --git a/documentation/3rdparty/protocols/note.md b/documentation/3rdparty/protocols/note.md new file mode 100644 index 0000000..63eaf98 --- /dev/null +++ b/documentation/3rdparty/protocols/note.md @@ -0,0 +1,14 @@ + +Protocol Documentation +--- +[V3.14](Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.14.pdf) + +Source: https://github.com/jrbenito/canadianSolar-pvoutput/blob/732efe68b71f67129f5b31442f82f2be0d79e605/docs/ + +Note: The original file name doesn't match the version specified in the document. + +---- +[V3.04](Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.04.pdf) + +Source: http://www.growatt.pl/dokumenty/Inne/Growatt%20PV%20Inverter%20Modbus%20RS485%20RTU%20Protocol%20V3.04.pdf + diff --git a/documentation/README.md b/documentation/README.md index 114fbde..a4ea9d8 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -10,12 +10,14 @@ This README file contains an index of all files in the documentation directory. - [grafana.md](dashboards/grafana.md) - [homeassistant.md](dashboards/homeassistant.md) - [nodered.md](dashboards/nodered.md) - Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 +- [README.md](dashboards/README.md) - README Index **devices** - [EG4.md](devices/EG4.md) - EG4 to MQTT - [Growatt.md](devices/Growatt.md) - Growatt To MQTT +- [README.md](devices/README.md) - README Index - [Sigineer.md](devices/Sigineer.md) - Sigineer to MQTT - [SOK.md](devices/SOK.md) - SOK to MQTT - [SolArk.md](devices/SolArk.md) - SolArk to MQTT @@ -25,6 +27,7 @@ This README file contains an index of all files in the documentation directory. - [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - CSV - [protocols.md](usage/protocols.md) - Custom / Editing Protocols +- [README.md](usage/README.md) - README Index - [transports.md](usage/transports.md) - Protocol **usage/configuration_examples** @@ -32,10 +35,13 @@ This README file contains an index of all files in the documentation directory. - [modbus_rtu_to_modbus_tcp.md](usage/configuration_examples/modbus_rtu_to_modbus_tcp.md) - ModBus RTU to ModBus TCP - [modbus_rtu_to_mqtt.md](usage/configuration_examples/modbus_rtu_to_mqtt.md) - ModBus RTU to MQTT +- [README.md](usage/configuration_examples/README.md) - README Index **3rdparty** +- [README.md](3rdparty/README.md) - README Index + **3rdparty/protocols** @@ -50,12 +56,13 @@ This README file contains an index of all files in the documentation directory. - [hdhk_16ch_ac_module_modbus_rtu_chinese.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_chinese.pdf) - [hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf](3rdparty/protocols/hdhk_16ch_ac_module_modbus_rtu_translated_english.pdf) - [MAX Series Modbus RTU Protocol.pdf](3rdparty/protocols/MAX%20Series%20Modbus%20RTU%20Protocol.pdf) +- [note.md](3rdparty/protocols/note.md) - [OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf](3rdparty/protocols/OffGrid-Modbus-RS485RS232-RTU-Protocol-V0.14-20210420.pdf) - [PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf](3rdparty/protocols/PACE-BMS-Modbus-Protocol-for-RS485-V1.3-20170627.pdf) - [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) - [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty/protocols/PACE-CAN-communication-protocal%EF%BC%88PACE-CAN-TY%EF%BC%89-20161216-.pdf) - [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty/protocols/PYLON%20LFP%20Battery%20communication%20protocol%20-%20RS485%20V2.8%2020161216.pdf) -- [README.md](3rdparty/protocols/README.md) +- [README.md](3rdparty/protocols/README.md) - README Index - [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](3rdparty/protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) - [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](3rdparty/protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) - [Sol-Ark ModBus V1.1.pdf](3rdparty/protocols/Sol-Ark%20ModBus%20V1.1.pdf) diff --git a/documentation/dashboards/README.md b/documentation/dashboards/README.md new file mode 100644 index 0000000..5a44987 --- /dev/null +++ b/documentation/dashboards/README.md @@ -0,0 +1,6 @@ +# README Index + +This README file contains an index of all files in the documentation directory. + +## File List + diff --git a/documentation/devices/README.md b/documentation/devices/README.md new file mode 100644 index 0000000..5a44987 --- /dev/null +++ b/documentation/devices/README.md @@ -0,0 +1,6 @@ +# README Index + +This README file contains an index of all files in the documentation directory. + +## File List + diff --git a/documentation/usage/README.md b/documentation/usage/README.md new file mode 100644 index 0000000..594dc75 --- /dev/null +++ b/documentation/usage/README.md @@ -0,0 +1,13 @@ +# README Index + +This README file contains an index of all files in the documentation directory. + +## File List + +**configuration_examples** + + +- [modbus_rtu_to_modbus_tcp.md](configuration_examples/modbus_rtu_to_modbus_tcp.md) - ModBus RTU to ModBus TCP +- [modbus_rtu_to_mqtt.md](configuration_examples/modbus_rtu_to_mqtt.md) - ModBus RTU to MQTT +- [README.md](configuration_examples/README.md) - README Index + diff --git a/documentation/usage/configuration_examples/README.md b/documentation/usage/configuration_examples/README.md new file mode 100644 index 0000000..5a44987 --- /dev/null +++ b/documentation/usage/configuration_examples/README.md @@ -0,0 +1,6 @@ +# README Index + +This README file contains an index of all files in the documentation directory. + +## File List + From 4960645cb896677be68624525f225ef42ab82661 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 13:04:55 -0500 Subject: [PATCH 17/25] remove readme.md indexes --- documentation/.scripts/generate_indexes.py | 3 +++ documentation/README.md | 6 ------ documentation/usage/README.md | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/documentation/.scripts/generate_indexes.py b/documentation/.scripts/generate_indexes.py index 7e14415..159e742 100644 --- a/documentation/.scripts/generate_indexes.py +++ b/documentation/.scripts/generate_indexes.py @@ -50,6 +50,9 @@ def generate_readme(directory : str, folder_order : str = [], output_file : str file_path = os.path.relpath(os.path.join(root, file), directory).replace("\\", "/") #use linux path structure file_path = urllib.parse.quote(file_path) + if file == "README.md": #skip + continue + if file.endswith(".md"): first_header = extract_first_header(os.path.join(root, file)) if first_header: diff --git a/documentation/README.md b/documentation/README.md index a4ea9d8..c3b377d 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -10,14 +10,12 @@ This README file contains an index of all files in the documentation directory. - [grafana.md](dashboards/grafana.md) - [homeassistant.md](dashboards/homeassistant.md) - [nodered.md](dashboards/nodered.md) - Setting up PythonProtocolGateway on a RasPi with NodeRed Dashboard 2.0 -- [README.md](dashboards/README.md) - README Index **devices** - [EG4.md](devices/EG4.md) - EG4 to MQTT - [Growatt.md](devices/Growatt.md) - Growatt To MQTT -- [README.md](devices/README.md) - README Index - [Sigineer.md](devices/Sigineer.md) - Sigineer to MQTT - [SOK.md](devices/SOK.md) - SOK to MQTT - [SolArk.md](devices/SolArk.md) - SolArk to MQTT @@ -27,7 +25,6 @@ This README file contains an index of all files in the documentation directory. - [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - CSV - [protocols.md](usage/protocols.md) - Custom / Editing Protocols -- [README.md](usage/README.md) - README Index - [transports.md](usage/transports.md) - Protocol **usage/configuration_examples** @@ -35,12 +32,10 @@ This README file contains an index of all files in the documentation directory. - [modbus_rtu_to_modbus_tcp.md](usage/configuration_examples/modbus_rtu_to_modbus_tcp.md) - ModBus RTU to ModBus TCP - [modbus_rtu_to_mqtt.md](usage/configuration_examples/modbus_rtu_to_mqtt.md) - ModBus RTU to MQTT -- [README.md](usage/configuration_examples/README.md) - README Index **3rdparty** -- [README.md](3rdparty/README.md) - README Index **3rdparty/protocols** @@ -62,7 +57,6 @@ This README file contains an index of all files in the documentation directory. - [PACE-BMS-RS485-communication-protocol-20180615.pdf](3rdparty/protocols/PACE-BMS-RS485-communication-protocol-20180615.pdf) - [PACE-CAN-communication-protocal(PACE-CAN-TY)-20161216-.pdf](3rdparty/protocols/PACE-CAN-communication-protocal%EF%BC%88PACE-CAN-TY%EF%BC%89-20161216-.pdf) - [PYLON LFP Battery communication protocol - RS485 V2.8 20161216.pdf](3rdparty/protocols/PYLON%20LFP%20Battery%20communication%20protocol%20-%20RS485%20V2.8%2020161216.pdf) -- [README.md](3rdparty/protocols/README.md) - README Index - [RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf](3rdparty/protocols/RS485-protocol-pylon-low-voltage-V3.3-20180821.pdf) - [Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf](3rdparty/protocols/Sigineer-Solar-Inverter-RS485-Port-Modbus-RTU-Protocol-v0.11-20200302.pdf) - [Sol-Ark ModBus V1.1.pdf](3rdparty/protocols/Sol-Ark%20ModBus%20V1.1.pdf) diff --git a/documentation/usage/README.md b/documentation/usage/README.md index 594dc75..2df2285 100644 --- a/documentation/usage/README.md +++ b/documentation/usage/README.md @@ -9,5 +9,4 @@ This README file contains an index of all files in the documentation directory. - [modbus_rtu_to_modbus_tcp.md](configuration_examples/modbus_rtu_to_modbus_tcp.md) - ModBus RTU to ModBus TCP - [modbus_rtu_to_mqtt.md](configuration_examples/modbus_rtu_to_mqtt.md) - ModBus RTU to MQTT -- [README.md](configuration_examples/README.md) - README Index From 66bc871a343a439ad0e6cf02768327a261ba05d7 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 13:07:42 -0500 Subject: [PATCH 18/25] fix header --- documentation/README.md | 4 ++-- documentation/usage/creating_and_editing_protocols.md | 2 ++ documentation/usage/transports.md | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/documentation/README.md b/documentation/README.md index c3b377d..9b6944e 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -23,9 +23,9 @@ This README file contains an index of all files in the documentation directory. **usage** -- [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - CSV +- [creating_and_editing_protocols.md](usage/creating_and_editing_protocols.md) - Creating and Editing Protocols ‐ JSON ‐ CSV - [protocols.md](usage/protocols.md) - Custom / Editing Protocols -- [transports.md](usage/transports.md) - Protocol +- [transports.md](usage/transports.md) - Transports **usage/configuration_examples** diff --git a/documentation/usage/creating_and_editing_protocols.md b/documentation/usage/creating_and_editing_protocols.md index 92b0a2d..670aaf7 100644 --- a/documentation/usage/creating_and_editing_protocols.md +++ b/documentation/usage/creating_and_editing_protocols.md @@ -1,3 +1,5 @@ +# Creating and Editing Protocols ‐ JSON ‐ CSV + "Protocols" are defined through 2 file types. The first is .json, which contains the default settings and optionally codes. diff --git a/documentation/usage/transports.md b/documentation/usage/transports.md index aec5ab7..195aa75 100644 --- a/documentation/usage/transports.md +++ b/documentation/usage/transports.md @@ -1,3 +1,5 @@ +# Transports + A transport is configured by creating a configuration section, starting with "transport." ``` [transport.0] From 85f903d21bf5a677b6d2404d0462732bf8e3f684 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 13:42:35 -0500 Subject: [PATCH 19/25] folder organization for protocols --- classes/protocol_settings.py | 29 +++++++++++++++++-- .../eg4_3000ehv_v1.holding_registry_map.csv | 0 protocols/{ => eg4}/eg4_3000ehv_v1.json | 0 .../eg4_v58.holding_registry_map.csv | 0 .../{ => eg4}/eg4_v58.input_registry_map.csv | 0 protocols/{ => eg4}/eg4_v58.json | 0 ...rowatt_2020_v1.24.holding_registry_map.csv | 0 .../growatt_2020_v1.24.input_registry_map.csv | 0 .../{ => growatt}/growatt_2020_v1.24.json | 0 .../v0.14.holding_registry_map.csv | 0 .../v0.14.input_registry_map.csv | 0 protocols/{ => growatt}/v0.14.json | 0 .../pace_bms_v1.3.holding_registry_map.csv | 0 protocols/{ => pace}/pace_bms_v1.3.json | 0 protocols/{ => pylon}/pylon_rs485_v3.3.json | 0 .../pylon_rs485_v3.3.registry_map.csv | 0 .../sigineer_v0.11.holding_registry_map.csv | 0 .../sigineer_v0.11.input_registry_map.csv | 0 protocols/{ => sigineer}/sigineer_v0.11.json | 0 .../solark_v1.1.holding_registry_map.csv | 0 protocols/{ => solark}/solark_v1.1.json | 0 protocols/{ => victron}/victron_gx_3.3.json | 0 .../victron_gx_v3.3.holding_registry_map.csv | 0 pytests/test_protocol_settings.py | 10 ++++++- 24 files changed, 35 insertions(+), 4 deletions(-) rename protocols/{ => eg4}/eg4_3000ehv_v1.holding_registry_map.csv (100%) rename protocols/{ => eg4}/eg4_3000ehv_v1.json (100%) rename protocols/{ => eg4}/eg4_v58.holding_registry_map.csv (100%) rename protocols/{ => eg4}/eg4_v58.input_registry_map.csv (100%) rename protocols/{ => eg4}/eg4_v58.json (100%) rename protocols/{ => growatt}/growatt_2020_v1.24.holding_registry_map.csv (100%) rename protocols/{ => growatt}/growatt_2020_v1.24.input_registry_map.csv (100%) rename protocols/{ => growatt}/growatt_2020_v1.24.json (100%) rename protocols/{ => growatt}/v0.14.holding_registry_map.csv (100%) rename protocols/{ => growatt}/v0.14.input_registry_map.csv (100%) rename protocols/{ => growatt}/v0.14.json (100%) rename protocols/{ => pace}/pace_bms_v1.3.holding_registry_map.csv (100%) rename protocols/{ => pace}/pace_bms_v1.3.json (100%) rename protocols/{ => pylon}/pylon_rs485_v3.3.json (100%) rename protocols/{ => pylon}/pylon_rs485_v3.3.registry_map.csv (100%) rename protocols/{ => sigineer}/sigineer_v0.11.holding_registry_map.csv (100%) rename protocols/{ => sigineer}/sigineer_v0.11.input_registry_map.csv (100%) rename protocols/{ => sigineer}/sigineer_v0.11.json (100%) rename protocols/{ => solark}/solark_v1.1.holding_registry_map.csv (100%) rename protocols/{ => solark}/solark_v1.1.json (100%) rename protocols/{ => victron}/victron_gx_3.3.json (100%) rename protocols/{ => victron}/victron_gx_v3.3.holding_registry_map.csv (100%) diff --git a/classes/protocol_settings.py b/classes/protocol_settings.py index 6549109..f1801e0 100644 --- a/classes/protocol_settings.py +++ b/classes/protocol_settings.py @@ -1,6 +1,7 @@ import csv from dataclasses import dataclass from enum import Enum +import glob from typing import Union from defs.common import strtoint import itertools @@ -300,7 +301,12 @@ def load__json(self, file : str = '', settings_dir : str = ''): if not file: file = self.protocol + '.json' - path = settings_dir + '/' + file + path = self.find_protocol_file(file, settings_dir) + + #if path does not exist; nothing to load. skip. + if not path: + print("ERROR: '"+file+"' not found") + return with open(path) as f: self.codes = json.loads(f.read()) @@ -618,6 +624,23 @@ def calculate_registry_ranges(self, map : list[registry_map_entry], max_register ranges.append((min(registers), max(registers)-min(registers)+1)) ## APPENDING A TUPLE! return ranges + def find_protocol_file(self, file : str, base_dir : str = '' ) -> str: + + path = base_dir + '/' + file + if os.path.exists(path): + return path + + suffix = file.split('_', 1)[0] + + path = base_dir + '/' + suffix +'/' + file + if os.path.exists(path): + return path + + #find file by name, recurisvely. last resort + search_pattern = os.path.join(base_dir, '**', file) + matches = glob.glob(search_pattern, recursive=True) + return matches[0] if matches else None + def load_registry_map(self, registry_type : Registry_Type, file : str = '', settings_dir : str = ''): if not settings_dir: @@ -629,10 +652,10 @@ def load_registry_map(self, registry_type : Registry_Type, file : str = '', sett else: file = self.protocol + '.'+registry_type.name.lower()+'_registry_map.csv' - path = settings_dir + '/' + file + path = self.find_protocol_file(file, settings_dir) #if path does not exist; nothing to load. skip. - if not os.path.exists(path): + if not path: return self.registry_map[registry_type] = self.load__registry(path, registry_type) diff --git a/protocols/eg4_3000ehv_v1.holding_registry_map.csv b/protocols/eg4/eg4_3000ehv_v1.holding_registry_map.csv similarity index 100% rename from protocols/eg4_3000ehv_v1.holding_registry_map.csv rename to protocols/eg4/eg4_3000ehv_v1.holding_registry_map.csv diff --git a/protocols/eg4_3000ehv_v1.json b/protocols/eg4/eg4_3000ehv_v1.json similarity index 100% rename from protocols/eg4_3000ehv_v1.json rename to protocols/eg4/eg4_3000ehv_v1.json diff --git a/protocols/eg4_v58.holding_registry_map.csv b/protocols/eg4/eg4_v58.holding_registry_map.csv similarity index 100% rename from protocols/eg4_v58.holding_registry_map.csv rename to protocols/eg4/eg4_v58.holding_registry_map.csv diff --git a/protocols/eg4_v58.input_registry_map.csv b/protocols/eg4/eg4_v58.input_registry_map.csv similarity index 100% rename from protocols/eg4_v58.input_registry_map.csv rename to protocols/eg4/eg4_v58.input_registry_map.csv diff --git a/protocols/eg4_v58.json b/protocols/eg4/eg4_v58.json similarity index 100% rename from protocols/eg4_v58.json rename to protocols/eg4/eg4_v58.json diff --git a/protocols/growatt_2020_v1.24.holding_registry_map.csv b/protocols/growatt/growatt_2020_v1.24.holding_registry_map.csv similarity index 100% rename from protocols/growatt_2020_v1.24.holding_registry_map.csv rename to protocols/growatt/growatt_2020_v1.24.holding_registry_map.csv diff --git a/protocols/growatt_2020_v1.24.input_registry_map.csv b/protocols/growatt/growatt_2020_v1.24.input_registry_map.csv similarity index 100% rename from protocols/growatt_2020_v1.24.input_registry_map.csv rename to protocols/growatt/growatt_2020_v1.24.input_registry_map.csv diff --git a/protocols/growatt_2020_v1.24.json b/protocols/growatt/growatt_2020_v1.24.json similarity index 100% rename from protocols/growatt_2020_v1.24.json rename to protocols/growatt/growatt_2020_v1.24.json diff --git a/protocols/v0.14.holding_registry_map.csv b/protocols/growatt/v0.14.holding_registry_map.csv similarity index 100% rename from protocols/v0.14.holding_registry_map.csv rename to protocols/growatt/v0.14.holding_registry_map.csv diff --git a/protocols/v0.14.input_registry_map.csv b/protocols/growatt/v0.14.input_registry_map.csv similarity index 100% rename from protocols/v0.14.input_registry_map.csv rename to protocols/growatt/v0.14.input_registry_map.csv diff --git a/protocols/v0.14.json b/protocols/growatt/v0.14.json similarity index 100% rename from protocols/v0.14.json rename to protocols/growatt/v0.14.json diff --git a/protocols/pace_bms_v1.3.holding_registry_map.csv b/protocols/pace/pace_bms_v1.3.holding_registry_map.csv similarity index 100% rename from protocols/pace_bms_v1.3.holding_registry_map.csv rename to protocols/pace/pace_bms_v1.3.holding_registry_map.csv diff --git a/protocols/pace_bms_v1.3.json b/protocols/pace/pace_bms_v1.3.json similarity index 100% rename from protocols/pace_bms_v1.3.json rename to protocols/pace/pace_bms_v1.3.json diff --git a/protocols/pylon_rs485_v3.3.json b/protocols/pylon/pylon_rs485_v3.3.json similarity index 100% rename from protocols/pylon_rs485_v3.3.json rename to protocols/pylon/pylon_rs485_v3.3.json diff --git a/protocols/pylon_rs485_v3.3.registry_map.csv b/protocols/pylon/pylon_rs485_v3.3.registry_map.csv similarity index 100% rename from protocols/pylon_rs485_v3.3.registry_map.csv rename to protocols/pylon/pylon_rs485_v3.3.registry_map.csv diff --git a/protocols/sigineer_v0.11.holding_registry_map.csv b/protocols/sigineer/sigineer_v0.11.holding_registry_map.csv similarity index 100% rename from protocols/sigineer_v0.11.holding_registry_map.csv rename to protocols/sigineer/sigineer_v0.11.holding_registry_map.csv diff --git a/protocols/sigineer_v0.11.input_registry_map.csv b/protocols/sigineer/sigineer_v0.11.input_registry_map.csv similarity index 100% rename from protocols/sigineer_v0.11.input_registry_map.csv rename to protocols/sigineer/sigineer_v0.11.input_registry_map.csv diff --git a/protocols/sigineer_v0.11.json b/protocols/sigineer/sigineer_v0.11.json similarity index 100% rename from protocols/sigineer_v0.11.json rename to protocols/sigineer/sigineer_v0.11.json diff --git a/protocols/solark_v1.1.holding_registry_map.csv b/protocols/solark/solark_v1.1.holding_registry_map.csv similarity index 100% rename from protocols/solark_v1.1.holding_registry_map.csv rename to protocols/solark/solark_v1.1.holding_registry_map.csv diff --git a/protocols/solark_v1.1.json b/protocols/solark/solark_v1.1.json similarity index 100% rename from protocols/solark_v1.1.json rename to protocols/solark/solark_v1.1.json diff --git a/protocols/victron_gx_3.3.json b/protocols/victron/victron_gx_3.3.json similarity index 100% rename from protocols/victron_gx_3.3.json rename to protocols/victron/victron_gx_3.3.json diff --git a/protocols/victron_gx_v3.3.holding_registry_map.csv b/protocols/victron/victron_gx_v3.3.holding_registry_map.csv similarity index 100% rename from protocols/victron_gx_v3.3.holding_registry_map.csv rename to protocols/victron/victron_gx_v3.3.holding_registry_map.csv diff --git a/pytests/test_protocol_settings.py b/pytests/test_protocol_settings.py index df8cd34..dba99ac 100644 --- a/pytests/test_protocol_settings.py +++ b/pytests/test_protocol_settings.py @@ -1,6 +1,8 @@ import sys import os import pytest +import glob + #move up a folder for tests sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) @@ -8,11 +10,17 @@ from classes.protocol_settings import protocol_settings # List of protocols to test -protocols = [os.path.splitext(f)[0] for f in os.listdir("protocols") if f.endswith('.json')] +# Create the search pattern to find .json files recursively +search_pattern = os.path.join("protocols", '**', '*.json') +# Use glob to find all files matching the pattern +files = glob.glob(search_pattern, recursive=True) +# Extract file names without extension +protocols = [os.path.splitext(os.path.basename(f))[0] for f in files] # Parameterized test function @pytest.mark.parametrize("protocol", protocols) def test_protocol_setting(protocol : str): + print(protocol) protocolSettings : protocol_settings = protocol_settings(protocol) From 243d4d0ce49cc07f46be1eda1d6dada836b5191b Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 13:56:33 -0500 Subject: [PATCH 20/25] support for newer versions on pymodbus --- classes/transports/modbus_rtu.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index 84f2097..2a0419b 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -1,6 +1,11 @@ import logging from classes.protocol_settings import Registry_Type, protocol_settings -from pymodbus.client.sync import ModbusSerialClient + +try: + from pymodbus.client.sync import ModbusSerialClient +except ImportError: + from pymodbus.client import ModbusSerialClient + from .modbus_base import modbus_base from configparser import SectionProxy from defs.common import find_usb_serial_port, get_usb_serial_port_info, strtoint From bc3e9d90789fa54c426d27c9464c1d2b31677ae7 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 14:01:20 -0500 Subject: [PATCH 21/25] pymodbus compatability --- classes/transports/modbus_rtu.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index 2a0419b..5fd2ce2 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -1,6 +1,9 @@ import logging from classes.protocol_settings import Registry_Type, protocol_settings +import inspect + + try: from pymodbus.client.sync import ModbusSerialClient except ImportError: @@ -38,10 +41,19 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings address : int = settings.getint("address", 0) self.addresses = [address] - self.client = ModbusSerialClient(method='rtu', port=self.port, - baudrate=int(self.baudrate), - stopbits=1, parity='N', bytesize=8, timeout=2 - ) + # Get the signature of the __init__ method + init_signature = inspect.signature(ModbusSerialClient.__init__) + + if 'method' in init_signature.parameters: + self.client = ModbusSerialClient(method='rtu', port=self.port, + baudrate=int(self.baudrate), + stopbits=1, parity='N', bytesize=8, timeout=2 + ) + else: + self.client = ModbusSerialClient(port=self.port, + baudrate=int(self.baudrate), + stopbits=1, parity='N', bytesize=8, timeout=2 + ) def read_registers(self, start, count=1, registry_type : Registry_Type = Registry_Type.INPUT, **kwargs): From 63ed627df554e43a6627c4266e38e87300ba88b1 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 14:11:44 -0500 Subject: [PATCH 22/25] pymodbus update compatability --- classes/transports/modbus_rtu.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index 5fd2ce2..c6a3f25 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -19,6 +19,8 @@ class modbus_rtu(modbus_base): baudrate : int = 9600 client : ModbusSerialClient + pymodbus_address_arg = 'unit' + def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): #logger = logging.getLogger(__name__) #logging.basicConfig(level=logging.DEBUG) @@ -41,6 +43,11 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings address : int = settings.getint("address", 0) self.addresses = [address] + # pymodbus compatability; unit was renamed to address + if 'address' in inspect.signature(ModbusSerialClient.read_holding_registers).parameters: + self.pymodbus_address_arg = 'address' + + # Get the signature of the __init__ method init_signature = inspect.signature(ModbusSerialClient.__init__) @@ -60,6 +67,10 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr if 'unit' not in kwargs: kwargs = {'unit': int(self.addresses[0]), **kwargs} + #compatability + if self.pymodbus_address_arg != 'unit': + kwargs['address'] = kwargs.pop('unit') + if registry_type == Registry_Type.INPUT: return self.client.read_input_registers(start, count, **kwargs) elif registry_type == Registry_Type.HOLDING: @@ -72,6 +83,10 @@ def write_register(self, register : int, value : int, **kwargs): if 'unit' not in kwargs: kwargs = {'unit': self.addresses[0], **kwargs} + #compatability + if self.pymodbus_address_arg != 'unit': + kwargs['address'] = kwargs.pop('unit') + self.client.write_register(register, value, **kwargs) #function code 0x06 writes to holding register def connect(self): From 7596232fadb5d1b3777f2c7283999fb9a929b922 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 14:19:04 -0500 Subject: [PATCH 23/25] fix kwarg --- classes/transports/modbus_rtu.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/classes/transports/modbus_rtu.py b/classes/transports/modbus_rtu.py index c6a3f25..8e94e72 100644 --- a/classes/transports/modbus_rtu.py +++ b/classes/transports/modbus_rtu.py @@ -19,7 +19,7 @@ class modbus_rtu(modbus_base): baudrate : int = 9600 client : ModbusSerialClient - pymodbus_address_arg = 'unit' + pymodbus_slave_arg = 'unit' def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings = None): #logger = logging.getLogger(__name__) @@ -44,8 +44,8 @@ def __init__(self, settings : SectionProxy, protocolSettings : protocol_settings self.addresses = [address] # pymodbus compatability; unit was renamed to address - if 'address' in inspect.signature(ModbusSerialClient.read_holding_registers).parameters: - self.pymodbus_address_arg = 'address' + if 'slave' in inspect.signature(ModbusSerialClient.read_holding_registers).parameters: + self.pymodbus_slave_arg = 'slave' # Get the signature of the __init__ method @@ -68,8 +68,8 @@ def read_registers(self, start, count=1, registry_type : Registry_Type = Registr kwargs = {'unit': int(self.addresses[0]), **kwargs} #compatability - if self.pymodbus_address_arg != 'unit': - kwargs['address'] = kwargs.pop('unit') + if self.pymodbus_slave_arg != 'unit': + kwargs['slave'] = kwargs.pop('unit') if registry_type == Registry_Type.INPUT: return self.client.read_input_registers(start, count, **kwargs) @@ -84,8 +84,8 @@ def write_register(self, register : int, value : int, **kwargs): kwargs = {'unit': self.addresses[0], **kwargs} #compatability - if self.pymodbus_address_arg != 'unit': - kwargs['address'] = kwargs.pop('unit') + if self.pymodbus_slave_arg != 'unit': + kwargs['slave'] = kwargs.pop('unit') self.client.write_register(register, value, **kwargs) #function code 0x06 writes to holding register From 59cce7f9db930d3f238dce2e56b4ca95a26c1099 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Sat, 17 Aug 2024 14:23:06 -0500 Subject: [PATCH 24/25] added support for pymodbus 2.3 to 3.7 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0533626..5527353 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -pymodbus==2.3.0 +pymodbus==3.7.0 paho-mqtt \ No newline at end of file From 419aec46bd88377d823153637be2c1ae2ab77c33 Mon Sep 17 00:00:00 2001 From: HotNoob Date: Fri, 6 Sep 2024 17:50:52 -0500 Subject: [PATCH 25/25] add pyserial requirement --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 5527353..b649569 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ pymodbus==3.7.0 -paho-mqtt \ No newline at end of file +paho-mqtt +pyserial \ No newline at end of file