Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions check_ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ codespell
ruff check --fix --exit-non-zero-on-fix .
pylint --recursive=y examples pymodbus test
zuban check pymodbus examples test
if [ $1 ]; then
exit 1
fi
pytest -x --cov --numprocesses auto
echo "Ready to push"
2 changes: 1 addition & 1 deletion examples/client_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
try:
import helper # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)
Expand Down
2 changes: 1 addition & 1 deletion examples/client_async_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
try:
import client_async # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)
Expand Down
2 changes: 1 addition & 1 deletion examples/client_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
try:
import client_sync # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)
Expand Down
2 changes: 1 addition & 1 deletion examples/client_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
try:
import helper # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)
Expand Down
19 changes: 4 additions & 15 deletions examples/custom_msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,19 @@

from pymodbus import FramerType
from pymodbus.client import AsyncModbusTcpClient as ModbusClient
from pymodbus.datastore import (
ModbusDeviceContext,
ModbusSequentialDataBlock,
ModbusServerContext,
)
from pymodbus.datastore import ModbusServerContext
from pymodbus.exceptions import ModbusIOException
from pymodbus.pdu import ModbusPDU
from pymodbus.pdu.bit_message import ReadCoilsRequest
from pymodbus.server import ServerAsyncStop, StartAsyncTcpServer
from pymodbus.simulator import DataType, SimData, SimDevice


# --------------------------------------------------------------------------- #
# create your custom message
# --------------------------------------------------------------------------- #
# The following is simply a read coil request that always reads 16 coils.
# Since the function code is already registered with the decoder factory,
# Since the function code is already registered with the decoder,
# this will be decoded as a read coil response. If you implement a new
# method that is not currently implemented, you must register the request
# and response with the active DecodePDU object.
Expand Down Expand Up @@ -121,16 +118,8 @@ def __init__(self, address, device_id=1, transaction=0):

async def main(host="localhost", port=5020):
"""Run versions of read coil."""
store = ModbusServerContext(devices=ModbusDeviceContext(
di=ModbusSequentialDataBlock(0, [17] * 100),
co=ModbusSequentialDataBlock(0, [17] * 100),
hr=ModbusSequentialDataBlock(0, [17] * 100),
ir=ModbusSequentialDataBlock(0, [17] * 100),
),
single=True
)
task = asyncio.create_task(StartAsyncTcpServer(
context=store,
context=SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)),
address=(host, port),
custom_pdu=[CustomRequest])
)
Expand Down
7 changes: 0 additions & 7 deletions examples/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,6 @@ def get_commandline(server: bool = False, description: str | None = None, extras
type=str,
)
if server:
parser.add_argument(
"--store",
choices=["sequential", "sparse", "factory", "none"],
help="set type of datastore",
default="sequential",
type=str,
)
parser.add_argument(
"--device_ids",
help="set number of device_ids, default is 0 (any)",
Expand Down
14 changes: 2 additions & 12 deletions examples/package_test_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,8 @@
ModbusException,
pymodbus_apply_logging_config,
)
from pymodbus.datastore import (
ModbusDeviceContext,
ModbusSequentialDataBlock,
ModbusServerContext,
)
from pymodbus.logging import Log
from pymodbus.simulator import DataType, SimData, SimDevice
from pymodbus.transport import NULLMODEM_HOST, CommParams, CommType, ModbusProtocol


Expand Down Expand Up @@ -149,13 +145,7 @@ class ServerTester: # pylint: disable=too-few-public-methods
def __init__(self, comm: CommType):
"""Initialize runtime tester."""
self.comm = comm
self.store = ModbusDeviceContext(
di=ModbusSequentialDataBlock(0, [17] * 100),
co=ModbusSequentialDataBlock(0, [17] * 100),
hr=ModbusSequentialDataBlock(0, [17] * 100),
ir=ModbusSequentialDataBlock(0, [17] * 100),
)
self.context = ModbusServerContext(devices=self.store, single=True)
self.context = SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100))
self.identity = ModbusDeviceIdentification(
info_name={"VendorName": "VendorName"}
)
Expand Down
63 changes: 9 additions & 54 deletions examples/server_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
server_async.py [-h] [--comm {tcp,udp,serial,tls}]
[--framer {ascii,rtu,socket,tls}]
[--log {critical,error,warning,info,debug}]
[--port PORT] [--store {sequential,sparse,factory,none}]
[--port PORT]
[--device_ids DEVICE_IDS]

-h, --help
Expand All @@ -22,8 +22,6 @@
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--device_ids DEVICE IDs
set list of devices to respond to

Expand All @@ -35,32 +33,25 @@
import asyncio
import logging
import sys
from collections.abc import Callable
from typing import Any


try:
import helper # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)

from pymodbus import ModbusDeviceIdentification
from pymodbus import __version__ as pymodbus_version
from pymodbus.datastore import (
ModbusDeviceContext,
ModbusSequentialDataBlock,
ModbusServerContext,
ModbusSparseDataBlock,
)
from pymodbus.server import (
StartAsyncSerialServer,
StartAsyncTcpServer,
StartAsyncTlsServer,
StartAsyncUdpServer,
)
from pymodbus.simulator import DataType, SimData, SimDevice


_logger = logging.getLogger(__file__)
Expand All @@ -70,53 +61,17 @@
def setup_server(description=None, context=None, cmdline=None):
"""Run server setup."""
args = helper.get_commandline(server=True, description=description, cmdline=cmdline)
if context:
if context: # pragma: no cover
args.context = context
datablock: Callable[[], Any]
if not args.context:
if not args.context: # pragma: no cover
_logger.info("### Create datastore")
# The datastores only respond to the addresses that are initialized
# If you initialize a DataBlock to addresses of 0x00 to 0xFF, a request to
# 0x100 will respond with an invalid address exception.
# This is because many devices exhibit this kind of behavior (but not all)
if args.store == "sequential": # pragma: no cover
# Continuing, use a sequential block without gaps.
datablock = lambda : ModbusSequentialDataBlock(0x00, [17] * 100) # pylint: disable=unnecessary-lambda-assignment
elif args.store == "sparse": # pragma: no cover
# Continuing, or use a sparse DataBlock which can have gaps
datablock = lambda : ModbusSparseDataBlock({0x00: 0, 0x05: 1}) # pylint: disable=unnecessary-lambda-assignment
elif args.store == "factory" or True: # pragma: no cover # pylint: disable=condition-evals-to-constant
# Alternately, use the factory methods to initialize the DataBlocks
# or simply do not pass them to have them initialized to 0x00 on the
# full address range::
datablock = lambda : ModbusSequentialDataBlock(0x00, [0x00] * 65536) # pylint: disable=unnecessary-lambda-assignment

# Build data storage
if args.device_ids > 1: # pragma: no cover
# The server then makes use of a server context that allows the server
# to respond with different device contexts for different device ids.
# By default it will return the same context for every device id supplied
# (broadcast mode).
# However, this can be overloaded by setting the single flag to False and
# then supplying a dictionary of device id to context mapping::
context = {
device_id : ModbusDeviceContext(
di=datablock(),
co=datablock(),
hr=datablock(),
ir=datablock(),
)
for device_id in range(args.device_ids)
}

single = False
args.context = [SimDevice(device_id, SimData(0, datatype=DataType.REGISTERS, values=[17]*100))
for device_id in range(args.device_ids)]
else:
context = ModbusDeviceContext(
di=datablock(), co=datablock(), hr=datablock(), ir=datablock()
)
single = True

# Build data storage
args.context = ModbusServerContext(devices=context, single=single)
args.context = SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100))

# ----------------------------------------------------------------------- #
# initialize the server information
Expand Down
17 changes: 3 additions & 14 deletions examples/server_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,15 @@
import sys

from pymodbus import FramerType, pymodbus_apply_logging_config
from pymodbus.datastore import (
ModbusDeviceContext,
ModbusSequentialDataBlock,
ModbusServerContext,
)
from pymodbus.pdu import ModbusPDU
from pymodbus.server import ModbusTcpServer
from pymodbus.simulator import DataType, SimData, SimDevice


try:
import helper # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)
Expand Down Expand Up @@ -57,16 +53,9 @@ async def setup(self, cmdline):
"""Prepare server."""
args = helper.get_commandline(server=True, description="server hooks", cmdline=cmdline)
pymodbus_apply_logging_config(logging.DEBUG)
datablock = ModbusSequentialDataBlock(0x00, [17] * 100)
context = ModbusServerContext(
devices=ModbusDeviceContext(
di=datablock, co=datablock, hr=datablock, ir=datablock
),
single=True,
)
address: tuple[str, int] = (args.host if args.host else "", args.port if args.port else 0)
self.server = ModbusTcpServer(
context,
SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)),
framer=FramerType.SOCKET,
identity=None,
address=address,
Expand Down
6 changes: 2 additions & 4 deletions examples/server_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
server_sync.py [-h] [--comm {tcp,udp,serial,tls}]
[--framer {ascii,rtu,socket,tls}]
[--log {critical,error,warning,info,debug}]
[--port PORT] [--store {sequential,sparse,factory,none}]
[--port PORT]
[--device_ids DEVICE_IDS]

-h, --help
Expand All @@ -22,8 +22,6 @@
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--device_ids DEVICE_IDS
set list of devices to respond to

Expand All @@ -42,7 +40,7 @@
import helper # type: ignore[import-not-found]
import server_async # type: ignore[import-not-found]
except ImportError:
print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\
print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\
https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\
for more information.")
sys.exit(-1)
Expand Down
Loading