using System.Text.Json; using System.Text.Json.Serialization; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; namespace ZB.MOM.WW.OtOpcUa.Driver.Calculation; /// /// Test-connect probe for the Calculation pseudo-driver. There is no backend to connect to — /// the driver computes tags from other tags' values — so the probe just confirms the driver config /// parses (mini-design §7). Per-script compile verification belongs to the editor diagnostics + the /// tag editor's inline panel, not the probe (which receives only the driver config). Never throws; /// returns Ok with negligible latency. /// public sealed class CalculationDriverProbe : IDriverProbe { // Mirrors CalculationDriverFactoryExtensions.JsonOptions / CalculationDriver.ReinitJsonOptions // (AllowTrailingCommas + ReadCommentHandling included) so a config blob the real spawn/reinit path // tolerates never fails Test-Connect as "invalid JSON" — the probe must never be STRICTER than the // path it is standing in for. private static readonly JsonSerializerOptions Opts = new() { PropertyNameCaseInsensitive = true, UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip, ReadCommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, Converters = { new JsonStringEnumConverter() }, }; /// public string DriverType => CalculationDriverFactoryExtensions.DriverTypeName; /// public Task ProbeAsync(string configJson, TimeSpan timeout, CancellationToken ct) { if (string.IsNullOrWhiteSpace(configJson)) return Task.FromResult(new DriverProbeResult(false, "Config JSON is empty.", null)); try { // Parse-only: a Calculation driver's config is well-formed as long as it deserialises to an // object (the RawTags array is optional — a driver with no calc tags is still valid). _ = JsonSerializer.Deserialize(configJson, Opts); } catch (Exception ex) { return Task.FromResult(new DriverProbeResult(false, $"Config JSON is invalid: {ex.Message}", null)); } return Task.FromResult(new DriverProbeResult(true, null, TimeSpan.Zero)); } }