Skip to content

Commit ae08c13

Browse files
committed
Update tests for pymodbus>3
1 parent c73f860 commit ae08c13

2 files changed

Lines changed: 61 additions & 59 deletions

File tree

modbus4mqtt/modbus_interface.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
from queue import Queue
55
from pymodbus.client import ModbusTcpClient, ModbusUdpClient, ModbusTlsClient
6-
from pymodbus.framer import FramerAscii, FramerRTU, FramerSocket, FramerTLS
6+
from pymodbus.framer import FramerType
77

88
from SungrowModbusTcpClient import SungrowModbusTcpClient
99

@@ -76,10 +76,10 @@ def connect(self):
7676
# "serial": (ModbusSerialClient, ModbusRtuFramer),
7777
}
7878
framers = {
79-
"ascii": FramerAscii,
80-
"rtu": FramerRTU,
81-
"socket": FramerSocket,
82-
"tls": FramerTLS,
79+
"ascii": FramerType.ASCII,
80+
"rtu": FramerType.RTU,
81+
"socket": FramerType.SOCKET,
82+
"tls": FramerType.TLS,
8383
}
8484

8585
if self._variant is None:
@@ -95,12 +95,12 @@ def connect(self):
9595
raise ValueError("Unknown modbus framer: {}".format(desired_framer))
9696

9797
client = clients[desired_client]
98+
9899
if desired_framer is None:
99-
framer = FramerSocket
100-
else:
101-
framer = framers[desired_framer]
100+
desired_framer = "socket"
101+
framer = framers[desired_framer]
102102

103-
self._mb = client(host=self._ip, port=self._port, RetryOnEmpty=True, framer=framer, retries=1, timeout=1)
103+
self._mb = client(host=self._ip, port=self._port, framer=framer, retries=1, timeout=1)
104104

105105
def add_monitor_register(self, table, addr, type='uint16'):
106106
# Accepts a modbus register and table to monitor
@@ -170,9 +170,9 @@ def set_value(self, table, addr, value, mask=0xFFFF, type='uint16'):
170170

171171
def _perform_write(self, addr, value):
172172
if self._write_mode == WriteMode.Single:
173-
self._mb.write_register(addr, value, unit=self._unit)
173+
self._mb.write_register(address=addr, value=value, device_id=self._unit)
174174
else:
175-
self._mb.write_registers(addr, [value], unit=self._unit)
175+
self._mb.write_registers(address=addr, values=[value], device_id=self._unit)
176176

177177
def _process_writes(self, max_block_s=DEFAULT_WRITE_BLOCK_INTERVAL_S):
178178
# TODO I am not entirely happy with this system. It's supposed to prevent
@@ -197,7 +197,7 @@ def _process_writes(self, max_block_s=DEFAULT_WRITE_BLOCK_INTERVAL_S):
197197
# This specific read-before-write operation doesn't work on my modbus solar inverter -
198198
# I get "Modbus Error: [Input/Output] Modbus Error: [Invalid Message] Incomplete message received, expected at least 8 bytes (0 received)"
199199
# I suspect it's a different modbus opcode that tries to do clever things that my device doesn't support.
200-
# result = self._mb.mask_write_register(address=addr, and_mask=(1<<16)-1-mask, or_mask=value, unit=0x01)
200+
# result = self._mb.mask_write_register(address=addr, and_mask=(1<<16)-1-mask, or_mask=value, device_id=0x01)
201201
# print("Result: {}".format(result))
202202
old_value = self._scan_value_range('holding', addr, 1)[0]
203203
and_mask = (1 << 16) - 1 - mask
@@ -215,9 +215,9 @@ def _process_writes(self, max_block_s=DEFAULT_WRITE_BLOCK_INTERVAL_S):
215215
def _scan_value_range(self, table, start, count):
216216
result = None
217217
if table == 'input':
218-
result = self._mb.read_input_registers(start, count, unit=self._unit)
218+
result = self._mb.read_input_registers(address=start, count=count, device_id=self._unit)
219219
elif table == 'holding':
220-
result = self._mb.read_holding_registers(start, count, unit=self._unit)
220+
result = self._mb.read_holding_registers(address=start, count=count, device_id=self._unit)
221221
try:
222222
return result.registers
223223
except:

tests/test_modbus.py

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ def setUp(self):
2828
def tearDown(self):
2929
pass
3030

31-
def read_input_registers(self, start, count, unit):
32-
return self.modbusRegister(registers=self.input_registers.registers[start:start+count])
31+
def read_input_registers(self, address, count, device_id):
32+
return self.modbusRegister(registers=self.input_registers.registers[address:address+count])
3333

34-
def read_holding_registers(self, start, count, unit):
35-
return self.modbusRegister(registers=self.holding_registers.registers[start:start+count])
34+
def read_holding_registers(self, address, count, device_id):
35+
return self.modbusRegister(registers=self.holding_registers.registers[address:address+count])
3636

37-
def write_holding_register(self, address, value, unit):
37+
def write_holding_register(self, address, value, device_id):
3838
self.holding_registers.registers[address] = value
3939

40-
def write_holding_registers(self, address, values, unit):
40+
def write_holding_registers(self, address, values, device_id):
4141
self.assertEqual(len(values), 1)
4242
self.holding_registers.registers[address] = values[0]
4343

@@ -47,7 +47,7 @@ def connect_success(self):
4747
def connect_failure(self):
4848
return True
4949

50-
def throw_exception(self, addr, value, unit):
50+
def throw_exception(self, address, value, device_id):
5151
raise ValueError('Oh noooo!')
5252

5353
def perform_variant_test(self, mock_modbus, variant, expected_framer):
@@ -57,16 +57,16 @@ def perform_variant_test(self, mock_modbus, variant, expected_framer):
5757

5858
m = modbus_interface.modbus_interface(ip='1.1.1.1', port=111, variant=variant)
5959
m.connect()
60-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=expected_framer, retries=1, timeout=1)
60+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=expected_framer, retries=1, timeout=1)
6161

6262
def test_connection_variants(self):
6363
with patch('modbus4mqtt.modbus_interface.ModbusTcpClient') as mock_modbus:
64-
self.perform_variant_test(mock_modbus, None, modbus_interface.FramerSocket)
65-
self.perform_variant_test(mock_modbus, 'tcp', modbus_interface.FramerSocket)
66-
self.perform_variant_test(mock_modbus, 'rtu-over-tcp', modbus_interface.FramerRTU)
64+
self.perform_variant_test(mock_modbus, None, modbus_interface.FramerType.SOCKET)
65+
self.perform_variant_test(mock_modbus, 'tcp', modbus_interface.FramerType.SOCKET)
66+
self.perform_variant_test(mock_modbus, 'rtu-over-tcp', modbus_interface.FramerType.RTU)
6767
with patch('modbus4mqtt.modbus_interface.ModbusUdpClient') as mock_modbus:
68-
self.perform_variant_test(mock_modbus, 'udp', modbus_interface.FramerSocket)
69-
self.perform_variant_test(mock_modbus, 'rtu-over-udp', modbus_interface.FramerRTU)
68+
self.perform_variant_test(mock_modbus, 'udp', modbus_interface.FramerType.SOCKET)
69+
self.perform_variant_test(mock_modbus, 'rtu-over-udp', modbus_interface.FramerType.RTU)
7070

7171
m = modbus_interface.modbus_interface(ip='1.1.1.1', port=111, variant='notexisiting')
7272
self.assertRaises(ValueError, m.connect)
@@ -82,7 +82,7 @@ def test_connect(self):
8282

8383
m = modbus_interface.modbus_interface(ip='1.1.1.1', port=111)
8484
m.connect()
85-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=modbus_interface.FramerSocket, retries=1, timeout=1)
85+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=modbus_interface.FramerType.SOCKET, retries=1, timeout=1)
8686

8787
# Confirm registers are added to the correct tables.
8888
m.add_monitor_register('holding', 5)
@@ -97,14 +97,16 @@ def test_connect(self):
9797
self.assertEqual(m.get_value('holding', 5), 5)
9898
self.assertEqual(m.get_value('input', 6), 6)
9999

100+
100101
# Ensure we read a batch of DEFAULT_SCAN_BATCHING registers even though we only
101102
# added one register in each table as interesting
102-
mock_modbus().read_holding_registers.assert_any_call(0, 10, unit=1)
103-
mock_modbus().read_input_registers.assert_any_call(0, 10, unit=1)
103+
mock_modbus().read_holding_registers.assert_any_call(address=0, count=10, device_id=1)
104+
mock_modbus().read_input_registers.assert_any_call(address=0, count=10, device_id=1)
104105

105106
m.set_value('holding', 5, 7)
106107
m.poll()
107-
mock_modbus().write_register.assert_any_call(5, 7, unit=1)
108+
109+
mock_modbus().write_register.assert_any_call(address=5, value=7, device_id=1)
108110

109111
self.assertRaises(ValueError, m.set_value, 'input', 5, 7)
110112

@@ -120,10 +122,10 @@ def test_connect(self):
120122

121123
m.poll()
122124

123-
mock_modbus().read_holding_registers.assert_any_call(0, 10, unit=1)
124-
mock_modbus().read_holding_registers.assert_any_call(10, 10, unit=1)
125-
mock_modbus().read_input_registers.assert_any_call(0, 10, unit=1)
126-
mock_modbus().read_input_registers.assert_any_call(10, 10, unit=1)
125+
mock_modbus().read_holding_registers.assert_any_call(address=0, count=10, device_id=1)
126+
mock_modbus().read_holding_registers.assert_any_call(address=10, count=10, device_id=1)
127+
mock_modbus().read_input_registers.assert_any_call(address=0, count=10, device_id=1)
128+
mock_modbus().read_input_registers.assert_any_call(address=10, count=10, device_id=1)
127129

128130
def test_invalid_tables_and_addresses(self):
129131
with patch('modbus4mqtt.modbus_interface.ModbusTcpClient') as mock_modbus:
@@ -154,8 +156,8 @@ def test_write_queuing(self):
154156
mock_modbus().write_register.assert_not_called()
155157
m._writing = False
156158
m.set_value('holding', 6, 8)
157-
mock_modbus().write_register.assert_any_call(5, 7, unit=1)
158-
mock_modbus().write_register.assert_any_call(6, 8, unit=1)
159+
mock_modbus().write_register.assert_any_call(address=5, value=7, device_id=1)
160+
mock_modbus().write_register.assert_any_call(address=6, value=8, device_id=1)
159161

160162
def test_exception_on_write(self):
161163
with patch('modbus4mqtt.modbus_interface.ModbusTcpClient') as mock_modbus:
@@ -203,7 +205,7 @@ def test_scan_batching_of_one(self):
203205

204206
m = modbus_interface.modbus_interface('1.1.1.1', 111, 2, scan_batching=1)
205207
m.connect()
206-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=modbus_interface.FramerSocket, retries=1, timeout=1)
208+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=modbus_interface.FramerType.SOCKET, retries=1, timeout=1)
207209

208210
# Confirm registers are added to the correct tables.
209211
m.add_monitor_register('holding', 5)
@@ -219,10 +221,10 @@ def test_scan_batching_of_one(self):
219221
self.assertEqual(m.get_value('input', 7), 7)
220222

221223
# Ensure each register is scanned with a separate read call.
222-
mock_modbus().read_holding_registers.assert_any_call(5, 1, unit=1)
223-
mock_modbus().read_holding_registers.assert_any_call(6, 1, unit=1)
224-
mock_modbus().read_input_registers.assert_any_call(6, 1, unit=1)
225-
mock_modbus().read_input_registers.assert_any_call(7, 1, unit=1)
224+
mock_modbus().read_holding_registers.assert_any_call(address=5, count=1, device_id=1)
225+
mock_modbus().read_holding_registers.assert_any_call(address=6, count=1, device_id=1)
226+
mock_modbus().read_input_registers.assert_any_call(address=6, count=1, device_id=1)
227+
mock_modbus().read_input_registers.assert_any_call(address=7, count=1, device_id=1)
226228

227229
def test_scan_batching_bad_value(self):
228230
with patch('modbus4mqtt.modbus_interface.ModbusTcpClient') as mock_modbus:
@@ -290,7 +292,7 @@ def test_multi_byte_write_counts(self):
290292
m = modbus_interface.modbus_interface('1.1.1.1', 111, 2, word_order=modbus_interface.WordOrder.HighLow)
291293
# m = modbus_interface.modbus_interface('1.1.1.1', 111, 2, word_order=modbus_interface.WordOrder.LowHigh)
292294
m.connect()
293-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=modbus_interface.FramerSocket, retries=1, timeout=1)
295+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=modbus_interface.FramerType.SOCKET, retries=1, timeout=1)
294296

295297
for i in range(1,11):
296298
m.add_monitor_register('holding', i)
@@ -300,23 +302,23 @@ def test_multi_byte_write_counts(self):
300302
m.set_value('holding', 1, 65535, 0xFFFF, 'uint16')
301303
m.poll()
302304
# Confirm that it only wrote one register.
303-
mock_modbus().write_register.assert_any_call(1, 65535, unit=1)
305+
mock_modbus().write_register.assert_any_call(address=1, value=65535, device_id=1)
304306
mock_modbus().reset_mock()
305307

306308
m.set_value('holding', 1, 689876135, 0xFFFF, 'uint32')
307309
m.poll()
308310

309-
mock_modbus().write_register.assert_any_call(1, int.from_bytes(b'\x29\x1E','big'), unit=1)
310-
mock_modbus().write_register.assert_any_call(2, int.from_bytes(b'\xAC\xA7','big'), unit=1)
311+
mock_modbus().write_register.assert_any_call(address=1, value=int.from_bytes(b'\x29\x1E','big'), device_id=1)
312+
mock_modbus().write_register.assert_any_call(address=2, value=int.from_bytes(b'\xAC\xA7','big'), device_id=1)
311313
mock_modbus().reset_mock()
312314

313315
m.set_value('holding', 1, 5464681683516384647, 0xFFFF, 'uint64')
314316
m.poll()
315317

316-
mock_modbus().write_register.assert_any_call(1, int.from_bytes(b'\x4B\xD6','big'), unit=1)
317-
mock_modbus().write_register.assert_any_call(2, int.from_bytes(b'\x73\x09','big'), unit=1)
318-
mock_modbus().write_register.assert_any_call(3, int.from_bytes(b'\xBC\x93','big'), unit=1)
319-
mock_modbus().write_register.assert_any_call(4, int.from_bytes(b'\xE5\x87','big'), unit=1)
318+
mock_modbus().write_register.assert_any_call(address=1, value=int.from_bytes(b'\x4B\xD6','big'), device_id=1)
319+
mock_modbus().write_register.assert_any_call(address=2, value=int.from_bytes(b'\x73\x09','big'), device_id=1)
320+
mock_modbus().write_register.assert_any_call(address=3, value=int.from_bytes(b'\xBC\x93','big'), device_id=1)
321+
mock_modbus().write_register.assert_any_call(address=4, value=int.from_bytes(b'\xE5\x87','big'), device_id=1)
320322
mock_modbus().reset_mock()
321323

322324
def test_multi_byte_write_counts_LowHigh_order(self):
@@ -325,24 +327,24 @@ def test_multi_byte_write_counts_LowHigh_order(self):
325327

326328
m = modbus_interface.modbus_interface('1.1.1.1', 111, 2, word_order=modbus_interface.WordOrder.LowHigh)
327329
m.connect()
328-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=modbus_interface.FramerSocket, retries=1, timeout=1)
330+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=modbus_interface.FramerType.SOCKET, retries=1, timeout=1)
329331

330332
for i in range(1,11):
331333
m.add_monitor_register('holding', i)
332334
m.set_value('holding', 1, 689876135, 0xFFFF, 'uint32')
333335
m.poll()
334336

335-
mock_modbus().write_register.assert_any_call(1, int.from_bytes(b'\xAC\xA7','big'), unit=1)
336-
mock_modbus().write_register.assert_any_call(2, int.from_bytes(b'\x29\x1E','big'), unit=1)
337+
mock_modbus().write_register.assert_any_call(address=1, value=int.from_bytes(b'\xAC\xA7','big'), device_id=1)
338+
mock_modbus().write_register.assert_any_call(address=2, value=int.from_bytes(b'\x29\x1E','big'), device_id=1)
337339
mock_modbus().reset_mock()
338340

339341
m.set_value('holding', 1, 5464681683516384647, 0xFFFF, 'uint64')
340342
m.poll()
341343

342-
mock_modbus().write_register.assert_any_call(1, int.from_bytes(b'\xE5\x87','big'), unit=1)
343-
mock_modbus().write_register.assert_any_call(2, int.from_bytes(b'\xBC\x93','big'), unit=1)
344-
mock_modbus().write_register.assert_any_call(3, int.from_bytes(b'\x73\x09','big'), unit=1)
345-
mock_modbus().write_register.assert_any_call(4, int.from_bytes(b'\x4B\xD6','big'), unit=1)
344+
mock_modbus().write_register.assert_any_call(address=1, value=int.from_bytes(b'\xE5\x87','big'), device_id=1)
345+
mock_modbus().write_register.assert_any_call(address=2, value=int.from_bytes(b'\xBC\x93','big'), device_id=1)
346+
mock_modbus().write_register.assert_any_call(address=3, value=int.from_bytes(b'\x73\x09','big'), device_id=1)
347+
mock_modbus().write_register.assert_any_call(address=4, value=int.from_bytes(b'\x4B\xD6','big'), device_id=1)
346348
mock_modbus().reset_mock()
347349

348350
def perform_multi_byte_read_write_values_test(self, write_mode):
@@ -354,7 +356,7 @@ def perform_multi_byte_read_write_values_test(self, write_mode):
354356

355357
m = modbus_interface.modbus_interface('1.1.1.1', 111, 2, scan_batching=1, write_mode=write_mode)
356358
m.connect()
357-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=modbus_interface.FramerSocket, retries=1, timeout=1)
359+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=modbus_interface.FramerType.SOCKET, retries=1, timeout=1)
358360

359361
for i in range(1,11):
360362
m.add_monitor_register('holding', i)
@@ -395,7 +397,7 @@ def test_multi_byte_read_write_values_LowHigh(self):
395397

396398
m = modbus_interface.modbus_interface('1.1.1.1', 111, 2, scan_batching=1, word_order=modbus_interface.WordOrder.LowHigh)
397399
m.connect()
398-
mock_modbus.assert_called_with(host='1.1.1.1', port=111, RetryOnEmpty=True, framer=modbus_interface.FramerSocket, retries=1, timeout=1)
400+
mock_modbus.assert_called_with(host='1.1.1.1', port=111, framer=modbus_interface.FramerType.SOCKET, retries=1, timeout=1)
399401

400402
for i in range(1,11):
401403
m.add_monitor_register('holding', i)

0 commit comments

Comments
 (0)