0
# Client Operations
1
2
TCP client functionality for connecting to and communicating with Modbus servers. The ModbusClient class provides synchronous communication with automatic connection management, comprehensive error handling, and support for all standard Modbus function codes.
3
4
## Capabilities
5
6
### ModbusClient Class
7
8
Main client class for Modbus/TCP communication with automatic connection management and comprehensive error handling.
9
10
```python { .api }
11
class ModbusClient:
12
"""
13
Modbus TCP client with automatic connection management.
14
15
Parameters:
16
host (str): Hostname or IPv4/IPv6 address (default: 'localhost')
17
port (int): TCP port number (default: 502)
18
unit_id (int): Unit ID for requests (default: 1)
19
timeout (float): Socket timeout in seconds (default: 30.0)
20
auto_open (bool): Automatically open connection when needed (default: True)
21
auto_close (bool): Automatically close connection after each request (default: False)
22
"""
23
def __init__(self, host='localhost', port=502, unit_id=1, timeout=30.0, auto_open=True, auto_close=False):
24
"""Initialize Modbus TCP client."""
25
```
26
27
#### Connection Management
28
29
```python { .api }
30
def open(self):
31
"""
32
Open TCP connection to server.
33
34
Returns:
35
bool: True if connection successful, False otherwise
36
"""
37
38
def close(self):
39
"""Close TCP connection."""
40
41
@property
42
def is_open(self):
43
"""bool: True if TCP connection is open, False otherwise (read-only)."""
44
```
45
46
#### Properties
47
48
```python { .api }
49
@property
50
def host(self):
51
"""str: Server hostname or IP address."""
52
53
@property
54
def port(self):
55
"""int: TCP port number."""
56
57
@property
58
def unit_id(self):
59
"""int: Unit ID for Modbus requests."""
60
61
@property
62
def timeout(self):
63
"""float: Socket timeout in seconds."""
64
65
@property
66
def auto_open(self):
67
"""bool: Automatic connection opening enabled."""
68
69
@property
70
def auto_close(self):
71
"""bool: Automatic connection closing enabled."""
72
73
@property
74
def version(self):
75
"""str: Package version (read-only)."""
76
77
@property
78
def last_error(self):
79
"""int: Last error code (read-only)."""
80
81
@property
82
def last_error_as_txt(self):
83
"""str: Last error as text (read-only)."""
84
85
@property
86
def last_except(self):
87
"""int: Last Modbus exception code (read-only)."""
88
89
@property
90
def last_except_as_txt(self):
91
"""str: Last exception as short text (read-only)."""
92
93
@property
94
def last_except_as_full_txt(self):
95
"""str: Last exception as detailed text (read-only)."""
96
```
97
98
### Reading Functions
99
100
Functions for reading data from Modbus servers using standard function codes.
101
102
```python { .api }
103
def read_coils(self, bit_addr, bit_nb=1):
104
"""
105
Read coils (function code 1).
106
107
Parameters:
108
bit_addr (int): Starting coil address (0-65535)
109
bit_nb (int): Number of coils to read (1-2000, default: 1)
110
111
Returns:
112
list[bool] or None: List of coil values, None on error
113
"""
114
115
def read_discrete_inputs(self, bit_addr, bit_nb=1):
116
"""
117
Read discrete inputs (function code 2).
118
119
Parameters:
120
bit_addr (int): Starting input address (0-65535)
121
bit_nb (int): Number of inputs to read (1-2000, default: 1)
122
123
Returns:
124
list[bool] or None: List of input values, None on error
125
"""
126
127
def read_holding_registers(self, reg_addr, reg_nb=1):
128
"""
129
Read holding registers (function code 3).
130
131
Parameters:
132
reg_addr (int): Starting register address (0-65535)
133
reg_nb (int): Number of registers to read (1-125, default: 1)
134
135
Returns:
136
list[int] or None: List of register values (0-65535), None on error
137
"""
138
139
def read_input_registers(self, reg_addr, reg_nb=1):
140
"""
141
Read input registers (function code 4).
142
143
Parameters:
144
reg_addr (int): Starting register address (0-65535)
145
reg_nb (int): Number of registers to read (1-125, default: 1)
146
147
Returns:
148
list[int] or None: List of register values (0-65535), None on error
149
"""
150
```
151
152
### Writing Functions
153
154
Functions for writing data to Modbus servers using standard function codes.
155
156
```python { .api }
157
def write_single_coil(self, bit_addr, bit_value):
158
"""
159
Write single coil (function code 5).
160
161
Parameters:
162
bit_addr (int): Coil address (0-65535)
163
bit_value (bool): Value to write
164
165
Returns:
166
bool: True on success, False on error
167
"""
168
169
def write_single_register(self, reg_addr, reg_value):
170
"""
171
Write single register (function code 6).
172
173
Parameters:
174
reg_addr (int): Register address (0-65535)
175
reg_value (int): Value to write (0-65535)
176
177
Returns:
178
bool: True on success, False on error
179
"""
180
181
def write_multiple_coils(self, bits_addr, bits_value):
182
"""
183
Write multiple coils (function code 15).
184
185
Parameters:
186
bits_addr (int): Starting coil address (0-65535)
187
bits_value (list[bool]): List of coil values to write
188
189
Returns:
190
bool: True on success, False on error
191
"""
192
193
def write_multiple_registers(self, regs_addr, regs_value):
194
"""
195
Write multiple registers (function code 16).
196
197
Parameters:
198
regs_addr (int): Starting register address (0-65535)
199
regs_value (list[int]): List of register values to write (0-65535)
200
201
Returns:
202
bool: True on success, False on error
203
"""
204
205
def write_read_multiple_registers(self, write_addr, write_values, read_addr, read_nb=1):
206
"""
207
Write and read multiple registers (function code 23).
208
209
Parameters:
210
write_addr (int): Starting write address (0-65535)
211
write_values (list[int]): List of values to write (0-65535)
212
read_addr (int): Starting read address (0-65535)
213
read_nb (int): Number of registers to read (1-125, default: 1)
214
215
Returns:
216
list[int] or None: List of read register values, None on error
217
"""
218
```
219
220
### Device Identification
221
222
Functions for reading device identification information.
223
224
```python { .api }
225
def read_device_identification(self, read_code=1, object_id=0):
226
"""
227
Read device identification (function code 43).
228
229
Parameters:
230
read_code (int): Read device ID code (1-4, default: 1)
231
1: Basic identification (mandatory objects)
232
2: Regular identification (basic + optional)
233
3: Extended identification (regular + private)
234
4: Individual object access
235
object_id (int): Object ID when read_code=4 (0-255, default: 0)
236
237
Returns:
238
DeviceIdentificationResponse or None: Device identification response, None on error
239
"""
240
```
241
242
### Advanced Operations
243
244
```python { .api }
245
def custom_request(self, pdu):
246
"""
247
Send custom PDU request.
248
249
Parameters:
250
pdu (bytes): Protocol Data Unit to send
251
252
Returns:
253
bytes or None: Response PDU, None on error
254
"""
255
256
def on_tx_rx(self, frame, is_tx):
257
"""
258
Hook for transmission/reception events (override in subclass).
259
260
Parameters:
261
frame (bytes): Frame data
262
is_tx (bool): True for transmission, False for reception
263
"""
264
```
265
266
## Usage Examples
267
268
### Basic Client Usage
269
270
```python
271
from pyModbusTCP.client import ModbusClient
272
273
# Create client with automatic connection
274
client = ModbusClient(host="192.168.1.100", port=502, unit_id=1, auto_open=True)
275
276
# Read holding registers
277
values = client.read_holding_registers(0, 10)
278
if values:
279
print(f"Register values: {values}")
280
else:
281
print(f"Error: {client.last_error_as_txt}")
282
283
# Write and verify
284
success = client.write_single_register(100, 1234)
285
if success:
286
result = client.read_holding_registers(100, 1)
287
print(f"Written value: {result[0] if result else 'read failed'}")
288
```
289
290
### Manual Connection Management
291
292
```python
293
from pyModbusTCP.client import ModbusClient
294
295
# Create client without automatic connection
296
client = ModbusClient(host="192.168.1.100", auto_open=False)
297
298
# Manual connection management
299
if client.open():
300
print("Connected successfully")
301
302
# Perform operations
303
coils = client.read_coils(0, 16)
304
if coils:
305
print(f"Coils: {coils}")
306
307
# Close when done
308
client.close()
309
else:
310
print(f"Connection failed: {client.last_error_as_txt}")
311
```
312
313
### Device Identification
314
315
```python
316
from pyModbusTCP.client import ModbusClient
317
318
client = ModbusClient(host="192.168.1.100", auto_open=True)
319
320
# Read basic device identification
321
device_id = client.read_device_identification(read_code=1)
322
if device_id:
323
print(f"Vendor: {device_id.vendor_name}")
324
print(f"Product: {device_id.product_name}")
325
print(f"Version: {device_id.major_minor_revision}")
326
else:
327
print(f"Device identification failed: {client.last_error_as_txt}")
328
```
329
330
### Working with Floating Point Values
331
332
```python
333
from pyModbusTCP.client import ModbusClient
334
from pyModbusTCP.utils import decode_ieee, encode_ieee, word_list_to_long, long_list_to_word
335
336
client = ModbusClient(host="192.168.1.100", auto_open=True)
337
338
# Read IEEE 754 float from two registers
339
registers = client.read_holding_registers(0, 2)
340
if registers:
341
# Convert registers to 32-bit integer
342
float_as_int = word_list_to_long(registers, big_endian=True)[0]
343
# Decode as IEEE 754 float
344
float_value = decode_ieee(float_as_int)
345
print(f"Float value: {float_value}")
346
347
# Write IEEE 754 float to two registers
348
float_to_write = 123.456
349
# Encode as IEEE 754
350
float_as_int = encode_ieee(float_to_write)
351
# Convert to register list
352
registers = long_list_to_word([float_as_int], big_endian=True)
353
# Write to device
354
success = client.write_multiple_registers(0, registers)
355
if success:
356
print("Float written successfully")
357
```
358
359
## Exception Classes
360
361
```python { .api }
362
class ModbusClient._InternalError(Exception):
363
"""Base class for internal client errors."""
364
365
class ModbusClient._NetworkError(_InternalError):
366
"""
367
Network-related errors during Modbus communication.
368
369
Attributes:
370
code (int): Error code from MB_ERR constants
371
message (str): Error message
372
"""
373
374
class ModbusClient._ModbusExcept(_InternalError):
375
"""
376
Modbus protocol exceptions from server responses.
377
378
Attributes:
379
code (int): Exception code from EXP constants
380
"""
381
```
382
383
## Types
384
385
```python { .api }
386
class DeviceIdentificationResponse:
387
"""
388
Response object for device identification queries.
389
390
Attributes:
391
conformity_level (int): Supported access and object type
392
more_follows (int): Indicates if more objects are available (0x00 or 0xFF)
393
next_object_id (int): Next object ID for following transaction
394
objects_by_id (dict): Dictionary with requested objects (key: object_id, value: bytes)
395
396
Properties (read-only):
397
vendor_name (bytes): Vendor name (object ID 0x00)
398
product_code (bytes): Product code (object ID 0x01)
399
major_minor_revision (bytes): Major/minor revision (object ID 0x02)
400
vendor_url (bytes): Vendor URL (object ID 0x03)
401
product_name (bytes): Product name (object ID 0x04)
402
model_name (bytes): Model name (object ID 0x05)
403
user_application_name (bytes): User application name (object ID 0x06)
404
"""
405
```