using System; using System.Runtime.InteropServices; using ArchestrA.MxAccess; using ZB.MOM.WW.OtOpcUa.Host.Domain; namespace ZB.MOM.WW.OtOpcUa.Host.MxAccess { /// /// Wraps the real ArchestrA.MxAccess.LMXProxyServer COM object, forwarding calls to IMxProxy. /// Uses strongly-typed interop — same pattern as the reference LmxProxy implementation. (MXA-001) /// public sealed class MxProxyAdapter : IMxProxy { private LMXProxyServer? _lmxProxy; /// /// Occurs when the COM proxy publishes a live data-change callback for a subscribed Galaxy attribute. /// public event MxDataChangeHandler? OnDataChange; /// /// Occurs when the COM proxy confirms completion of a write request. /// public event MxWriteCompleteHandler? OnWriteComplete; /// /// Creates and registers the COM proxy session that backs live MXAccess operations. /// /// The client name reported to the Wonderware runtime. /// The runtime connection handle assigned by the COM server. public int Register(string clientName) { _lmxProxy = new LMXProxyServer(); _lmxProxy.OnDataChange += ProxyOnDataChange; _lmxProxy.OnWriteComplete += ProxyOnWriteComplete; var handle = _lmxProxy.Register(clientName); if (handle <= 0) throw new InvalidOperationException($"LMXProxyServer.Register returned invalid handle: {handle}"); return handle; } /// /// Unregisters the COM proxy session and releases the underlying COM object. /// /// The runtime connection handle returned by . public void Unregister(int handle) { if (_lmxProxy != null) try { _lmxProxy.OnDataChange -= ProxyOnDataChange; _lmxProxy.OnWriteComplete -= ProxyOnWriteComplete; _lmxProxy.Unregister(handle); } finally { Marshal.ReleaseComObject(_lmxProxy); _lmxProxy = null; } } /// /// Resolves a Galaxy attribute reference into a runtime item handle through the COM proxy. /// /// The runtime connection handle. /// The fully qualified Galaxy attribute reference. /// The item handle assigned by the COM proxy. public int AddItem(int handle, string address) { return _lmxProxy!.AddItem(handle, address); } /// /// Removes an item handle from the active COM proxy session. /// /// The runtime connection handle. /// The item handle to remove. public void RemoveItem(int handle, int itemHandle) { _lmxProxy!.RemoveItem(handle, itemHandle); } /// /// Enables supervisory callbacks for the specified runtime item. /// /// The runtime connection handle. /// The item handle to monitor. public void AdviseSupervisory(int handle, int itemHandle) { _lmxProxy!.AdviseSupervisory(handle, itemHandle); } /// /// Disables supervisory callbacks for the specified runtime item. /// /// The runtime connection handle. /// The item handle to stop monitoring. public void UnAdviseSupervisory(int handle, int itemHandle) { _lmxProxy!.UnAdvise(handle, itemHandle); } /// /// Writes a value to the specified runtime item through the COM proxy. /// /// The runtime connection handle. /// The item handle to write. /// The value to send to the runtime. /// The Wonderware security classification applied to the write. public void Write(int handle, int itemHandle, object value, int securityClassification) { _lmxProxy!.Write(handle, itemHandle, value, securityClassification); } private void ProxyOnDataChange(int hLMXServerHandle, int phItemHandle, object pvItemValue, int pwItemQuality, object pftItemTimeStamp, ref MXSTATUS_PROXY[] ItemStatus) { OnDataChange?.Invoke(hLMXServerHandle, phItemHandle, pvItemValue, pwItemQuality, pftItemTimeStamp, ref ItemStatus); } private void ProxyOnWriteComplete(int hLMXServerHandle, int phItemHandle, ref MXSTATUS_PROXY[] ItemStatus) { OnWriteComplete?.Invoke(hLMXServerHandle, phItemHandle, ref ItemStatus); } } }