Repository navigation
feat(opc): read the live edge from the SCADA's OPC UA - #145
Merged
Merged
Conversation
The archive poll could show a change only once the SCADA flushed it, 1 to 3 minutes late for a fast pen and up to a day for a constant one, so a change could not reach the chart within 1 s. The live edge now reads the SCADA's OPC UA server through OpcUaLiveSource in a new SemiPlot.DataSource.OpcUa project, the second implementation of ILiveSource. One ManagedSession per process dials the configured opc.tcp://<host>:<port> from the new opc/ section (tracked as 127.0.0.1 and 49875), keeps that address, finds the project ID by browsing for the root folder and subscribes each pen set at 100 ms with a monitored-item queue of 1. SourceTimestamp, true UTC, becomes the sample time. A lost session writes one break per pen 1 ms past its newest stamp, a Bad notification writes a break, and the chart writes one ahead of a pen's first live sample past its last column, so a pen-set change draws no gap. Pens the source cannot serve are one Warning entry per subscription. OPC UA has its own status-bar indicator and a Warning through ArchiveFailureMapper, after a 30 s grace at start. A bad opc/ file is a startup failure; an unreachable server is not. Deleted: PostgresLiveSource, RealtimePoll, its two statements and poll_interval_ms with its settings field and resx keys. converge gains a required --opc-port and writes the stand's opc/opc.yaml; the AppHost passes 55875 and runs the demo writer with --archive-lag 60.
Member
Author
Acceptance on the real SCADA, 2026-10-21Simple-Scada 2.7.6.0 on this machine, project running, OPC UA on The archive side was a throwaway Postgres container. It held a
Not checked here:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #116
Problem
The chart's live edge polled the archive. Simple-Scada flushes the archive 1 to 3 minutes late for a fast pen,
about 8 minutes for a slow one and up to a day for a constant one, so a change on the plant could not reach the
chart within 1 s.
What changed
The live edge reads the SCADA's OPC UA server; history stays on the archive.
SemiPlot.DataSource.OpcUa, a new project:OpcUaLiveSourceis the second implementation ofILiveSource, registered byAddOpcUaLiveSource.ManagedSessionper process. It dials the configuredopc.tcp://<host>:<port>and keeps it(
UpdateBeforeConnect = false).Noneendpoint, and finds the project ID by browsingObjectsforroot, browsing again on every new session.SourceTimestamp, which is true UTC, becomesSample.TimestampUtc.Badnotification writes a break.Uncertaindraws as a value.TrendPenState) writes a break ahead of a pen's first live sample past its last column, so apen-set change draws no gap.
Warningentry per subscription.Warningand a recoveryInfogo throughArchiveFailureMapperwith the newLiveSourceErrorinSemiPlot.Core/Data/Errors.Unreachableback.opc/section (ConfigFiles/opc/opc.yaml,host: 127.0.0.1,port: 49875). A filethat does not parse or carries a bad value is a startup failure; an unreachable server is not.
DeliveredConfigurationTestscovers the loader.PostgresLiveSource,RealtimePoll, theRealtimePollandRealtimeBaselinestatements, andpoll_interval_mswith its settings field, resx keys and tests. A leftover key in an installed file isignored.
convergegains a required--opc-portand writesopc/opc.yaml. The AppHost passes 55875 and runsthe demo writer with
--archive-lag 60.[DEC:opc-live-edge]insources.md, and the README locked decision.data-integration.md#realtime, and its time boundary.trend-feature-spec.md.charting.md,overview.md,ui-text.md,testing-strategy.md,bench.md,AGENTS.md.scada-archive-observed.md.How it was verified
dotnet build SemiPlot.slnx: 0 errors, only the AppHost's twoNU1902.dotnet format --verify-no-changesexits 0.dotnet terseover every changed.csfile exits 0.SemiPlot.Tests.Unit: 2498/2498.SemiPlot.Tests.Integration: 205/205.OpcUaintegration filter passes 13/13 with no container, against the in-process demo server on freeports. Its coverage:
Dispose()under a droppingSynchronizationContext;git grepproves the deletions and that no OPC test names 49875.Known gaps left open
StartupFailureViewModelstill offers the settings dialog on anopc/failure. The dialog cannot editopc/until
opc-settingslands.Close()can land betweenOnLost's check andEmit(PenSubscriptionSet.cs:93-95).ApplyProjectAsyncignores a changed namespace index.ConnectAsyncretries after a successful discovery.ProjectMissingintoUnreachableand back, whichwrites two extra panel entries.