Skip to content

Commit

Permalink
Remove ModbusExceptions enum. (#2467)
Browse files Browse the repository at this point in the history
  • Loading branch information
janiversen authored Nov 24, 2024
1 parent 604546d commit 8d43c9e
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 55 deletions.
6 changes: 3 additions & 3 deletions examples/client_custom_msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from pymodbus import FramerType
from pymodbus.client import AsyncModbusTcpClient as ModbusClient
from pymodbus.pdu import ExceptionResponse, ModbusExceptions, ModbusPDU
from pymodbus.pdu import ExceptionResponse, ModbusPDU
from pymodbus.pdu.bit_message import ReadCoilsRequest


Expand Down Expand Up @@ -85,9 +85,9 @@ def decode(self, data):
def execute(self, context):
"""Execute."""
if not 1 <= self.count <= 0x7D0:
return ExceptionResponse(self.function_code, ModbusExceptions.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not context.validate(self.function_code, self.address, self.count):
return ExceptionResponse(self.function_code, ModbusExceptions.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
values = context.getValues(self.function_code, self.address, self.count)
return CustomModbusPDU(values)

Expand Down
3 changes: 1 addition & 2 deletions pymodbus/pdu/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
"ExceptionResponse",
"ExceptionResponse",
"FileRecord",
"ModbusExceptions",
"ModbusPDU",
]

from pymodbus.pdu.decoders import DecodePDU
from pymodbus.pdu.file_message import FileRecord
from pymodbus.pdu.pdu import ExceptionResponse, ModbusExceptions, ModbusPDU
from pymodbus.pdu.pdu import ExceptionResponse, ModbusPDU
5 changes: 2 additions & 3 deletions pymodbus/pdu/bit_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from pymodbus.constants import ModbusStatus
from pymodbus.datastore import ModbusSlaveContext
from pymodbus.pdu.pdu import ExceptionResponse, ModbusPDU
from pymodbus.pdu.pdu import ModbusExceptions as merror
from pymodbus.utilities import pack_bitstring, unpack_bitstring


Expand Down Expand Up @@ -95,7 +94,7 @@ class WriteSingleCoilRequest(WriteSingleCoilResponse):
async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a request against a datastore."""
if not context.validate(self.function_code, self.address, 1):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
await context.async_setValues(self.function_code, self.address, self.bits)
values = cast(list[bool], await context.async_getValues(self.function_code, self.address, 1))
return WriteSingleCoilResponse(address=self.address, bits=values, slave_id=self.slave_id, transaction_id=self.transaction_id)
Expand Down Expand Up @@ -131,7 +130,7 @@ async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a request against a datastore."""
count = len(self.bits)
if not context.validate(self.function_code, self.address, count):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
await context.async_setValues(
self.function_code, self.address, self.bits
)
Expand Down
5 changes: 2 additions & 3 deletions pymodbus/pdu/mei_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from pymodbus.datastore import ModbusSlaveContext
from pymodbus.device import DeviceInformationFactory, ModbusControlBlock
from pymodbus.pdu.pdu import ExceptionResponse, ModbusPDU
from pymodbus.pdu.pdu import ModbusExceptions as merror


_MCB = ModbusControlBlock()
Expand Down Expand Up @@ -55,9 +54,9 @@ def decode(self, data: bytes) -> None:
async def update_datastore(self, _context: ModbusSlaveContext) -> ModbusPDU:
"""Run a read exception status request against the store."""
if not 0x00 <= self.object_id <= 0xFF:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not 0x00 <= self.read_code <= 0x04:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)

information = DeviceInformationFactory.get(_MCB, self.read_code, self.object_id)
return ReadDeviceInformationResponse(read_code=self.read_code, information=information, slave_id=self.slave_id, transaction_id=self.transaction_id)
Expand Down
13 changes: 4 additions & 9 deletions pymodbus/pdu/pdu.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import asyncio
import struct
from abc import abstractmethod
from enum import Enum
from typing import cast

from pymodbus.exceptions import NotImplementedException
Expand Down Expand Up @@ -100,8 +99,10 @@ def calculateRtuFrameSize(cls, data: bytes) -> int:
)


class ModbusExceptions(int, Enum):
"""An enumeration of the valid modbus exceptions."""
class ExceptionResponse(ModbusPDU):
"""Base class for a modbus exception PDU."""

rtu_frame_size = 5

ILLEGAL_FUNCTION = 0x01
ILLEGAL_ADDRESS = 0x02
Expand All @@ -114,12 +115,6 @@ class ModbusExceptions(int, Enum):
GATEWAY_PATH_UNAVIABLE = 0x0A
GATEWAY_NO_RESPONSE = 0x0B


class ExceptionResponse(ModbusPDU):
"""Base class for a modbus exception PDU."""

rtu_frame_size = 5

def __init__(
self,
function_code: int,
Expand Down
25 changes: 12 additions & 13 deletions pymodbus/pdu/register_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from pymodbus.datastore import ModbusSlaveContext
from pymodbus.exceptions import ModbusIOException
from pymodbus.pdu.pdu import ExceptionResponse, ModbusPDU
from pymodbus.pdu.pdu import ModbusExceptions as merror


class ReadHoldingRegistersRequest(ModbusPDU):
Expand Down Expand Up @@ -36,7 +35,7 @@ def get_response_pdu_size(self) -> int:
async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a read holding request against a datastore."""
if not context.validate(self.function_code, self.address, self.count):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
values = cast(list[int], await context.async_getValues(
self.function_code, self.address, self.count
))
Expand Down Expand Up @@ -137,15 +136,15 @@ def decode(self, data: bytes) -> None:
async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a write single register request against a datastore."""
if not (1 <= self.read_count <= 0x07D):
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not 1 <= self.write_count <= 0x079:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not context.validate(
self.function_code, self.write_address, self.write_count
):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
if not context.validate(self.function_code, self.read_address, self.read_count):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
await context.async_setValues(
self.function_code, self.write_address, self.write_registers
)
Expand Down Expand Up @@ -190,9 +189,9 @@ class WriteSingleRegisterRequest(WriteSingleRegisterResponse):
async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a write single register request against a datastore."""
if not 0 <= self.registers[0] <= 0xFFFF:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not context.validate(self.function_code, self.address, 1):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)

await context.async_setValues(
self.function_code, self.address, self.registers
Expand Down Expand Up @@ -232,9 +231,9 @@ def decode(self, data: bytes) -> None:
async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a write single register request against a datastore."""
if not 1 <= self.count <= 0x07B:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not context.validate(self.function_code, self.address, self.count):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)

await context.async_setValues(
self.function_code, self.address, self.registers
Expand Down Expand Up @@ -287,11 +286,11 @@ def decode(self, data: bytes) -> None:
async def update_datastore(self, context: ModbusSlaveContext) -> ModbusPDU:
"""Run a mask write register request against the store."""
if not 0x0000 <= self.and_mask <= 0xFFFF:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not 0x0000 <= self.or_mask <= 0xFFFF:
return ExceptionResponse(self.function_code, merror.ILLEGAL_VALUE)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_VALUE)
if not context.validate(self.function_code, self.address, 1):
return ExceptionResponse(self.function_code, merror.ILLEGAL_ADDRESS)
return ExceptionResponse(self.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
values = (await context.async_getValues(self.function_code, self.address, 1))[0]
values = (values & self.and_mask) | (self.or_mask & ~self.and_mask)
await context.async_setValues(
Expand Down
7 changes: 3 additions & 4 deletions pymodbus/server/async_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from pymodbus.framer import FRAMER_NAME_TO_CLASS, FramerBase, FramerType
from pymodbus.logging import Log
from pymodbus.pdu import DecodePDU
from pymodbus.pdu import ModbusExceptions as merror
from pymodbus.pdu.pdu import ExceptionResponse
from pymodbus.transport import CommParams, CommType, ModbusProtocol

Expand Down Expand Up @@ -127,7 +126,7 @@ async def inner_handle(self):
except ModbusException:
pdu = ExceptionResponse(
40,
exception_code=merror.ILLEGAL_FUNCTION
exception_code=ExceptionResponse.ILLEGAL_FUNCTION
)
self.server_send(pdu, 0)
pdu = None
Expand Down Expand Up @@ -198,14 +197,14 @@ async def _async_execute(self, request, *addr):
Log.error("requested slave does not exist: {}", request.slave_id)
if self.server.ignore_missing_slaves:
return # the client will simply timeout waiting for a response
response = ExceptionResponse(0x00, merror.GATEWAY_NO_RESPONSE)
response = ExceptionResponse(0x00, ExceptionResponse.GATEWAY_NO_RESPONSE)
except Exception as exc: # pylint: disable=broad-except
Log.error(
"Datastore unable to fulfill request: {}; {}",
exc,
traceback.format_exc(),
)
response = ExceptionResponse(0x00, merror.SLAVE_FAILURE)
response = ExceptionResponse(0x00, ExceptionResponse.SLAVE_FAILURE)
# no response when broadcasting
if not broadcast:
response.transaction_id = request.transaction_id
Expand Down
3 changes: 1 addition & 2 deletions test/framer/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
FramerTLS,
)
from pymodbus.pdu import DecodePDU, ExceptionResponse
from pymodbus.pdu import ModbusExceptions as merror
from pymodbus.pdu.register_message import (
ReadHoldingRegistersRequest,
ReadHoldingRegistersResponse,
Expand Down Expand Up @@ -36,7 +35,7 @@ def set_calls():
result = server.buildFrame(response)
print(f" response --> {result}")
print(f" response --> {result.hex()}")
exception = ExceptionResponse(request.function_code, merror.ILLEGAL_ADDRESS)
exception = ExceptionResponse(request.function_code, ExceptionResponse.ILLEGAL_ADDRESS)
exception.transaction_id = tid
exception.slave_id = dev_id
result = server.buildFrame(exception)
Expand Down
4 changes: 2 additions & 2 deletions test/pdu/test_bit.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Bit Message Test Fixture."""

import pymodbus.pdu.bit_message as bit_msg
from pymodbus.pdu import ModbusExceptions
from pymodbus.pdu import ExceptionResponse


class TestModbusBitMessage:
Expand Down Expand Up @@ -97,7 +97,7 @@ async def test_write_single_coil_update_datastore(self, mock_context):
context = mock_context(False, default=True)
request = bit_msg.WriteSingleCoilRequest(address=2, bits=[True])
result = await request.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
assert result.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

context.valid = True
result = await request.update_datastore(context)
Expand Down
12 changes: 6 additions & 6 deletions test/pdu/test_register_read_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import pytest

from pymodbus.exceptions import ModbusIOException
from pymodbus.pdu import ModbusExceptions
from pymodbus.pdu import ExceptionResponse
from pymodbus.pdu.register_message import (
ReadHoldingRegistersRequest,
ReadHoldingRegistersResponse,
Expand Down Expand Up @@ -101,7 +101,7 @@ async def test_register_read_requests_count_errors(self):
]
for request in requests:
result = await request.update_datastore(None)
assert result.exception_code == ModbusExceptions.ILLEGAL_VALUE
assert result.exception_code == ExceptionResponse.ILLEGAL_VALUE

async def test_register_read_requests_validate_errors(self, mock_context):
"""This tests that the register request messages.
Expand All @@ -117,7 +117,7 @@ async def test_register_read_requests_validate_errors(self, mock_context):
]
for request in requests:
result = await request.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
assert result.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

async def test_register_read_requests_update_datastore(self, mock_context):
"""This tests that the register request messages.
Expand Down Expand Up @@ -150,15 +150,15 @@ async def test_read_write_multiple_registers_validate(self, mock_context):
read_address=1, read_count=10, write_address=2, write_registers=[0x00]
)
await request.update_datastore(context)
#assert response.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
#assert response.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

context.validate = lambda f, a, c: a == 2
await request.update_datastore(context)
#assert response.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
#assert response.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

request.write_byte_count = 0x100
await request.update_datastore(context)
#assert response.exception_code == ModbusExceptions.ILLEGAL_VALUE
#assert response.exception_code == ExceptionResponse.ILLEGAL_VALUE

def test_serializing_to_string(self):
"""Test serializing to string."""
Expand Down
16 changes: 8 additions & 8 deletions test/pdu/test_register_write_messages.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Test register write messages."""
from pymodbus.payload import BinaryPayloadBuilder, Endian
from pymodbus.pdu import ModbusExceptions
from pymodbus.pdu import ExceptionResponse
from pymodbus.pdu.register_message import (
MaskWriteRegisterRequest,
MaskWriteRegisterResponse,
Expand Down Expand Up @@ -83,11 +83,11 @@ async def test_write_single_register_request(self, mock_context):
context = mock_context()
request = WriteSingleRegisterRequest(address=0x00, registers=[0xF0000])
result = await request.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_VALUE
assert result.exception_code == ExceptionResponse.ILLEGAL_VALUE

request.registers[0] = 0x00FF
result = await request.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
assert result.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

context.valid = True
result = await request.update_datastore(context)
Expand All @@ -98,11 +98,11 @@ async def test_write_multiple_register_request(self, mock_context):
context = mock_context()
request = WriteMultipleRegistersRequest(address=0x00, registers=[0x00] * 10)
result = await request.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
assert result.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

request.count = 0x800 # outside of range
result = await request.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_VALUE
assert result.exception_code == ExceptionResponse.ILLEGAL_VALUE

context.valid = True
request = WriteMultipleRegistersRequest(address=0x00, registers=[0x00] * 10)
Expand Down Expand Up @@ -151,15 +151,15 @@ async def test_mask_write_register_request_invalid_update_datastore(self, mock_c
context = mock_context(valid=False, default=0x0000)
handle = MaskWriteRegisterRequest(0x0000, -1, 0x1010)
result = await handle.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_VALUE
assert result.exception_code == ExceptionResponse.ILLEGAL_VALUE

handle = MaskWriteRegisterRequest(0x0000, 0x0101, -1)
result = await handle.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_VALUE
assert result.exception_code == ExceptionResponse.ILLEGAL_VALUE

handle = MaskWriteRegisterRequest(0x0000, 0x0101, 0x1010)
result = await handle.update_datastore(context)
assert result.exception_code == ModbusExceptions.ILLEGAL_ADDRESS
assert result.exception_code == ExceptionResponse.ILLEGAL_ADDRESS

# -----------------------------------------------------------------------#
# Mask Write Register Response
Expand Down

0 comments on commit 8d43c9e

Please sign in to comment.