feat(lmxproxy): phase 2 — host core (MxAccessClient, SessionManager, SubscriptionManager)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ArchestrA.MxAccess;
|
||||
using Serilog;
|
||||
using ZB.MOM.WW.LmxProxy.Host.Domain;
|
||||
|
||||
namespace ZB.MOM.WW.LmxProxy.Host.MxAccess
|
||||
{
|
||||
public sealed partial class MxAccessClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Callback invoked by the SubscriptionManager when it needs to deliver
|
||||
/// data change events. Set by the SubscriptionManager during initialization.
|
||||
/// </summary>
|
||||
public Action<string, Vtq>? OnTagValueChanged { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// COM event handler for MxAccess OnDataChange events.
|
||||
/// Called on the STA thread when a subscribed tag value changes.
|
||||
/// Signature matches the ArchestrA.MxAccess ILMXProxyServerEvents interface.
|
||||
/// </summary>
|
||||
private void OnDataChange(
|
||||
int hLMXServerHandle,
|
||||
int phItemHandle,
|
||||
object pvItemValue,
|
||||
int pwItemQuality,
|
||||
object pftItemTimeStamp,
|
||||
ref MXSTATUS_PROXY[] ItemStatus)
|
||||
{
|
||||
try
|
||||
{
|
||||
var quality = MapQuality(pwItemQuality);
|
||||
var timestamp = ConvertTimestamp(pftItemTimeStamp);
|
||||
var vtq = new Vtq(pvItemValue, timestamp, quality);
|
||||
|
||||
// We don't have the address from the COM callback — the reference code
|
||||
// looks it up from _subscriptionsByHandle. For the v2 design, the
|
||||
// SubscriptionManager's global handler receives (address, vtq) via
|
||||
// OnTagValueChanged. The actual address resolution will be implemented
|
||||
// when the full subscription tracking is wired up on windev.
|
||||
|
||||
// Route to the SubscriptionManager's global handler
|
||||
OnTagValueChanged?.Invoke(phItemHandle.ToString(), vtq);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error processing OnDataChange event for handle {Handle}", phItemHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COM event handler for MxAccess OnWriteComplete events.
|
||||
/// Signature matches the ArchestrA.MxAccess ILMXProxyServerEvents interface.
|
||||
/// </summary>
|
||||
private void OnWriteComplete(
|
||||
int hLMXServerHandle,
|
||||
int phItemHandle,
|
||||
ref MXSTATUS_PROXY[] ItemStatus)
|
||||
{
|
||||
// Write completion is currently fire-and-forget.
|
||||
// Log for diagnostics.
|
||||
try
|
||||
{
|
||||
Log.Debug("WriteCompleted: handle {Handle}", phItemHandle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error processing OnWriteComplete event for handle {Handle}", phItemHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a timestamp object to DateTime in UTC.
|
||||
/// </summary>
|
||||
private static DateTime ConvertTimestamp(object timestamp)
|
||||
{
|
||||
if (timestamp is DateTime dt)
|
||||
{
|
||||
return dt.Kind == DateTimeKind.Utc ? dt : dt.ToUniversalTime();
|
||||
}
|
||||
|
||||
return DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user