-
Notifications
You must be signed in to change notification settings - Fork 964
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f1e5a2d
commit 18e91f2
Showing
21 changed files
with
565 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,104 @@ | ||
Simulator | ||
========= | ||
|
||
The simulator is a full fledged modbus simulator, which is | ||
constantly being evolved with user ideas / amendments. | ||
The simulator is a full fledged modbus server/simulator. | ||
|
||
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) | ||
The simulator allows the user to (all automated): | ||
|
||
- simulate a modbus device by adding a simple configuration, | ||
- test how a client handles modbus exceptions, | ||
- simulate a multipoint line, but adding multiple device configurations, | ||
- simulate devices that are not conforming to the protocol, | ||
- simulate communication problems (data loss etc), | ||
- test how a client handles modbus response and exceptions, | ||
- test a client apps correct use of the simulated device. | ||
|
||
The web interface allows the user to (online / manual) | ||
The web interface (activated optionally) allows the user to: | ||
|
||
- test how a client handles modbus errors, | ||
- test how a client handles communication errors like divided messages, | ||
- run your test server in the cloud, | ||
- introduce modbus errors (like e.g. wrong length), | ||
- introduce communication errors (like splitting a message), | ||
- monitor requests/responses, | ||
- inject modbus errors like malicious a response, | ||
- see/Change values online. | ||
- inject modbus errors like malicious a response, | ||
- run your test server in the cloud, | ||
|
||
The REST API allow the test process to be automated | ||
|
||
- spin up a test server with unix domain sockets in your test harness, | ||
- spin up a test server in your test harness, | ||
- set expected responses with a simple REST API command, | ||
- check the result with another simple REST API command, | ||
- check the result with a simple REST API command, | ||
- test your client app in a true end-to-end fashion. | ||
|
||
.. toctree:: | ||
:maxdepth: 4 | ||
:hidden: | ||
The web server uses the REST API internally, which helps to ensure that it | ||
actually works. | ||
|
||
|
||
Data model configuration | ||
------------------------ | ||
|
||
.. warning:: from v3.9.0 this is available as a "normal" datastore model. | ||
|
||
The simulator data model represent the registers and parameters of the simulated devices. | ||
The data model is defined using :class:`SimData` and :class:`SimDevice` before starting the | ||
server and cannot be changed without restarting the server. | ||
|
||
:class:`SimData` defines a group of continuous identical registers. This is the basis of the model, | ||
multiple :class:`SimData` should be used to mirror the physical device. | ||
|
||
:class:`SimDevice` defines device parameters and a list of :class:`SimData`. | ||
The list of :class:`SimData` can added as shared registers or as the 4 blocks, defined in modbus. | ||
:class:`SimDevice` can be used to simulate a single device, while a list of | ||
:class:`SimDevice` simulates a multipoint line (simulating a rs485 line or a tcp based serial forwarder). | ||
|
||
A server consist of communication parameters and a device or a list of devices | ||
|
||
:class:`SimDataType` is a helper class that defines legal datatypes. | ||
|
||
:class:`SimActions` is a helper class that defines built in actions. | ||
|
||
:github:`examples/simulator_datamodel.py` contains usage examples. | ||
|
||
SimData | ||
^^^^^^^ | ||
|
||
.. autoclass:: pymodbus.simulator.SimData | ||
:members: | ||
:undoc-members: | ||
:show-inheritance: | ||
|
||
SimDevice | ||
^^^^^^^^^ | ||
|
||
.. autoclass:: pymodbus.simulator.SimDevice | ||
:members: | ||
:undoc-members: | ||
:show-inheritance: | ||
|
||
SimDataType | ||
^^^^^^^^^^^ | ||
|
||
.. autoclass:: pymodbus.simulator.SimDataType | ||
:members: | ||
:undoc-members: | ||
:show-inheritance: | ||
|
||
|
||
Simulator server | ||
---------------- | ||
|
||
.. note:: This is a v4.0.0 functionality currently not available, please see the 3x simulator server. | ||
|
||
|
||
Web frontend | ||
------------ | ||
|
||
.. note:: This is a v4.0.0 functionality currently not available, please see the 3x simulator server. | ||
|
||
|
||
REST API | ||
-------- | ||
|
||
library/simulator/config | ||
library/simulator/datastore | ||
library/simulator/web | ||
library/simulator/restapi | ||
.. note:: This is a v4.0.0 functionality currently not available, please see the 3x simulator server. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
Simulator (3.x) | ||
=============== | ||
|
||
.. warning:: Beginning with v3.9.0 and ending with v4.0.0 this simulator will be replaced by a new version. | ||
|
||
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. | ||
|
||
.. toctree:: | ||
:maxdepth: 4 | ||
:hidden: | ||
|
||
library/simulator/config | ||
library/simulator/datastore | ||
library/simulator/web | ||
library/simulator/restapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python3 | ||
"""Pymodbus simulator datamodel examples. | ||
This example shows how to configure the simulator datamodel to mimic a real | ||
device. | ||
There are different examples, to show the flexibility of the simulator datamodel. | ||
.. tip:: This is NOT the pymodbus simulator, that is started as pymodbus.simulator. | ||
""" | ||
|
||
from pymodbus.simulator import SimCheckConfig, SimData, SimDataType, SimDevice | ||
|
||
|
||
def define_registers(): | ||
"""Define simulator data model. | ||
Coils and direct inputs are expressed as bits representing a relay in the device. | ||
There are no real difference between coils and direct inputs, but historically | ||
they have been divided. | ||
Holding registers and input registers are the same, but historically they have | ||
been divided. | ||
Coils and direct inputs are handled differently in shared vs non-shared models. | ||
- In a non-shared model the address is the bit directly. It can be thought of as if a | ||
register only contains 1 bit. | ||
- In a shared model the address is the register containing the bits. So a single bit CANNOT | ||
be addressed directly. | ||
""" | ||
# Define a group of coils (remark difference between shared and non-shared) | ||
block_coil = [SimData(0, count=100, datatype=SimDataType.DEFAULT), | ||
SimData(0, True, 16)] | ||
block_coil_shared = [SimData(0, 0xFFFF, 16)] | ||
|
||
# SimData can be reused with copying | ||
block_direct = block_coil | ||
|
||
# Define a group of registers (remark NO difference between shared and non-shared) | ||
block_holding = [SimData(10, count=100, datatype=SimDataType.DEFAULT), | ||
SimData(10, 123.4, datatype=SimDataType.FLOAT32), | ||
SimData(12, 123456789.3, datatype=SimDataType.FLOAT64), | ||
SimData(17, value=123, count=5, datatype=SimDataType.INT32), | ||
SimData(27, "Hello ", datatype=SimDataType.STRING)] | ||
block_input = block_holding | ||
block_shared = [SimData(10, 123.4, datatype=SimDataType.FLOAT32), | ||
SimData(12, 123456789.3, datatype=SimDataType.FLOAT64), | ||
SimData(16, 0xf0f0, datatype=SimDataType.BITS), | ||
SimData(17, value=123, count=5, datatype=SimDataType.INT32), | ||
SimData(27, "Hello ", datatype=SimDataType.STRING)] | ||
|
||
device_block = SimDevice(1, False, | ||
block_coil=block_coil, | ||
block_direct=block_direct, | ||
block_holding=block_holding, | ||
block_input=block_input) | ||
device_shared = SimDevice(2, False, | ||
block_shared=block_coil_shared+block_shared) | ||
assert not SimCheckConfig([device_block]) | ||
assert not SimCheckConfig([device_shared]) | ||
assert not SimCheckConfig([device_shared, device_block]) | ||
|
||
def main(): | ||
"""Combine setup and run.""" | ||
define_registers() | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
"""Simulator.""" | ||
|
||
__all__ = [ | ||
"SimCheckConfig", | ||
"SimData", | ||
"SimDataType", | ||
"SimDevice" | ||
] | ||
|
||
from pymodbus.simulator.simdata import SimCheckConfig, SimData, SimDataType, SimDevice |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
"""Simulator data model classes.""" | ||
from __future__ import annotations | ||
|
||
|
||
class SimCore: # pylint: disable=too-few-public-methods | ||
"""Datastore for the simulator/server.""" |
Oops, something went wrong.