using MessagePack; namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Shared.Contracts; /// /// Subscribe the Host to polling a set of tags on behalf of the Proxy. FOCAS is /// poll-only — there are no CNC-initiated callbacks — so the Host runs the poll loop and /// pushes frames whenever a value differs from /// the last observation. Delta-only + per-group interval keeps the wire quiet. /// [MessagePackObject] public sealed class SubscribeRequest { [Key(0)] public long SessionId { get; set; } [Key(1)] public long SubscriptionId { get; set; } [Key(2)] public int IntervalMs { get; set; } = 1000; [Key(3)] public SubscribeItem[] Items { get; set; } = System.Array.Empty(); } [MessagePackObject] public sealed class SubscribeItem { /// Opaque correlation id the Proxy uses to route notifications back to the right OPC UA MonitoredItem. [Key(0)] public long MonitoredItemId { get; set; } [Key(1)] public FocasAddressDto Address { get; set; } = new(); [Key(2)] public int DataType { get; set; } } [MessagePackObject] public sealed class SubscribeResponse { [Key(0)] public bool Success { get; set; } [Key(1)] public string? Error { get; set; } /// Items the Host refused (address mismatch, unsupported type). Empty on full success. [Key(2)] public long[] RejectedMonitoredItemIds { get; set; } = System.Array.Empty(); } [MessagePackObject] public sealed class UnsubscribeRequest { [Key(0)] public long SubscriptionId { get; set; } } [MessagePackObject] public sealed class OnDataChangeNotification { [Key(0)] public long SubscriptionId { get; set; } [Key(1)] public DataChange[] Changes { get; set; } = System.Array.Empty(); } [MessagePackObject] public sealed class DataChange { [Key(0)] public long MonitoredItemId { get; set; } [Key(1)] public uint StatusCode { get; set; } [Key(2)] public byte[]? ValueBytes { get; set; } [Key(3)] public int ValueTypeCode { get; set; } [Key(4)] public long SourceTimestampUtcUnixMs { get; set; } }