Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions doc/source/simulator/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,20 @@ Class definitions
:undoc-members:
:show-inheritance:
:member-order: bysource


Action data class examples
^^^^^^^^^^^^^^^^^^^^^^^^^^


.. autoclass:: pymodbus.simulator.SimDataMinMax
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource

.. autoclass:: pymodbus.simulator.SimDataIncrement
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource
18 changes: 7 additions & 11 deletions examples/server_datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,21 @@ def define_datamodel():
"""
# SimData can be instantiated with positional or optional parameters:
assert SimData(
5, 17, 10, DataType.REGISTERS
5, 10, 17, DataType.REGISTERS
) == SimData(
address=5, value=17, count=10, datatype=DataType.REGISTERS
)

# Define a group of coils/direct inputs non-shared (address=15..31 each 1 bit)
block1 = SimData(address=15, value=True, count=16, datatype=DataType.BITS)
block1 = SimData(address=15, count=16, value=True, datatype=DataType.BITS)
# Define a group of coils/direct inputs shared (address=15..31 each 16 bit)
block2 = SimData(address=15, value=0xFFFF, count=16, datatype=DataType.BITS)
block2 = SimData(address=15, count=16, value=0xFFFF, datatype=DataType.BITS)

# Define a group of holding/input registers (remark NO difference between shared and non-shared)
block3 = SimData(10, 123.4, datatype=DataType.FLOAT32)
block4 = SimData(17, value=123, count=5, datatype=DataType.INT64)
block5 = SimData(27, "Hello ", datatype=DataType.STRING)

# Please use DataType.DEFAULT to define register limits.
# this datatype only uses 1 object, whereas DataType.REGISTERS uses <count> objects,
# mean DataType.DEFAULT is factors more efficient and much less memory consuming
# JAN TO CORRECT.
block3 = SimData(10, 1, 123.4, datatype=DataType.FLOAT32)
block4 = SimData(17, count=5, value=123, datatype=DataType.INT64)
block5 = SimData(27, 1, "Hello ", datatype=DataType.STRING)

block_def = SimData(0, count=1000, datatype=DataType.REGISTERS)

# SimDevice can be instantiated with positional or optional parameters:
Expand Down
68 changes: 41 additions & 27 deletions pymodbus/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
values for the servers and clients.
"""
import enum
from typing import Union


INTERNAL_ERROR = "Pymodbus internal error"
Expand Down Expand Up @@ -120,43 +121,56 @@ class MoreData(enum.IntEnum):


class DataType(enum.IntEnum):
"""Register types, used to define of a group of registers.
"""Register types, used to define of a group of registers.

This is the types pymodbus recognizes, actually the modbus standard do NOT define e.g. INT32,
but since nearly every device contain e.g. values of type INT32, it is available in pymodbus,
with automatic conversions to/from registers.
"""
This is the types pymodbus recognizes, actually the modbus standard do NOT define e.g. INT32,
but since nearly every device contain e.g. values of type INT32, it is available in pymodbus,
with automatic conversions to/from registers.
"""

#: 1 integer == 1 register
INT16 = enum.auto()
#: 1 integer == 1 register
INT16 = enum.auto()

#: 1 positive integer == 1 register
UINT16 = enum.auto()
#: 1 positive integer == 1 register
UINT16 = enum.auto()

#: 1 integer == 2 registers
INT32 = enum.auto()
#: 1 integer == 2 registers
INT32 = enum.auto()

#: 1 positive integer == 2 registers
UINT32 = enum.auto()
#: 1 positive integer == 2 registers
UINT32 = enum.auto()

#: 1 integer == 4 registers
INT64 = enum.auto()
#: 1 integer == 4 registers
INT64 = enum.auto()

#: 1 positive integer == 4 register
UINT64 = enum.auto()
#: 1 positive integer == 4 register
UINT64 = enum.auto()

#: 1 float == 2 registers
FLOAT32 = enum.auto()
#: 1 float == 2 registers
FLOAT32 = enum.auto()

#: 1 float == 4 registers
FLOAT64 = enum.auto()
#: 1 float == 4 registers
FLOAT64 = enum.auto()

#: 1 string == (len(string) / 2) registers
STRING = enum.auto()
#: 1 string == (len(string) / 2) registers
STRING = enum.auto()

#: 16 bits == 1 register
BITS = enum.auto()
#: 16 bits == 1 register
BITS = enum.auto()

#: Registers == 16bit
REGISTERS = enum.auto()
#: Registers == 2 bytes (identical to UINT16)
REGISTERS = enum.auto()

DATATYPE_STRUCT: dict[DataType, tuple[Union[type, tuple[type, ...]], int]] = { # pylint: disable=consider-using-namedtuple-or-dataclass
DataType.INT16: (int, 1),
DataType.UINT16: (int, 1),
DataType.INT32: (int, 2),
DataType.UINT32: (int, 2),
DataType.INT64: (int, 4),
DataType.UINT64: (int, 4),
DataType.FLOAT32: (float, 2),
DataType.FLOAT64: (float, 4),
DataType.STRING: (str, -1),
DataType.BITS: ((list, int, bool), -2),
DataType.REGISTERS: (int, 1),
}
8 changes: 3 additions & 5 deletions pymodbus/simulator/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
"""Simulator."""

__all__ = [
"SimAction",
"SimCore",
"SimData",
"SimDevice",
"SimValueType",
]

from pymodbus.simulator.simcore import SimCore
from pymodbus.simulator.simdata import (
SimAction,
from .simcore import SimCore
from .simdata import (
SimData,
SimDevice,
SimValueType,
)
from .simdevice import SimDevice
3 changes: 2 additions & 1 deletion pymodbus/simulator/simcore.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Simulator data model implementation."""
from __future__ import annotations

from .simdata import SimData, SimDevice
from .simdata import SimData
from .simdevice import SimDevice


class SimCore:
Expand Down
Loading