Skip to content

Commit bd2cf8a

Browse files
Fredo70fchastagnoljaniversen
committed
Fix RemoteSlaveContext (#1599)
Co-authored-by: fchastagnol <frederic.chastagnol@pi-system.ch> Co-authored-by: jan iversen <jancasacondor@gmail.com>
1 parent ba53d93 commit bd2cf8a

File tree

6 files changed

+60
-29
lines changed

6 files changed

+60
-29
lines changed

pymodbus/bit_read_message.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
import struct
1313

1414
from pymodbus.constants import Defaults
15+
from pymodbus.pdu import ExceptionResponse, ModbusRequest, ModbusResponse
1516
from pymodbus.pdu import ModbusExceptions as merror
16-
from pymodbus.pdu import ModbusRequest, ModbusResponse
1717
from pymodbus.utilities import pack_bitstring, unpack_bitstring
1818

1919

@@ -171,6 +171,8 @@ def execute(self, context):
171171
if not context.validate(self.function_code, self.address, self.count):
172172
return self.doException(merror.IllegalAddress)
173173
values = context.getValues(self.function_code, self.address, self.count)
174+
if isinstance(values, ExceptionResponse):
175+
return values
174176
return ReadCoilsResponse(values)
175177

176178

@@ -237,6 +239,8 @@ def execute(self, context):
237239
if not context.validate(self.function_code, self.address, self.count):
238240
return self.doException(merror.IllegalAddress)
239241
values = context.getValues(self.function_code, self.address, self.count)
242+
if isinstance(values, ExceptionResponse):
243+
return values
240244
return ReadDiscreteInputsResponse(values)
241245

242246

pymodbus/bit_write_message.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import struct
1515

1616
from pymodbus.constants import ModbusStatus
17+
from pymodbus.pdu import ExceptionResponse, ModbusRequest, ModbusResponse
1718
from pymodbus.pdu import ModbusExceptions as merror
18-
from pymodbus.pdu import ModbusRequest, ModbusResponse
1919
from pymodbus.utilities import pack_bitstring, unpack_bitstring
2020

2121

@@ -90,8 +90,12 @@ def execute(self, context):
9090
if not context.validate(self.function_code, self.address, 1):
9191
return self.doException(merror.IllegalAddress)
9292

93-
context.setValues(self.function_code, self.address, [self.value])
93+
result = context.setValues(self.function_code, self.address, [self.value])
94+
if isinstance(result, ExceptionResponse):
95+
return result
9496
values = context.getValues(self.function_code, self.address, 1)
97+
if isinstance(values, ExceptionResponse):
98+
return values
9599
return WriteSingleCoilResponse(self.address, values[0])
96100

97101
def get_response_pdu_size(self):
@@ -222,7 +226,9 @@ def execute(self, context):
222226
if not context.validate(self.function_code, self.address, count):
223227
return self.doException(merror.IllegalAddress)
224228

225-
context.setValues(self.function_code, self.address, self.values)
229+
result = context.setValues(self.function_code, self.address, self.values)
230+
if isinstance(result, ExceptionResponse):
231+
return result
226232
return WriteMultipleCoilsResponse(self.address, count)
227233

228234
def __str__(self):

pymodbus/datastore/remote.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,34 @@ def reset(self):
3232
"""Reset all the datastores to their default values."""
3333
raise NotImplementedException()
3434

35-
def validate(self, fc_as_hex, address, count=1):
35+
def validate(self, _fc_as_hex, _address, _count):
3636
"""Validate the request to make sure it is in range.
3737
38-
:param fc_as_hex: The function we are working with
39-
:param address: The starting address
40-
:param count: The number of values to test
41-
:returns: True if the request in within range, False otherwise
38+
:returns: True
4239
"""
43-
Log.debug("validate[{}] {}:{}", fc_as_hex, address, count)
44-
group_fx = self.decode(fc_as_hex)
45-
if fc_as_hex in self._write_fc:
46-
func_fc = self.__set_callbacks[f"{group_fx}{fc_as_hex}"]
47-
else:
48-
func_fc = self.__get_callbacks[group_fx]
49-
self.result = func_fc(address, count)
50-
return not self.result.isError()
40+
return True
5141

5242
def getValues(self, fc_as_hex, _address, _count=1):
5343
"""Get values from real call in validate"""
5444
if fc_as_hex in self._write_fc:
5545
return [0]
46+
group_fx = self.decode(fc_as_hex)
47+
func_fc = self.__get_callbacks[group_fx]
48+
self.result = func_fc(_address, _count)
5649
return self.__extract_result(self.decode(fc_as_hex), self.result)
5750

5851
def setValues(self, fc_as_hex, address, values):
59-
"""Set the datastore with the supplied values.
60-
61-
Already done in validate
62-
"""
52+
"""Set the datastore with the supplied values."""
53+
group_fx = self.decode(fc_as_hex)
54+
if fc_as_hex in self._write_fc:
55+
func_fc = self.__set_callbacks[f"{group_fx}{fc_as_hex}"]
56+
if fc_as_hex in {0x0F, 0x10}:
57+
self.result = func_fc(address, values)
58+
else:
59+
self.result = func_fc(address, values[0])
60+
if self.result.isError():
61+
return self.result
62+
return None
6363

6464
def __str__(self):
6565
"""Return a string representation of the context.

pymodbus/register_read_message.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import struct
1515

1616
from pymodbus.constants import Defaults
17+
from pymodbus.pdu import ExceptionResponse, ModbusRequest, ModbusResponse
1718
from pymodbus.pdu import ModbusExceptions as merror
18-
from pymodbus.pdu import ModbusRequest, ModbusResponse
1919

2020

2121
class ReadRegistersRequestBase(ModbusRequest):
@@ -151,6 +151,9 @@ def execute(self, context):
151151
if not context.validate(self.function_code, self.address, self.count):
152152
return self.doException(merror.IllegalAddress)
153153
values = context.getValues(self.function_code, self.address, self.count)
154+
if isinstance(values, ExceptionResponse):
155+
return values
156+
154157
return ReadHoldingRegistersResponse(values)
155158

156159

@@ -209,6 +212,8 @@ def execute(self, context):
209212
if not context.validate(self.function_code, self.address, self.count):
210213
return self.doException(merror.IllegalAddress)
211214
values = context.getValues(self.function_code, self.address, self.count)
215+
if isinstance(values, ExceptionResponse):
216+
return values
212217
return ReadInputRegistersResponse(values)
213218

214219

@@ -324,7 +329,11 @@ def execute(self, context):
324329
return self.doException(merror.IllegalAddress)
325330
if not context.validate(self.function_code, self.read_address, self.read_count):
326331
return self.doException(merror.IllegalAddress)
327-
context.setValues(self.function_code, self.write_address, self.write_registers)
332+
result = context.setValues(
333+
self.function_code, self.write_address, self.write_registers
334+
)
335+
if isinstance(result, ExceptionResponse):
336+
return result
328337
registers = context.getValues(
329338
self.function_code, self.read_address, self.read_count
330339
)

pymodbus/register_write_message.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
# pylint: disable=missing-type-doc
1313
import struct
1414

15+
from pymodbus.pdu import ExceptionResponse, ModbusRequest, ModbusResponse
1516
from pymodbus.pdu import ModbusExceptions as merror
16-
from pymodbus.pdu import ModbusRequest, ModbusResponse
1717

1818

1919
class WriteSingleRegisterRequest(ModbusRequest):
@@ -68,7 +68,9 @@ def execute(self, context):
6868
if not context.validate(self.function_code, self.address, 1):
6969
return self.doException(merror.IllegalAddress)
7070

71-
context.setValues(self.function_code, self.address, [self.value])
71+
result = context.setValues(self.function_code, self.address, [self.value])
72+
if isinstance(result, ExceptionResponse):
73+
return result
7274
values = context.getValues(self.function_code, self.address, 1)
7375
return WriteSingleRegisterResponse(self.address, values[0])
7476

@@ -211,7 +213,9 @@ def execute(self, context):
211213
if not context.validate(self.function_code, self.address, self.count):
212214
return self.doException(merror.IllegalAddress)
213215

214-
context.setValues(self.function_code, self.address, self.values)
216+
result = context.setValues(self.function_code, self.address, self.values)
217+
if isinstance(result, ExceptionResponse):
218+
return result
215219
return WriteMultipleRegistersResponse(self.address, self.count)
216220

217221
def get_response_pdu_size(self):
@@ -330,8 +334,12 @@ def execute(self, context):
330334
if not context.validate(self.function_code, self.address, 1):
331335
return self.doException(merror.IllegalAddress)
332336
values = context.getValues(self.function_code, self.address, 1)[0]
337+
if isinstance(values, ExceptionResponse):
338+
return values
333339
values = (values & self.and_mask) | (self.or_mask & ~self.and_mask)
334-
context.setValues(self.function_code, self.address, [values])
340+
result = context.setValues(self.function_code, self.address, [values])
341+
if isinstance(result, ExceptionResponse):
342+
return result
335343
return MaskWriteRegisterResponse(self.address, self.and_mask, self.or_mask)
336344

337345

test/test_remote_datastore.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ def test_remote_slave_set_values(self):
2525
"""Test setting values against a remote slave context"""
2626
client = mock.MagicMock()
2727
client.write_coils = lambda a, b: WriteMultipleCoilsResponse()
28+
client.write_registers = lambda a, b: ExceptionResponse(0x10, 0x02)
2829

2930
context = RemoteSlaveContext(client)
30-
context.setValues(1, 0, [1])
31+
context.setValues(0x0F, 0, [1])
32+
result = context.setValues(0x10, 1, [1])
33+
assert result.exception_code == 0x02
34+
assert result.function_code == 0x90
3135

3236
def test_remote_slave_get_values(self):
3337
"""Test getting values from a remote slave context"""
@@ -64,4 +68,4 @@ def test_remote_slave_validate_values(self):
6468
assert result
6569

6670
result = context.validate(3, 0, 10)
67-
assert not result
71+
assert result

0 commit comments

Comments
 (0)