or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client.mddatastore.mdindex.mdpdu.mdserver.md

client.mddocs/

0

# Client Operations

1

2

PyModbus provides comprehensive client implementations supporting all standard Modbus function codes. Clients are available in both synchronous and asynchronous variants across multiple transport protocols (TCP, UDP, Serial, TLS).

3

4

## Capabilities

5

6

### Client Classes

7

8

PyModbus offers dedicated client classes for each transport protocol in both synchronous and asynchronous variants.

9

10

```python { .api }

11

# Synchronous client classes

12

class ModbusTcpClient:

13

def __init__(self, host="127.0.0.1", port=502, framer=FramerType.SOCKET,

14

timeout=3, retries=3, retry_on_empty=False, close_comm_on_error=False,

15

strict=True, source_address=None, **kwargs): ...

16

def connect(self) -> bool: ...

17

def close(self) -> None: ...

18

19

class ModbusUdpClient:

20

def __init__(self, host="127.0.0.1", port=502, framer=FramerType.SOCKET,

21

timeout=3, retries=3, retry_on_empty=False, **kwargs): ...

22

def connect(self) -> bool: ...

23

def close(self) -> None: ...

24

25

class ModbusSerialClient:

26

def __init__(self, port=None, framer=FramerType.RTU, timeout=3, retries=3,

27

retry_on_empty=False, close_comm_on_error=False, strict=True,

28

baudrate=19200, bytesize=8, parity="N", stopbits=1, **kwargs): ...

29

def connect(self) -> bool: ...

30

def close(self) -> None: ...

31

32

class ModbusTlsClient:

33

def __init__(self, host="127.0.0.1", port=802, framer=FramerType.TLS,

34

timeout=3, retries=3, sslctx=None, certfile=None, keyfile=None,

35

password=None, server_hostname=None, **kwargs): ...

36

def connect(self) -> bool: ...

37

def close(self) -> None: ...

38

39

# Asynchronous client classes

40

class AsyncModbusTcpClient:

41

def __init__(self, host="127.0.0.1", port=502, framer=FramerType.SOCKET,

42

timeout=3, retries=3, retry_on_empty=False, close_comm_on_error=False,

43

strict=True, source_address=None, **kwargs): ...

44

async def connect(self) -> bool: ...

45

def close(self) -> None: ...

46

47

class AsyncModbusUdpClient:

48

def __init__(self, host="127.0.0.1", port=502, framer=FramerType.SOCKET,

49

timeout=3, retries=3, retry_on_empty=False, **kwargs): ...

50

async def connect(self) -> bool: ...

51

def close(self) -> None: ...

52

53

class AsyncModbusSerialClient:

54

def __init__(self, port=None, framer=FramerType.RTU, timeout=3, retries=3,

55

retry_on_empty=False, close_comm_on_error=False, strict=True,

56

baudrate=19200, bytesize=8, parity="N", stopbits=1, **kwargs): ...

57

async def connect(self) -> bool: ...

58

def close(self) -> None: ...

59

60

class AsyncModbusTlsClient:

61

def __init__(self, host="127.0.0.1", port=802, framer=FramerType.TLS,

62

timeout=3, retries=3, sslctx=None, certfile=None, keyfile=None,

63

password=None, server_hostname=None, **kwargs): ...

64

async def connect(self) -> bool: ...

65

def close(self) -> None: ...

66

```

67

68

### Base Client Classes and Mixin

69

70

All client classes inherit core functionality from base classes and the ModbusClientMixin providing standard Modbus operations.

71

72

```python { .api }

73

# Base client classes

74

class ModbusBaseClient:

75

"""Base asynchronous client class."""

76

def __init__(self, framer=None, **kwargs): ...

77

def connect(self) -> bool: ...

78

def close(self) -> None: ...

79

def execute(self, request) -> ModbusResponse: ...

80

def register(self, custom_response_class): ...

81

def set_max_no_responses(self, count: int): ...

82

83

class ModbusBaseSyncClient:

84

"""Base synchronous client class."""

85

def __init__(self, framer=None, **kwargs): ...

86

def connect(self) -> bool: ...

87

def close(self) -> None: ...

88

def execute(self, request) -> ModbusResponse: ...

89

def register(self, custom_response_class): ...

90

def set_max_no_responses(self, count: int): ...

91

92

class ModbusClientMixin:

93

"""

94

Mixin class providing all Modbus function code methods.

95

All client classes inherit from this mixin to provide standard operations.

96

"""

97

# Note: All the operation methods below (coils, registers, etc.)

98

# are provided by this mixin class

99

```

100

101

### Connection Management Methods

102

103

```python { .api }

104

def connect(self) -> bool: ...

105

def close(self) -> None: ...

106

def is_socket_open(self) -> bool: ...

107

```

108

109

### Coil Operations

110

111

Functions for reading and writing coil (binary) values.

112

113

```python { .api }

114

def read_coils(self, address, count=1, device_id=0) -> ReadCoilsResponse:

115

"""

116

Read coil status (FC 01).

117

118

Parameters:

119

- address (int): Starting address

120

- count (int): Number of coils to read

121

- device_id (int): Device identifier

122

123

Returns:

124

ReadCoilsResponse with .bits attribute containing list of boolean values

125

"""

126

127

def write_coil(self, address, value, device_id=0) -> WriteSingleCoilResponse:

128

"""

129

Write single coil (FC 05).

130

131

Parameters:

132

- address (int): Coil address

133

- value (bool): Coil value

134

- device_id (int): Device identifier

135

136

Returns:

137

WriteSingleCoilResponse

138

"""

139

140

def write_coils(self, address, values, device_id=0) -> WriteMultipleCoilsResponse:

141

"""

142

Write multiple coils (FC 15).

143

144

Parameters:

145

- address (int): Starting address

146

- values (list): List of boolean values

147

- device_id (int): Device identifier

148

149

Returns:

150

WriteMultipleCoilsResponse

151

"""

152

```

153

154

### Discrete Input Operations

155

156

Functions for reading discrete input values.

157

158

```python { .api }

159

def read_discrete_inputs(self, address, count=1, device_id=0) -> ReadDiscreteInputsResponse:

160

"""

161

Read discrete input status (FC 02).

162

163

Parameters:

164

- address (int): Starting address

165

- count (int): Number of inputs to read

166

- device_id (int): Device identifier

167

168

Returns:

169

ReadDiscreteInputsResponse with .bits attribute containing list of boolean values

170

"""

171

```

172

173

### Register Operations

174

175

Functions for reading and writing register (16-bit integer) values.

176

177

```python { .api }

178

def read_holding_registers(self, address, count=1, device_id=0) -> ReadHoldingRegistersResponse:

179

"""

180

Read holding registers (FC 03).

181

182

Parameters:

183

- address (int): Starting address

184

- count (int): Number of registers to read

185

- device_id (int): Device identifier

186

187

Returns:

188

ReadHoldingRegistersResponse with .registers attribute containing list of int values

189

"""

190

191

def read_input_registers(self, address, count=1, device_id=0) -> ReadInputRegistersResponse:

192

"""

193

Read input registers (FC 04).

194

195

Parameters:

196

- address (int): Starting address

197

- count (int): Number of registers to read

198

- device_id (int): Device identifier

199

200

Returns:

201

ReadInputRegistersResponse with .registers attribute containing list of int values

202

"""

203

204

def write_register(self, address, value, device_id=0) -> WriteSingleRegisterResponse:

205

"""

206

Write single register (FC 06).

207

208

Parameters:

209

- address (int): Register address

210

- value (int): Register value (0-65535)

211

- device_id (int): Device identifier

212

213

Returns:

214

WriteSingleRegisterResponse

215

"""

216

217

def write_registers(self, address, values, device_id=0) -> WriteMultipleRegistersResponse:

218

"""

219

Write multiple registers (FC 16).

220

221

Parameters:

222

- address (int): Starting address

223

- values (list): List of register values

224

- device_id (int): Device identifier

225

226

Returns:

227

WriteMultipleRegistersResponse

228

"""

229

230

def readwrite_registers(self, read_address, read_count, write_address, write_registers, device_id=0) -> ReadWriteMultipleRegistersResponse:

231

"""

232

Read and write multiple registers in single transaction (FC 23).

233

234

Parameters:

235

- read_address (int): Starting read address

236

- read_count (int): Number of registers to read

237

- write_address (int): Starting write address

238

- write_registers (list): Values to write

239

- device_id (int): Device identifier

240

241

Returns:

242

ReadWriteMultipleRegistersResponse with .registers attribute

243

"""

244

245

def mask_write_register(self, address, and_mask, or_mask, device_id=0) -> MaskWriteRegisterResponse:

246

"""

247

Mask write register (FC 22).

248

249

Parameters:

250

- address (int): Register address

251

- and_mask (int): AND mask

252

- or_mask (int): OR mask

253

- device_id (int): Device identifier

254

255

Returns:

256

MaskWriteRegisterResponse

257

"""

258

```

259

260

### File Record Operations

261

262

Functions for reading and writing file records.

263

264

```python { .api }

265

def read_file_record(self, records, device_id=0) -> ReadFileRecordResponse:

266

"""

267

Read file record (FC 20).

268

269

Parameters:

270

- records (list): List of file record requests

271

- device_id (int): Device identifier

272

273

Returns:

274

ReadFileRecordResponse

275

"""

276

277

def write_file_record(self, records, device_id=0) -> WriteFileRecordResponse:

278

"""

279

Write file record (FC 21).

280

281

Parameters:

282

- records (list): List of file record data

283

- device_id (int): Device identifier

284

285

Returns:

286

WriteFileRecordResponse

287

"""

288

289

def read_fifo_queue(self, address, device_id=0) -> ReadFifoQueueResponse:

290

"""

291

Read FIFO queue (FC 24).

292

293

Parameters:

294

- address (int): FIFO pointer address

295

- device_id (int): Device identifier

296

297

Returns:

298

ReadFifoQueueResponse

299

"""

300

```

301

302

### Diagnostic Operations

303

304

Functions for device diagnostics and status reporting.

305

306

```python { .api }

307

def diag_read_diagnostic_register(self, device_id=0) -> DiagnosticStatusResponse:

308

"""Read diagnostic register."""

309

310

def diag_change_ascii_input_delimiter(self, device_id=0) -> DiagnosticStatusResponse:

311

"""Change ASCII input delimiter."""

312

313

def diag_force_listen_only_mode(self, device_id=0) -> DiagnosticStatusResponse:

314

"""Force listen only mode."""

315

316

def diag_clear_counters(self, device_id=0) -> DiagnosticStatusResponse:

317

"""Clear counters and diagnostic register."""

318

319

def diag_read_bus_message_count(self, device_id=0) -> DiagnosticStatusResponse:

320

"""Read bus message count."""

321

322

def diag_read_bus_comm_error_count(self, device_id=0) -> DiagnosticStatusResponse:

323

"""Read bus communication error count."""

324

325

def diag_read_bus_exception_error_count(self, device_id=0) -> DiagnosticStatusResponse:

326

"""Read bus exception error count."""

327

328

def diag_read_device_message_count(self, device_id=0) -> DiagnosticStatusResponse:

329

"""Read device message count."""

330

331

def diag_read_device_no_response_count(self, device_id=0) -> DiagnosticStatusResponse:

332

"""Read device no response count."""

333

334

def diag_read_device_nak_count(self, device_id=0) -> DiagnosticStatusResponse:

335

"""Read device NAK count."""

336

337

def diag_read_device_busy_count(self, device_id=0) -> DiagnosticStatusResponse:

338

"""Read device busy count."""

339

340

def diag_read_bus_char_overrun_count(self, device_id=0) -> DiagnosticStatusResponse:

341

"""Read bus character overrun count."""

342

343

def diag_read_iop_overrun_count(self, device_id=0) -> DiagnosticStatusResponse:

344

"""Read IOP overrun count."""

345

346

def diag_clear_overrun_counter(self, device_id=0) -> DiagnosticStatusResponse:

347

"""Clear overrun counter and flag."""

348

349

def diag_get_clear_modbus_plus(self, device_id=0) -> DiagnosticStatusResponse:

350

"""Get/clear Modbus Plus statistics."""

351

```

352

353

### Device Information Operations

354

355

Functions for retrieving device information and identification.

356

357

```python { .api }

358

def read_device_information(self, read_code=None, object_id=0x00, device_id=0) -> ReadDeviceInformationResponse:

359

"""

360

Read device information (FC 43).

361

362

Parameters:

363

- read_code (int): Read device ID code (0x01, 0x02, 0x03, 0x04)

364

- object_id (int): Object ID to read

365

- device_id (int): Device identifier

366

367

Returns:

368

ReadDeviceInformationResponse with device information

369

"""

370

371

def report_device_id(self, device_id=0) -> ReportServerIdResponse:

372

"""

373

Report device identification (FC 17).

374

375

Parameters:

376

- device_id (int): Device identifier

377

378

Returns:

379

ReportServerIdResponse with device ID information

380

"""

381

```

382

383

### Event Operations

384

385

Functions for reading communication events and counters.

386

387

```python { .api }

388

def read_exception_status(self, device_id=0) -> ReadExceptionStatusResponse:

389

"""

390

Read exception status (FC 07).

391

392

Returns:

393

ReadExceptionStatusResponse with status byte

394

"""

395

396

def get_com_event_counter(self, device_id=0) -> GetCommEventCounterResponse:

397

"""

398

Get communication event counter (FC 11).

399

400

Returns:

401

GetCommEventCounterResponse with event count

402

"""

403

404

def get_com_event_log(self, device_id=0) -> GetCommEventLogResponse:

405

"""

406

Get communication event log (FC 12).

407

408

Returns:

409

GetCommEventLogResponse with event log data

410

"""

411

```

412

413

### Data Conversion Methods

414

415

Utility methods for converting between Python data types and Modbus register values.

416

417

```python { .api }

418

def convert_to_registers(self, value, data_type) -> list:

419

"""

420

Convert Python value to Modbus registers.

421

422

Parameters:

423

- value: Python value to convert

424

- data_type: Data type constant (INT16, INT32, FLOAT32, etc.)

425

426

Returns:

427

List of register values

428

"""

429

430

def convert_from_registers(self, registers, data_type):

431

"""

432

Convert Modbus registers to Python value.

433

434

Parameters:

435

- registers (list): List of register values

436

- data_type: Data type constant

437

438

Returns:

439

Converted Python value

440

"""

441

```

442

443

## Usage Examples

444

445

### TCP Client with Error Handling

446

447

```python

448

from pymodbus.client import ModbusTcpClient

449

from pymodbus import FramerType, ModbusException

450

451

client = ModbusTcpClient('192.168.1.10', port=502, framer=FramerType.SOCKET)

452

453

try:

454

if client.connect():

455

# Read holding registers

456

result = client.read_holding_registers(0, count=10, device_id=1)

457

if not result.isError():

458

print(f"Registers: {result.registers}")

459

else:

460

print(f"Error reading registers: {result}")

461

462

# Write multiple registers

463

values = [100, 200, 300, 400, 500]

464

result = client.write_registers(10, values, device_id=1)

465

if result.isError():

466

print(f"Error writing registers: {result}")

467

else:

468

print("Failed to connect to Modbus server")

469

470

except ModbusException as e:

471

print(f"Modbus exception: {e}")

472

finally:

473

client.close()

474

```

475

476

### Serial Client with RTU Framing

477

478

```python

479

from pymodbus.client import ModbusSerialClient

480

from pymodbus import FramerType

481

482

client = ModbusSerialClient(

483

port='/dev/ttyUSB0',

484

baudrate=9600,

485

bytesize=8,

486

parity='N',

487

stopbits=1,

488

framer=FramerType.RTU,

489

timeout=1

490

)

491

492

if client.connect():

493

try:

494

# Read coils

495

result = client.read_coils(0, count=16, device_id=1)

496

if not result.isError():

497

print(f"Coil states: {result.bits}")

498

499

# Write single coil

500

client.write_coil(5, True, device_id=1)

501

502

finally:

503

client.close()

504

```

505

506

### Async Client Pattern

507

508

```python

509

import asyncio

510

from pymodbus.client import AsyncModbusTcpClient

511

512

async def async_modbus_client():

513

client = AsyncModbusTcpClient('127.0.0.1', port=502)

514

515

try:

516

await client.connect()

517

518

# Read input registers

519

result = await client.read_input_registers(0, count=5, device_id=1)

520

if not result.isError():

521

print(f"Input registers: {result.registers}")

522

523

# Read/write operation

524

result = await client.readwrite_registers(

525

read_address=0, read_count=5,

526

write_address=10, write_registers=[1, 2, 3],

527

device_id=1

528

)

529

if not result.isError():

530

print(f"Read values: {result.registers}")

531

532

finally:

533

client.close()

534

535

# Run async client

536

asyncio.run(async_modbus_client())

537

```

538

539

### Data Type Conversion with Struct

540

541

```python

542

from pymodbus.client import ModbusTcpClient

543

import struct

544

545

client = ModbusTcpClient('127.0.0.1')

546

client.connect()

547

548

# Write float32 value using struct

549

float_value = 123.45

550

# Pack float as 2 registers (32-bit big-endian)

551

packed = struct.pack('>f', float_value)

552

registers = [struct.unpack('>H', packed[0:2])[0], struct.unpack('>H', packed[2:4])[0]]

553

client.write_registers(0, registers, device_id=1)

554

555

# Read float32 value

556

result = client.read_holding_registers(0, count=2, device_id=1)

557

if not result.isError():

558

# Unpack registers back to float

559

packed = struct.pack('>HH', result.registers[0], result.registers[1])

560

float_value = struct.unpack('>f', packed)[0]

561

print(f"Float value: {float_value}")

562

563

client.close()

564

```