How to LET Modbus Forwarder check the function code and data before it forward to the client? #1645
-
Versions
Pymodbus Specific
DescriptionI want to deploy a filter between the original server and client. The filter would check the request (write single/multuple holding register(s)) in advance, and just forward the request packet with specify holding register(s) and responsable data. Thanks a lit. Code and LogsI tried to send request to write multiple coils to test the program. #!/usr/bin/env python3
"""Pymodbus synchronous forwarder.
This is a repeater or converter and an example of just how powerful datastore is.
It consist of a server (any comm) and a client (any comm), functionality:
a) server receives a read/write request from external client:
- client sends a new read/write request to target server
- client receives response and updates the datastore
- server sends new response to external client
Both server and client are tcp based, but it can be easily modified to any server/client
(see client_sync.py and server_sync.py for other communication types)
**WARNING** This example is a simple solution, that do only forward read requests.
"""
import asyncio
import logging
from pymodbus.client import ModbusTcpClient
from pymodbus.datastore import ModbusServerContext
from pymodbus.datastore.remote import RemoteSlaveContext
from pymodbus.server import StartAsyncTcpServer
_logger = logging.getLogger()
"""
A_scada_client--->Forwarder(localhost:5020)---->B_plc_server(192.168.72.161:502)
"""
async def run_forwarder():
"""Run forwarder setup."""
port="5020"
B_host="192.168.72.161"
B_port="502"
txt = f"### start forwarder, listen {port}, connect to {B_host}:{B_port}"
_logger.info(txt)
client = ModbusTcpClient(host=B_host,port=B_port)
client.connect()
#assert client.connected
# If required to communicate with a specified client use slave=<slave_id>
# in RemoteSlaveContext
# For e.g to forward the requests to slave with slave address 1 use
# store = RemoteSlaveContext(client, slave=1)
store = RemoteSlaveContext(client, slave=1)
context = ModbusServerContext(slaves=store, single=True)
await StartAsyncTcpServer(context=context, address=("", port))
# loop forever
if __name__ == "__main__":
asyncio.run(run_forwarder(),debug=True) |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments
-
There are no real sample code for your example, but it seems quite simple, you just need to customize remote_datastore. Be aware though remote_datastore only handles data request not e.g diagnostic requests. We have planned a more full fledge modbus repeater, which will be based on a new framer, to allow all requests to pass. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your advice. I still confuse the mean of "customize remote_datastore". Do you mean to customize the datablock with |
Beta Was this translation helpful? Give feedback.
-
Just read what I wrote, you need to customize the datastore, meaning change the source code. The filter you want is something we do not have, but it can be easily programmed in the remote datastore. |
Beta Was this translation helpful? Give feedback.
-
Converting to discussion since this is not a bug in pymodbus but merely a want for help. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your help. |
Beta Was this translation helpful? Give feedback.
Just read what I wrote, you need to customize the datastore, meaning change the source code. The filter you want is something we do not have, but it can be easily programmed in the remote datastore.