Skip to content

feat(plc4py/simulated): add in-process simulated PLC driver#2536

Open
Abdylreshit wants to merge 1 commit intoapache:developfrom
Abdylreshit:feature/plc4py-simulated-driver
Open

feat(plc4py/simulated): add in-process simulated PLC driver#2536
Abdylreshit wants to merge 1 commit intoapache:developfrom
Abdylreshit:feature/plc4py-simulated-driver

Conversation

@Abdylreshit
Copy link
Copy Markdown

Summary

Adds a new `simulated` driver to `plc4py`, matching the existing Java (`plc4j/drivers/simulated`) and Go (`plc4go/internal/simulated`) implementations. The mspec-generated protocol code under `plc4py/protocols/simulated/readwrite/` was already in the tree, but no Python driver consumed it; this PR fills that gap.

The driver runs entirely in-process — it does not open a network socket and does not need an external PLC or simulator — so it is useful both as a reference implementation of the `plc4py` driver SPI and in tests that need a working driver without infrastructure.

Tag semantics

Tag format: `TYPE/name:DATA_TYPE[count]` (same as the Java and Go drivers).

Tag type Read Write
STATE Returns the last written value, or `NOT_FOUND` if never written Stores the value in memory
RANDOM Returns a freshly generated random value for the data type `ACCESS_DENIED`
STDOUT `ACCESS_DENIED` Logs the value

All 19 data types from `simulated.mspec` are supported (`BOOL`, `BYTE`, `WORD`, `DWORD`, `LWORD`, `SINT`, `INT`, `DINT`, `LINT`, `USINT`, `UINT`, `UDINT`, `ULINT`, `REAL`, `LREAL`, `CHAR`, `WCHAR`, `STRING`, `WSTRING`), both scalar and arrays.

Files added

  • `plc4py/drivers/simulated/SimulatedTag.py` — tag parser (regex, enum, builder)
  • `plc4py/drivers/simulated/SimulatedConfiguration.py` — URL config
  • `plc4py/drivers/simulated/SimulatedDevice.py` — in-memory state store + random-value generator
  • `plc4py/drivers/simulated/SimulatedConnection.py` — connection, driver and pluggy loader
  • `plc4py/tests/unit/plc4py/drivers/simulated/` — 20 unit tests (tag-parser unit tests + end-to-end via `PlcDriverManager`)

Also registers the new driver via `pyproject.toml` entry points:
```toml
simulated = "plc4py.drivers.simulated.SimulatedConnection:SimulatedDriverLoader"
```

Test plan

  • `pytest tests/unit/plc4py/drivers/simulated/ -v` — 20 passed
  • `pytest` full suite — 97 passed, 36 xfailed (was 77 passed, 36 xfailed before; no regressions)
  • Tag parser handles STATE / RANDOM / STDOUT prefixes, arrays, dotted names, unknown types
  • `STATE` write → read round-trips preserve the value (scalar and array)
  • `RANDOM` reads return correctly-typed `PlcValue` instances; writes return `ACCESS_DENIED`
  • `STDOUT` writes succeed and are logged; reads return `ACCESS_DENIED`
  • Multi-tag read request dispatches each tag independently

Introduces a new 'simulated' driver under plc4py.drivers.simulated,
mirroring the existing Java and Go implementations. The mspec-generated
protocol code under plc4py/protocols/simulated/readwrite/ was already
present in the tree, but no Python driver consumed it; this change fills
that gap.

The driver does not open a network socket -- it dispatches read and write
requests directly to an in-memory SimulatedDevice. That makes it useful
both as a reference implementation of the driver SPI and in tests that
need a working driver without external infrastructure.

Tag format mirrors the Java/Go drivers: TYPE/name:DATA_TYPE[count]
(e.g. STATE/counter:INT, RANDOM/temperature:REAL, STDOUT/msg:STRING).

Supported tag types:
- STATE  -- read/write in-memory key-value store
- RANDOM -- reads return a freshly generated random value; writes are
            rejected with ACCESS_DENIED
- STDOUT -- writes are logged; reads return ACCESS_DENIED

All 19 data types from simulated.mspec are supported (BOOL, BYTE, WORD,
DWORD, LWORD, SINT, INT, DINT, LINT, USINT, UINT, UDINT, ULINT, REAL,
LREAL, CHAR, WCHAR, STRING, WSTRING), both scalar and arrays.

The driver is registered via the plc4py.drivers setuptools entry point.

Adds 20 unit tests (11 tag-parser tests + 9 end-to-end connection tests
covering STATE round-trip, RANDOM reads, STDOUT writes, arrays, and
multi-tag requests). Full test suite goes from 77 passed, 36 xfailed to
97 passed, 36 xfailed -- no regressions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant