Final two of the five driver test clients. Pattern carried forward from #249 (Modbus) + #250 (AB CIP, AB Legacy) — each CLI inherits Driver.Cli.Common for DriverCommandBase + SnapshotFormatter and adds a protocol-specific CommandBase + 4 commands (probe / read / write / subscribe). New projects: - src/ZB.MOM.WW.OtOpcUa.Driver.S7.Cli/ — otopcua-s7-cli. S7CommandBase carries host/port/cpu/rack/slot/timeout. Handles all S7 atomic types (Bool, Byte, Int16..UInt64, Float32/64, String, DateTime). DateTime parses via RoundtripKind so "2026-04-21T12:34:56Z" works. - src/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Cli/ — otopcua-twincat-cli. TwinCATCommandBase carries ams-net-id + ams-port + --poll-only toggle (flips UseNativeNotifications=false). Covers the full IEC 61131-3 atomic set: Bool, SInt/USInt, Int/UInt, DInt/UDInt, LInt/ULInt, Real, LReal, String, WString, Time/Date/DateTime/TimeOfDay. Structure writes refused as out-of-scope (same as AB CIP). IEC time/date variants marshal as UDINT on the wire per IEC spec. Subscribe banner announces "ADS notification" vs "polling" so the mechanism is obvious in bug reports. Tests (49 new, 122 cumulative driver-CLI): - S7: 22 tests. Every S7DataType has a happy-path + bounds case. DateTime round-trips an ISO-8601 string. Tag-name synthesis round-trips every S7 address form (DB / M / I / Q, bit/word/dword, strings). - TwinCAT: 27 tests. Full IEC type matrix including WString UTF-8 pass- through + the four IEC time/date variants landing on UDINT. Structure rejection case. Tag-name synthesis for Program scope, GVL scope, nested UDT members, and array elements. Docs: - docs/Driver.S7.Cli.md — address grammar cheat sheet + the PUT/GET-must- be-enabled gotcha every S7-1200/1500 operator hits. - docs/Driver.TwinCAT.Cli.md — AMS router prerequisite (XAR / standalone Router NuGet / remote AMS route) + per-command examples. Wiring: - ZB.MOM.WW.OtOpcUa.slnx grew 4 entries (2 src + 2 tests). Full-solution build clean. Both --help outputs verified end-to-end. Driver CLI suite complete: 5 CLIs (otopcua-{modbus,abcip,ablegacy,s7,twincat}-cli) sharing a common base + formatter. 122 CLI tests cumulative. Every driver family shipped in v2 now has a shell-level ad-hoc validation tool. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
94 lines
2.7 KiB
Markdown
94 lines
2.7 KiB
Markdown
# `otopcua-s7-cli` — Siemens S7 test client
|
|
|
|
Ad-hoc probe / read / write / subscribe tool for Siemens S7-300 / S7-400 /
|
|
S7-1200 / S7-1500 (and compatible soft-PLCs) over S7comm / ISO-on-TCP port 102.
|
|
Uses the **same** `S7Driver` the OtOpcUa server does (S7.Net under the hood).
|
|
|
|
Fourth of four driver test-client CLIs.
|
|
|
|
## Build + run
|
|
|
|
```powershell
|
|
dotnet run --project src/ZB.MOM.WW.OtOpcUa.Driver.S7.Cli -- --help
|
|
```
|
|
|
|
## Common flags
|
|
|
|
| Flag | Default | Purpose |
|
|
|---|---|---|
|
|
| `-h` / `--host` | **required** | PLC IP or hostname |
|
|
| `-p` / `--port` | `102` | ISO-on-TCP port (rarely changes) |
|
|
| `-c` / `--cpu` | `S71500` | S7200 / S7200Smart / S7300 / S7400 / S71200 / S71500 |
|
|
| `--rack` | `0` | Hardware rack (S7-400 distributed setups only) |
|
|
| `--slot` | `0` | CPU slot (S7-300 = 2, S7-400 = 2 or 3, S7-1200/1500 = 0) |
|
|
| `--timeout-ms` | `5000` | Per-operation timeout |
|
|
| `--verbose` | off | Serilog debug output |
|
|
|
|
## PUT/GET must be enabled
|
|
|
|
S7-1200 / S7-1500 ship with PUT/GET communication **disabled** by default.
|
|
Enable it in TIA Portal: *Device config → Protection & Security → Connection
|
|
mechanisms → "Permit access with PUT/GET communication from remote partner"*.
|
|
Without it the CLI's first read will surface `BadNotSupported`.
|
|
|
|
## S7 address grammar cheat sheet
|
|
|
|
| Form | Meaning |
|
|
|---|---|
|
|
| `DB1.DBW0` | DB number 1, word offset 0 |
|
|
| `DB1.DBD4` | DB number 1, dword offset 4 |
|
|
| `DB1.DBX2.3` | DB number 1, byte 2, bit 3 |
|
|
| `DB10.STRING[0]` | DB 10 string starting at offset 0 |
|
|
| `M0.0` | Merker bit 0.0 |
|
|
| `MW0` / `MD4` | Merker word / dword |
|
|
| `IW4` | Input word 4 |
|
|
| `QD8` | Output dword 8 |
|
|
|
|
## Commands
|
|
|
|
### `probe`
|
|
|
|
```powershell
|
|
# S7-1500 — default probe MW0
|
|
otopcua-s7-cli probe -h 192.168.1.30
|
|
|
|
# S7-300 (slot 2)
|
|
otopcua-s7-cli probe -h 192.168.1.31 -c S7300 --slot 2 -a DB1.DBW0
|
|
```
|
|
|
|
### `read`
|
|
|
|
```powershell
|
|
# DB word
|
|
otopcua-s7-cli read -h 192.168.1.30 -a DB1.DBW0 -t Int16
|
|
|
|
# Float32 from DB dword
|
|
otopcua-s7-cli read -h 192.168.1.30 -a DB1.DBD4 -t Float32
|
|
|
|
# Merker bit
|
|
otopcua-s7-cli read -h 192.168.1.30 -a M0.0 -t Bool
|
|
|
|
# 80-char S7 string
|
|
otopcua-s7-cli read -h 192.168.1.30 -a DB10.STRING[0] -t String --string-length 80
|
|
```
|
|
|
|
### `write`
|
|
|
|
```powershell
|
|
otopcua-s7-cli write -h 192.168.1.30 -a DB1.DBW0 -t Int16 -v 42
|
|
otopcua-s7-cli write -h 192.168.1.30 -a DB1.DBD4 -t Float32 -v 3.14
|
|
otopcua-s7-cli write -h 192.168.1.30 -a M0.0 -t Bool -v true
|
|
```
|
|
|
|
**Writes to M / Q are real** — they drive the PLC program. Be careful what you
|
|
flip on a running machine.
|
|
|
|
### `subscribe`
|
|
|
|
```powershell
|
|
otopcua-s7-cli subscribe -h 192.168.1.30 -a DB1.DBW0 -t Int16 -i 500
|
|
```
|
|
|
|
S7comm has no native push — the CLI polls through `PollGroupEngine` just like
|
|
Modbus / AB.
|