Skip to content

Commit 56eefe6

Browse files
committed
Merge branch 'dev'
2 parents de93b82 + d0d2084 commit 56eefe6

28 files changed

+600
-75
lines changed

Diff for: CHANGELOG.rst

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ helps make pymodbus a better product.
77

88
:ref:`Authors`: contains a complete list of volunteers have contributed to each major version.
99

10+
Version 3.8.5
11+
-------------
12+
* New simulator is WIP, not to be used. (#2568)
13+
* dev_id=0 no response expected (returns ExceptionResponse(0xff)). (#2567)
14+
* New simulator datastore. (#2535)
15+
1016
Version 3.8.4
1117
-------------
1218
* Parameterize string encoding in convert_to_registers and convert_from_registers (#2558)

Diff for: README.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ Our releases is defined as X.Y.Z, and we have strict rules what to release when:
2222

2323
Upgrade examples:
2424

25-
- 3.8.1 -> 3.8.3: just plugin the new version, no changes needed.
25+
- 3.8.1 -> 3.8.5: just plugin the new version, no changes needed.
2626
- 3.7.1 -> 3.8.0: Smaller changes to the pymodbus calls might be needed
2727
- 2.5.4 -> 3.0.0: Major changes in the application might be needed
2828

29-
Current release is `3.8.4 <https://github.com/pymodbus-dev/pymodbus/releases/tag/v3.8.4>`_.
29+
Current release is `3.8.5 <https://github.com/pymodbus-dev/pymodbus/releases/tag/v3.8.5>`_.
3030

3131
Bleeding edge (not released) is `dev <https://github.com/pymodbus-dev/pymodbus/tree/dev>`_.
3232

Diff for: doc/index.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ Please select a topic in the left hand column.
1212
source/client
1313
source/server
1414
source/repl
15+
source/simulator3
1516
source/simulator
1617
source/examples
1718
source/authors
1819
source/changelog
1920
source/internals
2021
source/roadmap
21-
22-
.. include:: ../README.rst
22+
23+
.. include:: ../README.rst

Diff for: doc/source/_static/examples.tgz

1.11 KB
Binary file not shown.

Diff for: doc/source/_static/examples.zip

1.11 KB
Binary file not shown.

Diff for: doc/source/library/simulator/config.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ each containing a list of servers/devices
2525
}
2626
2727
You can define as many server and devices as you like, when starting
28-
:ref:`pymodbus.simulator` you select one server and one device to simulate.
28+
:ref:`pymodbus.simulator (v3.x)` you select one server and one device to simulate.
2929

3030
A entry in “device_list” correspond to the dict you can use as parameter
3131
to datastore_simulator is you want to construct your own simulator.

Diff for: doc/source/library/simulator/web.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
Web frontend
2-
============
1+
Web frontend v3.x
2+
=================
33

44
TO BE DOCUMENTED.
55

66

77

8-
pymodbus.simulator
9-
------------------
8+
pymodbus.simulator (v3.x)
9+
-------------------------
1010

1111
The easiest way to run the simulator with web is to use "pymodbus.simulator" from the commandline.
1212

Diff for: doc/source/roadmap.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ It is the community that decides how pymodbus evolves NOT the maintainers !
1515

1616
The following bullet points are what the maintainers focus on:
1717

18-
- 3.8.5 bug fix release, with:
18+
- 3.8.6 bug fix release, with:
1919
- Currently not planned
2020
- 3.9.0, with:
2121
- All of branch wait_next_api

Diff for: doc/source/simulator.rst

+84-18
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,106 @@
11
Simulator
22
=========
33

4-
The simulator is a full fledged modbus simulator, which is
5-
constantly being evolved with user ideas / amendments.
4+
**WORK IN PROGRESS, do NOT use**
5+
6+
The simulator is a full fledged modbus server/simulator.
67

78
The purpose of the simulator is to provide support for client
89
application test harnesses with end-to-end testing simulating real life
910
modbus devices.
1011

11-
The datastore simulator allows the user to (all automated)
12+
The simulator allows the user to (all automated):
1213

1314
- simulate a modbus device by adding a simple configuration,
14-
- test how a client handles modbus exceptions,
15+
- simulate a multipoint line, but adding multiple device configurations,
16+
- simulate devices that are not conforming to the protocol,
17+
- simulate communication problems (data loss etc),
18+
- test how a client handles modbus response and exceptions,
1519
- test a client apps correct use of the simulated device.
1620

17-
The web interface allows the user to (online / manual)
21+
The web interface (activated optionally) allows the user to:
1822

19-
- test how a client handles modbus errors,
20-
- test how a client handles communication errors like divided messages,
21-
- run your test server in the cloud,
23+
- introduce modbus errors (like e.g. wrong length),
24+
- introduce communication errors (like splitting a message),
2225
- monitor requests/responses,
23-
- inject modbus errors like malicious a response,
2426
- see/Change values online.
27+
- inject modbus errors like malicious a response,
28+
- run your test server in the cloud,
2529

2630
The REST API allow the test process to be automated
2731

28-
- spin up a test server with unix domain sockets in your test harness,
32+
- spin up a test server in your test harness,
2933
- set expected responses with a simple REST API command,
30-
- check the result with another simple REST API command,
34+
- check the result with a simple REST API command,
3135
- test your client app in a true end-to-end fashion.
3236

33-
.. toctree::
34-
:maxdepth: 4
35-
:hidden:
37+
The web server uses the REST API internally, which helps to ensure that it
38+
actually works.
39+
40+
41+
Data model configuration
42+
------------------------
43+
44+
.. warning:: from v3.9.0 this is available as a "normal" datastore model.
45+
46+
The simulator data model represent the registers and parameters of the simulated devices.
47+
The data model is defined using :class:`SimData` and :class:`SimDevice` before starting the
48+
server and cannot be changed without restarting the server.
49+
50+
:class:`SimData` defines a group of continuous identical registers. This is the basis of the model,
51+
multiple :class:`SimData` should be used to mirror the physical device.
52+
53+
:class:`SimDevice` defines device parameters and a list of :class:`SimData`.
54+
The list of :class:`SimData` can added as shared registers or as the 4 blocks, defined in modbus.
55+
:class:`SimDevice` can be used to simulate a single device, while a list of
56+
:class:`SimDevice` simulates a multipoint line (simulating a rs485 line or a tcp based serial forwarder).
57+
58+
A server consist of communication parameters and a device or a list of devices
59+
60+
:class:`SimDataType` is a helper class that defines legal datatypes.
61+
62+
:class:`SimActions` is a helper class that defines built in actions.
63+
64+
:github:`examples/simulator_datamodel.py` contains usage examples.
65+
66+
SimData
67+
^^^^^^^
68+
69+
.. autoclass:: pymodbus.simulator.SimData
70+
:members:
71+
:undoc-members:
72+
:show-inheritance:
73+
74+
SimDevice
75+
^^^^^^^^^
76+
77+
.. autoclass:: pymodbus.simulator.SimDevice
78+
:members:
79+
:undoc-members:
80+
:show-inheritance:
81+
82+
SimDataType
83+
^^^^^^^^^^^
84+
85+
.. autoclass:: pymodbus.simulator.SimDataType
86+
:members:
87+
:undoc-members:
88+
:show-inheritance:
89+
90+
91+
Simulator server
92+
----------------
93+
94+
.. note:: This is a v4.0.0 functionality currently not available, please see the 3x simulator server.
95+
96+
97+
Web frontend
98+
------------
99+
100+
.. note:: This is a v4.0.0 functionality currently not available, please see the 3x simulator server.
101+
102+
103+
REST API
104+
--------
36105

37-
library/simulator/config
38-
library/simulator/datastore
39-
library/simulator/web
40-
library/simulator/restapi
106+
.. note:: This is a v4.0.0 functionality currently not available, please see the 3x simulator server.

Diff for: doc/source/simulator3.rst

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Simulator (3.x)
2+
===============
3+
4+
.. warning:: Beginning with v3.9.0 and ending with v4.0.0 this simulator will be replaced by a new version.
5+
6+
The simulator is a full fledged modbus simulator, which is
7+
constantly being evolved with user ideas / amendments.
8+
9+
The purpose of the simulator is to provide support for client
10+
application test harnesses with end-to-end testing simulating real life
11+
modbus devices.
12+
13+
The datastore simulator allows the user to (all automated)
14+
15+
- simulate a modbus device by adding a simple configuration,
16+
- test how a client handles modbus exceptions,
17+
- test a client apps correct use of the simulated device.
18+
19+
The web interface allows the user to (online / manual)
20+
21+
- test how a client handles modbus errors,
22+
- test how a client handles communication errors like divided messages,
23+
- run your test server in the cloud,
24+
- monitor requests/responses,
25+
- inject modbus errors like malicious a response,
26+
- see/Change values online.
27+
28+
The REST API allow the test process to be automated
29+
30+
- spin up a test server with unix domain sockets in your test harness,
31+
- set expected responses with a simple REST API command,
32+
- check the result with another simple REST API command,
33+
- test your client app in a true end-to-end fashion.
34+
35+
.. toctree::
36+
:maxdepth: 4
37+
:hidden:
38+
39+
library/simulator/config
40+
library/simulator/datastore
41+
library/simulator/web
42+
library/simulator/restapi

Diff for: examples/client_async_calls.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ async def async_execute_diagnostic_requests(client):
266266
assert not rr.isError() # test that call was OK
267267
rr = await client.diag_getclear_modbus_response(slave=SLAVE)
268268
assert not rr.isError() # test that call was OK
269-
assert not await client.diag_force_listen_only(slave=SLAVE, no_response_expected=True)
269+
rr = await client.diag_force_listen_only(slave=SLAVE, no_response_expected=True)
270+
assert rr.isError() # test that call was OK, error indicate no response
270271

271272

272273
# ------------------------

Diff for: examples/simulator_datamodel.py

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python3
2+
"""Pymodbus simulator datamodel examples.
3+
4+
**WORK IN PROGRESS, do NOT use**
5+
6+
This example shows how to configure the simulator datamodel to mimic a real
7+
device.
8+
9+
There are different examples, to show the flexibility of the simulator datamodel.
10+
11+
.. tip:: This is NOT the pymodbus simulator, that is started as pymodbus.simulator.
12+
"""
13+
14+
from pymodbus.simulator import SimCheckConfig, SimData, SimDataType, SimDevice
15+
16+
17+
def define_registers():
18+
"""Define simulator data model.
19+
20+
Coils and direct inputs are expressed as bits representing a relay in the device.
21+
There are no real difference between coils and direct inputs, but historically
22+
they have been divided.
23+
24+
Holding registers and input registers are the same, but historically they have
25+
been divided.
26+
27+
Coils and direct inputs are handled differently in shared vs non-shared models.
28+
29+
- In a non-shared model the address is the bit directly. It can be thought of as if a
30+
register only contains 1 bit.
31+
- In a shared model the address is the register containing the bits. So a single bit CANNOT
32+
be addressed directly.
33+
"""
34+
# Define a group of coils (remark difference between shared and non-shared)
35+
block_coil = [SimData(0, count=100, datatype=SimDataType.DEFAULT),
36+
SimData(0, True, 16)]
37+
block_coil_shared = [SimData(0, 0xFFFF, 16)]
38+
39+
# SimData can be reused with copying
40+
block_direct = block_coil
41+
42+
# Define a group of registers (remark NO difference between shared and non-shared)
43+
block_holding = [SimData(10, count=100, datatype=SimDataType.DEFAULT),
44+
SimData(10, 123.4, datatype=SimDataType.FLOAT32),
45+
SimData(12, 123456789.3, datatype=SimDataType.FLOAT64),
46+
SimData(17, value=123, count=5, datatype=SimDataType.INT32),
47+
SimData(27, "Hello ", datatype=SimDataType.STRING)]
48+
block_input = block_holding
49+
block_shared = [SimData(10, 123.4, datatype=SimDataType.FLOAT32),
50+
SimData(12, 123456789.3, datatype=SimDataType.FLOAT64),
51+
SimData(16, 0xf0f0, datatype=SimDataType.BITS),
52+
SimData(17, value=123, count=5, datatype=SimDataType.INT32),
53+
SimData(27, "Hello ", datatype=SimDataType.STRING)]
54+
55+
device_block = SimDevice(1, False,
56+
block_coil=block_coil,
57+
block_direct=block_direct,
58+
block_holding=block_holding,
59+
block_input=block_input)
60+
device_shared = SimDevice(2, False,
61+
block_shared=block_coil_shared+block_shared)
62+
assert not SimCheckConfig([device_block])
63+
assert not SimCheckConfig([device_shared])
64+
assert not SimCheckConfig([device_shared, device_block])
65+
66+
def main():
67+
"""Combine setup and run."""
68+
define_registers()
69+
70+
if __name__ == "__main__":
71+
main()

Diff for: pymodbus/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@
1818
from pymodbus.pdu import ExceptionResponse
1919

2020

21-
__version__ = "3.8.4"
21+
__version__ = "3.8.5"
2222
__version_full__ = f"[pymodbus, version {__version__}]"

0 commit comments

Comments
 (0)