Files
lmxopcua/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/TwinCATDeviceDiagnostics.cs
T
Joseph Doherty fbcb521d1b fix(twincat): review fixes for sum-read and diagnostics (#645)
Strict width+kind eligibility for sum-batched scalars (others read singly); latch only on ADS
1793/1794, split 1792/1797/1798 without latching; 32 KiB per-command budget and 500-item ceiling;
short sum response handled per item. Diagnostics: opt-in diagnosticsEnabled (default off), reuse the
probe's ReadState, sample after the host-state transition, JitterMs renamed HeadroomMs, compact
per-device line so many devices fit the 16-entry cap, unavailable-symbol latch cleared on reconnect.
AdminUI: min/max on sum-read max, diagnostics checkbox. Pure planner extracted and unit-tested.

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
2026-10-08 19:29:35 -04:00

27 lines
1.5 KiB
C#

namespace ZB.MOM.WW.OtOpcUa.Driver.TwinCAT;
/// <summary>
/// One device's probe-sampled PLC facts (Gitea #645 / #314), surfaced through the driver's
/// <see cref="Core.Abstractions.IDriverDiagnostics"/> bag to the <c>/hosts</c> page. Every field is
/// best-effort: a runtime that does not export a system symbol leaves that field at its last known value
/// (null if never seen).
/// </summary>
/// <param name="AdsState">The ADS device state name (<c>Run</c>, <c>Stop</c>, <c>Config</c>, …).</param>
/// <param name="AppName">The running PLC application's name (<c>_AppInfo.AppName</c>).</param>
/// <param name="OnlineChangeCnt">How many online changes the application has taken (<c>_AppInfo.OnlineChangeCnt</c>).</param>
/// <param name="CycleTimeMs">The first PLC task's configured cycle time in milliseconds.</param>
/// <param name="LastExecTimeMs">How long the task's last cycle took to execute, in milliseconds.</param>
/// <param name="UpdatedUtc">When the snapshot was taken.</param>
internal sealed record TwinCATDeviceDiagnostics(
string? AdsState,
string? AppName,
uint? OnlineChangeCnt,
double? CycleTimeMs,
double? LastExecTimeMs,
DateTime UpdatedUtc)
{
/// <summary>Gets cycle time minus last execution time: how much of the cycle was spare. Negative means the
/// task overran its cycle. (Not jitter — that needs the variation across cycles.)</summary>
public double? HeadroomMs => CycleTimeMs is { } c && LastExecTimeMs is { } x ? c - x : null;
}