diff --git a/pymodbus/pdu/device.py b/pymodbus/pdu/device.py index 4ecdf5ca4..cfd231c33 100644 --- a/pymodbus/pdu/device.py +++ b/pymodbus/pdu/device.py @@ -205,7 +205,7 @@ def __getitem__(self, key): :param key: The register to read """ - return self.stat_data.setdefault(key, "") + return self.stat_data.get(key, "") def __str__(self): """Build a representation of the device. diff --git a/pymodbus/pdu/mei_message.py b/pymodbus/pdu/mei_message.py index 34bdef7c5..0d3a03422 100644 --- a/pymodbus/pdu/mei_message.py +++ b/pymodbus/pdu/mei_message.py @@ -101,6 +101,10 @@ async def datastore_update( return ExceptionResponse(self.function_code, ExcCodes.ILLEGAL_VALUE) information = DeviceInformationFactory.get(_MCB, self.read_code, self.object_id) + if self.read_code == DeviceInformation.SPECIFIC and ( + 0x07 <= self.object_id < 0x80 or not information.get(self.object_id) + ): + return ExceptionResponse(self.function_code, ExcCodes.ILLEGAL_ADDRESS) return ReadDeviceInformationResponse( read_code=self.read_code, information=information, diff --git a/test/pdu/test_device.py b/test/pdu/test_device.py index dc80e6019..d73df32d3 100644 --- a/test/pdu/test_device.py +++ b/test/pdu/test_device.py @@ -171,6 +171,7 @@ def test_modbus_device_identification_get(self): assert self.ident[0x08] != "x" assert self.ident[0x10] != "reserved" assert not self.ident[0x54] + assert 0x54 not in dict(self.ident) def test_modbus_device_identification_summary(self): """Test device identification summary creation.""" diff --git a/test/pdu/test_mei_messages.py b/test/pdu/test_mei_messages.py index 7788f8105..09885adf7 100644 --- a/test/pdu/test_mei_messages.py +++ b/test/pdu/test_mei_messages.py @@ -80,6 +80,14 @@ async def test_read_device_information_request(self, mock_server_context): with pytest.raises(KeyError): _ = result.information[0x81] + handle = ReadDeviceInformationRequest( + read_code=DeviceInformation.SPECIFIC, object_id=0x00 + ) + result = await handle.datastore_update(context, 0) + assert cast(ReadDeviceInformationResponse, result).information == { + 0x00: "Company" + } + handle = ReadDeviceInformationRequest( read_code=DeviceInformation.EXTENDED, object_id=0x80 ) @@ -101,6 +109,17 @@ async def test_read_device_information_request_error(self, mock_server_context): assert (await handle.datastore_update(context, 0)).function_code == 0xAB handle.object_id = 0x100 assert (await handle.datastore_update(context, 0)).function_code == 0xAB + handle = ReadDeviceInformationRequest( + read_code=DeviceInformation.SPECIFIC, object_id=0x54 + ) + result = await handle.datastore_update(context, 0) + assert result.exception_code == ExcCodes.ILLEGAL_ADDRESS + ModbusControlBlock().Identity[0xFE] = "" + handle = ReadDeviceInformationRequest( + read_code=DeviceInformation.SPECIFIC, object_id=0xFE + ) + result = await handle.datastore_update(context, 0) + assert result.exception_code == ExcCodes.ILLEGAL_ADDRESS def test_read_device_information_calc1(self): """Test calculateRtuFrameSize, short buffer."""