Phase 3 PR 62 -- Siemens S7 native driver project scaffold #61

Merged
dohertj2 merged 1 commits from phase-3-pr62-s7-driver-scaffold into v2 2026-04-19 00:05:18 -04:00
Owner

Summary

First non-Modbus in-process driver. Scaffolds src/ZB.MOM.WW.OtOpcUa.Driver.S7 using S7netplus (managed .NET, MIT, port 102 ISO-on-TCP).

  • S7DriverOptions — Host, Port=102, CpuType=S71500, Rack=0, Slot=0, Timeout, Tags, Probe (default MW0).
  • S7TagDefinition — Address string (DB1.DBW0, M0.0, QD4…), S7DataType enum (Bool/Byte/Int16/UInt16/Int32/UInt32/Int64/UInt64/Float32/Float64/String/DateTime), StringLength=254 (S7 max).
  • S7Driver : IDriver — opens Plc(CpuType, Host, Rack, Slot), awaits OpenAsync with linked CTS, tracks health, closes cleanly on fault or shutdown.
  • Internal Gate (SemaphoreSlim) + Plc exposed to test project via InternalsVisibleTo so PR 64's Read/Write can stack on the same single-connection serialization per S7netplus convention.

Validation

  • 5/5 unit tests pass (S7DriverScaffoldTests)
  • dotnet build ZB.MOM.WW.OtOpcUa.slnx: 0 errors
  • No regression in Modbus / Galaxy suites

Scope boundaries

ITagDiscovery / IReadable / IWritable / ISubscribable / IHostConnectivityProbe deliberately NOT in this PR — they depend on the S7 address parser (PR 63) and land in PRs 64-65.

Test plan

  • Default options target S7-1500 / port 102 / slot 0
  • Initialize against unreachable host → Faulted + throws
  • Solution builds clean
  • No existing driver suite regresses
## Summary First non-Modbus in-process driver. Scaffolds `src/ZB.MOM.WW.OtOpcUa.Driver.S7` using **S7netplus** (managed .NET, MIT, port 102 ISO-on-TCP). - `S7DriverOptions` — Host, Port=102, CpuType=S71500, Rack=0, Slot=0, Timeout, Tags, Probe (default `MW0`). - `S7TagDefinition` — Address string (`DB1.DBW0`, `M0.0`, `QD4`…), `S7DataType` enum (Bool/Byte/Int16/UInt16/Int32/UInt32/Int64/UInt64/Float32/Float64/String/DateTime), `StringLength=254` (S7 max). - `S7Driver : IDriver` — opens `Plc(CpuType, Host, Rack, Slot)`, awaits `OpenAsync` with linked CTS, tracks health, closes cleanly on fault or shutdown. - Internal `Gate` (SemaphoreSlim) + `Plc` exposed to test project via `InternalsVisibleTo` so PR 64's Read/Write can stack on the same single-connection serialization per S7netplus convention. ## Validation - 5/5 unit tests pass (`S7DriverScaffoldTests`) - `dotnet build ZB.MOM.WW.OtOpcUa.slnx`: **0 errors** - No regression in Modbus / Galaxy suites ## Scope boundaries `ITagDiscovery` / `IReadable` / `IWritable` / `ISubscribable` / `IHostConnectivityProbe` deliberately NOT in this PR — they depend on the S7 address parser (PR 63) and land in PRs 64-65. ## Test plan - [x] Default options target S7-1500 / port 102 / slot 0 - [x] Initialize against unreachable host → Faulted + throws - [x] Solution builds clean - [x] No existing driver suite regresses
dohertj2 added 1 commit 2026-04-19 00:05:15 -04:00
Phase 3 PR 62 -- Siemens S7 native driver project scaffold (S7comm via S7netplus). First non-Modbus in-process driver. Creates src/ZB.MOM.WW.OtOpcUa.Driver.S7 (.NET 10, x64 -- S7netplus is managed, no bitness constraint like MXAccess) + tests/ZB.MOM.WW.OtOpcUa.Driver.S7.Tests + slnx entries. Depends on S7netplus 0.20.0 which is the latest version on NuGet resolvable in this cache (0.21.0 per driver-specs.md is not yet published; 0.20.0 covers the same Plc+CpuType+ReadAsync surface). S7DriverOptions captures the connection settings documented in driver-specs.md \u00A75: Host, Port (default 102 ISO-on-TCP), CpuType (default S71500 per most-common deployment), Rack=0, Slot=0 (S7-1200/1500 onboard PN convention; S7-300/400 operators must override to slot 2 or 3), Timeout=5s, Tags list + Probe settings with default MW0 probe address. S7TagDefinition uses S7.Net-style address strings (DB1.DBW0, M0.0, I0.0, QD4) with an S7DataType enum (Bool, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float32, Float64, String, DateTime -- the full type matrix from the spec); StringLength defaults to 254 (S7 STRING max). S7Driver implements the IDriver-only subset per the PR plan: InitializeAsync opens a managed Plc with the configured CpuType + Host + Rack + Slot, pins WriteTimeout / ReadTimeout on the underlying TcpClient, awaits Plc.OpenAsync with a linked CTS bounded by Options.Timeout so the ISO handshake itself respects the configured bound; health transitions Unknown -> Initializing -> Healthy on success or Unknown -> Initializing -> Faulted on handshake failure, with a best-effort Plc.Close() on the faulted path so retries don't leak the TcpClient. ShutdownAsync closes the Plc and flips health back to Unknown. DisposeAsync routes through ShutdownAsync + disposes the SemaphoreSlim. Internal Gate + Plc accessors are exposed to the test project (InternalsVisibleTo) so PRs 63-65 can stack read/write/subscribe on the same serialization semaphore per the S7netplus documented 'one Plc per PLC, SemaphoreSlim-serialized' pattern. ITagDiscovery, IReadable, IWritable, ISubscribable, IHostConnectivityProbe are all deliberately omitted from this PR -- they depend on the S7AddressParser (PR 63) and land sequenced in PRs 64-65. Unit tests (S7DriverScaffoldTests, 5 facts): default options target S7-1500 / port 102 / slot 0, default probe interval 5s, tag defaults to writable with StringLength 254, driver reports DriverType=S7 + Unknown health pre-init, Initialize against RFC-5737 reserved IP 192.0.2.1 with 250ms timeout transitions to Faulted and throws (tests the connect-failure path doesn't leave the driver in an ambiguous state). 5/5 pass. dotnet build ZB.MOM.WW.OtOpcUa.slnx: 0 errors. No regression in Modbus / Galaxy suites. PR 63 ships S7AddressParser next, PR 64 wires IReadable/IWritable over S7netplus, PR 65 adds discovery + polling-overlay subscribe + probe. 0575280a3b
dohertj2 merged commit 5e67c49f7c into v2 2026-04-19 00:05:18 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#61