docs: add Phase 7 status reconciliation document
Audits every Phase 7 plan stream (A-H) against the repo, confirms the exit gate is fully closed, and records the five genuine remaining gaps: OPC UA method-call dispatch for alarm Ack/Confirm/Shelve, the /virtual-tags and /scripted-alarms Admin UI tabs, the script log viewer, and the missing production IHistoryWriter for virtual-tag historization. Also notes that docs/v2/v2-release-readiness.md carries a stale "out of scope" label — Phase 7 shipped completely after that doc was last updated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -98,6 +98,7 @@ Design decisions + phase plans + execution notes. Load-bearing cross-references
|
||||
- [v2/test-data-sources.md](v2/test-data-sources.md) — integration-test simulator matrix (includes the pinned libplctag `ab_server` version for AB CIP tests)
|
||||
- [v2/multi-host-dispatch.md](v2/multi-host-dispatch.md) — per-PLC circuit breakers (Phase 6.1 decision #144)
|
||||
- [v2/v2-release-readiness.md](v2/v2-release-readiness.md) — release-readiness tracker
|
||||
- [v2/phase-7-status.md](v2/phase-7-status.md) — Phase 7 reconciliation: what shipped vs. the plan, and the five remaining gaps
|
||||
- [v2/implementation/phase-*-*.md](v2/implementation/) — per-phase execution plans with exit-gate evidence
|
||||
|
||||
## v1 archive
|
||||
|
||||
197
docs/v2/phase-7-status.md
Normal file
197
docs/v2/phase-7-status.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# Phase 7 Status — Scripting Runtime, Virtual Tags, Scripted Alarms, Historian Sink
|
||||
|
||||
> **Reconciliation date**: 2026-05-18
|
||||
> **Based on**: `docs/v2/implementation/phase-7-scripting-and-alarming.md` (the plan) and
|
||||
> `docs/v2/implementation/exit-gate-phase-7.md` (the exit-gate audit) cross-checked against
|
||||
> the actual repository files. See "Evidence sources" at the bottom.
|
||||
|
||||
## Summary verdict
|
||||
|
||||
**Phase 7 core is fully shipped and the exit gate is closed.** All eight plan streams
|
||||
(A–H, where H = exit gate) plus the three deferred follow-ups (tasks #239 / #240 / #241)
|
||||
landed before the 2026-04-23 exit-gate audit. The `v2-release-readiness.md` note
|
||||
"Phase 7 — out of scope for v2 GA" is a stale label: the work shipped after that doc
|
||||
was last updated. The four `Core.*` Phase 7 projects exist, have tests, and are wired
|
||||
into the running server. Five targeted gaps remain open (see section below).
|
||||
|
||||
---
|
||||
|
||||
## Work-item status by plan stream
|
||||
|
||||
### Stream A — `Core.Scripting` (Roslyn engine, sandbox, AST inference, logger)
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| A.1 — Project scaffold + `ScriptContext` base class (`GetTag` / `SetVirtualTag` / `Logger` / `Now` / `Deadband`) | **Done** | `src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/ScriptContext.cs`, `ScriptGlobals.cs` |
|
||||
| A.2 — `DependencyExtractor : CSharpSyntaxWalker` — literal-only path check, `Inputs` + `Outputs` sets | **Done** | `DependencyExtractor.cs`; literal-reject logic exercised by 7 test files in `Core.Scripting.Tests` |
|
||||
| A.3 — Compile cache keyed on `SHA-256(source)` | **Done** | `CompiledScriptCache.cs` (`ConcurrentDictionary<string, Lazy<ScriptEvaluator<...>>>`) |
|
||||
| A.4 — Per-evaluation timeout (250 ms default) | **Done** | `TimedScriptEvaluator.cs`; `TimedScriptEvaluatorTests.cs` |
|
||||
| A.5 — Serilog sink wiring; `scripts-*.log` companion mirror to main log at WARN on ERROR | **Done** | `ScriptLoggerFactory.cs`, `ScriptLogCompanionSink.cs`; `ScriptLogCompanionSinkTests.cs` |
|
||||
| A.6 — Tests (AST extraction, sandbox escape, exception isolation, timeout, logger binding) | **Done** | `ScriptSandboxTests.cs`, `DependencyExtractorTests.cs`, `CompiledScriptCacheTests.cs`, `ScriptLoggerFactoryTests.cs`, `TimedScriptEvaluatorTests.cs` — 7 test files |
|
||||
|
||||
Shipped as PRs #177–#179 (63 tests).
|
||||
|
||||
### Stream B — Virtual tag engine
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| B.1 — `VirtualTagEngine` + `DependencyGraph` | **Done** | `VirtualTagEngine.cs`, `DependencyGraph.cs` |
|
||||
| B.2 — `ChangeTriggerDispatcher` (subscribe to referenced driver tags via `ITagUpstreamSource`) | **Done** | `VirtualTagEngine.OnUpstreamChange` internal subscriber path |
|
||||
| B.3 — `TimerTriggerDispatcher` (per-tag `IntervalMs` via timer-wheel) | **Done** | `TimerTriggerScheduler.cs` |
|
||||
| B.4 — `EvaluationPipeline` (serial, per-tag isolation, `_evalGate` semaphore) | **Done** | `VirtualTagEngine.EvaluateInternalAsync`; `_evalGate SemaphoreSlim(1,1)` |
|
||||
| B.5 — `IVirtualTagSource` implementing `IReadable` + `ISubscribable` | **Done** | `VirtualTagSource.cs` |
|
||||
| B.6 — History routing (`IHistoryWriter.Record` when `Historize=true`) | **Partial** | `IHistoryWriter.cs` + `NullHistoryWriter` present; no production writer is wired into the virtual-tag path. `docs/VirtualTags.md` §"Upstream reads + history" explicitly notes: "no production writer is currently wired for virtual tags". Virtual-tag historization is functional at the engine level but has no live sink. |
|
||||
| B.7 — Tests: dependency graph, cascade, timer, change+timer combined, error propagation, historize | **Done** | `DependencyGraphTests.cs`, `VirtualTagEngineTests.cs`, `TimerTriggerSchedulerTests.cs`, `VirtualTagSourceTests.cs` — 5 test files |
|
||||
|
||||
Shipped as PR #180 (36 tests).
|
||||
|
||||
### Stream C — Scripted alarm engine + Part 9 state machine + template messages
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| C.1 — `ScriptedAlarmEngine` skeleton + alarm config model | **Done** | `ScriptedAlarmEngine.cs`, `ScriptedAlarmDefinition.cs` |
|
||||
| C.2 — `Part9StateMachine` (Enable/Disable/Active/Ack/Confirm/Shelve/Unshelve/Comment/ShelvingCheck) | **Done** | `Part9StateMachine.cs`; `Part9StateMachineTests.cs` |
|
||||
| C.3 — Predicate evaluation on input change; activate/clear transitions | **Done** | `ScriptedAlarmEngine.ReevaluateAsync`; `_alarmsReferencing` inverse index |
|
||||
| C.4 — Startup recovery (`ActiveState` re-derived; Enabled/Ack/Confirm/Shelve loaded from store) | **Done** | `ScriptedAlarmEngine.LoadAsync`; `IAlarmStateStore.LoadAsync` |
|
||||
| C.5 — Template substitution (`{TagPath}` tokens resolved at emission time) | **Done** | `MessageTemplate.cs`; `MessageTemplateTests.cs` |
|
||||
| C.6 — OPC UA method binding (Acknowledge / Confirm / AddComment / OneShotShelve / TimedShelve / Unshelve) | **Partial** | Engine methods exist and are tested. `ScriptedAlarmSource.AcknowledgeAsync` defaults the user to `"opcua-client"`. The plan's Stream G wiring of these methods to OPC UA `MethodCall` dispatch on the condition nodes (so OPC UA client method calls reach the engine with the authenticated principal) is noted in the e2e smoke doc as "not yet wired through `DriverNodeManager.MethodCall` dispatch." Operators acknowledge through Admin UI today; the Part 9 method-call path is a follow-up. |
|
||||
| C.7 — `IAlarmSource` implementation / fan-out registration | **Done** | `ScriptedAlarmSource.cs` |
|
||||
| C.8 — Tests: all state transitions, startup recovery, template substitution, shelving timer expiry | **Done** | `Part9StateMachineTests.cs`, `ScriptedAlarmEngineTests.cs`, `ScriptedAlarmSourceTests.cs`, `MessageTemplateTests.cs` — 5 test files |
|
||||
|
||||
Shipped as PR #181 (47 tests).
|
||||
|
||||
### Stream D — Historian alarm sink (SQLite store-and-forward + Wonderware IPC)
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| D.1 — `Core.AlarmHistorian` project; `IAlarmHistorianSink`; `SqliteStoreAndForwardSink` (backoff, dead-letter, capacity) | **Done** | `IAlarmHistorianSink.cs`, `SqliteStoreAndForwardSink.cs`; `SqliteStoreAndForwardSinkTests.cs` |
|
||||
| D.2 — Live-historian smoke against dev box Aveva Historian; document the exact SDK entry point | **Partial** | The smoke (`docs/v2/implementation/phase-7-e2e-smoke.md`) ran but the IPC path via Galaxy.Host to `aahClientManaged` was the original plan. That path changed: the production implementation uses `Driver.Historian.Wonderware.Client` (`WonderwareHistorianClient.WriteBatchAsync`) over a named-pipe sidecar, not Galaxy.Host. There is no separate `docs/v2/historian-alarm-api.md` artifact documenting the SDK entry point as the plan called for; the implementation detail is in `WonderwareHistorianClient.cs` inline. |
|
||||
| D.3 — `Driver.Galaxy.Shared` contract additions (`HistorianAlarmEventRequest` / `Response` / `ConnectivityStatusNotification`) | **Changed** | The plan routed alarm writes through Galaxy.Host IPC. The shipped implementation uses `Driver.Historian.Wonderware.Client` (a standalone sidecar project) instead. `HistorianAlarmEventRequest` / `HistorianAlarmEventResponse` as named protos never shipped; the equivalent contract is the `AlarmHistorianEventDto` / `WriteAlarmEventsRequest` / `WriteAlarmEventsReply` MessagePack DTOs in `Driver.Historian.Wonderware.Client/Ipc/`. Galaxy.Host still exists as the mxaccessgw entry point but does not carry historian writes. |
|
||||
| D.4 — `Driver.Galaxy.Host` handler for alarm writes | **Changed** | Not shipped via Galaxy.Host. The sidecar (`Driver.Historian.Wonderware.Client`) is the production path. `IAlarmHistorianWriter` is implemented by `WonderwareHistorianClient`, not by a Galaxy.Host frame handler. |
|
||||
| D.5 — Drain worker in main server (poll SQLite queue, batch 100 events, exponential backoff) | **Done** | `SqliteStoreAndForwardSink.StartDrainLoop`; backoff ladder 1s → 2s → 5s → 15s → 60s; `Phase7Composer.ResolveHistorianSink` starts it with a 2-second drain cadence |
|
||||
| D.6 — Per-alarm `HistorizeToAveva` toggle; `AlarmHistorizationPolicy` per source | **Done** | `ScriptedAlarm.HistorizeToAveva` column (default `true`); `Phase7EngineComposer.RouteToHistorianAsync` checks it; Galaxy defaults `false` |
|
||||
| D.7 — `/alarms/historian` diagnostics view in Admin (queue depth, drain rate, last error, retry dead-lettered) | **Done** | `AlarmsHistorian.razor`; `HistorianDiagnosticsService.cs` |
|
||||
| D.8 — Tests | **Done** | `SqliteStoreAndForwardSinkTests.cs`; `Phase7ComposerWriterSelectionTests.cs` covers historian-writer resolution |
|
||||
|
||||
Shipped as PR #182 (14 tests). Architecture deviated from the plan (Wonderware sidecar instead of Galaxy.Host IPC) but the functional goals are met.
|
||||
|
||||
### Stream E — Config DB schema + generation-sealed cache extensions
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| E.1 — EF migration for `Script` / `VirtualTag` / `ScriptedAlarm` / `ScriptedAlarmState` tables | **Done** | Migration `20260420231641_AddPhase7ScriptingTables.cs`; entities in `Configuration/Entities/` |
|
||||
| E.2 — `sp_PublishGeneration` extension (sealed-cache snapshot includes Phase 7 rows) | **Done** | Migration `20260420232000_ExtendComputeGenerationDiffWithPhase7.cs` |
|
||||
| E.3 — CRUD services: `VirtualTagService`, `ScriptedAlarmService`, `ScriptService`, `ScriptedAlarmStateService` | **Done** | All four exist in `Admin/Services/`; `GetStateAsync` on `ScriptedAlarmService` serves the state query |
|
||||
| E.4 — Tests: migration up/down; publish atomicity; audit trail | **Done** | `Phase7ServicesTests.cs` (13 tests covering CRUD + hash behavior + harness) |
|
||||
|
||||
Shipped as PR #183 (12 tests in configuration; 13 more in Admin.Tests).
|
||||
|
||||
### Stream F — Admin UI scripting tab
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| F.1 — Monaco editor Razor component (CDN bundle + textarea fallback) | **Done** | `ScriptEditor.razor` (textarea with Monaco JS interop, `otOpcUaScriptEditor.attach`) |
|
||||
| F.2 — `/virtual-tags` tab (list view, edit pane, dependency preview, publish gate) | **Partial** | The `ScriptsTab.razor` is the single tab covering script CRUD, dependency preview, and harness. There is no separate `/virtual-tags` tab UI — virtual tags are managed through the script service alone; no VirtualTag list/edit form exists in the Admin UI. The per-tag fields (`EquipmentId`, `DataType`, `ChangeTriggered`, `TimerIntervalMs`, `Historize`) are accessible via the `VirtualTagService` backend but have no corresponding UI form. |
|
||||
| F.3 — `/scripted-alarms` tab (alarm type, severity, message template, `HistorizeToAveva`, detail page with shelve/ack state read-only) | **Partial** | No dedicated scripted-alarms tab razor page exists (confirmed by Glob + Grep searches). Scripted alarm CRUD (`ScriptedAlarmService`) exists as a service but has no Admin UI page. |
|
||||
| F.4 — Test harness (modal, synthetic inputs, output + logger display) | **Partial** | `ScriptTestHarnessService.cs` is complete and tested. `ScriptsTab.razor` calls `Harness.RunVirtualTagAsync` with zero-value synthetic inputs derived from the extractor. A full interactive input-form modal was not shipped — the harness zeroes all inputs automatically rather than prompting the operator per-tag. |
|
||||
| F.5 — Script log viewer (SignalR tail of `scripts-*.log` filtered by `ScriptName`, load-more) | **Not started** | No SignalR stream of the scripts log is wired in the Admin UI. The `AlertHub` / `FleetStatusHub` exist but there is no `ScriptLogHub`. |
|
||||
| F.6 — `/alarms/historian` diagnostics view | **Done** | `AlarmsHistorian.razor` + `HistorianDiagnosticsService.cs` |
|
||||
| F.7 — Playwright smoke (author calc tag, verify in equipment tree; author alarm, verify in `AlarmsAndConditions`) | **Not started** | `tests/Server/ZB.MOM.WW.OtOpcUa.Admin.E2ETests/` exists but its `UnsTabDragDropE2ETests.cs` is the only Playwright test; no Phase 7 Admin UI playwright scenario. |
|
||||
|
||||
Shipped as PR #185 (13 Admin service tests; UI completeness is partial — see gaps section).
|
||||
|
||||
### Stream G — Address-space integration
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| G.1 — `EquipmentNodeWalker` extension emits `NodeSourceKind.Virtual` + `NodeSourceKind.ScriptedAlarm` variables | **Done** | PR #184; `NodeSourceKind` discriminator confirmed in exit gate |
|
||||
| G.2 — `DriverNodeManager` dispatch routes reads by source; writes to non-Driver rejected with `BadUserAccessDenied` | **Done** | PR #186 follow-up; `OpcUaApplicationHost.SetPhase7Sources` threads `_virtualReadable` + `_scriptedAlarmReadable` into the node manager |
|
||||
| G.3 — `AlarmTracker` composition (`ScriptedAlarmEngine` registers as additional `IAlarmSource`) | **Done** | `ScriptedAlarmSource` adapts engine to `IAlarmSource`; `Phase7EngineComposer.Compose` wires it |
|
||||
| G.4 — Tests: mixed equipment folder browsable via Client.CLI; read/subscribe round-trip; alarm transitions in event stream | **Done** | `Phase7ComposerMappingTests.cs`, `Phase7EngineComposerTests.cs`, `ScriptedAlarmReadableTests.cs`, `CachedTagUpstreamSourceTests.cs`, `DriverSubscriptionBridgeTests.cs` — 6 test files in `Server.Tests/Phase7/` |
|
||||
| OPC UA method binding for alarm Ack/Confirm/Shelve | **Not started** | Noted explicitly in `phase-7-e2e-smoke.md` §"Known limitations": `DriverNodeManager.MethodCall` dispatch for scripted alarm methods is not wired. Engine has the methods; the OPC UA call path does not reach them. |
|
||||
|
||||
Shipped across PRs #184 + #186 (5 + 7 tests).
|
||||
|
||||
### Stream H — Exit gate
|
||||
|
||||
| Plan item | Status | Evidence |
|
||||
|-----------|--------|----------|
|
||||
| H.1 — Compliance script real-checks | **Done** | `scripts/compliance/phase-7-compliance.ps1` |
|
||||
| H.2 — Full solution `dotnet test` baseline | **Done** | Exit gate records ~197 new tests + solution baseline |
|
||||
| H.3 — `plan.md` Migration Strategy §6 update | **Not verified** | Not explicitly confirmed; minor — the plan doc is not the primary status artifact |
|
||||
| H.4 — Phase-status memory update | **Done** | Memory updated (see `project_alarms_over_gateway_epic.md` + `project_server_history_alarm_subsystems.md`) |
|
||||
| H.5 — Merge `v2/phase-7-scripting-and-alarming` → `v2` | **Done** | All PRs (#177–#186) merged |
|
||||
|
||||
### Post-gate follow-ups (tasks #239 / #240 / #241)
|
||||
|
||||
All three are verified closed in the 2026-04-23 exit-gate audit:
|
||||
|
||||
| Task | Item | Status |
|
||||
|------|------|--------|
|
||||
| #239 | `SealedBootstrap` composition root — `Phase7Composer.PrepareAsync` + `OpcUaServerService` wiring | **Done** |
|
||||
| #240 | Live OPC UA e2e smoke — `scripts/e2e/test-phase7-virtualtags.ps1` | **Done** (partial pass: 3/7 stages reach `PASS`; writer/subscribe/alarm stages blocked by live Galaxy attribute activity + Historian SDK environment) |
|
||||
| #241 | `sp_ComputeGenerationDiff` extension for Script / VirtualTag / ScriptedAlarm diff sections | **Done** — migration `20260420232000_ExtendComputeGenerationDiffWithPhase7` |
|
||||
|
||||
---
|
||||
|
||||
## What genuinely remains
|
||||
|
||||
These are real open items, not issues with the plan reconciliation.
|
||||
|
||||
### Gap 1 — OPC UA method-call dispatch for scripted alarm Ack/Confirm/Shelve (Stream G / C.6)
|
||||
|
||||
`DriverNodeManager.MethodCall` does not route OPC UA `Acknowledge` / `Confirm` / `OneShotShelve` / `TimedShelve` / `Unshelve` / `AddComment` method invocations to the `ScriptedAlarmEngine`. Operators can acknowledge scripted alarms through the Admin UI today; OPC UA HMI clients expecting to use Part 9 method nodes directly cannot. Explicit in `phase-7-e2e-smoke.md` §"Known limitations".
|
||||
|
||||
### Gap 2 — Admin UI: no `/virtual-tags` tab or form (Stream F.2)
|
||||
|
||||
`VirtualTagService` CRUD is fully tested but no razor page exposes it. Operators must author virtual tags through direct SQL or Admin API calls. `ScriptsTab.razor` covers script CRUD only; virtual-tag fields (`EquipmentId`, `DataType`, trigger config, `Historize`) have no UI form.
|
||||
|
||||
### Gap 3 — Admin UI: no `/scripted-alarms` tab or form (Stream F.3)
|
||||
|
||||
`ScriptedAlarmService` CRUD is fully tested but no razor page exists. Only `ScriptsTab.razor` under the cluster detail view is present; there is no `ScriptedAlarmsTab.razor` or equivalent.
|
||||
|
||||
### Gap 4 — Script log viewer not shipped (Stream F.5)
|
||||
|
||||
The SignalR tail of `scripts-*.log` filtered by `ScriptName` was not implemented. `ScriptsTab.razor` shows script output from the in-process harness but has no live-log panel for production emissions.
|
||||
|
||||
### Gap 5 — Virtual-tag historization has no production sink (Stream B.6)
|
||||
|
||||
`IHistoryWriter` + `NullHistoryWriter` are present; `VirtualTagEngine` calls `IHistoryWriter.Record` per evaluation when `Historize=true`. `Phase7EngineComposer.Compose` passes `NullHistoryWriter` — no live writer is wired. Virtual-tag values are computed and served correctly but never persisted to any historian. Explicitly documented in `docs/VirtualTags.md` §"Upstream reads + history".
|
||||
|
||||
---
|
||||
|
||||
## What is definitely done
|
||||
|
||||
- All four `Core.*` projects (`Core.Scripting`, `Core.VirtualTags`, `Core.ScriptedAlarms`, `Core.AlarmHistorian`) ship with full implementation and test coverage.
|
||||
- Roslyn sandbox (allow-list + `ForbiddenTypeAnalyzer` defense-in-depth + 250 ms timeout + per-script Serilog sink + compile cache) is complete.
|
||||
- Virtual tag engine: dependency graph with iterative Tarjan SCC, topo-sort, change-trigger cascade, timer trigger, `IReadable` + `ISubscribable` adapter, per-tag error isolation.
|
||||
- Scripted alarm engine: full Part 9 state machine, startup recovery, template substitution, `IAlarmSource` fan-out, 5-second shelving timer, `IAlarmStateStore` (in-memory default; DB-backed via Config DB entities).
|
||||
- SQLite store-and-forward historian sink: drain loop with exponential backoff, dead-letter retention, bounded capacity, `RetryDeadLettered` operator action.
|
||||
- Config DB schema: `Script`, `VirtualTag`, `ScriptedAlarm`, `ScriptedAlarmState` tables with EF migrations and generation-diff extension.
|
||||
- Admin services: `ScriptService`, `VirtualTagService`, `ScriptedAlarmService`, `ScriptTestHarnessService`, `HistorianDiagnosticsService` — all backed by unit tests.
|
||||
- Admin UI: `ScriptsTab.razor` (Monaco-backed editor, dependency preview, test harness), `AlarmsHistorian.razor` (queue depth, drain state, retry dead-lettered).
|
||||
- Server-side composition: `Phase7Composer`, `Phase7EngineComposer`, `CachedTagUpstreamSource`, `DriverSubscriptionBridge`, `ScriptedAlarmReadable` — fully wired into `OpcUaServerService` startup sequence before `OpcUaApplicationHost.StartAsync`.
|
||||
- `EquipmentNodeWalker` emits `NodeSourceKind.Virtual` and `NodeSourceKind.ScriptedAlarm` variables; `DriverNodeManager` dispatches reads and rejects writes to virtual nodes.
|
||||
- `WonderwareHistorianClient.WriteBatchAsync` implements `IAlarmHistorianWriter` as the alarm-event write path (deviation from plan's Galaxy.Host route, but functionally equivalent).
|
||||
- Compliance script `scripts/compliance/phase-7-compliance.ps1` and e2e smoke `scripts/e2e/test-phase7-virtualtags.ps1` both present.
|
||||
|
||||
---
|
||||
|
||||
## Evidence sources
|
||||
|
||||
| Source | Path |
|
||||
|--------|------|
|
||||
| Phase 7 plan | `docs/v2/implementation/phase-7-scripting-and-alarming.md` |
|
||||
| Phase 7 exit gate | `docs/v2/implementation/exit-gate-phase-7.md` |
|
||||
| E2E smoke runbook | `docs/v2/implementation/phase-7-e2e-smoke.md` |
|
||||
| Virtual tags reference doc | `docs/VirtualTags.md` |
|
||||
| Scripted alarms reference doc | `docs/ScriptedAlarms.md` |
|
||||
| `Core.Scripting` sources | `src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/` |
|
||||
| `Core.VirtualTags` sources | `src/Core/ZB.MOM.WW.OtOpcUa.Core.VirtualTags/` |
|
||||
| `Core.ScriptedAlarms` sources | `src/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms/` |
|
||||
| `Core.AlarmHistorian` sources | `src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/` |
|
||||
| Server Phase7 composition | `src/Server/ZB.MOM.WW.OtOpcUa.Server/Phase7/` |
|
||||
| Admin services | `src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/Script*.cs`, `VirtualTagService.cs`, `HistorianDiagnosticsService.cs` |
|
||||
| Admin UI pages | `src/Server/ZB.MOM.WW.OtOpcUa.Admin/Components/Pages/Clusters/ScriptsTab.razor`, `AlarmsHistorian.razor` |
|
||||
| Historian sidecar writer | `src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Client/WonderwareHistorianClient.cs` |
|
||||
| EF migrations | `src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Migrations/20260420231641_AddPhase7ScriptingTables.cs`, `20260420232000_ExtendComputeGenerationDiffWithPhase7.cs` |
|
||||
Reference in New Issue
Block a user