modbus error failing to connect to ModbusTcpClient when reading/writing - python

Recently I have been tasked with a project involving reading Modbus data, specifically with the pymodbus package. before diving into this project I wanted to simulate some reading and writing of Modbus data (without having to use a machine) with python. Using the sample data they have on their homepage, I try to write using the client but encounter a Modbus error
Ive tried looking into the matter to see what I could dig up wonder if I need a server to write or read. However I am unsure as with my experiences with socket and serial I just needed an established connection with the correct port to simply write (however I understand that Modbus is different).
Here is the code
client = ModbusTcpClient('localhost')
client.write_coil(1, True)
result = client.read_coils(1,1)
print(result.bits[0])
client.close()
and here is my error "pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Failed to connect[ModbusTcpClient(localhost:502)]"
I expect the output to simply write Modbus without needing anything no necessarily listen on the other end, but instead I keep getting an error when trying to connect/write. (sorry if this is hard to comprehend, my brain is all over the place and I am extremely new to Modbus in general).

If you want to send Modbus queries and you don't have any Modbus hardware yet you need to run a dummy Modbus server on your computer.
You can take a look at the examples.
You might also need to add a rule to your firewall for port 502. If you are on Linux you can just switch ports to a higher number like 5020 on both ends to avoid this problem.

Related

Multi clients modbus to single modbus server

I have two python scripts which need to get data from the same modbus server.
However they cannot be simultaneously connected to the same modbus server, so I am looking for a "proxy" software.
This proxy will then sequentially transfer the modbus queries to the modbus server.
Solution should run on debian 11 lite.
Thanks!
I have the same challenges before and ended up with Modbus-to-MQTT bridge solution, because each protocol has its limit, Modbus is designed for master-slave poll in nature and MQTT is good for multiple clients/subscribers.
Modbus + MQTT, such a combination is just nice and could be very powerful in modern IoT applications. You can try modpoll, which is a python-based Modbus tool and can run as a Modbus-to-MQTT bridge in your case.
Assuming you are dealing with Modbus TCP you can try modbus-proxy:
Many modbus devices support only one or very few clients. This proxy
acts as a bridge between the client and the modbus device. It can be
seen as a layer 7 reverse proxy. This allows multiple clients to
communicate with the same modbus device.
When multiple clients are connected, cross messages are avoided by
serializing communication on a first come first served REQ/REP basis.
EDIT: According to your comment below:
...it is RTU over a linux file descriptor /dev/ttyS1
That seems to me a not-so-straightforward way of saying that you are dealing with a serial link.
If that's the case I'm afraid you need to go back all the way to the physical layer.
If you have a point-to-point serial connection (no matter the voltage levels you have, they can be TTL 3.3VDC or RS-232) there is no way you can have more than one Modbus client connecting to the same server.
For a serial link to have more than two devices (two or multiple clients sending queries to a Modbus server, for instance) you need a way for the devices to take control of the bus when they communicate and let go of it when they are idle. An RS-485 multipoint serial link is the most frequent solution to this problem.
If you follow the link you will find many resources and documentation. That might be a bit overwhelming but it is actually very easy: instead of connecting RX to TX as you'd do for a normal serial port you will have two cables for each device (they are called A and B or D+ and D-) that you can put together. And you only need to add a TTL to RS-485 transceiver in between each device and the bus (or RS-232 to RS-485, depending on your devices).
There are a couple of nuances:
You might need terminating resistors, but that should only be the case if your devices are far away (more than several meters) from each other.
If you go for the cheapest transceivers you might end up being forced to toggle the bus in your software, which is not a good solution. See my answer here for more details. And better aim for something with automatic TX enable.
The most complete reference on all these topics I know of is Jan Axelson's book Serial Port Complete. It's a bit old (the last edition was released in 2007) but still very relevant. And you can find older editions secondhand for next to nothing. If you need to work with serial ports, this book will be a very valuable companion.
Final note: if you are not able or willing to mess with the phy layer, you might, of course, find other solutions that are more palatable. You might, for instance, implement a software forwarder to take queries from your clients and convert them to Modbus RTU to be sent to your server. Pymodbus includes an example, but since you did not elaborate much I'm not sure it will be useful for your situation.

How we can generate traffic within the PyModbus library?

I want to generate some Modbus traffic, but I can't find any examples. In other words, I want to create a Modbus Simulator.
A good start would be to look at the examples folder.
An easy way to have something up and running is to follow these steps, assuming you have pymodbus installed:
Download and run the syncronous_server.py example from the command line
Download and run on a different command window the syncronous_client.py example.
You are done, from the output of both command lines you will be able to see the Modbus transactions that took place.
If you want to have a continuous stream of Modbus exchanges you can just modify the client to loop somewhere, for instance:
while True:
rr = client.read_holding_registers(1, 1, unit=UNIT)
time.sleep(1)
will keep reading a holding register about once every second.
There is no need to change anything on the server, it will be always listening until you kill it with Ctrl+C
Nothing will prevent you from having a different computer for the server and client as long as both are connected to the same network and you modify the client to point to the server address. In particular (line 70 on the example):
client = ModbusClient('localhost', port=5020)
Change localhost to your server's IP address, maybe something like 192.168.x.y.
In case you are not aware there are many alternatives to pymodbus to generate Modbus traffic. Modpoll is a classic, but you can also look at qModMaster.

Is it possible to use pyModbusTCP as modbus slave?

I'm perusing the pyModbusTCP with the intent of writing a Modbus slave running on Linux.
[begin rant]: pyModbusTCP uses the terms "client" and "server" instead of "slave/master", so the docs are a bit confusing. [end rant]
It seems all they do in the demos is use the library as a Master, either reading or writing from remote slave devices.
Is it possible to set up pyModbusTCP to act as a Modbus slave, listening to a port and allowing Modbus devices (PLCs, etc) to connect and read/write values from/to this slave?
As a bonus, is it possible to automatically execute a Python function (like an event) when a remote master reads or writes to/from this slave?
Thanks!
pyModbusTCP can work as Modbus slave. They call it “server”, you can find a simple example here http://pymodbustcp.readthedocs.io/en/latest/examples/server.html
Regarding your last question it looks like it’s not possible out of the box, but the source code looks relatively simple, maybe you can modify it. Specifically look at the DataBank class here https://github.com/sourceperl/pyModbusTCP/blob/master/pyModbusTCP/server.py

Am i overenginering it with websocket for IOT device Pushing data to endpoint

I have a raspberry pi running unix and it has a gps chip that sends text over its serial com pots.
I want to forward this data without doing any kind of parsing, just forward the data stream directly to a endpoint (running aspnet core, webapi and signalr).
Just like if i was doing sudo cat < /dev/ttyUSB0
To broadcast the data i will do a python script instead of cat in above command to read the data coming from usb0.
Since its text messages coming from the USB at a decent rate, i dont want to do a http request for each message. Instead of want to open a connection to the backend and just push data.
I set up a signalr rawconnection very easily and theres a signalr client for python, so its not a big task to make it all work.
I am conserned about, if there is overhead of using signalr (websockets) for this. is the alternative to just open a http post request and keep it alive?
I am guessing that signalr can provide me with some connection monitoring and help keeping the connection alive incase of failures. But are there any other benefits of using websockets for something like this.
Is the benefits higher than the costs, what are the costs?
as compared to http websocket is always a good choice for such cases.
benefits of websockets
but for iot related stuff MQTT is preferred.
here it is articulated really well https://systembash.com/mqtt-vs-websockets-vs-http2-the-best-iot-messaging-protocol/

UDP server to forward messages between clients

I'm starting to write an udp server to match two clients together and allow them to send/receive data to/from each other.
It's for a multiplayer game, and my goal is to create a p2p-like connection but with the intermediary server I'll make sure it will always work, even in cases where the user has a firewall, or is behind a nat.
The server should hande several matches (pairs of clients), I'm writing it in python and it's a bit harder than what I thought.
Is there any open source code for a server similar to this?
Take a look at the ZeroMq (0MQ) framework as an alternative to creating your own messaging. There's a python binding (pyzmq) for it.
This details how to write a UDP server in Python.

Categories

Resources