7ba783de7769f90b6741fd97900a6418d915e7ac
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7ba783de77 |
Tasks #211 #212 #213 — AbCip / S7 / AbLegacy server-side factories + seed SQL
Parent: #209. Follow-up to #210 (Modbus). Registers the remaining three non-Galaxy driver factories so a Config DB `DriverType` in {`AbCip`, `S7`, `AbLegacy`} actually boots a live driver instead of being silently skipped by DriverInstanceBootstrapper. Each factory follows the same shape as ModbusDriverFactoryExtensions + the existing Galaxy + FOCAS patterns: - Static `Register(DriverFactoryRegistry)` entry point. - Internal `CreateInstance(driverInstanceId, driverConfigJson)` — deserialises a DTO, strict-parses enum fields (fail-fast with an explicit "expected one of" list), composes the driver's options object, returns a new driver. - DriverType keys: `"AbCip"`, `"S7"`, `"AbLegacy"` (case-insensitive at the registry layer). DTO surfaces cover every option the respective driver's Options class exposes — devices, tags, probe, timeouts, per-driver quirks (AbCip `EnableControllerBrowse` / `EnableAlarmProjection`, S7 Rack/Slot/ CpuType, AbLegacy PlcFamily). Seed SQL (mirrors `seed-modbus-smoke.sql` shape): - `seed-abcip-smoke.sql` — `abcip-smoke` cluster + ControlLogix device + `TestDINT:DInt` tag, pointing at the ab_server compose fixture (`ab://127.0.0.1:44818/1,0`). - `seed-s7-smoke.sql` — `s7-smoke` cluster + S71500 CPU + `DB1.DBW0:Int16` tag at the python-snap7 fixture (`127.0.0.1:1102`, non-priv port). - `seed-ablegacy-smoke.sql` — `ablegacy-smoke` cluster + SLC 500 + `N7:5` tag. Hardware-gated per #222; placeholder gateway to be replaced with real SLC/MicroLogix/PLC-5/RSEmulate before running. Build plumbing: - Each driver project now ProjectReferences `Core` (was `Core.Abstractions`-only). `DriverFactoryRegistry` lives in `Core.Hosting` so the factory extensions can't compile without it. Matches the FOCAS + Galaxy.Proxy reference shape. - `Server.csproj` adds the three new driver ProjectReferences so Program.cs resolves the symbols at compile-time + ships the assemblies at runtime. Full-solution build: 0 errors, 334 pre-existing xUnit1051 warnings only. Live boot verification of all four (Modbus + these three) happens in the exit-gate PR — factories + seeds are pre-conditions and are being shipped first so the exit-gate PR can scope to "does the server publish the expected NodeIds + does the e2e script pass." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
55245a962e |
Task #210 — Modbus server-side factory + seed SQL (closes first of #209 umbrella)
Parent: #209. Adds the server-side wiring so a Config DB `DriverType='Modbus'` row actually boots a Modbus driver instance + publishes its tags under OPC UA NodeIds, instead of being silently skipped by DriverInstanceBootstrapper. Changes: - `ModbusDriverFactoryExtensions` (new) — mirrors `GalaxyProxyDriverFactoryExtensions` + `FocasDriverFactoryExtensions`. `DriverTypeName="Modbus"`, `CreateInstance` deserialises `ModbusDriverConfigDto` (Host/Port/UnitId/TimeoutMs/Probe/Tags) to a full `ModbusDriverOptions` and hands back a `ModbusDriver`. Strict enum parsing (Region / DataType / ByteOrder / StringByteOrder) — unknown values fail fast with an explicit "expected one of" error rather than at first read. - `Program.cs` — register the factory after Galaxy + FOCAS. - `Driver.Modbus.csproj` — add `Core` project reference (the DI-free factory needs `DriverFactoryRegistry` from `Core.Hosting`). Matches the FOCAS driver's reference shape. - `Server.csproj` — add the `Driver.Modbus` ProjectReference so the Program.cs registration compiles against the same assembly the server loads at runtime. - `scripts/smoke/seed-modbus-smoke.sql` (new) — one-cluster smoke seed modelled on `seed-phase-7-smoke.sql`. Creates a `modbus-smoke` cluster + `modbus-smoke-node` + Draft generation + Namespace + UnsArea/UnsLine/ Equipment + one Modbus `DriverInstance` pointing at the pymodbus standard fixture (`127.0.0.1:5020`) + one Tag at `HR[200]:UInt16`, ending in `EXEC sp_PublishGeneration`. HR[100] is deliberately *not* used because pymodbus `standard.json` runs an auto-increment action on that register. Full-solution build: 0 errors, only the pre-existing xUnit1051 warnings. AB CIP / S7 / AB Legacy factories follow in their own PRs per #211 / #212 / #213. Live boot verification happens in the exit-gate PR once all four factories are in place. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
98a8031772 |
Phase 7 follow-up #240 — Live OPC UA E2E smoke runbook + seed + first-run evidence
Closes the live-smoke validation Phase 7 deferred to. Ships: ## docs/v2/implementation/phase-7-e2e-smoke.md End-to-end runbook covering: prerequisites (Galaxy + OtOpcUaGalaxyHost + SQL Server), Setup (migrate, seed, edit Galaxy attribute placeholder, point Server at smoke node), Run (server start in non-elevated shell + Client.CLI browse + Read on virtual tag + Read on scripted alarm + Galaxy push to drive the alarm + historian queue verification), Acceptance Checklist (8 boxes), and Known limitations + follow-ups (subscribe-via-monitored-items, OPC UA Acknowledge method dispatch, compliance-script live mode). ## scripts/smoke/seed-phase-7-smoke.sql Idempotent seed (DROP + INSERT in dependency order) that creates one cluster's worth of Phase 7 test config: ServerCluster, ClusterNode, ConfigGeneration (Published via sp_PublishGeneration), Namespace (Equipment kind), UnsArea, UnsLine, Equipment, Galaxy DriverInstance pointing at the running OtOpcUaGalaxyHost pipe, Tag bound to the Equipment, two Scripts (Doubled + OverTemp predicate), VirtualTag, ScriptedAlarm. Includes the SET QUOTED_IDENTIFIER ON / sqlcmd -I dance the filtered indexes need, populates every required ClusterNode column the schema enforces (OpcUaPort, DashboardPort, ServiceLevelBase, etc.), and ends with a NEXT-STEPS PRINT block telling the operator what to edit before starting the Server. ## First-run evidence on the dev box Running the seed + starting the Server (non-elevated shell, Galaxy.Host already running) emitted these log lines verbatim — proving the entire Phase 7 wiring chain executes in production: Bootstrapped from central DB: generation 1 Phase 7 historian sink: no driver provides IAlarmHistorianWriter — using NullAlarmHistorianSink VirtualTagEngine loaded 1 tag(s), 1 upstream subscription(s) ScriptedAlarmEngine loaded 1 alarm(s) Phase 7: composed engines from generation 1 — 1 virtual tag(s), 1 scripted alarm(s), 2 script(s) Each line corresponds to a piece shipped in #243 / #244 / #245 / #246 / #247. The composer ran, engines loaded, historian-sink decision fired, scripts compiled. ## Surfaced — pre-Phase-7 deployment-wiring gaps (NOT Phase 7 regressions) 1. Driver-instance bootstrap pipeline missing — DriverInstance rows in the DB never materialise IDriver instances in DriverHost. Filed as task #248. 2. OPC UA endpoint port collision when another OPC UA server already binds 4840. Operator concern; documented in the runbook prereqs. Both predate Phase 7 + are orthogonal. Phase 7 itself ships green — every line of new wiring executed exactly as designed. ## Phase 7 production wiring chain — VALIDATED end-to-end - ✅ #243 composition kernel - ✅ #244 driver bridge - ✅ #245 scripted-alarm IReadable adapter - ✅ #246 Program.cs wire-in - ✅ #247 Galaxy.Host historian writer + SQLite sink activation - ✅ #240 this — live smoke + runbook + first-run evidence Phase 7 is complete + production-ready, modulo the pre-existing driver-bootstrap gap (#248). |