TL;DR:
Modbus is logical protocol used to convey data from devices to a controller; widely used in industrial controls/monitoring. The python code you found uses external modbus program (modpoll) to query inverter while the code we developed here uses python native modbus library.
Long version:
Modpoll is a program that implements ModBus Protocol. While RS-232 or RS-485 are the ports used to communicate (electrical and logical), you can understand they as a “serial raw communication”, think it as data pipe. What you will pass through that pipe is another matter. In case of many devices, the protocol of choice over RS-485/RS-232 is ModBus because it is widely used on industrial controls. Growatt protocol is Modbus (just for counter example, ABB Aurora inverters uses proprietary Aurora protocol and ABB sells a hardware that converts Aurora into Modbus). Important to say that Modbus is not tied to RS-XXX, Modbus has variations to work over serial lines like RS-xxx or even TCP (Modbus RTU and Modbus TCP).
Python has its own modbus library that is very simple yet effective to read Growatt inverter. I used this library because, in my opinion, external programs do a great job when you don´t have native options. Originally this code used external “curl” program to send http requests to pvoutput. Again, while curl is great http client CLI app,I rather use python native “request” library. So I moved from calling “curl” to using request and, in my opinion, it is cleaner and more controllable this way (mainly regarding error handling and code readability). But this just my opinion. Both ways did same thing very well (same applies to external modpoll and modbus library).
Back to your inverters:
Modbus allows for communication with many devices hence, assuming your inverters are daisy chained in a RS-485 bus, each of then had a own address in the bus (and since your had it working I think all is already setup); what needs to be modified in the code is:
- stores address for each of the inverters in the RS-485 and iterate of those address to query each inverter independently
- stores values from each inverter separately
- send values to pvoutput for the other inverters
What I would do:
-
modify the inverter classe to two classes:
Class InverterComm would handle communication with any number of inverters, hence one object per serial port (in your case one object)
Class Inverter would stores values read from inverter, hence one object per inverter
-
pvoutput routine shall use each object inverter above to send data to Pvouput (since eache inverter has its own systemId for instance)
This is one way, there are many others. As very simple quick&dirty solution is add a loop to inverter class adding some local properties (wh_today2, wh_today3, wh_lifetime2, …) to the other inverters, and loop in pvouput function send all that too. This is tight coupled hence less maintainable.