Files
lmxopcua/src/ZB.MOM.WW.LmxOpcUa.Host/Domain/Vtq.cs
Joseph Doherty a7576ffb38 Implement LmxOpcUa server — all 6 phases complete
Full OPC UA server on .NET Framework 4.8 (x86) exposing AVEVA System
Platform Galaxy tags via MXAccess. Mirrors Galaxy object hierarchy as
OPC UA address space, translating contained-name browse paths to
tag-name runtime references.

Components implemented:
- Configuration: AppConfiguration with 4 sections, validator
- Domain: ConnectionState, Quality, Vtq, MxDataTypeMapper, error codes
- MxAccess: StaComThread, MxAccessClient (partial classes), MxProxyAdapter
  using strongly-typed ArchestrA.MxAccess COM interop
- Galaxy Repository: SQL queries (hierarchy, attributes, change detection),
  ChangeDetectionService with auto-rebuild on deploy
- OPC UA Server: LmxNodeManager (CustomNodeManager2), LmxOpcUaServer,
  OpcUaServerHost with programmatic config, SecurityPolicy None
- Status Dashboard: HTTP server with HTML/JSON/health endpoints
- Integration: Full 14-step startup, graceful shutdown, component wiring

175 tests (174 unit + 1 integration), all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 05:55:27 -04:00

33 lines
1.2 KiB
C#

using System;
namespace ZB.MOM.WW.LmxOpcUa.Host.Domain
{
/// <summary>
/// Value-Timestamp-Quality triplet for tag data. (MXA-003, OPC-007)
/// </summary>
public readonly struct Vtq : IEquatable<Vtq>
{
public object? Value { get; }
public DateTime Timestamp { get; }
public Quality Quality { get; }
public Vtq(object? value, DateTime timestamp, Quality quality)
{
Value = value;
Timestamp = timestamp;
Quality = quality;
}
public static Vtq Good(object? value) => new Vtq(value, DateTime.UtcNow, Quality.Good);
public static Vtq Bad(Quality quality = Quality.Bad) => new Vtq(null, DateTime.UtcNow, quality);
public static Vtq Uncertain(object? value) => new Vtq(value, DateTime.UtcNow, Quality.Uncertain);
public bool Equals(Vtq other) =>
Equals(Value, other.Value) && Timestamp == other.Timestamp && Quality == other.Quality;
public override bool Equals(object? obj) => obj is Vtq other && Equals(other);
public override int GetHashCode() => HashCode.Combine(Value, Timestamp, Quality);
public override string ToString() => $"Vtq({Value}, {Timestamp:O}, {Quality})";
}
}