AndreySV / check_modbus

Nagios plugin for Modbus TCP and Modbus RTU
GNU General Public License v3.0
14 stars 20 forks source link

RTU over TCP support #6

Closed sq5gvm closed 10 years ago

sq5gvm commented 10 years ago

Hi Andrey, Are you interested in including support for feature (currently) requiring patching libmodbus? RTU-over-TCP support is usefull for scenarios where simple Ethernet-to-Serial converter is used to access modbus network. In most cases serial converters (such as Tibbo DS100, Planet ICS-100, GridConnect Net232jr etc) do not translate Modbus-RTU to Modbus-TCP packets, but simply encapsulate RAW serial port data into TCP stream. At this moment libmodbus does not support this transport method (it's not standard compliant) but there exists feature request #192 (https://github.com/stephane/libmodbus/issues/192) and patch (https://groups.google.com/forum/#!msg/libmodbus/xm8S6MMDhgM/Qd97y9_mhwgJ) that addresses this issue. I don't know if it will be supported by libmodbus as it's not part of modbus standard but it's solution used in real life :D

I'm cleaning up and updating my code adding support for RTU-over-TCP transport mode into check_modbus which I've been using successfully for the last 6+ months with multiple Serial-to-Ethernet converters and patched libmodbus libraries (3.0.3-3.0.6). See branches sq5gvm/rtutcp_support and sq5gvm/rtutcp_support_0.3 in my repo (status: cleanup in progress) for more insight. Of course RTU-over-TCP "protocol" support is enabled only when available.

regards Miroslaw

AndreySV commented 10 years ago

Have you tried to use standard libmodbus/check_modbus with something like socat pty,link=$HOME/dev/ttyV0,waitslave tcp:SerialMachine:3333 ? Such solutions would be better.

sq5gvm commented 10 years ago

I've tried using socat (and few other solutions) but there were always some drawbacks:

After switching to patched libmodbus and check_modbus all problems disappeared (probably because connection is negotiated every time and buffers are flushed correctly).

Note: * Using modbus (RTU and TCP) is sometimes evil/not safe :D OK when orphaned data was from different device as deviceId is present in modbus frame and frame is simply dropped. Worse if deviceId is the same but registry address is different - we'll receive and process data as correct because THERE IS NO adress information in RTU reply frame and as such we have no way to detect such errors. Real life situation from my test: circuit from time to time check_modbus reported 230V instead of 110V because it got earlier "orphaned" reply to query asking for data from second A/D converter from the same device.

Miroslaw

AndreySV commented 10 years ago

I see. Currently I prefer not to merge unsupported libmodbus functionality. If more people are highly interested in such functionality, we can discuss this again. But I recommend to discuss this at libmodbus github page to allow Stephane and other developers to see that support of Modbus-RTU over TCP is demanded.

Actually I've never been needed support of Modbus-RTU over TCP and my colleges as well only heard about that, but nobody used that. Maybe one of the reasons is evil/unsafe behavior, that you described.

sq5gvm commented 10 years ago

OK. I'll keep my branches up-to-date in case libmodbus maintainers decide to include support for it and for those willing to use it after patching library. Evil/Unsafe behavior is not limited to RTU-over-TCP but whole Modbus-RTU and probably Modbus-TCP (if it permits multiple queries using the same connection/data channel). There is no way to verify that REQUESTED registries are being returned in response frame :(

Miroslaw

AndreySV commented 10 years ago

By design Modbus-TCP does not have such evil behavior. Every Modbus-TCP frame can have transaction identifier field. Client should generate every time new transaction identifier and server replies with the id from the request. It solves the problem. But not all software/devices implement this.

One time I had an OPC server that generates unique transaction identifiers and checks this field in the response packet, but the Modbus-TCP server always replied with zero transaction id. Communication was not possible.

Sure, Modbus-RTU has theoretically such problem too, but usually it works pretty good.