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>
33 lines
1.2 KiB
C#
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})";
|
|
}
|
|
}
|