Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modbus TCP connection handling #21

Open
jmkelly opened this issue Dec 30, 2020 · 8 comments
Open

Modbus TCP connection handling #21

jmkelly opened this issue Dec 30, 2020 · 8 comments

Comments

@jmkelly
Copy link
Contributor

jmkelly commented Dec 30, 2020

I've noticed that when I initially connect modbus4mqtt on my SG-5K-D, I get a readout for all the registers, and unless I've got a register in there that is wrong, no errors. As it keeps running though, I'm only getting readouts on a few registers that regularly update and lots of exceptions on less frequently changing registers.

I was wondering if this could be something to do with a single tcp connection staying alive for the whole time that modbus5mqtt is running? I've looked at the code, and I'm not all that familiar with python, but am I correct in assuming that once a tcp connection is made to the inverter, it is kept open? If this is the case, then I was wondering what your thoughts on tearing down the connection and then re establishing it each tcp call to the inverter?

@jmkelly
Copy link
Contributor Author

jmkelly commented Dec 30, 2020

I did some more reading. From what I can tell, the connection is being established, then isn't explicitly closed.

In the SunGrowModbus library at https://github.com/rpvelloso/Sungrow-Modbus/blob/59130209e5e77dd105cd17c012c6a83f3c864bb7/SungrowModbusTcpClient/SungrowModbusTcpClient.py#L48 the existing connection is closed when a new connection is made.

in the Modbus libary, the connection isn't shutdown unless you call it, or there is a connection error (from my quick scan).
https://github.com/riptideio/pymodbus/blob/efb90fb05882d606933a97435dd37ae87ead5449/pymodbus/client/sync.py#L202

I'd be interested in spiking out and testing connect, read data and close the connection explicitly, but I'm struggling to find exactly where the open / read / close would sit. And also what implications of doing this may have....

@jmkelly jmkelly changed the title Modbus to sungrow inverter connection ideas Modbus TCP connection handling Dec 30, 2020
@tjhowse
Copy link
Owner

tjhowse commented Dec 30, 2020

Correct - We start up a TCP connection when the service starts and it remains open as long as it can. If you wanted to experiment with opening and closing the connection with each poll, a good place for that would be in modbus_interface.poll()

https://github.com/tjhowse/modbus4mqtt/blob/master/modbus4mqtt/modbus_interface.py#L62

And then remove the connect code here: https://github.com/tjhowse/modbus4mqtt/blob/master/modbus4mqtt/modbus4mqtt.py#L41

However this isn't the intended use of a modbus interface. It's expecting to have a long-running connections open. Reconnecting on every poll would result in a lot of overhead. I would love to understand the real reason for the errors before attempting a fix. I've connected directly to my SH5k-20 via ethernet rather than using the wifi-to-rs485 solarinfo dongle. I still get errors, but not enough to affect operation. I suspect part of the reason for my errors is the fact I'm running both pvstats and modbus4mqtt, and they're giving the inverter too much to think about.

Maybe there's some kind of keepalive signal the Sungrow inverter is expecting? Like a heartbeat signal? I'd like to look at a packet capture of a "proper" modbus TCP connection to see whether the interface is expecting something like that.

I strongly suspect that the Sungrow implementation of modbus is only "inspired" by the modbus spec, not actually modbus-compliant. There may be some interface settings that can be tweaked on our side to make the connections happier.

I have a task on the backlog to report multiple values in one message to MQTT via a JSON message: #9 Once this is implemented I can retire pvstats from my system and work on getting the error rate down. However my system is different to most in two ways: A) I'm not using wifi and, B) I've blocked the inverter from talking to the internet.

@jmkelly
Copy link
Contributor Author

jmkelly commented Dec 31, 2020

thanks for the information, I'm a total noob to modbus, so its good to get more perspective. Any suggestions on how to do the packet capture? I'm running over wifi and connected to internet, so I'm thinking i could pick up the outgoing traffic to iSolarCloud if I can intercept the traffic going via my router (google wifi).

Looks something like https://geeknizer.com/capture-sniff-wifi-traffic/ in combination with wireshark may do the trick, when I get a chance, I'll try to set it up and get something happening.

If you have any easier suggestions though, I'm all ears.

@tjhowse
Copy link
Owner

tjhowse commented Jan 1, 2021

When I've been sniffing the connection to my inverter I used a packet squirrel, however they only work on ethernet connections - not wifi.

In any case the link from domestic inverters to the sungrow cloud services is a pseudo-encrypted MQTT link, not modbus. We'd need a reference implementation of a sungrow-endorsed modbus interface to one of their devices to classify exactly what connection parameters keep the connection happy. At the moment modbus4mqtt assumes that it doesn't need to do anything special to the connection to keep it connected. I know a few companies across the world are working on custom integrations to home inverters, but I'm not aware of anything specific to sungrow yet.

@tjhowse
Copy link
Owner

tjhowse commented Jan 2, 2021

I've just remembered I had this doc floating around. I have it referenced in another project, page 89 is most interesting: https://c.tjhowse.com/misc/SolarInfo%20Logger%20User%20Manual.pdf

@jmkelly
Copy link
Contributor Author

jmkelly commented Jan 3, 2021 via email

@tjhowse
Copy link
Owner

tjhowse commented Jan 4, 2021

Nothing specific - just adding some potentially useful context.

@icypete
Copy link
Contributor

icypete commented Jan 14, 2021

I'm wondering if a middle ground solution would be to set a reconnect period, after which the connection is closed and reconnected. This would be independent of the polling period. For example we can poll every 5 seconds, but every (say) 10min the TCP connection is closed and re-established.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants