# python-snap7 server profiles JSON-driven seed profiles for `snap7.server.Server` from [python-snap7](https://github.com/gijzelaerr/python-snap7) (MIT). Shape mirrors the pymodbus profiles under `tests/ZB.MOM.WW.OtOpcUa.Driver.Modbus.IntegrationTests/Pymodbus/` — a PowerShell launcher + per-family JSON + a Python shim that the launcher exec's. | File | What it seeds | Test category | |---|---|---| | [`s7_1500.json`](s7_1500.json) | DB1 (1024 bytes) with smoke values at known offsets (i16 @ DBW10, i32 @ DBD20, f32 @ DBD30, bool @ DBX50.3, scratch word @ DBW100, STRING "Hello" @ 200) + MB (256 bytes) with probe marker at MW0. | `Trait=Integration, Device=S7_1500` | Default port **1102** (non-privileged; sidesteps Windows Firewall prompt + Linux's root-required bind on port 102). The fixture (`Snap7ServerFixture`) defaults to `localhost:1102`. Override via `S7_SIM_ENDPOINT` to point at a real S7 CPU on port 102. The S7 driver threads `_options.Port` through to S7netplus's 5-arg `Plc` ctor, so the non-standard port works end-to-end. ## Install ```powershell pip install "python-snap7>=2.0" ``` `python-snap7` wraps the upstream `snap7` C library; the install pulls platform-specific binaries automatically. Requires Python ≥ 3.10. Windows Firewall will prompt on first bind; allow Private network. ## Run Foreground (Ctrl+C to stop): ```powershell .\serve.ps1 -Profile s7_1500 ``` Non-default port: ```powershell .\serve.ps1 -Profile s7_1500 -Port 102 ``` Or invoke the Python shim directly: ```powershell python .\server.py .\s7_1500.json --port 1102 ``` ## Run the integration tests In a separate shell with the simulator running: ```powershell cd C:\Users\dohertj2\Desktop\lmxopcua dotnet test tests\ZB.MOM.WW.OtOpcUa.Driver.S7.IntegrationTests ``` Tests auto-skip with a clear `SkipReason` when `localhost:1102` isn't reachable within 2 seconds. ## What's encoded in `s7_1500.json` | Address | Type | Seed | Purpose | |---|---|---|---| | `DB1.DBW0` | u16 | `4242` | read-back probe | | `DB1.DBW10` | i16 | `-12345` | smoke i16 read | | `DB1.DBD20` | i32 | `1234567890` | smoke i32 read | | `DB1.DBD30` | f32 | `3.14159` | smoke f32 read (big-endian) | | `DB1.DBX50.3` | bool | `true` | smoke bool read at bit 3 | | `DB1.DBW100` | u16 | `0` | scratch for write-then-read | | `DB1.STRING[200]` | S7 STRING | `"Hello"` (max 32, cur 5) | smoke string read | | `MW0` | u16 | `1` | `S7ProbeOptions.ProbeAddress` default | Seed types supported by `server.py`: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `f32`, `bool` (with `"bit": 0..7`), `ascii` (S7 STRING type with configurable `max_len`). ## Known limitations (python-snap7 upstream) The `snap7.server.Server` docstring admits: > "Legacy S7 server implementation. Emulates a Siemens S7 PLC for testing > and development purposes. [...] pure Python emulator implementation that > simulates PLC behaviour for protocol compliance testing rather than > full industrial-grade functionality." What that means in practice — things this fixture does NOT cover: - **S7-1500 Optimized-DB symbolic access** — the real S7-1500 with TIA Portal optimization enabled uses symbolic addressing that's wire-incompatible with absolute DB addressing. Our driver targets non-optimized DBs; so does snap7's server. Rig test required to verify against an Optimized CPU. - **PG / OP / S7-Basic session types** — S7netplus uses OP session; the simulator accepts whatever session type is requested, unlike real CPUs that allocate session slots differently. - **SCL variant-specific behaviour** — e.g. S7-1200 missing certain PDU types, S7-300's older handshake, S7-400 multi-CPU racks with non-zero slot. Simulator collapses all into one generic CPU emulation. - **PUT/GET-disabled-by-default** — real S7-1200/1500 CPUs refuse reads when PUT/GET is off in TIA Portal hardware config; the driver maps that to `BadDeviceFailure`. Simulator has no such toggle + always accepts. ## References - [python-snap7 GitHub](https://github.com/gijzelaerr/python-snap7) — source + install - [snap7.server API](https://python-snap7.readthedocs.io/en/latest/API/server.html) — `Server` class reference - [`docs/drivers/S7-Test-Fixture.md`](../../../docs/drivers/S7-Test-Fixture.md) — coverage map + gap inventory - [`docs/v2/s7.md`](../../../docs/v2/s7.md) — driver-side addressing + family notes