Pymodbus
Pymodbus
Release 3.7.0dev
2 Client 11
2.1 Client performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2 Client protocols/framers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.1 Serial (RS-485) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.2 TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.3 TLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.4 UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Client usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.4 Client device addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.5 Client response handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6 Client interface classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6.1 Client serial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6.2 Client TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.6.3 Client TLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.6.4 Client UDP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.7 Modbus calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3 Server 33
4 REPL 39
4.1 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.2 Usage Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
i
4.3 DEMO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.4 REPL client classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.5 REPL server classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.5.1 Pymodbus REPL (Read Evaluate Print Loop) . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.5.1.1 Pymodbus REPL Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.5.1.2 Pymodbus REPL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5 Simulator 55
5.1 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.1.1 Json file layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.1.2 Server entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.1.3 Server configuration examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.1.4 Device entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.1.4.1 Setup section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.1.4.2 Invalid section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.1.4.3 Write section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.1.4.4 Bits section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.1.4.5 Uint16 section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.1.4.6 Uint32 section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.1.4.7 Float32 section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.1.4.8 String section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.1.4.9 Repeat section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.1.5 Device configuration examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.1.6 Configuration used for test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.2 Simulator datastore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.3 Web frontend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.3.1 pymodbus.simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.4 Pymodbus simulator ReST API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6 Examples 77
6.1 Ready to run examples: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.1.1 Simple asynchronous client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.1.2 Simple synchronous client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
6.1.3 Client performance sync vs async . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.2 Advanced examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.2.1 Client asynchronous calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.2.2 Client asynchronous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
6.2.3 Client calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.4 Client custom message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2.5 Client payload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2.6 Client synchronous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2.7 Server asynchronous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2.8 Server callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
6.2.9 Server tracer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
6.2.10 Server payload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
6.2.11 Server synchronous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
6.2.12 Server updating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
6.2.13 Simulator example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
6.2.14 Simulator datastore example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
6.2.15 Message generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.2.16 Message Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.2.17 Modbus forwarder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.3 Examples contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
6.3.1 Solar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
ii
6.3.2 Redis datastore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.3.3 Serial Forwarder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
6.3.4 Sqlalchemy datastore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7 Authors 93
7.1 Pymodbus version 3 family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
7.2 Pymodbus version 2 family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.3 Pymodbus version 1 family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.4 Pymodbus version 0 family . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
8 Changelog 99
8.1 Version 3.6.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.2 Version 3.6.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.3 Version 3.6.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.4 Version 3.6.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.5 Version 3.5.4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.6 Version 3.5.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.7 Version 3.5.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.8 Version 3.5.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
8.9 Version 3.5.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.10 Version 3.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.11 Version 3.4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.12 Version 3.3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
8.13 Version 3.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.14 Version 3.3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
8.15 Version 3.2.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.16 Version 3.2.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8.17 Version 3.2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
8.18 Version 3.1.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.19 Version 3.1.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8.20 Version 3.1.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
8.21 Version 3.1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
8.22 Version 3.0.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
8.23 Version 3.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
8.24 Version 3.0.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
8.25 Version 2.5.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
8.26 Version 2.5.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
8.27 Version 2.5.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
8.28 Version 2.5.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
8.29 Version 2.4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
8.30 Version 2.3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
8.31 Version 2.2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
8.32 Version 2.1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.33 Version 2.0.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.34 Version 2.0.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.35 Version 1.5.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.36 Version 1.5.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.37 Version 1.5.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
8.38 Version 1.4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
8.39 Version 1.3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
8.40 Version 1.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
8.41 Version 1.2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
8.42 Version 1.1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
8.43 Version 1.0.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
iii
9 API changes 121
9.1 API changes 3.6.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
9.2 API changes 3.5.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
9.3 API changes 3.4.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
9.4 API changes 3.3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.5 API changes 3.2.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.6 API changes 3.1.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
9.7 API changes 3.0.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Index 189
iv
PyModbus, Release 3.7.0dev
CONTENTS: 1
PyModbus, Release 3.7.0dev
2 CONTENTS:
CHAPTER
ONE
Pymodbus is a full Modbus protocol implementation offering client/server with synchronous/asynchronous API a well
as simulators.
Current release is 3.6.3.
Bleeding edge (not released) is dev.
All changes are described in release notes and all API changes are documented
A big thanks to all the volunteers that helps make pymodbus a great project.
Source code on github
3
PyModbus, Release 3.7.0dev
The client is the most typically used. It is embedded into applications, where it abstract the modbus protocol from the
application by providing an easy to use API. The client is integrated into some well known projects like home-assistant.
Although most system administrators will find little need for a Modbus server, the server is handy to verify the func-
tionality of an application.
The simulator and/or server is often used to simulate real life devices testing applications. The server is excellent to
perform high volume testing (e.g. houndreds of devices connected to the application). The advantage of the server is
that it runs not only a “normal” computers but also on small ones like Raspberry PI.
Since the library is written in python, it allows for easy scripting and/or integration into their existing solutions.
For more information please browse the project documentation:
https://readthedocs.org/docs/pymodbus/en/latest/index.html
1.3 Install
You can install using pip by issuing the following commands in a terminal window:
Activate the virtual environment, this command needs repeated in every new terminal:
source .venv/bin/activate
For those of you that just want to get started fast, here you go:
client = ModbusTcpClient('MyDevice.lan')
client.connect()
client.write_coil(1, True)
result = client.read_coils(1,1)
print(result.bits[0])
client.close()
1.5 Contributing
Just fork the repo and raise your Pull Request against dev branch.
We always have more work than time, so feel free to open a discussion / issue on a theme you want to solve.
If your company would like your device tested or have a cloud based device simulation, feel free to contact us. We are
happy to help your company solve your modbus challenges.
That said, the current work mainly involves polishing the library and solving issues:
• Fixing bugs/feature requests
• Architecture documentation
• Functional testing against any reference we can find
There are 2 bigger projects ongoing:
• rewriting the internal part of all clients (both sync and async)
• Add features to and simulator, and enhance the web design
on github open a pull request, check that CI turns green and then wait for review␣
˓→comments.
cd pytest
pytest
1.6.1 Architecture
There are no documentation of the architecture (help is welcome), but most classes and methods are documented:
Pymodbus internals
cd doc
./build_html
TWO
CLIENT
Pymodbus offers both a synchronous client and a asynchronous client. Both clients offer simple calls for
each type of request, as well as a unified response, removing a lot of the complexities in the modbus protocol.
In addition to the “pure” client, pymodbus offers a set of utilities converting to/from registers to/from “normal” python
values.
The client is NOT thread safe, meaning the application must ensure that calls are serialized. This is only a problem
for synchronous applications that use multiple threads or for asynchronous applications that use multiple asyncio.
create_task.
It is allowed to have multiple client objects that e.g. each communicate with a TCP based device.
There are currently a big performance gab between the 2 clients (try it on your computer exam-
ples/client_performance.py). This is due to a rather old implementation of the synchronous client, we are currently
working to update the client code. Our aim is to achieve a similar data rate with both clients and at least double the
data rate while keeping the stability. Table below is a test with 1000 calls each reading 10 registers.
Pymodbus offers clients with transport different protocols and different framers
11
PyModbus, Release 3.7.0dev
Pymodbus do not connect to the device (server) but connects to a comm port or usb port on the local computer.
RS-485 is a half duplex protocol, meaning the servers do nothing until the client sends a request then the server being
addressed responds. The client controls the traffic and as a consequence one RS-485 line can only have 1 client but
upto 254 servers (physical devices).
RS-485 is a simple 2 wire cabling with a pullup resistor. It is important to note that many USB converters do not have
a builtin resistor, this must be added manually. When experiencing many faulty packets and retries this is often the
problem.
2.2.2 TCP
Pymodbus connects directly to the device using a standard socket and have a one-to-one connection with the device.
In case of multiple TCP devices the application must instantiate multiple client objects one for each connection.
Tip: a TCP device often represent multiple physical devices (e.g Ethernet-RS485 converter), each of these devices
can be addressed normally
2.2.3 TLS
A variant of TCP that uses encryption and certificates. TLS is mostly used when the devices are connected to the
internet.
2.2.4 UDP
A broadcast variant of TCP. UDP allows addressing of many devices with a single request, however there are no control
that a device have received the packet.
Using pymodbus client to set/get information from a device (server) is done in a few simple steps, like the following
synchronous example:
12 Chapter 2. Client
PyModbus, Release 3.7.0dev
The line client = ModbusAsyncTcpClient('MyDevice.lan') only creates the object it does not activate any-
thing.
The line await client.connect() connects to the device (or comm port), if this cannot connect successfully within
the timeout it throws an exception. If connected successfully reconnecting later is handled automatically
The line await client.write_coil(1, True, slave=1) is an example of a write request, set address 1 to True
on device 1 (slave).
The line result = await client.read_coils(2, 3, slave=1) is an example of a read request, get the value
of address 2, 3 and 4 (count = 3) from device 1 (slave).
The last line client.close() closes the connection and render the object inactive.
Large parts of the implementation are shared between the different classes, to ensure high stability and efficient main-
tenance.
The synchronous clients are not thread safe nor is a single client intended to be used from multiple threads. Due to
the nature of the modbus protocol, it makes little sense to have client calls split over different threads, however the
application can do it with proper locking implemented.
The asynchronous client only runs in the thread where the asyncio loop is created, it does not provide mechanisms to
prevent (semi)parallel calls, that must be prevented at application level.
With TCP, TLS and UDP, the tcp/ip address of the physical device is defined when creating the object. The logical
devices represented by the device is addressed with the slave= parameter.
With Serial, the comm port is defined when creating the object. The physical devices are addressed with the slave=
parameter.
slave=0 is used as broadcast in order to address all devices. However experience shows that modern devices do not
allow broadcast, mostly because it is inheriently dangerous. With slave=0 the application can get upto 254 responses
on a single request!
The simple request calls (mixin) do NOT support broadcast, if an application wants to use broadcast it must call
client.execute and deal with the responses.
All simple request calls (mixin) return a unified result independent whether it´s a read, write or diagnostic call.
The application should evaluate the result generically:
try:
rr = await client.read_coils(1, 1, slave=1)
except ModbusException as exc:
_logger.error(f"ERROR: exception in pymodbus {exc}")
raise exc
if rr.isError():
_logger.error("ERROR: pymodbus returned an error!")
raise ModbusException(txt)
except ModbusException as exc: happens generally when pymodbus experiences an internal error. There are a
few situation where a unexpected response from a device can cause an exception.
rr.isError() is set whenever the device reports a problem.
And in case of read retrieve the data depending on type of request
• rr.bits is set for coils / input_register requests
• rr.registers is set for other requests
There are a client class for each type of communication and for asynchronous/synchronous
14 Chapter 2. Client
PyModbus, Release 3.7.0dev
await client.connect()
...
client.close()
def run():
client = ModbusSerialClient("dev/serial0")
client.connect()
...
client.close()
16 Chapter 2. Client
PyModbus, Release 3.7.0dev
send(request)
Send data on the underlying socket.
If receive buffer still holds some data then flush it.
Sleep if last send finished less than 3.5 character times ago.
recv(size)
Read data from the underlying descriptor.
is_socket_open()
Check if socket is open.
await client.connect()
...
client.close()
18 Chapter 2. Client
PyModbus, Release 3.7.0dev
client.connect()
...
client.close()
await client.connect()
...
client.close()
20 Chapter 2. Client
PyModbus, Release 3.7.0dev
client.connect()
...
client.close()
await client.connect()
...
client.close()
22 Chapter 2. Client
PyModbus, Release 3.7.0dev
client.connect()
...
client.close()
request = ReadCoilsRequest(1,10)
response = client.execute(request)
# or
request = ReadCoilsRequest(1,10)
response = await client.execute(request)
Tip: All methods can be used directly (synchronous) or with await <method> (asynchronous) depending on the
client used.
24 Chapter 2. Client
PyModbus, Release 3.7.0dev
26 Chapter 2. Client
PyModbus, Release 3.7.0dev
28 Chapter 2. Client
PyModbus, Release 3.7.0dev
30 Chapter 2. Client
PyModbus, Release 3.7.0dev
32 Chapter 2. Client
CHAPTER
THREE
SERVER
33
PyModbus, Release 3.7.0dev
34 Chapter 3. Server
PyModbus, Release 3.7.0dev
build_html_server(_params, html)
Build html server page.
build_json_calls(params, json_dict)
Build html calls page.
build_json_log(params, json_dict)
Build json log page.
build_json_registers(params, json_dict)
Build html registers page.
build_json_server(params, json_dict)
Build html server page.
async handle_html(request)
Handle html.
async handle_html_static(request)
Handle static html.
async handle_json(request)
Handle api registers.
helper_build_html_submit(params)
Build html register submit.
async run_forever(only_start=False)
Start modbus and http servers.
server_request_tracer(request, *_addr)
Trace requests.
All server requests passes this filter before being handled.
server_response_manipulator(response)
Manipulate responses.
All server responses passes this filter before being sent. The filter returns:
• response, either original or modified
• skip_encoding, signals whether or not to encode the response
async start_modbus_server(app)
Start Modbus server as asyncio task.
async stop()
Stop modbus and http servers.
async stop_modbus_server(app)
Stop modbus server.
class pymodbus.server.ModbusTcpServer(context, framer=Framer.SOCKET , identity=None, address=('',
502), ignore_missing_slaves=False, broadcast_enable=False,
response_manipulator=None, request_tracer=None)
Bases: ModbusBaseServer
A modbus threaded tcp socket server.
35
PyModbus, Release 3.7.0dev
We inherit and overload the socket server so that we can control the client threads as well as have a single server
context instance.
class pymodbus.server.ModbusTlsServer(context, framer=Framer.TLS, identity=None, address=('', 502),
sslctx=None, certfile=None, keyfile=None, password=None,
ignore_missing_slaves=False, broadcast_enable=False,
response_manipulator=None, request_tracer=None)
Bases: ModbusTcpServer
A modbus threaded tls socket server.
We inherit and overload the socket server so that we can control the client threads as well as have a single server
context instance.
class pymodbus.server.ModbusUdpServer(context, framer=Framer.SOCKET , identity=None, address=('',
502), ignore_missing_slaves=False, broadcast_enable=False,
response_manipulator=None, request_tracer=None)
Bases: ModbusBaseServer
A modbus threaded udp socket server.
We inherit and overload the socket server so that we can control the client threads as well as have a single server
context instance.
async pymodbus.server.ServerAsyncStop()
Terminate server.
pymodbus.server.ServerStop()
Terminate server.
async pymodbus.server.StartAsyncSerialServer(context=None, identity=None, custom_functions=[],
**kwargs)
Start and run a serial modbus server.
Parameters
• context – The ModbusServerContext datastore
• identity – An optional identify structure
• custom_functions – An optional list of custom function classes supported by server in-
stance.
• kwargs – The rest
async pymodbus.server.StartAsyncTcpServer(context=None, identity=None, address=None,
custom_functions=[], **kwargs)
Start and run a tcp modbus server.
Parameters
• context – The ModbusServerContext datastore
• identity – An optional identify structure
• address – An optional (interface, port) to bind to.
• custom_functions – An optional list of custom function classes supported by server in-
stance.
• kwargs – The rest
36 Chapter 3. Server
PyModbus, Release 3.7.0dev
37
PyModbus, Release 3.7.0dev
38 Chapter 3. Server
CHAPTER
FOUR
REPL
4.1 Dependencies
bash-3.2$ pymodbus.console
Usage: pymodbus.console [OPTIONS] COMMAND [ARGS]...
Options:
--version Show the version and exit.
--verbose Verbose logs
--support-diag Support Diagnostic messages
--help Show this message and exit.
Commands:
serial
tcp
TCP Options
Options:
--host TEXT Modbus TCP IP
--port INTEGER Modbus TCP port
--help Show this message and exit.
39
PyModbus, Release 3.7.0dev
SERIAL Options
Options:
--method TEXT Modbus Serial Mode (rtu/ascii)
--port TEXT Modbus RTU port
--baudrate INTEGER Modbus RTU serial baudrate to use.
--bytesize [5|6|7|8] Modbus RTU serial Number of data bits. Possible
values: FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS.
--parity [N|E|O|M|S] Modbus RTU serial parity. Enable parity checking.
Possible values: PARITY_NONE, PARITY_EVEN, PARITY_ODD
PARITY_MARK, PARITY_SPACE. Default to 'N'
--stopbits [1|1.5|2] Modbus RTU serial stop bits. Number of stop bits.
Possible values: STOPBITS_ONE,
STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO. Default to '1'
--xonxoff INTEGER Modbus RTU serial xonxoff. Enable software flow
control.
--rtscts INTEGER Modbus RTU serial rtscts. Enable hardware (RTS/CTS)
flow control.
--dsrdtr INTEGER Modbus RTU serial dsrdtr. Enable hardware (DSR/DTR)
flow control.
--timeout FLOAT Modbus RTU serial read timeout.
--write-timeout FLOAT Modbus RTU serial write timeout.
--help Show this message and exit.
> help
Available commands:
client.change_ascii_input_delimiter Diagnostic sub command, Change message␣
˓→delimiter for future requests.
40 Chapter 4. REPL
PyModbus, Release 3.7.0dev
SERIAL
42 Chapter 4. REPL
PyModbus, Release 3.7.0dev
Every command has auto suggestion on the arguments supported, arg and value are to be supplied in arg=val format.
> result.raw
{
"registers": [
15626,
55203,
28733,
18368
]
}
For Holding and Input register reads, the decoded value could be viewed with result.decode
>
> client.get_serial_settings
{
"t1.5": 0.00171875,
"baudrate": 9600,
"read timeout": 0.5,
"port": "/dev/ptyp0",
"t3.5": 0.00401,
"bytesize": 8,
"parity": "N",
"stopbits": 1.0
}
> client.set_timeout value=1
null
> client.get_timeout
(continues on next page)
44 Chapter 4. REPL
PyModbus, Release 3.7.0dev
> client.get_serial_settings
{
"t1.5": 0.00171875,
"baudrate": 9600,
"read timeout": 1.0,
"port": "/dev/ptyp0",
"t3.5": 0.00401,
"bytesize": 8,
"parity": "N",
"stopbits": 1.0
}
4.3 DEMO
4.3. DEMO 45
PyModbus, Release 3.7.0dev
force_listen_only_mode(data=0, **kwargs)
Force addressed remote device to its Listen Only Mode.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
get_clear_modbus_plus(data=0, **kwargs)
Get/clear stats of remote modbus plus device.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
get_com_event_counter(**kwargs)
Read status word and an event count.
From the remote device’s communication event counter.
Parameters
kwargs –
Returns
get_com_event_log(**kwargs)
Read status word.
Event count, message count, and a field of event bytes from the remote device.
Parameters
kwargs –
Returns
mask_write_register(address=0, and_mask=65535, or_mask=0, slave=0, **kwargs)
Mask content of holding register at address with and_mask and or_mask.
Parameters
• address – Reference address of register
• and_mask – And Mask
• or_mask – OR Mask
• slave – Modbus slave slave ID
• kwargs –
Returns
read_coils(address, count=1, slave=0, **kwargs)
Read count coils from a given slave starting at address.
Parameters
• address – The starting address to read from
• count – The number of coils to read
46 Chapter 4. REPL
PyModbus, Release 3.7.0dev
48 Chapter 4. REPL
PyModbus, Release 3.7.0dev
return_bus_exception_error_count(data=0, **kwargs)
Return count of Modbus exceptions returned by remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_bus_message_count(data=0, **kwargs)
Return count of message detected on bus by remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_diagnostic_register(data=0, **kwargs)
Read 16-bit diagnostic register.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_iop_overrun_count(data=0, **kwargs)
Return count of iop overrun errors by remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_query_data(message=0, **kwargs)
Loop back data sent in response.
Parameters
• message – Message to be looped back
• kwargs –
Returns
return_slave_bus_char_overrun_count(data=0, **kwargs)
Return count of messages not handled.
By remote slave due to character overrun condition.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_slave_busy_count(data=0, **kwargs)
Return count of server busy exceptions sent by remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_slave_message_count(data=0, **kwargs)
Return count of messages addressed to remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_slave_no_ack_count(data=0, **kwargs)
Return count of NO ACK exceptions sent by remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
return_slave_no_response_count(data=0, **kwargs)
Return count of No responses by remote slave.
Parameters
• data – Data field (0x0000)
• kwargs –
Returns
write_coil(address, value, slave=0, **kwargs)
Write value to coil at address.
Parameters
• address – coil offset to write to
• value – bit value to write
• slave – Modbus slave slave ID
• kwargs –
Returns
write_coils(address, values, slave=0, **kwargs)
Write value to coil at address.
Parameters
• address – coil offset to write to
• values – list of bit values to write (comma separated)
50 Chapter 4. REPL
PyModbus, Release 3.7.0dev
get_serial_settings()
Get Current Serial port settings.
Returns
Current Serial settings as dict.
get_stopbits()
Get number of stop bits.
Returns
Current Stop bits
get_timeout()
Get serial Port Read timeout.
Returns
Current read imeout.
set_baudrate(value)
Set baudrate setter.
Parameters
value – <supported baudrate>
set_bytesize(value)
Set Byte size.
Parameters
value – Possible values (5, 6, 7, 8)
set_parity(value)
Set parity Setter.
Parameters
value – Possible values (“N”, “E”, “O”, “M”, “S”)
set_port(value)
Set serial Port setter.
Parameters
value – New port
set_stopbits(value)
Set stop bit.
Parameters
value – Possible values (1, 1.5, 2)
set_timeout(value)
Read timeout setter.
Parameters
value – Read Timeout in seconds
class pymodbus.repl.client.mclient.ModbusTcpClient(**kwargs)
Bases: ExtendedRequestSupport, ModbusTcpClient
TCP client.
pymodbus.repl.client.mclient.handle_brodcast(func)
Handle broadcast.
52 Chapter 4. REPL
PyModbus, Release 3.7.0dev
pymodbus.repl.client.mclient.make_response_dict(resp)
Make response dict.
Pymodbus REPL comes with many handy features such as payload decoder to directly retrieve the values in desired
format and supports all the diagnostic function codes directly .
For more info on REPL Client refer pymodbus/repl/client/README.rst
Pymodbus also comes with a REPL server to quickly run an asynchronous server with additional capabilities out of the
box like simulating errors, delay, mangled messages etc.
For more info on REPL Server refer pymodbus/repl/server/README.rst
54 Chapter 4. REPL
CHAPTER
FIVE
SIMULATOR
The simulator is a full fledged modbus simulator, which is constantly being evolved with user ideas / amendments.
The purpose of the simulator is to provide support for client application test harnesses with end-to-end testing simulating
real life modbus devices.
The datastore simulator allows the user to (all automated)
• simulate a modbus device by adding a simple configuration,
• test how a client handles modbus exceptions,
• test a client apps correct use of the simulated device.
The web interface allows the user to (online / manual)
• test how a client handles modbus errors,
• test how a client handles communication errors like divided messages,
• run your test server in the cloud,
• monitor requests/responses,
• inject modbus errors like malicious a response,
• see/Change values online.
The REST API allow the test process to be automated
• spin up a test server with unix domain sockets in your test harness,
• set expected responses with a simple REST API command,
• check the result with another simple REST API command,
• test your client app in a true end-to-end fashion.
The simulator replaces REPL server classes but not REPL client classes
5.1 Configuration
Configuring the pymodbus simulator is done with a json file, or if only using the datastore simulator a python dict
(same structure as the device part of the json file).
55
PyModbus, Release 3.7.0dev
The json file consist of 2 main entries “server_list” (see Server entries) and “device_list” (see Device entries) each
containing a list of servers/devices
{
"server_list": {
"<name>": { ... },
...
},
"device_list": {
"<name>": { ... },
...
}
}
You can define as many server and devices as you like, when starting pymodbus.simulator you select one server and
one device to simulate.
A entry in “device_list” correspond to the dict you can use as parameter to datastore_simulator is you want to construct
your own simulator.
The entries for a tcp server with minimal parameters look like:
{
"server_list": {
"server": {
"comm": "tcp",
"host": "0.0.0.0",
"port": 5020,
"framer": "socket",
}
}
"device_list": {
...
}
}
The example uses “comm”: “tcp”, so the entries are arguments to pymodbus.server.ModbusTcpServer, where
detailed information are available.
The entry “comm” allows the following values:
• “serial”, to use pymodbus.server.ModbusSerialServer,
• “tcp”, to use pymodbus.server.ModbusTcpServer,
• “tls”, to use pymodbus.server.ModbusTlsServer,
• “udp”; to use pymodbus.server.ModbusUdpServer.
The entry “framer” allows the following values:
• “ascii” to use pymodbus.framer.ascii_framer.ModbusAsciiFramer,
• “binary to use pymodbus.framer.ascii_framer.ModbusBinaryFramer,
56 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
Warning: not all “framer” types can be used with all “comm” types.
e.g. "framer": “tls” only works with “comm”: “tls”!
{
"server_list": {
"server": {
"comm": "tcp",
"host": "0.0.0.0",
"port": 5020,
"ignore_missing_slaves": false,
"framer": "socket",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
},
"server_try_serial": {
"comm": "serial",
"port": "/dev/tty0",
"stopbits": 1,
"bytesize": 8,
"parity": "N",
"baudrate": 9600,
"timeout": 3,
"reconnect_delay": 2,
"framer": "rtu",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
},
"server_try_tls": {
"comm": "tls",
"host": "0.0.0.0",
"port": 5020,
(continues on next page)
5.1. Configuration 57
PyModbus, Release 3.7.0dev
58 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
When reading holding register 1 (block 4) you get a different register as when reading input register 1 (block 1). Each
block references a different physical register memory, in other words the size of the needed memory is the sum of the
block sizes.
The second form uses 1 shared block, most modern devices use this form for 2 main reasons:
5.1. Configuration 59
PyModbus, Release 3.7.0dev
• the modbus protocol implementation do not connect directly to the sensors but to a shared memory controlled
by a small microprocessor.
• designers can group related information independent of type (e.g. a bay controller with register 1 as coil, register
2 as input and register 3 as holding)
When reading holding register 1 the same phyical register is accessed as when reading input register 1. Each block
references the same physical register memory, in other words the size of the needed memory is the size of the largest
block.
The datastore simulator supports both types.
60 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
Tip: if shared is set to false, please remember to adjust the addresses, depending on in which group they
are.
assuming all sizes are set to 10, the addresses for configuration are as follows:
• coils have addresses 0-9,
• discrete_inputs have addresses 10-19,
• input_registers have addresses 20-29,
• holding_registers have addresses 30-39
when configuring the the datatypes (when calling each block start with 0).
This is needed because the datatypes can be in different blocks.
“type exception”
Defines is the server returns a modbus exception if a read/write request violates the specified type. E.g.
Read holding register 10 with count 1, but the 10,11 are defined as UINT32 and thus can only be read with
multiples of 2.
This feature is designed to control that a client access the device in the manner it was designed.
“defaults”
Defines how to defines registers not configured or or only partial configured.
“value” defines the default value for each type.
“action” defines the default action for each type. Actions are functions that are called whenever the register
is accessed and thus allows automatic manipulation.
The datastore simulator have a number of builtin actions, and allows custom actions to be added:
• “random”, change the value with every access,
5.1. Configuration 61
PyModbus, Release 3.7.0dev
"invalid": [
5,
[10, 15]
],
Defines invalid registers which cannot be read or written. When accessed the response in a modbus exception invalid
address. In the example registers 5, 10, 11, 12, 13, 14, 15 will produce an exception response.
Registers can be singulars (first entry) or arrays (second entry)
"write": [
4,
[5, 6]
],
Defines registers which can be written to. When writing to registers not defined here the response is a modbus exception
invalid address.
Registers can be singulars (first entry) or arrays (second entry)
"bits": [
5,
[6, 7],
{"addr": 8, "value": 7},
{"addr": 9, "value": 7, "action": "random"},
{"addr": [11, 12], "value": 7, "action": "random"}
],
62 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
"uint16": [
5,
[6, 7],
{"addr": 8, "value": 30123},
{"addr": 9, "value": 712, "action": "increment"},
{"addr": [11, 12], "value": 517, "action": "random"}
],
"uint32": [
[6, 7],
{"addr": [8, 9], "value": 300123},
{"addr": [10, 13], "value": 400712, "action": "increment"},
{"addr": [14, 15], "value": 500517, "action": "random"}
],
"float32": [
[6, 7],
{"addr": [8, 9], "value": 3123.17},
{"addr": [10, 13], "value": 712.5, "action": "increment"},
{"addr": [14, 15], "value": 517.0, "action": "random"}
],
5.1. Configuration 63
PyModbus, Release 3.7.0dev
"string": [
7,
[8, 9],
{"addr": [16, 20], "value": "A_B_C_D_E_"}
],
"repeat": [
{"addr": [0, 2], "to": [10, 11]},
{"addr": [0, 2], "to": [10, 15]},
]
is a special command to copy configuration if a device contains X bay controllers, configure one and use repeat for X-1.
First entry copies registers 0-2 to 10-11, resulting in 10 == 0, 11 == 1, 12 unchanged.
Second entry copies registers 0-2 to 10-15, resulting in 10 == 0, 11 == 1, 12 == 2, 13 == 0, 14 == 1, 15 == 2, 16
unchanged.
{
"server_list": {
...
},
"device_list": {
"device": {
"setup": {
"co size": 63000,
"di size": 63000,
"hr size": 63000,
"ir size": 63000,
"shared blocks": true,
"type exception": true,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
(continues on next page)
64 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
5.1. Configuration 65
PyModbus, Release 3.7.0dev
66 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
5.1. Configuration 67
PyModbus, Release 3.7.0dev
{
"server_list": {
"server": {
"comm": "tcp",
"host": "0.0.0.0",
"port": 5020,
"ignore_missing_slaves": false,
"framer": "socket",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
},
"server_try_serial": {
"comm": "serial",
"port": "/dev/tty0",
"stopbits": 1,
"bytesize": 8,
"parity": "N",
"baudrate": 9600,
"timeout": 3,
"reconnect_delay": 2,
"framer": "rtu",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
},
"server_try_tls": {
"comm": "tls",
"host": "0.0.0.0",
"port": 5020,
"certfile": "certificates/pymodbus.crt",
"keyfile": "certificates/pymodbus.key",
"ignore_missing_slaves": false,
"framer": "tls",
"identity": {
(continues on next page)
68 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
5.1. Configuration 69
PyModbus, Release 3.7.0dev
70 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
5.1. Configuration 71
PyModbus, Release 3.7.0dev
The simulator datastore is an advanced datastore. The simulator allows to simulate the registers of a real life modbus
device by adding a simple dict (definition see Device entries).
The simulator datastore allows to add actions (functions) to a register, and thus allows a low level automation.
Documentation pymodbus.datastore.ModbusSimulatorContext
72 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
TO BE DOCUMENTED.
5.3.1 pymodbus.simulator
The easiest way to run the simulator with web is to use “pymodbus.simulator” from the commandline.
TO BE DOCUMENTED. HTTP server for modbus simulator.
class pymodbus.server.simulator.http_server.CallTracer(call: bool = False, fc: int = -1, address: int
= -1, count: int = -1, data: bytes = b'')
Bases: object
Define call/response traces.
class pymodbus.server.simulator.http_server.CallTypeMonitor(active: bool = False, trace_response:
bool = False, range_start: int = -1,
range_stop: int = -1, function: int =
-1, hex: bool = False, decode: bool =
False)
Bases: object
Define Request/Response monitor.
class pymodbus.server.simulator.http_server.CallTypeResponse(active: int = -1, split: int = 0, delay:
int = 0, junk_len: int = 10,
error_response: int = 0,
change_rate: int = 0, clear_after: int
= 1)
Bases: object
Define Response manipulation.
class pymodbus.server.simulator.http_server.ModbusSimulatorServer(modbus_server: str = 'server',
modbus_device: str = 'device',
http_host: str = '0.0.0.0',
http_port: int = 8080,
log_file: str = 'server.log',
json_file: str = 'setup.json',
custom_actions_module: str |
None = None)
Bases: object
ModbusSimulatorServer.
Parameters
• modbus_server – Server name in json file (default: “server”)
• modbus_device – Device name in json file (default: “client”)
• http_host – TCP host for HTTP (default: “localhost”)
• http_port – TCP port for HTTP (default: 8080)
• json_file – setup file (default: “setup.json”)
• custom_actions_module – python module with custom actions (default: none)
if either http_port or http_host is none, HTTP will not be started. This class starts a http server, that serves a
couple of endpoints:
• “<addr>/” static files
• “<addr>/api/log” log handling, HTML with GET, REST-API with post
• “<addr>/api/registers” register handling, HTML with GET, REST-API with post
• “<addr>/api/calls” call (function code / message) handling, HTML with GET, REST-API with post
• “<addr>/api/server” server handling, HTML with GET, REST-API with post
Example:
async start_modbus_server(app)
Start Modbus server as asyncio task.
async stop_modbus_server(app)
Stop modbus server.
async run_forever(only_start=False)
Start modbus and http servers.
async stop()
Stop modbus and http servers.
async handle_html_static(request)
Handle static html.
async handle_html(request)
Handle html.
async handle_json(request)
Handle api registers.
build_html_registers(params, html)
Build html registers page.
build_html_calls(params, html)
Build html calls page.
build_html_log(_params, html)
Build html log page.
build_html_server(_params, html)
Build html server page.
74 Chapter 5. Simulator
PyModbus, Release 3.7.0dev
build_json_registers(params, json_dict)
Build html registers page.
build_json_calls(params, json_dict)
Build html calls page.
build_json_log(params, json_dict)
Build json log page.
build_json_server(params, json_dict)
Build html server page.
helper_build_html_submit(params)
Build html register submit.
action_clear(_params, _range_start, _range_stop)
Clear register filter.
action_stop(_params, _range_start, _range_stop)
Stop call monitoring.
action_reset(_params, _range_start, _range_stop)
Reset call simulation.
action_add(params, range_start, range_stop)
Build list of registers matching filter.
action_monitor(params, range_start, range_stop)
Start monitoring calls.
action_set(params, _range_start, _range_stop)
Set register value.
action_simulate(params, _range_start, _range_stop)
Simulate responses.
server_response_manipulator(response)
Manipulate responses.
All server responses passes this filter before being sent. The filter returns:
• response, either original or modified
• skip_encoding, signals whether or not to encode the response
server_request_tracer(request, *_addr)
Trace requests.
All server requests passes this filter before being handled.
TO BE DOCUMENTED.
76 Chapter 5. Simulator
CHAPTER
SIX
EXAMPLES
These examples are very basic examples, showing how a client can communicate with a server.
You need to modify the code to adapt it to your situation.
Source: examples/simple_async_client.py
#!/usr/bin/env python3
"""Pymodbus asynchronous client example.
usage: simple_client_async.py
77
PyModbus, Release 3.7.0dev
print("get client")
if comm == "tcp":
client = ModbusClient.AsyncModbusTcpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# source_address=("localhost", 0),
)
elif comm == "udp":
client = ModbusClient.AsyncModbusUdpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# source_address=None,
)
elif comm == "serial":
client = ModbusClient.AsyncModbusSerialClient(
port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
baudrate=9600,
bytesize=8,
parity="N",
stopbits=1,
# handle_local_echo=False,
)
elif comm == "tls":
client = ModbusClient.AsyncModbusTlsClient(
host,
port=port,
framer=Framer.TLS,
# timeout=10,
(continues on next page)
78 Chapter 6. Examples
PyModbus, Release 3.7.0dev
print("connect to server")
await client.connect()
# test client is connected
assert client.connected
print("close connection")
client.close()
if __name__ == "__main__":
asyncio.run(
run_async_simple_client("tcp", "127.0.0.1", 5020), debug=True
) # pragma: no cover
Source: examples/simple_sync_client.py
#!/usr/bin/env python3
"""Pymodbus synchronous client example.
usage: simple_client_async.py
# --------------------------------------------------------------------------- #
# import the various client implementations
# --------------------------------------------------------------------------- #
import pymodbus.client as ModbusClient
from pymodbus import (
ExceptionResponse,
Framer,
ModbusException,
pymodbus_apply_logging_config,
)
print("get client")
if comm == "tcp":
client = ModbusClient.ModbusTcpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,y
# close_comm_on_error=False,
# strict=True,
# source_address=("localhost", 0),
)
elif comm == "udp":
client = ModbusClient.ModbusUdpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
(continues on next page)
80 Chapter 6. Examples
PyModbus, Release 3.7.0dev
print("connect to server")
client.connect()
if __name__ == "__main__":
run_sync_simple_client("tcp", "127.0.0.1", "5020") # pragma: no cover
Source: examples/client_performance.py
#!/usr/bin/env python3
"""Test performance of client: sync vs. async.
This example show how much faster the async version is.
example run:
(pymodbus) % ./client_performance.py
--- Testing sync client v3.4.1
running 1000 call (each 10 registers), took 114.10 seconds
Averages 114.10 ms pr call and 11.41 ms pr register.
--- Testing async client v3.4.1
running 1000 call (each 10 registers), took 0.33 seconds
Averages 0.33 ms pr call and 0.03 ms pr register.
"""
import asyncio
import time
LOOP_COUNT = 1000
REGISTER_COUNT = 10
def run_sync_client_test():
"""Run sync client."""
print("--- Testing sync client v3.4.1")
client = ModbusSerialClient(
"/dev/ttys007",
framer_name=Framer.RTU,
baudrate=9600,
(continues on next page)
82 Chapter 6. Examples
PyModbus, Release 3.7.0dev
start_time = time.time()
for _i in range(LOOP_COUNT):
rr = client.read_input_registers(1, REGISTER_COUNT, slave=1)
if rr.isError():
print(f"Received Modbus library error({rr})")
break
client.close()
run_time = time.time() - start_time
avg_call = (run_time / LOOP_COUNT) * 1000
avg_register = avg_call / REGISTER_COUNT
print(
f"running {LOOP_COUNT} call (each {REGISTER_COUNT} registers), took {run_time:.
˓→2f} seconds"
)
print(f"Averages {avg_call:.2f} ms pr call and {avg_register:.2f} ms pr register.")
start_time = time.time()
for _i in range(LOOP_COUNT):
rr = await client.read_input_registers(1, REGISTER_COUNT, slave=1)
if rr.isError():
print(f"Received Modbus library error({rr})")
break
client.close()
run_time = time.time() - start_time
avg_call = (run_time / LOOP_COUNT) * 1000
avg_register = avg_call / REGISTER_COUNT
print(
f"running {LOOP_COUNT} call (each {REGISTER_COUNT} registers), took {run_time:.
˓→2f} seconds"
)
print(f"Averages {avg_call:.2f} ms pr call and {avg_register:.2f} ms pr register.")
if __name__ == "__main__":
run_sync_client_test()
asyncio.run(run_async_client_test())
These examples are considered essential usage examples, and are guaranteed to work, because they are tested au-
tomatilly with each dev branch commit using CI.
Tip: The examples needs to be run from within the examples directory, unless you modify them. Most examples use
helper.py and client_*.py or server_*.py. This is done to avoid maintaining the same code in multiple files.
• examples.zip
• examples.tgz
Source: examples/client_async_calls.py
Pymodbus Client modbus async all calls example.
Please see method async_template_call for a template on how to make modbus calls and check for different error
conditions.
The handle* functions each handle a set of modbus calls with the same register type (e.g. coils).
All available modbus calls are present.
If you are performing a request that is not available in the client mixin, you have to perform the request like this instead:
request = ClearCountersRequest()
response = client.execute(request)
if isinstance(response, ClearCountersResponse):
... do something with the response
This example uses client_async.py and client_sync.py to handle connection, and have the same options.
The corresponding server must be started before e.g. as:
./server_async.py
Source: examples/client_async.py
Pymodbus asynchronous client example.
usage:
-h, --help
(continues on next page)
84 Chapter 6. Examples
PyModbus, Release 3.7.0dev
Source: examples/client_calls.py
Pymodbus Client modbus all calls example.
Please see method template_call for a template on how to make modbus calls and check for different error conditions.
The handle* functions each handle a set of modbus calls with the same register type (e.g. coils).
All available modbus calls are present.
If you are performing a request that is not available in the client mixin, you have to perform the request like this instead:
request = ClearCountersRequest()
response = client.execute(request)
if isinstance(response, ClearCountersResponse):
... do something with the response
This example uses client_async.py and client_sync.py to handle connection, and have the same options.
The corresponding server must be started before e.g. as:
./server_async.py
Source: examples/client_custom_msg.py
Pymodbus Synchronous Client Examples.
The following is an example of how to use the synchronous modbus client implementation from pymodbus:
Source: examples/client_payload.py
Pymodbus Client Payload Example.
This example shows how to build a client with a complicated memory layout using builder.
Works out of the box together with payload_server.py
Source: examples/client_sync.py
Pymodbus Synchronous Client Example.
An example of a single threaded synchronous client.
usage:
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
--baudrate BAUDRATE
set serial device baud rate
--host HOST
set host, default is 127.0.0.1
Source: examples/server_async.py
Pymodbus asynchronous Server Example.
An example of a multi threaded asynchronous server.
usage:
86 Chapter 6. Examples
PyModbus, Release 3.7.0dev
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--slaves SLAVES
set number of slaves to respond to
Source: examples/server_callback.py
Pymodbus Server With Callbacks.
This is an example of adding callbacks to a running modbus server when a value is written to it.
Source: examples/server_hook.py
Pymodbus Server With request/response manipulator.
This is an example of using the builtin request/response tracer to manipulate the messages to/from the modbus server
Source: examples/server_payload.py
Pymodbus Server Payload Example.
This example shows how to initialize a server with a complicated memory layout using builder.
Source: examples/server_sync.py
Pymodbus Synchronous Server Example.
An example of a single threaded synchronous server.
usage:
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--slaves SLAVES
set number of slaves to respond to
Source: examples/server_updating.py
Pymodbus asynchronous Server with updating task Example.
An example of an asynchronous server and a task that runs continuously alongside the server and updates values.
usage:
-h, --help
show this help message and exit
(continues on next page)
88 Chapter 6. Examples
PyModbus, Release 3.7.0dev
Source: examples/simulator.py
Pymodbus simulator server/client Example.
An example of how to use the simulator (server) with a client.
for usage see documentation of simulator
Source: examples/datastore_simulator.py
Pymodbus datastore simulator Example.
An example of using simulator datastore with json interface.
usage:
server_simulator.py [-h]
[--log {critical,error,warning,info,debug}]
[--port PORT]
-h, --help
show this help message and exit
-l, --log {critical,error,warning,info,debug}
set log level
-p, --port PORT
set port to use
Source: examples/message_generator.py
Modbus Message Generator.
Source: examples/message_parser.py
Modbus Message Parser.
The following is an example of how to parse modbus messages using the supplied framers.
Source: examples/modbus_forwarder.py
Pymodbus synchronous forwarder.
This is a repeater or converter and an example of just how powerful datastore is.
It consist of a server (any comm) and a client (any comm), functionality:
a) server receives a read/write request from external client:
• client sends a new read/write request to target server
• client receives response and updates the datastore
• server sends new response to external client
Both server and client are tcp based, but it can be easily modified to any server/client (see client_sync.py and
server_sync.py for other communication types)
WARNING This example is a simple solution, that do only forward read requests.
These examples are supplied by users of pymodbus. The pymodbus team thanks for sharing the examples.
6.3.1 Solar
Source: examples/contrib/solar.py
Pymodbus Synchronous Client Example.
Modified to test long term connection.
90 Chapter 6. Examples
PyModbus, Release 3.7.0dev
Source: examples/contrib/redis_datastore.py
Datastore using redis.
Source: examples/contrib/serial_forwarder.py
Pymodbus SerialRTU2TCP Forwarder
usage : python3 serial_forwarder.py –log DEBUG –port “/dev/ttyUSB0” –baudrate 9600 –server_ip “192.168.1.27”
–server_port 5020 –slaves 1 2 3
Source: examples/contrib/sql_datastore.py
Datastore using SQL.
92 Chapter 6. Examples
CHAPTER
SEVEN
AUTHORS
Thanks to
• AKJ7
• Alex
• Alex Ruddick
• Alexandre CUER
• Alois Hockenschlohe
• Arjan
• André Srinivasan
• banana-sun
• Blaise Thompson
• cgernert
• corollaries
• Chandler Riehm
• Chris Hung
• Christian Krause
• dhoomakethu
• DominicDataP
• Dries
• duc996
• Farzad Panahi
• Fredo70
• Gao Fang
93
PyModbus, Release 3.7.0dev
• Ghostkeeper
• Hangyu Fan
• Hayden Roche
• Iktek
• Jakob Ruhe
• Jakob Schlyter
• James Braza
• jan iversen
• Jerome Velociter
• Joe Burmeister
• Kenny Johansson
• Matthias Straka
• Logan Gunthorpe
• Marko Luther
• Logan Gunthorpe
• Marko Luther
• Matthias Straka
• Mickaël Schoentgen
• Pavel Kostromitinov
• peufeu2
• Philip Couling
• Sebastian Machuca
• Sefa Keleş
• Thijs W
• Totally a booplicate
• WouterTuinstra
• wriswith
• yyokusa
Thanks to
• alecjohanson
• Alexey Andreyev
• Andrea Canidio
• Carlos Gomez
94 Chapter 7. Authors
PyModbus, Release 3.7.0dev
• Cougar
• Christian Sandberg
• dhoomakethu
• dices
• Dmitri Zimine
• Emil Vanherp
• er888kh
• Eric Duminil
• Erlend Egeberg Aasland
• hackerboygn
• Jian-Hong Pan
• Jose J Rodriguez
• Justin Searle
• Karl Palsson
• Kim Hansen
• Kristoffer Sjöberg
• Kyle Altendorf
• Lars Kruse
• Malte Kliemann
• Memet Bilgin
• Michael Corcoran
• Mike
• sanjay
• Sekenre
• Siarhei Farbotka
• Steffen Vogel
• tcplomp
• Thor Michael Støre
• Tim Gates
• Ville Skyttä
• Wild Stray
• Yegor Yefremov
Thanks to
• Antoine Pitrou
• Bart de Waal
• bashwork
• bje-
• Claudio Catterina
• Chintalagiri Shashank
• dhoomakethu
• dragoshenron
• Elvis Stansvik
• Eren Inan Canpolat
• Everley
• Fabio Bonelli
• fleimgruber
• francozappa
• Galen Collins
• Gordon Broom
• Hamilton Kibbe
• Hynek Petrak
• idahogray
• Ingo van Lil
• Jack
• jbiswas
• jon mills
• Josh Kelley
• Karl Palsson
• Matheus Frata
• Patrick Fuller
• Perry Kundert
• Philippe Gauthier
• Rahul Raghunath
• sanjay
• schubduese42
• semyont
96 Chapter 7. Authors
PyModbus, Release 3.7.0dev
• Semyon Teplitsky
• Stuart Longland
• Yegor Yefremov
Thanks to
• Albert Brandl
• Galen Collins
Import to github was based on code from:
• S.W.A.C. GmbH, Germany.
• S.W.A.C. Bohemia s.r.o., Czech Republic.
• Hynek Petrak
• Galen Collins
98 Chapter 7. Authors
CHAPTER
EIGHT
CHANGELOG
All these version would not be possible without a lot of work from volunteers!
We, the maintainers, are greatful for each pull requests small or big, that helps make pymodbus a better product.
Authors: contains a complete list of volunteers have contributed to each major version.
99
PyModbus, Release 3.7.0dev
• Update README.rst
• Correct README link. (#1316)
• More direct readme links for REPL (#1314)
• Add classifier for 3.11 (#1312)
• Update README.rst (#1313)
• Delete ModbusCommonBlock.png (#1311)
• Add modbus standard to README. (#1308)
• fix no auto reconnect after close/connect in TCPclient (#1298)
• Update examples.rst (#1307)
• var name clarification (#1304)
• Bump external libraries. (#1302)
• Reorganize documentation to make it easier accessible (#1299)
• Simulator documentation (first version). (#1296)
• Updated datastore Simulator. (#1255)
• Update links to pydmodbus-dev (#1291)
• Change riptideio to pymodbus-dev. (#1292)
• #1258 Avoid showing unit as a seperate command line argument (#1288)
• Solve docker cache problem. (#1287)
• Faulty release!
• Add kwarg reset_socket to control closing of the socket on read failures (set to True by default).
• Add –reset-socket/–no-reset-socket to REPL client.
• Fix Issues with Serial client where in partial data was read when the response size is unknown.
• Fix Infinite sleep loop in RTU Framer.
• Add pygments as extra requirement for repl.
• Add support to modify modbus client attributes via repl.
• Update modbus repl documentation.
• More verbose logs for repl.
• Async client implementation based on Tornado, Twisted and asyncio with backward compatibility support for
twisted client.
• Allow reusing existing[running] asyncio loop when creating async client based on asyncio.
• Allow reusing address for Modbus TCP sync server.
• Add support to install tornado as extra requirement while installing pymodbus.
• Support Pymodbus REPL
• Add support to python 3.7.
• Bug fix and enhancements in examples.
• Async client implementation based on Tornado, Twisted and asyncio
• Added isError method to exceptions, Any response received can be tested for success before proceeding.
• Add examples for MEI read device information request
• Improve transaction speeds for sync clients (RTU/ASCII), now retry on empty happens only when
retry_on_empty kwarg is passed to client during intialization
• Fix tcp servers (sync/async) not processing requests with transaction id > 255
• Introduce new api to check if the received response is an error or not (response.isError())
• Move timing logic to framers so that irrespective of client, correct timing logics are followed.
• Move framers from transaction.py to respective modules
• Fix modbus payload builder and decoder
• Async servers can now have an option to defer reactor.run() when using
Start<Tcp/Serial/Udo>Server(. . . ,defer_reactor_run=True)
• Fix UDP client issue while handling MEI messages (ReadDeviceInformationRequest)
• Add expected response lengths for WriteMultipleCoilRequest and WriteMultipleRegisterRequest
• Fix _rtu_byte_count_pos for GetCommEventLogResponse
• Add support for repeated MEI device information Object IDs
• Fix struct errors while decoding stray response
• Modbus read retries works only when empty/no message is received
• Change test runner from nosetest to pytest
• Fix Misc examples
• Add new example for SqlStore and RedisStore (db store slave context)
• Fix minor comaptibility issues with utilities.
• Update test requirements
• Update/Add new unit tests
• Move twisted requirements to extra so that it is not installed by default on pymodbus installtion
• Reworking the transaction managers to be more explicit and to handle modbus RTU over TCP.
• Adding examples for a number of unique requested use cases
• Allow RTU framers to fail fast instead of staying at fault
• Working on datastore saving and loading
• Adding support for payload builders to form complex encoding and decoding of messages.
• Adding BCD and binary payload builders
• Adding support for pydev
• Cleaning up the build tools
• Adding a message encoding generator for testing.
• Now passing kwargs to base of PDU so arguments can be used correctly at all levels of the protocol.
• A number of bug fixes (see bug tracker and commit messages)
NINE
API CHANGES
Versions (X.Y.Z) where Z > 0 e.g. 3.0.1 do NOT have API changes!
121
PyModbus, Release 3.7.0dev
TEN
PYMODBUS INTERNALS
10.1 NullModem
Pymodbus offers a special NullModem transport to help end-to-end test without network.
The NullModem is activated by setting host= (port= for serial) to NULLMODEM_HOST (import pymodbus.transport)
The NullModem works with the normal transport types, and simply substitutes the physical connection: - Serial (RS-
485) typically using a dongle - TCP - TLS - UDP
The NullModem is currently integrated in - Modbus<x>Client - AsyncModbus<x>Client - Modbus<x>Server -
AsyncModbus<x>Server
Of course the NullModem requires that server and client(s) run in the same python instance.
10.2 Datastore
125
PyModbus, Release 3.7.0dev
Parameters
values – Either a list or a dictionary of values
Returns
An initialized datastore
reset()
Reset the store to the initially provided defaults.
validate(address, count=1)
Check to see if the request is in range.
Parameters
• address – The starting address
• count – The number of values to test for
Returns
True if the request in within range, False otherwise
getValues(address, count=1)
Return the requested values of the datastore.
Parameters
• address – The starting address
• count – The number of values to retrieve
Returns
The requested values from a:a+c
setValues(address, values, use_as_default=False)
Set the requested values of the datastore.
Parameters
• address – The starting address
• values – The new values to be set
• use_as_default – Use the values as default
Raises
ParameterException –
class pymodbus.datastore.ModbusSlaveContext(*_args, **kwargs)
This creates a modbus data model with each data access stored in a block.
reset()
Reset all the datastores to their default values.
validate(fc_as_hex, address, count=1)
Validate the request to make sure it is in range.
Parameters
• fc_as_hex – The function we are working with
• address – The starting address
• count – The number of values to test
Returns
True if the request in within range, False otherwise
getValues(fc_as_hex, address, count=1)
Get count values from datastore.
Parameters
• fc_as_hex – The function we are working with
• address – The starting address
• count – The number of values to retrieve
Returns
The requested values from a:a+c
setValues(fc_as_hex, address, values)
Set the datastore with the supplied values.
Parameters
• fc_as_hex – The function we are working with
• address – The starting address
• values – The new values to be set
register(function_code, fc_as_hex, datablock=None)
Register a datablock with the slave context.
Parameters
• function_code – function code (int)
• fc_as_hex – string representation of function code (e.g “cf” )
• datablock – datablock to associate with this function code
class pymodbus.datastore.ModbusServerContext(slaves=None, single=True)
This represents a master collection of slave contexts.
If single is set to true, it will be treated as a single context so every slave_id returns the same context. If single
is set to false, it will be interpreted as a collection of slave contexts.
slaves()
Define slaves.
class pymodbus.datastore.ModbusSimulatorContext(config: dict[str, Any], custom_actions: dict[str,
Callable])
Modbus simulator.
Parameters
• config – A dict with structure as shown below.
• actions – A dict with “<name>”: <function> structure.
Raises
RuntimeError – if json contains errors (msg explains what)
It builds and maintains a virtual copy of a device, with simulation of device specific functions.
The device is described in a dict, user supplied actions will be added to the builtin actions.
It is used in conjunction with a pymodbus server.
Example:
store = ModbusSimulatorContext(<config dict>, <actions dict>)
StartAsyncTcpServer(<host>, context=store)
Now the server will simulate the defined device with features like:
- invalid addresses
- write protected addresses
- optional control of access for string, uint32, bit/bits
- builtin actions for e.g. reset/datetime, value increment by read
- custom actions
},
"invalid": [ --> List of invalid addresses, IO exception returned
51, --> single register
[78, 99], --> start, end registers, repeated as needed
],
"write": [ --> allow write, efault is ReadOnly
[5, 5] --> start, end bytes, repeated as needed
],
"bits": [ --> Define bits (1 register == 1 byte)
[30, 31], --> start, end registers, repeated as needed
{"addr": [32, 34], "value": 0xF1}, --> with value
{"addr": [35, 36], "action": "increment"}, --> with action
{"addr": [37, 38], "action": "increment", "value": 0xF1} --> with action␣
˓→and value
(continues on next page)
],
"uint16": [ --> Define uint16 (1 register == 2 bytes)
--> same as type_bits
],
"uint32": [ --> Define 32 bit integers (2 registers == 4 bytes)
--> same as type_bits
],
"float32": [ --> Define 32 bit floats (2 registers == 4 bytes)
--> same as type_bits
],
"string": [ --> Define strings (variable number of registers (each 2 bytes))
[21, 22], --> start, end registers, define 1 string
{"addr": 23, 25], "value": "ups"}, --> with value
{"addr": 26, 27], "action": "user"}, --> with action
{"addr": 28, 29], "action": "", "value": "user"} --> with action and value
],
"repeat": [ --> allows to repeat section e.g. for n devices
{"addr": [100, 200], "to": [50, 275]} --> Repeat registers 100-200 to 50+␣
˓→until 275
]
}
get_text_register(register)
Get raw register.
classmethod build_registers_from_value(value, is_int)
Build registers from int32 or float32.
classmethod build_value_from_registers(registers, is_int)
Build int32 or float32 value from registers.
10.3 Framer
Ascii_framer.
class pymodbus.framer.ascii_framer.ModbusAsciiFramer(decoder, client=None)
Bases: ModbusFramer
Modbus ASCII Frame Controller.
[ Start ][Address ][ Function ][ Data ][ LRC ][ End ]
1c 2c 2c Nc 2c 2c
This framer is used for serial transmission. Unlike the RTU protocol, the data in this framer is transferred in
plain text ascii.
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Built off of a modbus request/response
Parameters
message – The request/response to send
Returns
The encoded packet
checkFrame()
Check and decode the next frame.
Returns
True if we successful, False otherwise
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, _tid=None, **kwargs)
Process new packet pattern.
getFrame()
Get the next frame from the buffer.
Returns
The frame data or “”
isFrameReady()
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data
in the buffer.
Returns
True if ready, False otherwise
method = 'ascii'
Binary framer.
class pymodbus.framer.binary_framer.ModbusBinaryFramer(decoder, client=None)
Bases: ModbusFramer
Modbus Binary Frame Controller.
[ Start ][Address ][ Function ][ Data ][ CRC ][ End ]
1b 1b 1b Nb 2b 1b
The idea here is that we implement the RTU protocol, however, instead of using timing for message delimiting,
we use start and end of message characters (in this case { and }). Basically, this is a binary framer.
The only case we have to watch out for is when a message contains the { or } characters. If we encounter these
characters, we simply duplicate them. Hopefully we will not encounter those characters that often and will save
a little bit of bandwitch without a real-time system.
Protocol defined by jamod.sourceforge.net.
advanceFrame() → None
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The request/response to send
Returns
The encoded packet
checkFrame() → bool
Check and decode the next frame.
Returns
True if we are successful, False otherwise
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, _tid=None, **kwargs)
Process new packet pattern.
getFrame()
Get the next frame from the buffer.
Returns
The frame data or “”
isFrameReady() → bool
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data
in the buffer.
Returns
True if ready, False otherwise
method = 'binary'
RTU framer.
class pymodbus.framer.rtu_framer.ModbusRtuFramer(decoder, client=None)
Bases: ModbusFramer
Modbus RTU Frame controller.
[ Start Wait ] [Address ][ Function Code] [ Data ][ CRC ][ End Wait ]
3.5 chars 1b 1b Nb 2b 3.5 chars
Wait refers to the amount of time required to transmit at least x many characters. In this case it is 3.5 characters.
Also, if we receive a wait of 1.5 characters at any point, we must trigger an error message. Also, it appears as
though this message is little endian. The logic is simplified as the following:
block-on-read:
read until 3.5 delay
check for errors
decode
The following table is a listing of the baud wait times for the specified baud rates:
------------------------------------------------------------------
Baud 1.5c (18 bits) 3.5c (38 bits)
------------------------------------------------------------------
1200 13333.3 us 31666.7 us
4800 3333.3 us 7916.7 us
9600 1666.7 us 3958.3 us
19200 833.3 us 1979.2 us
38400 416.7 us 989.6 us
------------------------------------------------------------------
1 Byte = start + 8 bits + parity + stop = 11 bits
(1/Baud)(bits) = delay seconds
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The populated request/response to send
checkFrame()
Check if the next frame is available.
Return True if we were successful.
1. Populate header
2. Discard frame if UID does not match
decode_data(data)
Decode data.
populateHeader(data=None)
Try to set the headers uid, len and crc.
This method examines self._buffer and writes meta information into self._header.
Beware that this method will raise an IndexError if self._buffer is not yet long enough.
populateResult(result)
Populate the modbus result header.
The serial packets do not have any header information that is copied.
Parameters
result – The response packet
recvPacket(size)
Receive packet from the bus with specified len.
Parameters
size – Number of bytes to read
Returns
resetFrame()
Reset the entire message frame.
This allows us to skip over errors that may be in the stream. It is hard to know if we are simply out of sync
or if there is an error in the stream as we have no way to check the start or end of the message (python just
doesn’t have the resolution to check for millisecond delays).
sendPacket(message)
Send packets on the bus with 3.5char delay between frames.
Parameters
message – Message to be sent over the bus
Returns
Socket framer.
class pymodbus.framer.socket_framer.ModbusSocketFramer(decoder, client=None)
Bases: ModbusFramer
Modbus Socket Frame controller.
Before each modbus TCP message is an MBAP header which is used as a message frame. It allows us to easily
separate messages as follows:
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The populated request/response to send
checkFrame()
Check and decode the next frame.
Return true if we were successful.
decode_data(data)
Decode data.
10.4 Constants
EXTENDED = 3
REGULAR = 2
SPECIFIC = 4
Note: I am simply borrowing the format strings from the python struct module for my convenience.
AUTO = '@'
BIG = '>'
LITTLE = '<'
GET_STATISTICS = 3
OFF
This indicates that the given modbus entity is off
SLAVE_ON
This indicates that the given modbus slave is running
SLAVE_OFF
This indicates that the given modbus slave is not running
OFF = 0
ON = 65280
READY = 0
SLAVE_OFF = 0
SLAVE_ON = 255
WAITING = 65535
NOTHING = 0
decode(data)
Decode a modbus exception response.
Parameters
data – The packet data to decode
encode()
Encode a modbus exception response.
Returns
The encoded exception packet
class pymodbus.Framer(value, names=None, *, module=None, qualname=None, type=None, start=1,
boundary=None)
Bases: str, Enum
These represent the different framers.
ASCII = 'ascii'
BINARY = 'binary'
RTU = 'rtu'
SOCKET = 'socket'
TLS = 'tls'
exception pymodbus.ModbusException(string)
Bases: Exception
Base modbus exception.
isError()
Error
pymodbus.pymodbus_apply_logging_config(level: str | int = 10, log_file_name: str | None = None)
Apply basic logging configuration used by default by Pymodbus maintainers.
Parameters
• level – (optional) set log level, if not set it is inherited.
• log_file_name – (optional) log additional to file
Please call this function to format logging appropriately when opening issues.
Bit Reading Request/Response messages.
class pymodbus.bit_read_message.ReadBitsResponseBase(values, slave=0, **kwargs)
Bases: ModbusResponse
Base class for Messages responding to bit-reading values.
The requested bits can be found in the .bits list.
bits
A list of booleans representing bit values
decode(data)
Decode response pdu.
Parameters
data – The packet data to decode
encode()
Encode response pdu.
Returns
The encoded packet message
getBit(address)
Get the specified bit’s value.
Parameters
address – The bit to query
Returns
The value of the requested bit
resetBit(address)
Set the specified bit to 0.
Parameters
address – The bit to reset
setBit(address, value=1)
Set the specified bit.
Parameters
• address – The bit to set
• value – The value to set the bit to
class pymodbus.bit_read_message.ReadCoilsRequest(address=None, count=None, slave=0, **kwargs)
Bases: ReadBitsRequestBase
This function code is used to read from 1 to 2000(0x7d0) contiguous status of coils in a remote device.
The Request PDU specifies the starting address, ie the address of the first coil specified, and the number of coils.
In the PDU Coils are addressed starting at zero. Therefore coils numbered 1-16 are addressed as 0-15.
execute(context)
Run a read coils request against a datastore.
Before running the request, we make sure that the request is in the max valid range (0x001-0x7d0). Next
we make sure that the request is valid against the current datastore.
Parameters
context – The datastore to request from
Returns
An initialized ReadCoilsResponse, or an ExceptionResponse if an error occurred
function_code = 1
function_code_name = 'read_coils'
If the returned output quantity is not a multiple of eight, the remaining bits in the final data byte will be padded
with zeros (toward the high order end of the byte). The Byte Count field specifies the quantity of complete bytes
of data.
The requested coils can be found in boolean form in the .bits list.
function_code = 1
function_code_name = 'read_discrete_input'
To either ON or OFF in a remote device. The Request PDU specifies the coil references to be forced. Coils are
addressed starting at zero. Therefore coil numbered 1 is addressed as 0.
The requested ON/OFF states are specified by contents of the request data field. A logical “1” in a bit position
of the field requests the corresponding output to be ON. A logical “0” requests it to be OFF.”
decode(data)
Decode a write coils request.
Parameters
data – The packet data to decode
encode()
Encode write coils request.
Returns
The byte encoded message
execute(context)
Run a write coils request against a datastore.
Parameters
context – The datastore to request from
Returns
The populated response or exception message
function_code = 15
function_code_name = 'write_coils'
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Output Address (2 byte) + Quantity of Outputs (2 Bytes) :return:
class pymodbus.bit_write_message.WriteMultipleCoilsResponse(address=None, count=None,
**kwargs)
Bases: ModbusResponse
The normal response returns the function code.
Starting address, and quantity of coils forced.
decode(data)
Decode a write coils response.
Parameters
data – The packet data to decode
encode()
Encode write coils response.
Returns
The byte encoded message
function_code = 15
function_code_name = 'write_coil'
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Output Address (2 byte) + Output Value (2 Bytes) :return:
class pymodbus.bit_write_message.WriteSingleCoilResponse(address=None, value=None, **kwargs)
Bases: ModbusResponse
The normal response is an echo of the request.
Returned after the coil state has been written.
decode(data)
Decode a write coil response.
Parameters
data – The packet data to decode
encode()
Encode write coil response.
Returns
The byte encoded message
function_code = 5
property ModelName
property ProductCode
property ProductName
property UserApplicationName
property VendorName
property VendorUrl
summary()
Return a summary of the main items.
Returns
An dictionary of the main items
update(value)
Update the values of this identity.
using another identify as the value
Parameters
value – The value to copy values from
class pymodbus.device.ModbusPlusStatistics
Bases: object
This is used to maintain the current modbus plus statistics count.
As of right now this is simply a stub to complete the modbus implementation. For more information, see the
modbus implementation guide page 87.
encode()
Return a summary of the modbus plus statistics.
Returns
54 16-bit words representing the status
reset()
Clear all of the modbus plus statistics.
summary()
Return a summary of the modbus plus statistics.
Returns
54 16-bit words representing the status
Diagnostic Record Read/Write.
These need to be tied into a the current server context or linked to the appropriate data
class pymodbus.diag_message.ChangeAsciiInputDelimiterRequest(data=0, **kwargs)
Bases: DiagnosticStatusSimpleRequest
Change ascii input delimiter.
The character “CHAR” passed in the request data field becomes the end of message delimiter for future messages
(replacing the default LF character). This function is useful in cases of a Line Feed is not required at the end of
ASCII messages.
execute(*args)
Execute the diagnostic request on the given device.
Returns
The initialized response message
sub_function_code = 3
class pymodbus.diag_message.DiagnosticStatusRequest(**kwargs)
Bases: ModbusRequest
This is a base class for all of the diagnostic request functions.
decode(data)
Decode a diagnostic request.
Parameters
data – The data to decode into the function code
encode()
Encode a diagnostic response.
we encode the data set in self.message
Returns
The encoded packet
function_code = 8
function_code_name = 'diagnostic_status'
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Sub function code (2 byte) + Data (2 * N bytes) :return:
class pymodbus.diag_message.DiagnosticStatusResponse(**kwargs)
Bases: ModbusResponse
Diagnostic status.
This is a base class for all of the diagnostic response functions
It works by performing all of the encoding and decoding of variable data and lets the higher classes define what
extra data to append and how to execute a request
decode(data)
Decode diagnostic response.
Parameters
data – The data to decode into the function code
encode()
Encode diagnostic response.
we encode the data set in self.message
Returns
The encoded packet
function_code = 8
class pymodbus.diag_message.ForceListenOnlyModeResponse(**kwargs)
Bases: DiagnosticStatusResponse
Forces the addressed remote device to its Listen Only Mode for MODBUS communications.
This isolates it from the other devices on the network, allowing them to continue communicating without inter-
ruption from the addressed remote device. No response is returned.
This does not send a response
should_respond = False
sub_function_code = 4
sub_function_code = 1
sub_function_code = 13
sub_function_code = 19
sub_function_code = 18
execute(*args)
Execute the diagnostic request on the given device.
Returns
The initialized response message
sub_function_code = 16
decode(event)
Decode the event message to its status bits.
Parameters
event – The event to decode
Raises
ParameterException –
encode()
Encode the status bits to an event message.
Returns
The encoded event message
value = 0
class pymodbus.events.EnteredListenModeEvent
Bases: ModbusEvent
Enter Remote device Listen Only Mode.
The remote device stores this type of event byte when it enters the Listen Only Mode. The event is defined by a
content of 04 hex.
decode(event)
Decode the event message to its status bits.
Parameters
event – The event to decode
Raises
ParameterException –
encode()
Encode the status bits to an event message.
Returns
The encoded event message
value = 4
class pymodbus.events.ModbusEvent
Bases: object
Define modbus events.
decode(event)
Decode the event message to its status bits.
Parameters
event – The event to decode
Raises
NotImplementedException –
encode()
Encode the status bits to an event message.
Raises
NotImplementedException –
class pymodbus.events.RemoteReceiveEvent(**kwargs)
Bases: ModbusEvent
Remote device MODBUS Receive Event.
The remote device stores this type of event byte when a query message is received. It is stored before the remote
device processes the message. This event is defined by bit 7 set to logic “1”. The other bits will be set to a logic
“1” if the corresponding condition is TRUE. The bit layout is:
Bit Contents
----------------------------------
0 Not Used
2 Not Used
3 Not Used
4 Character Overrun
5 Currently in Listen Only Mode
6 Broadcast Receive
7 1
Bit Contents
-----------------------------------------------------------
0 Read Exception Sent (Exception Codes 1-3)
1 Slave Abort Exception Sent (Exception Code 4)
2 Slave Busy Exception Sent (Exception Codes 5-6)
3 Slave Program NAK Exception Sent (Exception Code 7)
4 Write Timeout Error Occurred
5 Currently in Listen Only Mode
6 1
7 0
decode(event)
Decode the event message to its status bits.
Parameters
event – The event to decode
encode()
Encode the status bits to an event message.
Returns
The encoded event message
Pymodbus Exceptions.
Custom exceptions to be used in the Modbus code.
exception pymodbus.exceptions.ConnectionException(string='')
Bases: ModbusException
Error resulting from a bad connection.
exception pymodbus.exceptions.InvalidMessageReceivedException(string='')
Bases: ModbusException
Error resulting from invalid response received or decoded.
exception pymodbus.exceptions.MessageRegisterException(string='')
Bases: ModbusException
Error resulting from failing to register a custom message request/response.
exception pymodbus.exceptions.ModbusIOException(string='', function_code=None)
Bases: ModbusException
Error resulting from data i/o.
exception pymodbus.exceptions.NoSuchSlaveException(string='')
Bases: ModbusException
Error resulting from making a request to a slave that does not exist.
exception pymodbus.exceptions.NotImplementedException(string='')
Bases: ModbusException
Error resulting from not implemented function.
exception pymodbus.exceptions.ParameterException(string='')
Bases: ModbusException
Error resulting from invalid parameter.
Modbus Request/Response Decoder Factories.
The following factories make it easy to decode request/response messages. To add a new request/response pair to be
decodeable by the library, simply add them to the respective function lookup table (order doesn’t matter, but it does
help keep things organized).
Regardless of how many functions are added to the lookup, O(1) behavior is kept as a result of a pre-computed lookup
dictionary.
class pymodbus.factory.ClientDecoder
Bases: object
Response Message Factory (Client).
To add more implemented functions, simply add them to the list
decode(message)
Decode a response packet.
Parameters
message – The raw packet to decode
Returns
The decoded modbus message or None if error
function_table = [<class
'pymodbus.register_read_message.ReadHoldingRegistersResponse'>, <class
'pymodbus.bit_read_message.ReadDiscreteInputsResponse'>, <class
'pymodbus.register_read_message.ReadInputRegistersResponse'>, <class
'pymodbus.bit_read_message.ReadCoilsResponse'>, <class
'pymodbus.bit_write_message.WriteMultipleCoilsResponse'>, <class
'pymodbus.register_write_message.WriteMultipleRegistersResponse'>, <class
'pymodbus.register_write_message.WriteSingleRegisterResponse'>, <class
'pymodbus.bit_write_message.WriteSingleCoilResponse'>, <class
'pymodbus.register_read_message.ReadWriteMultipleRegistersResponse'>, <class
'pymodbus.diag_message.DiagnosticStatusResponse'>, <class
'pymodbus.other_message.ReadExceptionStatusResponse'>, <class
'pymodbus.other_message.GetCommEventCounterResponse'>, <class
'pymodbus.other_message.GetCommEventLogResponse'>, <class
'pymodbus.other_message.ReportSlaveIdResponse'>, <class
'pymodbus.file_message.ReadFileRecordResponse'>, <class
'pymodbus.file_message.WriteFileRecordResponse'>, <class
'pymodbus.register_write_message.MaskWriteRegisterResponse'>, <class
'pymodbus.file_message.ReadFifoQueueResponse'>, <class
'pymodbus.mei_message.ReadDeviceInformationResponse'>]
lookupPduClass(function_code)
Use function_code to determine the class of the PDU.
Parameters
function_code – The function code specified in a frame.
Returns
The class of the PDU that has a matching function_code.
register(function)
Register a function and sub function class with the decoder.
class pymodbus.factory.ServerDecoder
Bases: object
Request Message Factory (Server).
To add more implemented functions, simply add them to the list
decode(message)
Decode a request packet.
Parameters
message – The raw modbus request packet
Returns
The decoded modbus message or None if error
classmethod getFCdict()
Build function code - class list.
lookupPduClass(function_code)
Use function_code to determine the class of the PDU.
Parameters
function_code – The function code specified in a frame.
Returns
The class of the PDU that has a matching function_code.
register(function=None)
Register a function and sub function class with the decoder.
Parameters
function – Custom function class to register
Raises
MessageRegisterException –
File Record Read/Write Messages.
Currently none of these messages are implemented
class pymodbus.file_message.FileRecord(**kwargs)
Bases: object
Represents a file record and its relevant data.
class pymodbus.file_message.ReadFifoQueueRequest(address=0, **kwargs)
Bases: ModbusRequest
Read fifo queue request.
This function code allows to read the contents of a First-In-First-Out (FIFO) queue of register in a remote device.
The function returns a count of the registers in the queue, followed by the queued data. Up to 32 registers can be
read: the count, plus up to 31 queued data registers.
The queue count register is returned first, followed by the queued data registers. The function reads the queue
contents, but does not clear them.
decode(data)
Decode the incoming request.
Parameters
data – The data to decode into the address
encode()
Encode the request packet.
Returns
The byte encoded packet
execute(_context)
Run a read exception status request against the store.
Returns
The populated response
function_code = 24
function_code_name = 'read_fifo_queue'
The quantity of registers to be read, combined with all other fields in the expected response, must not exceed the
allowable length of the MODBUS PDU: 235 bytes.
decode(data)
Decode the incoming request.
Parameters
data – The data to decode into the address
encode()
Encode the request packet.
Returns
The byte encoded packet
execute(_context)
Run a read exception status request against the store.
Returns
The populated response
function_code = 20
function_code_name = 'read_file_record'
execute(_context)
Run the write file record request against the context.
Returns
The populated response
function_code = 21
function_code_name = 'write_file_record'
function_code_name = 'read_device_information'
sub_function_code = 14
sub_function_code = 14
encode()
Encode the message.
execute(_context=None)
Run a read exception status request against the store.
Returns
The populated response
function_code = 11
function_code_name = 'get_event_counter'
class pymodbus.other_message.GetCommEventLogRequest(**kwargs)
Bases: ModbusRequest
This function code is used to get a status word.
Event count, message count, and a field of event bytes from the remote device.
The status word and event counts are identical to that returned by the Get Communications Event Counter function
(11, 0B hex).
The message counter contains the quantity of messages processed by the remote device since its last restart, clear
counters operation, or power-up. This count is identical to that returned by the Diagnostic function (code 08),
sub-function Return Bus Message Count (code 11, 0B hex).
The event bytes field contains 0-64 bytes, with each byte corresponding to the status of one MODBUS send or
receive operation for the remote device. The remote device enters the events into the field in chronological order.
Byte 0 is the most recent event. Each new byte flushes the oldest byte from the field.
decode(data)
Decode data part of the message.
Parameters
data – The incoming data
encode()
Encode the message.
execute(_context=None)
Run a read exception status request against the store.
Returns
The populated response
function_code = 12
function_code_name = 'get_event_log'
class pymodbus.other_message.GetCommEventLogResponse(**kwargs)
Bases: ModbusResponse
Get Comm event log response.
The normal response contains a two-byte status word field, a two-byte event count field, a two-byte message
count field, and a field containing 0-64 bytes of events. A byte count field defines the total length of the data in
these four field
decode(data)
Decode a the response.
Parameters
data – The packet data to decode
encode()
Encode the response.
Returns
The byte encoded message
function_code = 12
function_code_name = 'read_exception_status'
function_code_name = 'report_slave_id'
Parameters
data – The packet data to decode
encode()
Encode the response.
Returns
The byte encoded message
function_code = 17
builder = BinaryPayloadBuilder(byteorder=Endian.Little)
builder.add_8bit_uint(1)
builder.add_16bit_uint(2)
payload = builder.build()
reset() → None
Reset the payload buffer.
to_coils() → list[bool]
Convert the payload buffer into a coil layout that can be used as a context block.
Returns
The coil layout to use as a block
to_registers()
Convert the payload buffer to register layout that can be used as a context block.
Returns
The register layout to use as a block
class pymodbus.payload.BinaryPayloadDecoder(payload, byteorder=Endian.LITTLE,
wordorder=Endian.BIG)
Bases: object
A utility that helps decode payload messages from a modbus response message.
It really is just a simple wrapper around the struct module, however it saves time looking up the format strings.
What follows is a simple example:
decoder = BinaryPayloadDecoder(payload)
first = decoder.decode_8bit_uint()
second = decoder.decode_16bit_uint()
decode_8bit_int()
Decode a 8 bit signed int from the buffer.
decode_8bit_uint()
Decode a 8 bit unsigned int from the buffer.
decode_bits(package_len=1)
Decode a byte worth of bits from the buffer.
decode_string(size=1)
Decode a string from the buffer.
Parameters
size – The size of the string to decode
classmethod fromCoils(coils, byteorder=Endian.LITTLE, _wordorder=Endian.BIG)
Initialize a payload decoder with the result of reading of coils.
classmethod fromRegisters(registers, byteorder=Endian.LITTLE, wordorder=Endian.BIG)
Initialize a payload decoder.
With the result of reading a collection of registers from a modbus device.
The registers are treated as a list of 2 byte values. We have to do this because of how the data has already
been decoded by the rest of the library.
Parameters
• registers – The register results to initialize with
• byteorder – The Byte order of each word
• wordorder – The endianness of the word (when wordcount is >= 2)
Returns
An initialized PayloadDecoder
Raises
ParameterException –
reset()
Reset the decoder pointer back to the start.
skip_bytes(nbytes)
Skip n bytes in the buffer.
Parameters
nbytes – The number of bytes to skip
Contains base classes for modbus request/response/error packets.
class pymodbus.pdu.ExceptionResponse(function_code, exception_code=None, **kwargs)
Bases: ModbusResponse
Base class for a modbus exception PDU.
ExceptionOffset = 128
decode(data)
Decode a modbus exception response.
Parameters
data – The packet data to decode
encode()
Encode a modbus exception response.
Returns
The encoded exception packet
class pymodbus.pdu.IllegalFunctionRequest(function_code, **kwargs)
Bases: ModbusRequest
Define the Modbus slave exception type “Illegal Function”.
This exception code is returned if the slave:
ErrorCode = 1
decode(_data)
Decode so this failure will run correctly.
execute(_context)
Build an illegal function request error response.
Returns
The error response packet
class pymodbus.pdu.ModbusExceptions
Bases: object
An enumeration of the valid modbus exceptions.
Acknowledge = 5
GatewayNoResponse = 11
GatewayPathUnavailable = 10
IllegalAddress = 2
IllegalFunction = 1
IllegalValue = 3
MemoryParityError = 8
SlaveBusy = 6
SlaveFailure = 4
classmethod decode(code)
Give an error code, translate it to a string error name.
Parameters
code – The code number to translate
class pymodbus.pdu.ModbusRequest(slave=0, **kwargs)
Bases: ModbusPDU
Base class for a modbus request PDU.
doException(exception)
Build an error response based on the function.
Parameters
exception – The exception to return
Raises
An exception response
function_code = -1
isError() → bool
Check if the error is a success or failure.
should_respond = True
function_code_name = 'read_holding_registers'
This function code is used to read the contents of a contiguous block of holding registers in a remote device.
The Request PDU specifies the starting register address and the number of registers. In the PDU Registers are
addressed starting at zero. Therefore registers numbered 1-16 are addressed as 0-15.
The requested registers can be found in the .registers list.
function_code = 3
function_code_name = 'read_input_registers'
getRegister(index)
Get the requested register.
Parameters
index – The indexed register to retrieve
Returns
The request register
registers
A list of register values
class pymodbus.register_read_message.ReadWriteMultipleRegistersRequest(**kwargs)
Bases: ModbusRequest
Read/write multiple registers.
This function code performs a combination of one read operation and one write operation in a single MODBUS
transaction. The write operation is performed before the read.
Holding registers are addressed starting at zero. Therefore holding registers 1-16 are addressed in the PDU as
0-15.
The request specifies the starting address and number of holding registers to be read as well as the starting address,
number of holding registers, and the data to be written. The byte count specifies the number of bytes to follow
in the write data field.”
decode(data)
Decode the register request packet.
Parameters
data – The request to decode
encode()
Encode the request packet.
Returns
The encoded packet
execute(context)
Run a write single register request against a datastore.
Parameters
context – The datastore to request from
Returns
An initialized ReadWriteMultipleRegistersResponse, or an ExceptionResponse if
an error occurred
function_code = 23
function_code_name = 'read_write_multiple_registers'
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Byte Count(1 byte) + 2 * Quantity of Coils (n Bytes) :return:
class pymodbus.register_read_message.ReadWriteMultipleRegistersResponse(values=None,
**kwargs)
Bases: ModbusResponse
Read/write multiple registers.
The normal response contains the data from the group of registers that were read. The byte count field specifies
the quantity of bytes to follow in the read data field.
The requested registers can be found in the .registers list.
decode(data)
Decode the register response packet.
Parameters
data – The response to decode
encode()
Encode the response packet.
Returns
The encoded packet
function_code = 23
function_code_name = 'mask_write_register'
class pymodbus.register_write_message.WriteMultipleRegistersRequest(address=None,
values=None, slave=None,
**kwargs)
Bases: ModbusRequest
This function code is used to write a block.
Of contiguous registers (1 to approx. 120 registers) in a remote device.
The requested written values are specified in the request data field. Data is packed as two bytes per register.
decode(data)
Decode a write single register packet packet request.
Parameters
data – The request to decode
encode()
Encode a write single register packet packet request.
Returns
The encoded packet
execute(context)
Run a write single register request against a datastore.
Parameters
context – The datastore to request from
Returns
An initialized response, exception message otherwise
function_code = 16
function_code_name = 'write_registers'
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Starting Address (2 byte) + Quantity of Registers (2 Bytes) :return:
class pymodbus.register_write_message.WriteMultipleRegistersResponse(address=None,
count=None, **kwargs)
Bases: ModbusResponse
The normal response returns the function code.
Starting address, and quantity of registers written.
decode(data)
Decode a write single register packet packet request.
Parameters
data – The request to decode
encode()
Encode a write single register packet packet request.
Returns
The encoded packet
function_code = 16
function_code_name = 'write_register'
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Register Address(2 byte) + Register Value (2 bytes) :return:
get_response_pdu_size()
Get response pdu size.
Func_code (1 byte) + Starting Address (2 byte) + And_mask (2 Bytes) + OrMask (2 Bytes) :return:
Collection of transaction based abstractions.
class pymodbus.transaction.DictTransactionManager(client, **kwargs)
Bases: ModbusTransactionManager
Implements a transaction for a manager.
Where the results are keyed based on the supplied transaction id.
addTransaction(request, tid=None)
Add a transaction to the handler.
This holds the requests in case it needs to be resent. After being sent, the request is removed.
Parameters
• request – The request to hold on to
• tid – The overloaded transaction id to use
delTransaction(tid)
Remove a transaction matching the referenced tid.
Parameters
tid – The transaction to remove
getTransaction(tid)
Return a transaction matching the referenced tid.
If the transaction does not exist, None is returned
Parameters
tid – The transaction to retrieve
This framer is used for serial transmission. Unlike the RTU protocol, the data in this framer is transferred in
plain text ascii.
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Built off of a modbus request/response
Parameters
message – The request/response to send
Returns
The encoded packet
checkFrame()
Check and decode the next frame.
Returns
True if we successful, False otherwise
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, _tid=None, **kwargs)
Process new packet pattern.
getFrame()
Get the next frame from the buffer.
Returns
The frame data or “”
isFrameReady()
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data
in the buffer.
Returns
True if ready, False otherwise
method = 'ascii'
The idea here is that we implement the RTU protocol, however, instead of using timing for message delimiting,
we use start and end of message characters (in this case { and }). Basically, this is a binary framer.
The only case we have to watch out for is when a message contains the { or } characters. If we encounter these
characters, we simply duplicate them. Hopefully we will not encounter those characters that often and will save
a little bit of bandwitch without a real-time system.
Protocol defined by jamod.sourceforge.net.
advanceFrame() → None
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The request/response to send
Returns
The encoded packet
checkFrame() → bool
Check and decode the next frame.
Returns
True if we are successful, False otherwise
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, _tid=None, **kwargs)
Process new packet pattern.
getFrame()
Get the next frame from the buffer.
Returns
The frame data or “”
isFrameReady() → bool
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data
in the buffer.
Returns
True if ready, False otherwise
method = 'binary'
block-on-read:
read until 3.5 delay
check for errors
decode
The following table is a listing of the baud wait times for the specified baud rates:
------------------------------------------------------------------
Baud 1.5c (18 bits) 3.5c (38 bits)
------------------------------------------------------------------
(continues on next page)
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The populated request/response to send
checkFrame()
Check if the next frame is available.
Return True if we were successful.
1. Populate header
2. Discard frame if UID does not match
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, _tid=None, **kwargs)
Process new packet pattern.
getFrame()
Get the next frame from the buffer.
Returns
The frame data or “”
getFrameStart(slaves, broadcast, skip_cur_frame)
Scan buffer for a relevant frame start.
get_expected_response_length(data)
Get the expected response length.
Parameters
data – Message data read so far
Raises
IndexError – If not enough data to read byte count
Returns
Total frame size
isFrameReady()
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data
in the buffer.
Returns
True if ready, False otherwise
method = 'rtu'
populateHeader(data=None)
Try to set the headers uid, len and crc.
This method examines self._buffer and writes meta information into self._header.
Beware that this method will raise an IndexError if self._buffer is not yet long enough.
populateResult(result)
Populate the modbus result header.
The serial packets do not have any header information that is copied.
Parameters
result – The response packet
recvPacket(size)
Receive packet from the bus with specified len.
Parameters
size – Number of bytes to read
Returns
resetFrame()
Reset the entire message frame.
This allows us to skip over errors that may be in the stream. It is hard to know if we are simply out of sync
or if there is an error in the stream as we have no way to check the start or end of the message (python just
doesn’t have the resolution to check for millisecond delays).
sendPacket(message)
Send packets on the bus with 3.5char delay between frames.
Parameters
message – Message to be sent over the bus
Returns
class pymodbus.transaction.ModbusSocketFramer(decoder, client=None)
Bases: ModbusFramer
Modbus Socket Frame controller.
Before each modbus TCP message is an MBAP header which is used as a message frame. It allows us to easily
separate messages as follows:
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The populated request/response to send
checkFrame()
Check and decode the next frame.
Return true if we were successful.
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, tid=None, **kwargs)
Process new packet pattern.
This takes in a new request packet, adds it to the current packet stream, and performs framing on it. That
is, checks for complete messages, and once found, will process all that exist. This handles the case when
we read N + 1 or 1 // N messages at a time instead of 1.
The processed and decoded messages are pushed to the callback function to process and send.
getFrame()
Return the next frame from the buffered data.
Returns
The next full frame buffer
isFrameReady()
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder factory know that there is
still data in the buffer.
Returns
True if ready, False otherwise
method = 'socket'
No prefix MBAP header before decrypted PDU is used as a message frame for Modbus Security Application
Protocol. It allows us to easily separate decrypted messages which is PDU as follows:
[ Function Code] [ Data ]
1b Nb
advanceFrame()
Skip over the current framed message.
This allows us to skip over the current message after we have processed it or determined that it contains an
error. It also has to reset the current frame header handle
buildPacket(message)
Create a ready to send modbus packet.
Parameters
message – The populated request/response to send
checkFrame()
Check and decode the next frame.
Return true if we were successful.
decode_data(data)
Decode data.
frameProcessIncomingPacket(single, callback, slave, _tid=None, **kwargs)
Process new packet pattern.
getFrame()
Return the next frame from the buffered data.
Returns
The next full frame buffer
isFrameReady()
Check if we should continue decode logic.
This is meant to be used in a while loop in the decoding phase to let the decoder factory know that there is
still data in the buffer.
Returns
True if ready, False otherwise
method = 'tls'
Modbus Utilities.
A collection of utilities for packing data, unpacking data computing checksums, and decode checksums.
pymodbus.utilities.checkCRC(data, check)
Check if the data matches the passed in CRC.
Parameters
• data – The data to create a crc16 of
• check – The CRC to validate
Returns
True if matched, False otherwise
pymodbus.utilities.checkLRC(data, check)
Check if the passed in data matches the LRC.
Parameters
• data – The data to calculate
• check – The LRC to validate
Returns
True if matched, False otherwise
pymodbus.utilities.computeCRC(data)
Compute a crc16 on the passed in string.
For modbus, this is only used on the binary serial protocols (in this case RTU).
The difference between modbus’s crc16 and a normal crc16 is that modbus starts the crc value out at 0xffff.
Parameters
data – The data to create a crc16 of
Returns
The calculated CRC
pymodbus.utilities.computeLRC(data)
Use to compute the longitudinal redundancy check against a string.
This is only used on the serial ASCII modbus protocol. A full description of this implementation can be found
in appendix B of the serial line modbus description.
Parameters
data – The data to apply a lrc to
Returns
The calculated LRC
pymodbus.utilities.default(value)
Return the default value of object.
Parameters
value – The value to get the default of
Returns
The default value
pymodbus.utilities.pack_bitstring(bits: list[bool]) → bytes
Create a bytestring out of a list of bits.
Parameters
bits – A list of bits
example:
pymodbus.utilities.rtuFrameSize(data, byte_count_pos)
Calculate the size of the frame based on the byte count.
Parameters
• data – The buffer containing the frame.
p
pymodbus, 137
pymodbus.bit_read_message, 138
pymodbus.bit_write_message, 140
pymodbus.device, 143
pymodbus.diag_message, 144
pymodbus.events, 152
pymodbus.exceptions, 155
pymodbus.factory, 155
pymodbus.file_message, 157
pymodbus.framer.ascii_framer, 129
pymodbus.framer.binary_framer, 130
pymodbus.framer.rtu_framer, 132
pymodbus.framer.socket_framer, 134
pymodbus.mei_message, 160
pymodbus.other_message, 161
pymodbus.payload, 165
pymodbus.register_read_message, 170
pymodbus.register_write_message, 173
pymodbus.repl.client.mclient, 45
pymodbus.server, 33
pymodbus.server.simulator.http_server, 73
pymodbus.transaction, 176
pymodbus.utilities, 183
187
PyModbus, Release 3.7.0dev
189
PyModbus, Release 3.7.0dev
190 Index
PyModbus, Release 3.7.0dev
Index 191
PyModbus, Release 3.7.0dev
192 Index
PyModbus, Release 3.7.0dev
Index 193
PyModbus, Release 3.7.0dev
194 Index
PyModbus, Release 3.7.0dev
encode() (pymodbus.register_write_message.MaskWriteRegisterResponse
method), 151
method), 174 execute() (pymodbus.diag_message.ReturnSlaveNAKCountRequest
encode() (pymodbus.register_write_message.WriteMultipleRegistersRequest
method), 151
method), 174 execute() (pymodbus.diag_message.ReturnSlaveNoResponseCountReques
encode() (pymodbus.register_write_message.WriteMultipleRegistersResponse
method), 152
method), 175 execute() (pymodbus.file_message.ReadFifoQueueRequest
encode() (pymodbus.register_write_message.WriteSingleRegisterRequest
method), 157
method), 175 execute() (pymodbus.file_message.ReadFileRecordRequest
encode() (pymodbus.register_write_message.WriteSingleRegisterResponse
method), 159
method), 176 execute() (pymodbus.file_message.WriteFileRecordRequest
EnteredListenModeEvent (class in pymodbus.events), method), 159
153 execute() (pymodbus.mei_message.ReadDeviceInformationRequest
ExceptionOffset (pymodbus.ExceptionResponse method), 160
attribute), 137 execute() (pymodbus.other_message.GetCommEventCounterRequest
ExceptionResponse (class in pymodbus), 137 method), 162
execute() (pymodbus.bit_read_message.ReadCoilsRequestexecute() (pymodbus.other_message.GetCommEventLogRequest
method), 139 method), 163
execute() (pymodbus.bit_read_message.ReadDiscreteInputsRequest
execute() (pymodbus.other_message.ReadExceptionStatusRequest
method), 140 method), 163
execute() (pymodbus.bit_write_message.WriteMultipleCoilsRequest
execute() (pymodbus.other_message.ReportSlaveIdRequest
method), 141 method), 164
execute() (pymodbus.bit_write_message.WriteSingleCoilRequest
execute() (pymodbus.register_read_message.ReadHoldingRegistersReque
method), 142 method), 170
execute() (pymodbus.client.mixin.ModbusClientMixin execute() (pymodbus.register_read_message.ReadInputRegistersRequest
method), 24 method), 171
execute() (pymodbus.diag_message.ChangeAsciiInputDelimiterRequest
execute() (pymodbus.register_read_message.ReadWriteMultipleRegisters
method), 144 method), 172
execute() (pymodbus.diag_message.ClearCountersRequestexecute() (pymodbus.register_write_message.MaskWriteRegisterRequest
method), 145 method), 173
execute() (pymodbus.diag_message.ClearOverrunCountRequest
execute() (pymodbus.register_write_message.WriteMultipleRegistersRequ
method), 145 method), 174
execute() (pymodbus.diag_message.ForceListenOnlyModeRequest
execute() (pymodbus.register_write_message.WriteSingleRegisterRequest
method), 146 method), 175
execute() (pymodbus.diag_message.GetClearModbusPlusRequest
EXTENDED (pymodbus.constants.DeviceInformation at-
method), 147 tribute), 135
execute() (pymodbus.diag_message.RestartCommunicationsOptionRequest
ExtendedRequestSupport (class in pymod-
method), 147 bus.repl.client.mclient), 45
execute() (pymodbus.diag_message.ReturnBusCommunicationErrorCountRequest
method), 148 F
execute() (pymodbus.diag_message.ReturnBusExceptionErrorCountRequest
FifoTransactionManager (class in pymod-
method), 148 bus.transaction), 176
execute() (pymodbus.diag_message.ReturnBusMessageCountRequest
FileRecord (class in pymodbus.file_message), 157
method), 149 force_listen_only_mode() (pymod-
execute() (pymodbus.diag_message.ReturnDiagnosticRegisterRequestbus.repl.client.mclient.ExtendedRequestSupport
method), 149 method), 45
execute() (pymodbus.diag_message.ReturnIopOverrunCountRequest
ForceListenOnlyModeRequest (class in pymod-
method), 149 bus.diag_message), 146
execute() (pymodbus.diag_message.ReturnQueryDataRequest
ForceListenOnlyModeResponse (class in pymod-
method), 150 bus.diag_message), 146
execute() (pymodbus.diag_message.ReturnSlaveBusCharacterOverrunCountRequest
frameProcessIncomingPacket() (pymod-
method), 150 bus.framer.ascii_framer.ModbusAsciiFramer
execute() (pymodbus.diag_message.ReturnSlaveBusyCountRequest method), 130
method), 151 frameProcessIncomingPacket() (pymod-
execute() (pymodbus.diag_message.ReturnSlaveMessageCountRequest bus.framer.binary_framer.ModbusBinaryFramer
Index 195
PyModbus, Release 3.7.0dev
196 Index
PyModbus, Release 3.7.0dev
Index 197
PyModbus, Release 3.7.0dev
method), 46 bus.repl.client.mclient.ModbusSerialClient
get_com_event_log() (pymod- method), 52
bus.repl.client.mclient.ExtendedRequestSupport getBit() (pymodbus.bit_read_message.ReadBitsResponseBase
method), 46 method), 139
get_expected_response_length() (pymod- GetClearModbusPlusRequest (class in pymod-
bus.framer.rtu_framer.ModbusRtuFramer bus.diag_message), 147
method), 133 GetClearModbusPlusResponse (class in pymod-
get_expected_response_length() (pymod- bus.diag_message), 147
bus.transaction.ModbusRtuFramer method), GetCommEventCounterRequest (class in pymod-
180 bus.other_message), 161
get_parity() (pymod- GetCommEventCounterResponse (class in pymod-
bus.repl.client.mclient.ModbusSerialClient bus.other_message), 162
method), 51 GetCommEventLogRequest (class in pymod-
get_port() (pymodbus.repl.client.mclient.ModbusSerialClient bus.other_message), 162
method), 51 GetCommEventLogResponse (class in pymod-
get_response_pdu_size() (pymod- bus.other_message), 163
bus.bit_write_message.WriteMultipleCoilsRequestgetFCdict() (pymodbus.factory.ServerDecoder class
method), 141 method), 156
get_response_pdu_size() (pymod- getFrame() (pymodbus.framer.ascii_framer.ModbusAsciiFramer
bus.bit_write_message.WriteSingleCoilRequest method), 130
method), 142 getFrame() (pymodbus.framer.binary_framer.ModbusBinaryFramer
get_response_pdu_size() (pymod- method), 131
bus.diag_message.DiagnosticStatusRequest getFrame() (pymodbus.framer.rtu_framer.ModbusRtuFramer
method), 146 method), 133
get_response_pdu_size() (pymod- getFrame() (pymodbus.framer.socket_framer.ModbusSocketFramer
bus.diag_message.GetClearModbusPlusRequest method), 135
method), 147 getFrame() (pymodbus.transaction.ModbusAsciiFramer
get_response_pdu_size() (pymod- method), 178
bus.register_read_message.ReadWriteMultipleRegistersRequest
getFrame() (pymodbus.transaction.ModbusBinaryFramer
method), 172 method), 179
get_response_pdu_size() (pymod- getFrame() (pymodbus.transaction.ModbusRtuFramer
bus.register_write_message.WriteMultipleRegistersRequest method), 180
method), 174 getFrame() (pymodbus.transaction.ModbusSocketFramer
get_response_pdu_size() (pymod- method), 182
bus.register_write_message.WriteSingleRegisterRequest
getFrame() (pymodbus.transaction.ModbusTlsFramer
method), 175 method), 183
get_response_pdu_size() (pymod- getFrameStart() (pymod-
bus.register_write_message.WriteSingleRegisterResponse bus.framer.rtu_framer.ModbusRtuFramer
method), 176 method), 133
get_serial_settings() (pymod- getFrameStart() (pymod-
bus.repl.client.mclient.ModbusSerialClient bus.transaction.ModbusRtuFramer method),
method), 51 180
get_simulator_commandline() (in module pymod- getRegister() (pymod-
bus.server), 37 bus.register_read_message.ReadRegistersResponseBase
GET_STATISTICS (pymod- method), 172
bus.constants.ModbusPlusOperation attribute), getTransaction() (pymod-
136 bus.transaction.DictTransactionManager
get_stopbits() (pymod- method), 176
bus.repl.client.mclient.ModbusSerialClient getTransaction() (pymod-
method), 52 bus.transaction.FifoTransactionManager
get_text_register() (pymod- method), 177
bus.datastore.ModbusSimulatorContext getValues() (pymodbus.datastore.ModbusSlaveContext
method), 129 method), 127
get_timeout() (pymod- getValues() (pymodbus.datastore.ModbusSparseDataBlock
198 Index
PyModbus, Release 3.7.0dev
Index 199
PyModbus, Release 3.7.0dev
200 Index
PyModbus, Release 3.7.0dev
R
ProductCode (pymodbus.device.ModbusDeviceIdentification
property), 143 read_coils() (pymod-
ProductName (pymodbus.device.ModbusDeviceIdentification bus.client.mixin.ModbusClientMixin method),
property), 143 24
pymodbus read_coils() (pymod-
module, 137 bus.repl.client.mclient.ExtendedRequestSupport
pymodbus.bit_read_message method), 46
module, 138 read_device_information() (pymod-
pymodbus.bit_write_message bus.client.mixin.ModbusClientMixin method),
module, 140 32
pymodbus.device read_device_information() (pymod-
module, 143 bus.repl.client.mclient.ExtendedRequestSupport
pymodbus.diag_message method), 47
module, 144 read_discrete_inputs() (pymod-
pymodbus.events bus.client.mixin.ModbusClientMixin method),
module, 152 25
pymodbus.exceptions read_discrete_inputs() (pymod-
module, 155 bus.repl.client.mclient.ExtendedRequestSupport
pymodbus.factory method), 47
module, 155 read_exception_status() (pymod-
pymodbus.file_message bus.client.mixin.ModbusClientMixin method),
module, 157 26
pymodbus.framer.ascii_framer read_exception_status() (pymod-
module, 129 bus.repl.client.mclient.ExtendedRequestSupport
pymodbus.framer.binary_framer method), 47
module, 130 read_fifo_queue() (pymod-
pymodbus.framer.rtu_framer bus.client.mixin.ModbusClientMixin method),
module, 132 31
pymodbus.framer.socket_framer read_file_record() (pymod-
module, 134 bus.client.mixin.ModbusClientMixin method),
pymodbus.mei_message 30
module, 160 read_holding_registers() (pymod-
pymodbus.other_message bus.client.mixin.ModbusClientMixin method),
module, 161 25
pymodbus.payload read_holding_registers() (pymod-
module, 165 bus.repl.client.mclient.ExtendedRequestSupport
pymodbus.register_read_message method), 47
module, 170 read_input_registers() (pymod-
pymodbus.register_write_message bus.client.mixin.ModbusClientMixin method),
module, 173 25
pymodbus.repl.client.mclient read_input_registers() (pymod-
module, 45 bus.repl.client.mclient.ExtendedRequestSupport
pymodbus.server method), 47
module, 33 ReadBitsResponseBase (class in pymod-
pymodbus.server.simulator.http_server bus.bit_read_message), 138
module, 73 ReadCoilsRequest (class in pymod-
pymodbus.transaction bus.bit_read_message), 139
module, 176 ReadCoilsResponse (class in pymod-
pymodbus.utilities bus.bit_read_message), 139
module, 183 ReadDeviceInformationRequest (class in pymod-
pymodbus_apply_logging_config() (in module py- bus.mei_message), 160
modbus), 138 ReadDeviceInformationResponse (class in pymod-
bus.mei_message), 161
ReadDiscreteInputsRequest (class in pymod-
Index 201
PyModbus, Release 3.7.0dev
202 Index
PyModbus, Release 3.7.0dev
Index 203
PyModbus, Release 3.7.0dev
method), 52 bus.server.simulator.http_server.ModbusSimulatorServer
set_timeout() (pymod- method), 74
bus.repl.client.mclient.ModbusSerialClient sub_function_code (pymod-
method), 52 bus.diag_message.ChangeAsciiInputDelimiterRequest
setBit() (pymodbus.bit_read_message.ReadBitsResponseBase attribute), 144
method), 139 sub_function_code (pymod-
setValues() (pymodbus.datastore.ModbusSlaveContext bus.diag_message.ChangeAsciiInputDelimiterResponse
method), 127 attribute), 144
setValues() (pymodbus.datastore.ModbusSparseDataBlock sub_function_code (pymod-
method), 126 bus.diag_message.ClearCountersRequest
should_respond (pymod- attribute), 145
bus.diag_message.ForceListenOnlyModeResponsesub_function_code (pymod-
attribute), 146 bus.diag_message.ClearCountersResponse
should_respond (pymodbus.pdu.ModbusResponse at- attribute), 145
tribute), 170 sub_function_code (pymod-
skip_bytes() (pymod- bus.diag_message.ClearOverrunCountRequest
bus.payload.BinaryPayloadDecoder method), attribute), 145
168 sub_function_code (pymod-
SLAVE_OFF (pymodbus.constants.ModbusStatus at- bus.diag_message.ClearOverrunCountResponse
tribute), 137 attribute), 145
SLAVE_ON (pymodbus.constants.ModbusStatus attribute), sub_function_code (pymod-
137 bus.diag_message.ForceListenOnlyModeRequest
slaves() (pymodbus.datastore.ModbusServerContext attribute), 146
method), 127 sub_function_code (pymod-
SOCKET (pymodbus.Framer attribute), 138 bus.diag_message.ForceListenOnlyModeResponse
SPECIFIC (pymodbus.constants.DeviceInformation at- attribute), 146
tribute), 135 sub_function_code (pymod-
start_modbus_server() (pymod- bus.diag_message.GetClearModbusPlusRequest
bus.server.ModbusSimulatorServer method), attribute), 147
35 sub_function_code (pymod-
start_modbus_server() (pymod- bus.diag_message.GetClearModbusPlusResponse
bus.server.simulator.http_server.ModbusSimulatorServer attribute), 147
method), 74 sub_function_code (pymod-
StartAsyncSerialServer() (in module pymod- bus.diag_message.RestartCommunicationsOptionRequest
bus.server), 36 attribute), 147
StartAsyncTcpServer() (in module pymod- sub_function_code (pymod-
bus.server), 36 bus.diag_message.RestartCommunicationsOptionResponse
StartAsyncTlsServer() (in module pymod- attribute), 148
bus.server), 36 sub_function_code (pymod-
StartAsyncUdpServer() (in module pymod- bus.diag_message.ReturnBusCommunicationErrorCountRequest
bus.server), 37 attribute), 148
StartSerialServer() (in module pymodbus.server), sub_function_code (pymod-
37 bus.diag_message.ReturnBusCommunicationErrorCountResponse
StartTcpServer() (in module pymodbus.server), 37 attribute), 148
StartTlsServer() (in module pymodbus.server), 37 sub_function_code (pymod-
StartUdpServer() (in module pymodbus.server), 37 bus.diag_message.ReturnBusExceptionErrorCountRequest
stop() (pymodbus.server.ModbusSimulatorServer attribute), 148
method), 35 sub_function_code (pymod-
stop() (pymodbus.server.simulator.http_server.ModbusSimulatorServer
bus.diag_message.ReturnBusExceptionErrorCountResponse
method), 74 attribute), 148
stop_modbus_server() (pymod- sub_function_code (pymod-
bus.server.ModbusSimulatorServer method), bus.diag_message.ReturnBusMessageCountRequest
35 attribute), 149
stop_modbus_server() (pymod- sub_function_code (pymod-
204 Index
PyModbus, Release 3.7.0dev
bus.diag_message.ReturnBusMessageCountResponse bus.mei_message.ReadDeviceInformationResponse
attribute), 149 attribute), 161
sub_function_code (pymod- summary() (pymodbus.device.ModbusDeviceIdentification
bus.diag_message.ReturnDiagnosticRegisterRequest method), 143
attribute), 149 summary() (pymodbus.device.ModbusPlusStatistics
sub_function_code (pymod- method), 144
bus.diag_message.ReturnDiagnosticRegisterResponse
attribute), 149 T
sub_function_code (pymod- TLS (pymodbus.Framer attribute), 138
bus.diag_message.ReturnIopOverrunCountRequestto_coils() (pymodbus.payload.BinaryPayloadBuilder
attribute), 149 method), 167
sub_function_code (pymod- to_registers() (pymod-
bus.diag_message.ReturnIopOverrunCountResponse bus.payload.BinaryPayloadBuilder method),
attribute), 150 167
sub_function_code (pymod-
bus.diag_message.ReturnQueryDataRequest U
attribute), 150 unpack_bitstring() (in module pymodbus.utilities),
sub_function_code (pymod- 185
bus.diag_message.ReturnQueryDataResponse update() (pymodbus.device.ModbusDeviceIdentification
attribute), 150 method), 143
sub_function_code (pymod- UserApplicationName (pymod-
bus.diag_message.ReturnSlaveBusCharacterOverrunCountRequest
bus.device.ModbusDeviceIdentification prop-
attribute), 150 erty), 143
sub_function_code (pymod-
bus.diag_message.ReturnSlaveBusCharacterOverrunCountResponse
V
attribute), 150
validate() (pymodbus.datastore.ModbusSlaveContext
sub_function_code (pymod-
method), 126
bus.diag_message.ReturnSlaveBusyCountRequest
validate() (pymodbus.datastore.ModbusSparseDataBlock
attribute), 151
method), 126
sub_function_code (pymod-
value (pymodbus.events.CommunicationRestartEvent at-
bus.diag_message.ReturnSlaveBusyCountResponse
tribute), 153
attribute), 151
value (pymodbus.events.EnteredListenModeEvent
sub_function_code (pymod-
attribute), 153
bus.diag_message.ReturnSlaveMessageCountRequest
VendorName (pymodbus.device.ModbusDeviceIdentification
attribute), 151
property), 143
sub_function_code (pymod-
VendorUrl (pymodbus.device.ModbusDeviceIdentification
bus.diag_message.ReturnSlaveMessageCountResponse
property), 143
attribute), 151
sub_function_code (pymod-
bus.diag_message.ReturnSlaveNAKCountRequest
W
attribute), 152 WAITING (pymodbus.constants.ModbusStatus attribute),
sub_function_code (pymod- 136
bus.diag_message.ReturnSlaveNAKCountResponse write_coil() (pymod-
attribute), 152 bus.client.mixin.ModbusClientMixin method),
sub_function_code (pymod- 25
write_coil()
bus.diag_message.ReturnSlaveNoResponseCountRequest (pymod-
attribute), 152 bus.repl.client.mclient.ExtendedRequestSupport
sub_function_code (pymod- method), 50
write_coils()
bus.diag_message.ReturnSlaveNoResponseCountResponse (pymod-
attribute), 152 bus.client.mixin.ModbusClientMixin method),
sub_function_code (pymod- 30
bus.mei_message.ReadDeviceInformationRequest write_coils() (pymod-
attribute), 161 bus.repl.client.mclient.ExtendedRequestSupport
sub_function_code (pymod- method), 50
Index 205
PyModbus, Release 3.7.0dev
write_file_record() (pymod-
bus.client.mixin.ModbusClientMixin method),
31
write_register() (pymod-
bus.client.mixin.ModbusClientMixin method),
26
write_register() (pymod-
bus.repl.client.mclient.ExtendedRequestSupport
method), 51
write_registers() (pymod-
bus.client.mixin.ModbusClientMixin method),
30
write_registers() (pymod-
bus.repl.client.mclient.ExtendedRequestSupport
method), 51
WriteFileRecordRequest (class in pymod-
bus.file_message), 159
WriteFileRecordResponse (class in pymod-
bus.file_message), 160
WriteMultipleCoilsRequest (class in pymod-
bus.bit_write_message), 140
WriteMultipleCoilsResponse (class in pymod-
bus.bit_write_message), 141
WriteMultipleRegistersRequest (class in pymod-
bus.register_write_message), 174
WriteMultipleRegistersResponse (class in pymod-
bus.register_write_message), 174
WriteSingleCoilRequest (class in pymod-
bus.bit_write_message), 141
WriteSingleCoilResponse (class in pymod-
bus.bit_write_message), 142
WriteSingleRegisterRequest (class in pymod-
bus.register_write_message), 175
WriteSingleRegisterResponse (class in pymod-
bus.register_write_message), 175
206 Index