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
8 changes: 4 additions & 4 deletions examples/custom_msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class CustomModbusResponse(ModbusPDU):
function_code = 55

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down Expand Up @@ -77,7 +77,7 @@ class CustomRequest(ModbusPDU):
function_code = 55

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 8

Expand Down Expand Up @@ -145,10 +145,10 @@ async def main(host="localhost", port=5020):
await client.connect()

# add new modbus function code.
assert CustomModbusResponse.calculateRtuFrameSize(b"\x00\x00\x07\x00") == 12
assert CustomModbusResponse.x_calculateRtuFrameSize(b"\x00\x00\x07\x00") == 12
client.register(CustomModbusResponse)
device_id = 1
assert CustomRequest.calculateRtuFrameSize(b"") == 8
assert CustomRequest.x_calculateRtuFrameSize(b"") == 8
request1 = CustomRequest(32, device_id=device_id)
try:
result = await client.execute(False, request1)
Expand Down
2 changes: 1 addition & 1 deletion pymodbus/framer/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def handleFrame(
)
continue
try:
pdu, _pdu_size = self.decoder.decode(frame_data)
pdu = self.decoder.decode(frame_data)
except ModbusIOException as exc:
exc.transaction_id = tid
exc.dev_id = dev_id
Expand Down
5 changes: 1 addition & 4 deletions pymodbus/framer/rtu.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,8 @@ def decode(self, data: bytes) -> tuple[int, int, int, bytes]:
Log.debug("Short frame: {} wait for more data", data, ":hex")
return 0, 0, 0, self.EMPTY
dev_id = int(data[used_len])
if not (pdu_class := self.decoder.lookupPduClass(data[used_len:])):
if not (size := self.decoder.calculateRtuFrameSize(data[used_len:])):
continue
if not (size := pdu_class.calculateRtuFrameSize(data[used_len:])):
Log.debug("Frame - byte_count_pos wrong")
return 0, dev_id, 0, self.EMPTY
if data_len < used_len + size:
Log.debug("Frame - not ready")
return 0, dev_id, 0, self.EMPTY
Expand Down
10 changes: 5 additions & 5 deletions pymodbus/pdu/bit_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ReadCoilsRequest(ModbusPDU):
MAX_COUNT = 2000

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 8

Expand Down Expand Up @@ -65,7 +65,7 @@ class ReadCoilsResponse(ModbusPDU):
function_code = 1

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand All @@ -91,7 +91,7 @@ class WriteSingleCoilResponse(ModbusPDU):
function_code = 5

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 8

Expand Down Expand Up @@ -141,7 +141,7 @@ class WriteMultipleCoilsRequest(ModbusPDU):
MAX_COUNT = 2000

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[6]) + 6 + 3

Expand Down Expand Up @@ -215,7 +215,7 @@ class WriteMultipleCoilsResponse(ModbusPDU):
function_code = 15

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 8

Expand Down
17 changes: 11 additions & 6 deletions pymodbus/pdu/decoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def __init__(self, is_server: bool) -> None:
"""Initialize function_tables."""
self.pdu_inx = 0 if is_server else 1

def lookupPduClass(self, data: bytes) -> type[ModbusPDU] | None:
def _lookupPduClass(self, data: bytes) -> type[ModbusPDU] | None:
"""Use `function_code` to determine the class of the PDU."""
if (func_code := int(data[1])) & 0x80:
return ExceptionResponse
Expand Down Expand Up @@ -60,29 +60,34 @@ def register(self, custom_class: type[ModbusPDU]) -> None:
self.pdu_table = copy.deepcopy(DecodePDU.pdu_table)
self.pdu_table[custom_class.function_code] = (custom_class, custom_class)

def decode(self, frame: bytes) -> tuple[ModbusPDU, int]:
def decode(self, frame: bytes) -> ModbusPDU:
"""Decode a frame."""
function_code = 0
try:
if (function_code := int(frame[0])) > 0x80:
pdu_exp = ExceptionResponse(function_code & 0x7F)
pdu_exp.x_decode(frame[1:])
return pdu_exp, ExceptionResponse.calculateRtuFrameSize(frame)
if not (pdu_class := self.lookupPduClass(b"\x00" + frame)):
return pdu_exp
if not (pdu_class := self._lookupPduClass(b"\x00" + frame)):
raise ModbusIOException(
f"Unknown response {function_code}", function_code=function_code
)
pdu = pdu_class()
pdu_size = pdu.calculateRtuFrameSize(frame)
pdu.x_decode(frame[1:])
Log.debug(
"decoded PDU function_code({} sub {}) -> {} ",
pdu.function_code,
pdu.sub_function_code,
str(pdu),
)
return pdu, pdu_size
return pdu
except (ValueError, IndexError, struct.error) as exc:
raise ModbusIOException(
f"Unable to decode frame {exc}", function_code=function_code
) from exc

def calculateRtuFrameSize(self, data: bytes) -> int:
"""Calculate the size of a PDU."""
if not (pdu_class := self._lookupPduClass(data)):
return 0
return pdu_class.x_calculateRtuFrameSize(data)
4 changes: 2 additions & 2 deletions pymodbus/pdu/diag_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class DiagnosticBase(ModbusPDU):
sub_function_code: int = 9999

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 8

Expand Down Expand Up @@ -464,7 +464,7 @@ class GetClearModbusPlusResponse(DiagnosticBase):
sub_function_code = 0x0015

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of the message.

Func_code (1 byte) + Sub function code (2 byte) + Operation (2 byte) + Data (108 bytes)
Expand Down
2 changes: 1 addition & 1 deletion pymodbus/pdu/exceptionresponse.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ExceptionResponse(ModbusPDU):
"""Base class for a modbus exception PDU."""

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 5

Expand Down
12 changes: 6 additions & 6 deletions pymodbus/pdu/file_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ReadFileRecordRequest(ModbusPDU):
function_code = 0x14

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down Expand Up @@ -97,7 +97,7 @@ class ReadFileRecordResponse(ModbusPDU):
function_code = 0x14

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down Expand Up @@ -143,7 +143,7 @@ class WriteFileRecordRequest(ModbusPDU):
function_code = 0x15

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down Expand Up @@ -207,7 +207,7 @@ class WriteFileRecordResponse(ModbusPDU):
function_code = 0x15

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down Expand Up @@ -260,7 +260,7 @@ class ReadFifoQueueRequest(ModbusPDU):
function_code = 0x18

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 6

Expand Down Expand Up @@ -297,7 +297,7 @@ class ReadFifoQueueResponse(ModbusPDU):
function_code = 0x18

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of the message."""
hi_byte = int(data[2])
lo_byte = int(data[3])
Expand Down
4 changes: 2 additions & 2 deletions pymodbus/pdu/mei_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ReadDeviceInformationRequest(ModbusPDU):
sub_function_code = 0x0E

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 7

Expand Down Expand Up @@ -113,7 +113,7 @@ class ReadDeviceInformationResponse(ModbusPDU):
sub_function_code = 0x0E

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of the message."""
size = 8 # skip the header information
if (data_len := len(data)) < size:
Expand Down
16 changes: 8 additions & 8 deletions pymodbus/pdu/other_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ReadExceptionStatusRequest(ModbusPDU):
function_code = 0x07

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 4

Expand Down Expand Up @@ -49,7 +49,7 @@ class ReadExceptionStatusResponse(ModbusPDU):
function_code = 0x07

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 5

Expand All @@ -72,7 +72,7 @@ class GetCommEventCounterRequest(ModbusPDU):
function_code = 0x0B

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 4

Expand Down Expand Up @@ -100,7 +100,7 @@ class GetCommEventCounterResponse(ModbusPDU):
function_code = 0x0B

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 8

Expand All @@ -121,7 +121,7 @@ class GetCommEventLogRequest(ModbusPDU):
function_code = 0x0C

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 4

Expand Down Expand Up @@ -153,7 +153,7 @@ class GetCommEventLogResponse(ModbusPDU):
function_code = 0x0C

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down Expand Up @@ -203,7 +203,7 @@ class ReportDeviceIdRequest(ModbusPDU):
function_code = 0x11

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return 4

Expand Down Expand Up @@ -244,7 +244,7 @@ class ReportDeviceIdResponse(ModbusPDU):
function_code = 0x11

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
return int(data[2]) + 2 + 3

Expand Down
4 changes: 2 additions & 2 deletions pymodbus/pdu/pdu.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ async def datastore_update(
)

@classmethod
def calculateRtuFrameSize(cls, data: bytes) -> int:
def x_calculateRtuFrameSize(cls, data: bytes) -> int:
"""Calculate the size of a PDU."""
raise NotImplementedException(
f"calculateRtuFrameSize() not implemented {cls.__class__.__name__}"
f"x_calculateRtuFrameSize() not implemented {cls.__class__.__name__}"
)
Loading