Skip to content

Commit

Permalink
server tracer example.
Browse files Browse the repository at this point in the history
  • Loading branch information
janiversen committed Sep 9, 2023
1 parent 580ed3e commit 4194785
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
8 changes: 8 additions & 0 deletions doc/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ Callback Server example
^^^^^^^^^^^^^^^^^^^^^^^
.. literalinclude:: ../../examples/server_callback.py

Server tracer example
^^^^^^^^^^^^^^^^^^^^^
.. literalinclude:: ../../examples/server_hook.py

Custom Message client
^^^^^^^^^^^^^^^^^^^^^
.. literalinclude:: ../../examples/client_custom_msg.py
Expand Down Expand Up @@ -107,6 +111,10 @@ Examples contributions
These examples are supplied by users of pymodbus.
The pymodbus team thanks for sharing the examples.

Solar
^^^^^
.. literalinclude:: ../../examples/contrib/solar.py

Redis datastore
^^^^^^^^^^^^^^^
.. literalinclude:: ../../examples/contrib/redis_datastore.py
Expand Down
87 changes: 87 additions & 0 deletions examples/server_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""Pymodbus Server With request/response manipulator.
This is an example of using the builtin request/response tracer to
manipulate the messages to/from the modbus server
"""
import asyncio
import logging

from pymodbus import pymodbus_apply_logging_config
from pymodbus.datastore import (
ModbusSequentialDataBlock,
ModbusServerContext,
ModbusSlaveContext,
)
from pymodbus.server import ModbusTcpServer
from pymodbus.transaction import ModbusSocketFramer


class Manipulator:
"""A Class to run the server.
Using a class allows the easy use of global variables, but
are not strictly needed
"""

message_count: int = 1
server: ModbusTcpServer = None

def server_request_tracer(self, request, *_addr):
"""Trace requests.
All server requests passes this filter before being handled.
"""
print(f"---> REQUEST: {request}")

def server_response_manipulator(self, response):
"""Manipulate responses.
All server responses passes this filter before being sent.
The filter returns:
- response, either original or modified
- skip_encoding, signals whether or not to encode the response
"""
if not self.message_count:
print(f"---> RESPONSE: {response}")
self.message_count = 3
else:
print("---> RESPONSE: NONE")
response.should_respond = False
self.message_count -= 1
return response, False

async def setup(self):
"""Prepare server."""
pymodbus_apply_logging_config(logging.DEBUG)
datablock = ModbusSequentialDataBlock(0x00, [17] * 100)
context = ModbusServerContext(
slaves=ModbusSlaveContext(
di=datablock, co=datablock, hr=datablock, ir=datablock
),
single=True,
)
self.server = ModbusTcpServer(
context,
ModbusSocketFramer,
None,
("127.0.0.1", 5020),
request_tracer=self.server_request_tracer,
response_manipulator=self.server_response_manipulator,
)

async def run(self):
"""Attach Run server"""
await self.server.serve_forever()


async def main():
"""Run example."""
server = Manipulator()
await server.setup()
await server.run()


if __name__ == "__main__":
asyncio.run(main(), debug=True) # pragma: no cover

0 comments on commit 4194785

Please sign in to comment.