Skip to content

Commit 75b0d1c

Browse files
committed
Update repl to work with latest pymodbus on dev branch
1 parent 8791b62 commit 75b0d1c

File tree

6 files changed

+602
-591
lines changed

6 files changed

+602
-591
lines changed

poetry.lock

Lines changed: 549 additions & 534 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pymodbus_repl/client/main.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
from pygments.lexers.python import PythonLexer
1313
from pymodbus import __version__ as pymodbus_version
1414
from pymodbus.exceptions import ParameterException
15-
from pymodbus.transaction import (
16-
ModbusAsciiFramer,
17-
ModbusRtuFramer,
18-
ModbusSocketFramer,
15+
from pymodbus.framer import (
16+
FramerAscii,
17+
FramerRTU,
18+
FramerSocket,
1919
)
2020

2121
from pymodbus_repl import __VERSION__ as repl_version
@@ -261,7 +261,7 @@ def tcp(ctx, host, port, framer):
261261
kwargs = {"host": host, "port": port}
262262
kwargs.update(**ctx.obj)
263263
if framer == "rtu":
264-
kwargs["framer"] = ModbusRtuFramer
264+
kwargs["framer"] = FramerRTU
265265
client = ModbusTcpClient(**kwargs)
266266
cli = CLI(client)
267267
cli.run()
@@ -359,11 +359,11 @@ def serial( # pylint: disable=too-many-arguments
359359
"""Define serial communication."""
360360
method = method.lower()
361361
if method == "ascii":
362-
framer = ModbusAsciiFramer
362+
framer = FramerAscii
363363
elif method == "rtu":
364-
framer = ModbusRtuFramer
364+
framer = FramerRTU
365365
elif method == "socket":
366-
framer = ModbusSocketFramer
366+
framer = FramerSocket
367367
else:
368368
raise ParameterException("Invalid framer method requested")
369369
client = ModbusSerialClient(

pymodbus_repl/client/mclient.py

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
from pymodbus.client import ModbusTcpClient as _ModbusTcpClient
88
from pymodbus.client.base import ModbusBaseSyncClient as _ModbusBaseSyncClient
99
from pymodbus.exceptions import ModbusIOException
10-
from pymodbus.pdu import ExceptionResponse, ModbusExceptions
10+
from pymodbus.pdu import ExceptionResponse
1111
from pymodbus.pdu.diag_message import (
1212
ChangeAsciiInputDelimiterRequest,
1313
ClearCountersRequest,
1414
ClearOverrunCountRequest,
15-
DiagnosticStatusResponse,
1615
ForceListenOnlyModeRequest,
1716
GetClearModbusPlusRequest,
1817
RestartCommunicationsOptionRequest,
@@ -42,7 +41,7 @@
4241
ReportSlaveIdRequest,
4342
ReportSlaveIdResponse,
4443
)
45-
from pymodbus.pdu.register_write_message import MaskWriteRegisterResponse
44+
from pymodbus.pdu.register_message import MaskWriteRegisterResponse
4645

4746

4847
def make_response_dict(resp):
@@ -74,10 +73,13 @@ def _wrapper(*args, **kwargs):
7473

7574
return _wrapper
7675

76+
7777
if TYPE_CHECKING:
7878
_Base = _ModbusBaseSyncClient
7979
else:
8080
_Base = object
81+
82+
8183
class ExtendedRequestSupport(_Base): # pylint: disable=(too-many-public-methods
8284
"""Extended request support."""
8385

@@ -92,7 +94,7 @@ def _process_exception(resp, **kwargs):
9294
"original_function_code": f"{resp.original_code} ({hex(resp.original_code)})",
9395
"error_function_code": f"{resp.function_code} ({hex(resp.function_code)})",
9496
"exception code": resp.exception_code,
95-
"message": ModbusExceptions.decode(resp.exception_code),
97+
"message": ExceptionResponse.decode(resp.exception_code),
9698
}
9799
elif isinstance(resp, ModbusIOException):
98100
err = {
@@ -113,7 +115,7 @@ def read_coils(self, address, count=1, slave=0, **kwargs):
113115
:returns: List of register values
114116
"""
115117
resp = super().read_coils(
116-
address, count, slave, **kwargs
118+
address, count=count, slave=slave, **kwargs
117119
)
118120
if not resp.isError():
119121
return {"function_code": resp.function_code, "bits": resp.bits}
@@ -129,7 +131,7 @@ def read_discrete_inputs(self, address, count=1, slave=0, **kwargs):
129131
:return: List of bits
130132
"""
131133
resp = super().read_discrete_inputs(
132-
address, count, slave, **kwargs
134+
address, count=count, slave=slave, **kwargs
133135
)
134136
if not resp.isError():
135137
return {"function_code": resp.function_code, "bits": resp.bits}
@@ -146,7 +148,7 @@ def write_coil(self, address, value, slave=0, **kwargs):
146148
:return:
147149
"""
148150
resp = super().write_coil(
149-
address, value, slave, **kwargs
151+
address, value, slave=slave, **kwargs
150152
)
151153
return resp
152154

@@ -161,7 +163,7 @@ def write_coils(self, address, values, slave=0, **kwargs):
161163
:return:
162164
"""
163165
resp = super().write_coils(
164-
address, values, slave, **kwargs
166+
address, values, slave=slave, **kwargs
165167
)
166168
return resp
167169

@@ -176,7 +178,7 @@ def write_register(self, address, value, slave=0, **kwargs):
176178
:return:
177179
"""
178180
resp = super().write_register(
179-
address, value, slave, **kwargs
181+
address, value, slave=slave, **kwargs
180182
)
181183
return resp
182184

@@ -191,7 +193,7 @@ def write_registers(self, address, values, slave=0, **kwargs):
191193
:return:
192194
"""
193195
resp = super().write_registers(
194-
address, values, slave, **kwargs
196+
address, values, slave=slave, **kwargs
195197
)
196198
return resp
197199

@@ -205,7 +207,7 @@ def read_holding_registers(self, address, count=1, slave=0, **kwargs):
205207
:return:
206208
"""
207209
resp = super().read_holding_registers(
208-
address, count, slave, **kwargs
210+
address, count=count, slave=slave, **kwargs
209211
)
210212
if not resp.isError():
211213
return {"function_code": resp.function_code, "registers": resp.registers}
@@ -221,20 +223,20 @@ def read_input_registers(self, address, count=1, slave=0, **kwargs):
221223
:return:
222224
"""
223225
resp = super().read_input_registers(
224-
address, count, slave, **kwargs
226+
address, count=count, slave=slave, **kwargs
225227
)
226228
if not resp.isError():
227229
return {"function_code": resp.function_code, "registers": resp.registers}
228230
return ExtendedRequestSupport._process_exception(resp, slave=slave)
229231

230232
def readwrite_registers(
231-
self,
232-
read_address=0,
233-
read_count=0,
234-
write_address=0,
235-
values=0,
236-
slave=0,
237-
**kwargs,
233+
self,
234+
read_address=0,
235+
read_count=0,
236+
write_address=0,
237+
values=0,
238+
slave=0,
239+
**kwargs,
238240
):
239241
"""Read `read_count` number of holding registers.
240242
@@ -262,12 +264,12 @@ def readwrite_registers(
262264
return ExtendedRequestSupport._process_exception(resp, slave=slave)
263265

264266
def mask_write_register(
265-
self,
266-
address=0x0000,
267-
and_mask=0xFFFF,
268-
or_mask=0x0000,
269-
slave=0,
270-
**kwargs,
267+
self,
268+
address=0x0000,
269+
and_mask=0xFFFF,
270+
or_mask=0x0000,
271+
slave=0,
272+
**kwargs,
271273
):
272274
"""Mask content of holding register at `address` with `and_mask` and `or_mask`.
273275

pymodbus_repl/lib/reactive.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@
2828
)
2929
from pymodbus.device import ModbusDeviceIdentification
3030
from pymodbus.logging import Log
31-
from pymodbus.pdu import ExceptionResponse, ModbusExceptions
32-
from pymodbus.server.async_io import (
31+
from pymodbus.pdu import ExceptionResponse
32+
from pymodbus.server import (
3333
ModbusSerialServer,
3434
ModbusTcpServer,
3535
ModbusTlsServer,
3636
ModbusUdpServer,
3737
)
38-
from pymodbus.transaction import (
39-
ModbusAsciiFramer,
40-
ModbusRtuFramer,
41-
ModbusSocketFramer,
42-
ModbusTlsFramer,
38+
from pymodbus.framer import (
39+
FramerAscii,
40+
FramerRTU,
41+
FramerSocket,
42+
FramerTLS,
4343
)
4444

4545

@@ -51,17 +51,17 @@
5151
}
5252

5353
DEFAULT_FRAMER = {
54-
"tcp": ModbusSocketFramer,
55-
"rtu": ModbusRtuFramer,
56-
"tls": ModbusTlsFramer,
57-
"udp": ModbusSocketFramer,
58-
"ascii": ModbusAsciiFramer
54+
"tcp": FramerSocket,
55+
"rtu": FramerRTU,
56+
"tls": FramerTLS,
57+
"udp": FramerSocket,
58+
"ascii": FramerAscii
5959
}
6060

6161
DEFAULT_MANIPULATOR = {
6262
"response_type": "normal", # normal, error, delayed, empty
6363
"delay_by": 0,
64-
"error_code": ModbusExceptions.IllegalAddress,
64+
"error_code": ExceptionResponse.ILLEGAL_ADDRESS,
6565
"clear_after": 5, # request count
6666
}
6767
DEFAULT_MODBUS_MAP = {
@@ -149,7 +149,6 @@ def __init__(
149149
coils: BaseModbusDataBlock,
150150
input_registers: BaseModbusDataBlock,
151151
holding_registers: BaseModbusDataBlock,
152-
zero_mode: bool = False,
153152
randomize: int = 0,
154153
change_rate: int = 0,
155154
**kwargs,
@@ -159,7 +158,6 @@ def __init__(
159158
:param coils: Coils data block
160159
:param input_registers: Input registers data block
161160
:param holding_registers: Holding registers data block
162-
:param zero_mode: Enable zero mode for data blocks
163161
:param randomize: Randomize reads every <n> reads for DI and IR,
164162
default is disabled (0)
165163
:param change_rate: Rate in % of registers to change for DI and IR,
@@ -173,8 +171,7 @@ def __init__(
173171
di=discrete_inputs,
174172
co=coils,
175173
ir=input_registers,
176-
hr=holding_registers,
177-
zero_mode=zero_mode,
174+
hr=holding_registers
178175
)
179176
min_binary_value = kwargs.get("min_binary_value", 0)
180177
max_binary_value = kwargs.get("max_binary_value", 1)
@@ -200,8 +197,6 @@ def getValues(self, fc_as_hex, address, count=1):
200197
:param count: The number of values to retrieve
201198
:returns: The requested values from a:a+c
202199
"""
203-
if not self.zero_mode:
204-
address += 1
205200
Log.debug("getValues: fc-[{}] address-{}: count-{}", fc_as_hex, address, count)
206201
_block_type = self.decode(fc_as_hex)
207202
if self._randomize > 0 and _block_type in {"d", "i"}:
@@ -463,7 +458,6 @@ def create_context(
463458
**block,
464459
randomize=randomize,
465460
change_rate=change_rate,
466-
zero_mode=True,
467461
**data_block_settings,
468462
)
469463
if not single:
@@ -490,7 +484,7 @@ def factory( # pylint: disable=dangerous-default-value,too-many-arguments
490484
):
491485
"""Create ReactiveModbusServer.
492486
:param server: Modbus server type (tcp, rtu, tls, udp)
493-
:param framer: Modbus framer (ModbusSocketFramer, ModbusRTUFramer, ModbusTLSFramer)
487+
:param framer: Modbus framer (FramerSocket, FramerRTU, FramerTLS)
494488
:param context: Modbus server context to use
495489
:param slave: Modbus slave id
496490
:param single: Run in single mode

pymodbus_repl/server/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import typer
1414
from pymodbus import pymodbus_apply_logging_config
1515
from pymodbus.logging import Log
16-
from pymodbus.transaction import ModbusSocketFramer
16+
from pymodbus.framer import FramerType
1717
from typing_extensions import Annotated
1818

1919
from pymodbus_repl.lib.reactive import (
@@ -165,7 +165,7 @@ def run(
165165
# TBD extra_args = ctx.args
166166
web_app_config = ctx.obj
167167
loop = asyncio.get_event_loop()
168-
framer = DEFAULT_FRAMER.get(modbus_framer, ModbusSocketFramer)
168+
framer = DEFAULT_FRAMER.get(modbus_framer, FramerType.SOCKET)
169169
if modbus_config_path:
170170
with open(modbus_config_path, encoding="utf-8") as my_file:
171171
modbus_config = json.load(my_file)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ version=">=3.8.6"
2828
include = ["pymodbus_repl"]
2929

3030
[tool.poetry.group.dev.dependencies]
31-
pymodbus = {git = "https://github.com/pymodbus-dev/pymodbus", tag = "v3.7.0"}
3231
ruff = "^0.5.6"
3332
coverage = "^7.4.1"
3433
pytest-xdist = "^3.5.0"
@@ -37,6 +36,7 @@ twine = "^5.0.0"
3736
mypy = "^1.11.1"
3837
types-pygments = "^2.18.0.20240506"
3938
types-tabulate = "^0.9.0.20240106"
39+
pymodbus = {git = "https://github.com/pymodbus-dev/pymodbus.git", rev = "dev"}
4040

4141
[build-system]
4242
requires = ["poetry-core"]

0 commit comments

Comments
 (0)