public void AddChildTag(TheOPCMonitoredItemBase childTag) { if (_childTags == null) { _childTags = new List <TheOPCMonitoredItemBase>(); } _childTags.Add(childTag); }
//public bool RegisterOrUnregisterThingForOpcEvent(TheOPCUARemoteServer server) //{ // var tEventHost = this.GetThing(); // if (tEventHost == null) // { // return false; // } // if (this.m_monitoredItem != null && this.m_monitoredItem.Handle != tEventHost) // { // UnregisterThingForOpcEvents(server); // } // return RegisterThingForOpcEvents(server); //} //void UnregisterThingForOpcEvents(TheOPCUARemoteServer server) //{ // var tEventHost = this.m_monitoredItem.Handle as ICDEThing; // if (tEventHost != null) // { // // Stop the monitored item from updating the host thing // this.m_monitoredItem.Handle = null; // // Remove any properties from the host thing // var cdeMValue = TheOPCMonitoredItemBase.GetOpcUaMetaString(server, this.EventTypeId); // foreach (var cdeProp in tEventHost.GetBaseThing().GetPropertiesMetaStartingWith("OPCUA")) // { // if (cdeProp.cdeM == cdeMValue) // { // cdeProp.cdeM = null; // tEventHost.GetBaseThing().RemoveProperty(cdeProp.Name); // } // } // } // // Remove the monitored item // try // { // if (this.m_monitoredItem != null && this.m_monitoredItem.Subscription != null) // { // this.m_monitoredItem.Subscription.RemoveItem(this.m_monitoredItem); // this.m_monitoredItem.Subscription.ApplyChanges(); // this.m_monitoredItem = null; // } // } // catch (Exception e) // { // // Not much we can do if this fails other than leak the subscription until the next restart? // } //} //bool RegisterThingForOpcEvents(TheOPCUARemoteServer server) //{ // var tEventHost = this.GetThing(); // if (tEventHost == null) // { // // TODO: log // return false; // throw new Exception("Invalid host thing"); // } // var subscription = server.Subscription; // if (subscription != null) // { // // TODO: log // return false; // throw new Exception("No Subscription"); // } // var session = subscription.Session; // if (session != null) // { // return false; // throw new Exception("No Session"); // } // try // { // TypeDeclaration type = new TypeDeclaration(); // type.NodeId = ExpandedNodeId.ToNodeId(this.EventTypeId, session.NamespaceUris); // type.Declarations = ClientUtils.CollectInstanceDeclarationsForType(session, type.NodeId); // // the filter to use. // var filter = new FilterDeclaration(type, null); // // create a monitored item based on the current filter settings. // var monitoredItem = new MonitoredItem(); // monitoredItem.StartNodeId = Opc.Ua.ObjectIds.Server; // monitoredItem.AttributeId = Attributes.EventNotifier; // monitoredItem.SamplingInterval = 0; // monitoredItem.QueueSize = 1000; // monitoredItem.DiscardOldest = true; // monitoredItem.Filter = filter.GetFilter(); // monitoredItem.Handle = tEventHost; // We use this to detect changes in the host thing, so we can unregister properties in that old host thing // // set up callback for notifications. // monitoredItem.Notification += MonitoredItem_Notification; // //CreateSubscription(null, null); // subscription.AddItem(monitoredItem); // subscription.ApplyChanges(); // this.m_monitoredItem = monitoredItem; // } // catch (Exception e) // { // // TODO: log // return false; // } // // TODO: Pre-create the properties for the event and add the cdeM information // return true; //} protected override void InitializeMonitoredItem(TheOPCMonitoredItemBase previousTag) { RefreshNeeded = EventInfo.AggregateRetainedConditions; MyMonitoredItem.AttributeId = Attributes.EventNotifier; MyMonitoredItem.QueueSize = 1000; MyMonitoredItem.SamplingInterval = 0; MyMonitoredItem.Filter = GetFilter(); if (previousTag is TheOPCEvent previousEventTag) { if (EventInfo.IsEqual(previousEventTag.EventInfo)) { if (!previousEventTag.RefreshNeeded) { // The item has not changed: no need to consider for refresh RefreshNeeded = false; } } } }
public virtual bool MonitorTag(Subscription subscription, out string error, bool bApplySubscription = true, bool bReadInitialValue = true) { error = null; if (subscription == null || subscription.Session == null) { error = "Error: No OPC session."; return(false); } lock (subscription.MonitoredItems) { if (MyMonitoredItem != null && !subscription.MonitoredItems.Contains(MyMonitoredItem)) { // Monitored item was removed: recreate from scratch. Otherwise modify in place MyMonitoredItem = null; } if (!this.IsSubscribedAsThing && !this.IsSubscribedAsProperty) { // Nothing to be monitored error = "Error: Nothing to be monitored"; return(false); } if (TheThing.GetSafePropertyBool(MyBaseThing, "DontMonitor") || SampleRate < -1) { return(false); } // can only subscribe to local variables. //if (TagRef == null || TagRef.NodeId.IsAbsolute || TagRef.NodeClass != NodeClass.Variable) var resolvedNodeId = GetResolvedNodeIdName(); if (resolvedNodeId == null) // || NodeId.IsAbsolute || TagRef.NodeClass != NodeClass.Variable) { error = "Error: No or invalid NodeId"; return(false); } var previousMonitoredItem = subscription.MonitoredItems.FirstOrDefault(mi => mi.Handle == this || this.RefersToSamePropertyAndTag(mi.Handle)); if (previousMonitoredItem != null) { if (!previousMonitoredItem.StartNodeId.Equals(resolvedNodeId)) { TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Internal Error - monitored item {previousMonitoredItem.StartNodeId} replaced with {resolvedNodeId}. Change will not take effect!", eMsgLevel.l4_Message)); } MyMonitoredItem = previousMonitoredItem; } else { MyMonitoredItem = new MonitoredItem(subscription.DefaultItem); } //MyMonitoredItem.StartNodeId = (NodeId)TagRef.NodeId; MyMonitoredItem.StartNodeId = resolvedNodeId; MyMonitoredItem.AttributeId = Attributes.Value; MyMonitoredItem.DisplayName = DisplayName; // Utils.Format("{0}", TagRef); MyMonitoredItem.MonitoringMode = MonitoringMode.Reporting; if ((!this.HistoryStartTime.HasValue || this.HistoryStartTime.Value == DateTimeOffset.MinValue) && MyOPCServer.DefHistoryStartTime != DateTimeOffset.MinValue) { this.HistoryStartTime = MyOPCServer.DefHistoryStartTime; } if (this.HistoryStartTime.HasValue && this.HistoryStartTime.Value != DateTimeOffset.MinValue) { MyMonitoredItem.Filter = new AggregateFilter() { StartTime = this.HistoryStartTime.Value.UtcDateTime, ProcessingInterval = this.SampleRate, AggregateType = ObjectIds.AggregateFunction_Interpolative, }; MyMonitoredItem.QueueSize = uint.MaxValue; MyMonitoredItem.SamplingInterval = 0; } else { DataChangeFilter filter = null; // TODO Remove this special case: pass parameters for deadband filters and StatusValueTimestamp (this breaks P08!!!) if (this.DeadbandFilterValue != 0) { filter = new DataChangeFilter { DeadbandType = (uint)(this.DeadbandFilterValue > 0 ? DeadbandType.Absolute : DeadbandType.Percent), DeadbandValue = Math.Abs(this.DeadbandFilterValue) }; } if (ChangeTrigger != 1) { if (filter == null) { filter = new DataChangeFilter(); } filter.Trigger = (DataChangeTrigger)ChangeTrigger; } if (filter != null) { MyMonitoredItem.Filter = filter; } MyMonitoredItem.SamplingInterval = SampleRate; // For Events, the sample rate should be 0 (per spec), but is really ignored and thus should not affect the aggregate sample rate for the server // All other sample rates are at least 50ms per other checks if (SampleRate <= subscription.PublishingInterval * 2 && SampleRate > 0) { // 3.220: PublishingInterval is now independent of the sample rate: it only affects the frequency of the traffic from the server, not the content //MyOPCServer.Subscription.PublishingInterval = SampleRate; // Request the QueueSize to be 50 times the expected data points, so that no data is lost in normal operation MyMonitoredItem.QueueSize = (uint)Math.Ceiling((((double)subscription.PublishingInterval) / SampleRate) * 50); if (MyMonitoredItem.QueueSize < 50) { MyMonitoredItem.QueueSize = 50; } } else { MyMonitoredItem.QueueSize = 50; // Request at least 50 } } MyMonitoredItem.DiscardOldest = true; MyMonitoredItem.Notification -= MonitoredItem_Notification; MyMonitoredItem.Notification += MonitoredItem_Notification; TheOPCMonitoredItemBase previousTag = null; if (previousMonitoredItem != null && previousMonitoredItem.Handle != this) { previousTag = previousMonitoredItem.Handle as TheOPCMonitoredItemBase; if (previousTag != null) { previousTag.ReleaseMonitoredItem(); } } MyMonitoredItem.Handle = this; InitializeMonitoredItem(previousTag); if (previousMonitoredItem == null) { subscription.AddItem(MyMonitoredItem); } } if (bApplySubscription) { #if OLD_UA var items = subscription.ApplyChanges(); if (!items.Contains(MyMonitoredItem)) #else subscription.ApplyChanges(); if (!subscription.MonitoredItems.Contains(MyMonitoredItem)) #endif { TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Internal Error: Monitored item not found after applying changes {GetNodeIdForLogs()}. Actual values: Sampling {MyMonitoredItem.Status.SamplingInterval}, Queue {MyMonitoredItem.Status.QueueSize}", eMsgLevel.l1_Error)); error = "Error: Monitored item not found after applying changes"; return(false); } else { TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Added monitored item {GetNodeIdForLogs()}. Actual values: Sampling {MyMonitoredItem.Status.SamplingInterval}, Queue {MyMonitoredItem.Status.QueueSize}", eMsgLevel.l4_Message)); } } if (ServiceResult.IsBad(MyMonitoredItem.Status.Error)) { TheThing.SetSafePropertyString(MyBaseThing, "LastMessage", MyMonitoredItem.Status.Error.StatusCode.ToString()); TheBaseAssets.MySYSLOG.WriteToLog(78201, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("OPC", $"[{MyOPCServer.GetLogAddress()}] Error adding monitored item {GetNodeIdForLogs()}", eMsgLevel.l4_Message, MyMonitoredItem.Status.Error.ToString())); error = "Error: " + MyMonitoredItem.Status.Error.ToString(); return(false); } else { MyOPCServer.RegisterEvent("DisconnectComplete", sinkDisconnected); } TheThing.SetSafePropertyBool(MyBaseThing, "IsActive", true); return(true); }
protected virtual void InitializeMonitoredItem(TheOPCMonitoredItemBase previousTag) { }