/// <summary> /// Deletes a monitored item. /// </summary> protected override ServiceResult DeleteMonitoredItem( ISystemContext context, IMonitoredItem monitoredItem, out bool processed) { processed = false; // check for valid handle. if (!(monitoredItem.ManagerHandle is MemoryBufferState buffer)) { return(base.DeleteMonitoredItem( context, monitoredItem, out processed)); } // owned by this node manager. processed = true; // get the monitored item. if (!(monitoredItem is MemoryBufferMonitoredItem datachangeItem)) { return(StatusCodes.BadMonitoredItemIdInvalid); } // delete the item. buffer.DeleteItem(datachangeItem); return(ServiceResult.Good); }
/// <summary> /// Changes the monitoring mode for an item. /// </summary> protected override ServiceResult SetMonitoringMode( ISystemContext context, IMonitoredItem monitoredItem, MonitoringMode monitoringMode, out bool processed) { processed = false; // check for valid handle. MemoryBufferState buffer = monitoredItem.ManagerHandle as MemoryBufferState; if (buffer == null) { return(base.SetMonitoringMode( context, monitoredItem, monitoringMode, out processed)); } // owned by this node manager. processed = true; // get the monitored item. MemoryBufferMonitoredItem datachangeItem = monitoredItem as MemoryBufferMonitoredItem; if (datachangeItem == null) { return(StatusCodes.BadMonitoredItemIdInvalid); } // delete the item. MonitoringMode previousMode = datachangeItem.SetMonitoringMode(monitoringMode); // need to provide an immediate update after enabling. if (previousMode == MonitoringMode.Disabled && monitoringMode != MonitoringMode.Disabled) { DataValue initialValue = new DataValue(); initialValue.Value = null; initialValue.ServerTimestamp = DateTime.UtcNow; initialValue.SourceTimestamp = DateTime.MinValue; initialValue.StatusCode = StatusCodes.Good; MemoryTagState tag = new MemoryTagState(buffer, datachangeItem.Offset); ServiceResult error = tag.ReadAttribute( context, datachangeItem.AttributeId, NumericRange.Empty, null, initialValue); datachangeItem.QueueValue(initialValue, error); } return(ServiceResult.Good); }
/// <summary> /// Modifies the parameters for a monitored item. /// </summary> protected override ServiceResult ModifyMonitoredItem( ISystemContext context, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, IMonitoredItem monitoredItem, MonitoredItemModifyRequest itemToModify, out MonitoringFilterResult filterError) { filterError = null; // check for valid handle. MemoryBufferState buffer = monitoredItem.ManagerHandle as MemoryBufferState; if (buffer == null) { return(base.ModifyMonitoredItem( context, diagnosticsMasks, timestampsToReturn, monitoredItem, itemToModify, out filterError)); } // owned by this node manager. itemToModify.Processed = true; // get the monitored item. MemoryBufferMonitoredItem datachangeItem = monitoredItem as MemoryBufferMonitoredItem; if (datachangeItem == null) { return(StatusCodes.BadMonitoredItemIdInvalid); } // validate parameters. MonitoringParameters parameters = itemToModify.RequestedParameters; // no filters supported at this time. MonitoringFilter filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter); if (filter != null) { return(StatusCodes.BadFilterNotAllowed); } // modify the monitored item parameters. ServiceResult error = datachangeItem.Modify( diagnosticsMasks, timestampsToReturn, itemToModify.RequestedParameters.ClientHandle, itemToModify.RequestedParameters.SamplingInterval); return(ServiceResult.Good); }
/// <summary> /// Deletes the monitored item. /// </summary> public void DeleteItem(IMonitoredItem monitoredItem) { if (_monitoredItems != null) { for (var ii = 0; ii < _monitoredItems.Count; ii++) { if (ReferenceEquals(monitoredItem, _monitoredItems[ii])) { _monitoredItems.RemoveAt(ii); break; } } } }
/// <summary> /// Deletes the monitored item. /// </summary> public void DeleteItem(IMonitoredItem monitoredItem) { if (m_monitoredItems != null) { for (int ii = 0; ii < m_monitoredItems.Count; ii++) { if (Object.ReferenceEquals(monitoredItem, m_monitoredItems[ii])) { m_monitoredItems.RemoveAt(ii); break; } } } }
/// <summary> /// Initializes the context with a monitored item. /// </summary> /// <param name="monitoredItem">The monitored item.</param> public OperationContext(IMonitoredItem monitoredItem) { if (monitoredItem == null) { throw new ArgumentNullException("monitoredItem"); } m_channelContext = null; m_session = monitoredItem.Session; if (m_session != null) { m_identity = m_session.Identity; m_preferredLocales = m_session.PreferredLocales; } m_diagnosticsMask = DiagnosticsMasks.SymbolicId; m_stringTable = new StringTable(); m_auditLogEntryId = null; m_requestId = 0; m_requestType = RequestType.Unknown; m_clientHandle = 0; m_operationDeadline = DateTime.MaxValue; }
/// <summary> /// Modifies the parameters for a monitored item. /// </summary> protected virtual ServiceResult ModifyMonitoredItem( ISystemContext context, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, IMonitoredItem monitoredItem, MonitoredItemModifyRequest itemToModify, out MonitoringFilterResult filterError) { filterError = null; ServiceResult error = null; // check for valid handle. MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode; if (monitoredNode == null) { return ServiceResult.Good; } if (IsHandleInNamespace(monitoredNode.Node) == null) { return ServiceResult.Good; } // owned by this node manager. itemToModify.Processed = true; // check for valid monitored item. DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem; // validate parameters. MonitoringParameters parameters = itemToModify.RequestedParameters; // validate the data change filter. DataChangeFilter filter = null; Range range = null; if (!ExtensionObject.IsNull(parameters.Filter)) { error = ValidateDataChangeFilter( context, monitoredNode.Node, datachangeItem.AttributeId, parameters.Filter, out filter, out range); if (ServiceResult.IsBad(error)) { return error; } } double previousSamplingInterval = datachangeItem.SamplingInterval; // check if the variable needs to be sampled. double samplingInterval = itemToModify.RequestedParameters.SamplingInterval; if (datachangeItem.AttributeId == Attributes.Value) { BaseVariableState variable = monitoredNode.Node as BaseVariableState; if (variable.MinimumSamplingInterval > 0) { samplingInterval = CalculateSamplingInterval(variable, samplingInterval); } } // modify the monitored item parameters. error = datachangeItem.Modify( diagnosticsMasks, timestampsToReturn, itemToModify.RequestedParameters.ClientHandle, samplingInterval, itemToModify.RequestedParameters.QueueSize, itemToModify.RequestedParameters.DiscardOldest, filter, range); // do any post processing. OnModifyMonitoredItem( context, itemToModify, monitoredNode, datachangeItem, previousSamplingInterval); return ServiceResult.Good; }
/// <summary> /// Deletes a monitored item. /// </summary> protected virtual ServiceResult DeleteMonitoredItem( ISystemContext context, IMonitoredItem monitoredItem, out bool processed) { processed = false; // check for valid handle. MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode; if (monitoredNode == null) { return ServiceResult.Good; } if (IsHandleInNamespace(monitoredNode.Node) == null) { return ServiceResult.Good; } // owned by this node manager. processed = true; // get the source. NodeState source = monitoredNode.Node; // check for valid monitored item. DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem; // check if the variable needs to be sampled. if (datachangeItem.AttributeId == Attributes.Value) { BaseVariableState variable = monitoredNode.Node as BaseVariableState; if (variable.MinimumSamplingInterval > 0) { DeleteSampledItem(datachangeItem); } } // remove item. monitoredNode.DeleteItem(datachangeItem); // do any post processing. OnDeleteMonitoredItem(context, monitoredNode, datachangeItem); return ServiceResult.Good; }
/// <summary> /// Creates a new set of monitored items for a set of variables. /// </summary> /// <remarks> /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. /// </remarks> protected override ServiceResult CreateMonitoredItem( ISystemContext context, NodeState source, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterError, out IMonitoredItem monitoredItem) { filterError = null; monitoredItem = null; MemoryTagState tag = source as MemoryTagState; // use default behavoir for non-tag sources. if (tag == null) { return base.CreateMonitoredItem( context, source, subscriptionId, publishingInterval, diagnosticsMasks, timestampsToReturn, itemToCreate, ref globalIdCounter, out filterError, out monitoredItem); } // validate parameters. MonitoringParameters parameters = itemToCreate.RequestedParameters; // no filters supported at this time. MonitoringFilter filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter); if (filter != null) { return StatusCodes.BadFilterNotAllowed; } // index range not supported. if (itemToCreate.ItemToMonitor.ParsedIndexRange != NumericRange.Empty) { return StatusCodes.BadIndexRangeInvalid; } // data encoding not supported. if (!QualifiedName.IsNull(itemToCreate.ItemToMonitor.DataEncoding)) { return StatusCodes.BadDataEncodingInvalid; } // read initial value. DataValue initialValue = new DataValue(); initialValue.Value = null; initialValue.ServerTimestamp = DateTime.UtcNow; initialValue.SourceTimestamp = DateTime.MinValue; initialValue.StatusCode = StatusCodes.Good; ServiceResult error = source.ReadAttribute( context, itemToCreate.ItemToMonitor.AttributeId, itemToCreate.ItemToMonitor.ParsedIndexRange, itemToCreate.ItemToMonitor.DataEncoding, initialValue); if (ServiceResult.IsBad(error)) { return error; } // get the monitored node for the containing buffer. MemoryBufferState buffer = tag.Parent as MemoryBufferState; if (buffer == null) { return StatusCodes.BadInternalError; } // create a globally unique identifier. uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter); // determine the sampling interval. double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval; if (samplingInterval < 0) { samplingInterval = publishingInterval; } // create the item. MemoryBufferMonitoredItem datachangeItem = buffer.CreateDataChangeItem( context as ServerSystemContext, tag, subscriptionId, monitoredItemId, itemToCreate.ItemToMonitor, diagnosticsMasks, timestampsToReturn, itemToCreate.MonitoringMode, itemToCreate.RequestedParameters.ClientHandle, samplingInterval); /* // create the item. MemoryBufferMonitoredItem datachangeItem = buffer.CreateDataChangeItem( context, tag, monitoredItemId, itemToCreate.ItemToMonitor.AttributeId, diagnosticsMasks, timestampsToReturn, itemToCreate.MonitoringMode, itemToCreate.RequestedParameters.ClientHandle, samplingInterval); */ // report the initial value. datachangeItem.QueueValue(initialValue, null); // update monitored item list. monitoredItem = datachangeItem; return ServiceResult.Good; }
/// <summary> /// Creates a new set of monitored items for a set of variables. /// </summary> /// <remarks> /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. /// </remarks> protected virtual ServiceResult CreateMonitoredItem( ISystemContext context, NodeState source, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterError, out IMonitoredItem monitoredItem) { filterError = null; monitoredItem = null; ServiceResult error = null; // read initial value. DataValue initialValue = new DataValue(); initialValue.Value = null; initialValue.ServerTimestamp = DateTime.UtcNow; initialValue.SourceTimestamp = DateTime.MinValue; initialValue.StatusCode = StatusCodes.Good; error = source.ReadAttribute( context, itemToCreate.ItemToMonitor.AttributeId, itemToCreate.ItemToMonitor.ParsedIndexRange, itemToCreate.ItemToMonitor.DataEncoding, initialValue); if (ServiceResult.IsBad(error)) { return error; } // validate parameters. MonitoringParameters parameters = itemToCreate.RequestedParameters; // validate the data change filter. DataChangeFilter filter = null; Range range = null; if (!ExtensionObject.IsNull(parameters.Filter)) { error = ValidateDataChangeFilter( context, source, itemToCreate.ItemToMonitor.AttributeId, parameters.Filter, out filter, out range); if (ServiceResult.IsBad(error)) { return error; } } // create monitored node. MonitoredNode monitoredNode = source.Handle as MonitoredNode; if (monitoredNode == null) { source.Handle = monitoredNode = new MonitoredNode(m_server, this, source); } // create a globally unique identifier. uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter); // determine the sampling interval. double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval; if (samplingInterval < 0) { samplingInterval = publishingInterval; } // check if the variable needs to be sampled. bool samplingRequired = false; if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value) { BaseVariableState variable = source as BaseVariableState; if (variable.MinimumSamplingInterval > 0) { samplingInterval = CalculateSamplingInterval(variable, samplingInterval); samplingRequired = true; } } // create the item. DataChangeMonitoredItem datachangeItem = monitoredNode.CreateDataChangeItem( context, monitoredItemId, itemToCreate.ItemToMonitor.AttributeId, itemToCreate.ItemToMonitor.ParsedIndexRange, itemToCreate.ItemToMonitor.DataEncoding, diagnosticsMasks, timestampsToReturn, itemToCreate.MonitoringMode, itemToCreate.RequestedParameters.ClientHandle, samplingInterval, itemToCreate.RequestedParameters.QueueSize, itemToCreate.RequestedParameters.DiscardOldest, filter, range, false); if (samplingRequired) { CreateSampledItem(samplingInterval, datachangeItem); } // report the initial value. datachangeItem.QueueValue(initialValue, null); // do any post processing. OnCreateMonitoredItem(context, itemToCreate, monitoredNode, datachangeItem); // update monitored item list. monitoredItem = datachangeItem; return ServiceResult.Good; }
/// <summary> /// Deletes the monitored item. /// </summary> public void DeleteItem(IMonitoredItem monitoredItem) { if (m_monitoredItems != null) { for (int ii = 0; ii < m_monitoredItems.Count; ii++) { if (Object.ReferenceEquals(monitoredItem, m_monitoredItems[ii])) { m_monitoredItems.RemoveAt(ii); break; } } } }
/// <summary> /// Creates a new set of monitored items for a set of variables. /// </summary> /// <remarks> /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. /// </remarks> protected override ServiceResult CreateMonitoredItem( ISystemContext context, NodeState source, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterError, out IMonitoredItem monitoredItem) { filterError = null; monitoredItem = null; // use default behavoir for non-tag sources. if (!(source is MemoryTagState tag)) { return(base.CreateMonitoredItem( context, source, subscriptionId, publishingInterval, diagnosticsMasks, timestampsToReturn, itemToCreate, ref globalIdCounter, out filterError, out monitoredItem)); } // validate parameters. var parameters = itemToCreate.RequestedParameters; // no filters supported at this time. var filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter); if (filter != null) { return(StatusCodes.BadFilterNotAllowed); } // index range not supported. if (itemToCreate.ItemToMonitor.ParsedIndexRange != NumericRange.Empty) { return(StatusCodes.BadIndexRangeInvalid); } // data encoding not supported. if (!QualifiedName.IsNull(itemToCreate.ItemToMonitor.DataEncoding)) { return(StatusCodes.BadDataEncodingInvalid); } // read initial value. var initialValue = new DataValue { Value = null, ServerTimestamp = DateTime.UtcNow, SourceTimestamp = DateTime.MinValue, StatusCode = StatusCodes.Good }; var error = source.ReadAttribute( context, itemToCreate.ItemToMonitor.AttributeId, itemToCreate.ItemToMonitor.ParsedIndexRange, itemToCreate.ItemToMonitor.DataEncoding, initialValue); if (ServiceResult.IsBad(error)) { return(error); } // get the monitored node for the containing buffer. if (!(tag.Parent is MemoryBufferState buffer)) { return(StatusCodes.BadInternalError); } // create a globally unique identifier. var monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter); // determine the sampling interval. var samplingInterval = itemToCreate.RequestedParameters.SamplingInterval; if (samplingInterval < 0) { samplingInterval = publishingInterval; } // create the item. var datachangeItem = buffer.CreateDataChangeItem( context as ServerSystemContext, tag, monitoredItemId, itemToCreate.ItemToMonitor, diagnosticsMasks, timestampsToReturn, itemToCreate.MonitoringMode, itemToCreate.RequestedParameters.ClientHandle, samplingInterval); /* * // create the item. * MemoryBufferMonitoredItem datachangeItem = buffer.CreateDataChangeItem( * context, * tag, * monitoredItemId, * itemToCreate.ItemToMonitor.AttributeId, * diagnosticsMasks, * timestampsToReturn, * itemToCreate.MonitoringMode, * itemToCreate.RequestedParameters.ClientHandle, * samplingInterval); */ // report the initial value. datachangeItem.QueueValue(initialValue, null); // update monitored item list. monitoredItem = datachangeItem; return(ServiceResult.Good); }
/// <summary> /// Modifies the parameters for a monitored item. /// </summary> protected override ServiceResult ModifyMonitoredItem( ISystemContext context, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, IMonitoredItem monitoredItem, MonitoredItemModifyRequest itemToModify, out MonitoringFilterResult filterError) { filterError = null; // check for valid handle. MemoryBufferState buffer = monitoredItem.ManagerHandle as MemoryBufferState; if (buffer == null) { return base.ModifyMonitoredItem( context, diagnosticsMasks, timestampsToReturn, monitoredItem, itemToModify, out filterError); } // owned by this node manager. itemToModify.Processed = true; // get the monitored item. MemoryBufferMonitoredItem datachangeItem = monitoredItem as MemoryBufferMonitoredItem; if (datachangeItem == null) { return StatusCodes.BadMonitoredItemIdInvalid; } // validate parameters. MonitoringParameters parameters = itemToModify.RequestedParameters; // no filters supported at this time. MonitoringFilter filter = (MonitoringFilter)ExtensionObject.ToEncodeable(parameters.Filter); if (filter != null) { return StatusCodes.BadFilterNotAllowed; } // modify the monitored item parameters. ServiceResult error = datachangeItem.Modify( diagnosticsMasks, timestampsToReturn, itemToModify.RequestedParameters.ClientHandle, itemToModify.RequestedParameters.SamplingInterval); return ServiceResult.Good; }
/// <summary> /// Changes the monitoring mode for an item. /// </summary> protected virtual ServiceResult SetMonitoringMode( ServerSystemContext context, IMonitoredItem monitoredItem, MonitoringMode monitoringMode, NodeHandle handle) { // check for valid monitored item. MonitoredItem datachangeItem = monitoredItem as MonitoredItem; // update monitoring mode. MonitoringMode previousMode = datachangeItem.SetMonitoringMode(monitoringMode); // must send the latest value after enabling a disabled item. if (monitoringMode == MonitoringMode.Reporting && previousMode == MonitoringMode.Disabled) { handle.MonitoredNode.QueueValue(context, handle.Node, datachangeItem); } // report change. if (previousMode != monitoringMode) { OnMonitoringModeChanged( context, handle, datachangeItem, previousMode, monitoringMode); } return ServiceResult.Good; }
/// <summary> /// Adds a subscription to the source. /// </summary> public virtual void Subscribe(IMonitoredItem monitoredItem) { lock (DataLock) { if (m_monitoredItems == null) { m_monitoredItems = new Dictionary<uint,IMonitoredItem>(); } m_monitoredItems[monitoredItem.Id] = monitoredItem; } }
/// <summary> /// Queues an item that is ready to publish. /// </summary> public void ItemReadyToPublish(IMonitoredItem monitoredItem) { /* lock (m_itemsReadyToPublish) { m_itemsReadyToPublish.Enqueue(monitoredItem); } */ }
/// <summary> /// Changes the monitoring mode for an item. /// </summary> protected virtual ServiceResult SetMonitoringMode( ISystemContext context, IMonitoredItem monitoredItem, MonitoringMode monitoringMode, out bool processed) { processed = false; // check for valid handle. MonitoredNode monitoredNode = monitoredItem.ManagerHandle as MonitoredNode; if (monitoredNode == null) { return ServiceResult.Good; } if (IsHandleInNamespace(monitoredNode.Node) == null) { return ServiceResult.Good; } // owned by this node manager. processed = true; // check for valid monitored item. DataChangeMonitoredItem datachangeItem = monitoredItem as DataChangeMonitoredItem; // update monitoring mode. MonitoringMode previousMode = datachangeItem.SetMonitoringMode(monitoringMode); // need to provide an immediate update after enabling. if (previousMode == MonitoringMode.Disabled && monitoringMode != MonitoringMode.Disabled) { DataValue initialValue = new DataValue(); initialValue.Value = null; initialValue.ServerTimestamp = DateTime.UtcNow; initialValue.SourceTimestamp = DateTime.MinValue; initialValue.StatusCode = StatusCodes.Good; ServiceResult error = monitoredNode.Node.ReadAttribute( context, datachangeItem.AttributeId, datachangeItem.IndexRange, datachangeItem.DataEncoding, initialValue); datachangeItem.QueueValue(initialValue, error); } // do any post processing. OnSetMonitoringMode(context, monitoredNode, datachangeItem, previousMode, monitoringMode); return ServiceResult.Good; }
/// <summary> /// Creates a new set of monitored items for a set of variables. /// </summary> /// <remarks> /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. /// </remarks> protected override ServiceResult CreateMonitoredItem(ServerSystemContext context, NodeHandle handle, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterResult, out IMonitoredItem monitoredItem) { filterResult = null; monitoredItem = null; // validate parameters. MonitoringParameters parameters = itemToCreate.RequestedParameters; // validate attribute. if (!Attributes.IsValid(handle.Node.NodeClass, itemToCreate.ItemToMonitor.AttributeId)) { return(StatusCodes.BadAttributeIdInvalid); } NodeState cachedNode = AddNodeToComponentCache(context, handle, handle.Node); // check if the node is already being monitored. MonitoredNode2 monitoredNode = null; if (!MonitoredNodes.TryGetValue(handle.Node.NodeId, out monitoredNode)) { MonitoredNodes[handle.Node.NodeId] = monitoredNode = new MonitoredNode2(this, cachedNode); } handle.Node = monitoredNode.Node; handle.MonitoredNode = monitoredNode; // create a globally unique identifier. uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter); // determine the sampling interval. double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval; if (samplingInterval < 0) { samplingInterval = publishingInterval; } // ensure minimum sampling interval is not exceeded. if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value) { BaseVariableState variable = handle.Node as BaseVariableState; if (variable != null && samplingInterval < variable.MinimumSamplingInterval) { samplingInterval = variable.MinimumSamplingInterval; } } // put a large upper limit on sampling. if (samplingInterval == Double.MaxValue) { samplingInterval = 365 * 24 * 3600 * 1000.0; } // put an upper limit on queue size. uint queueSize = itemToCreate.RequestedParameters.QueueSize; if (queueSize > MaxQueueSize) { queueSize = MaxQueueSize; } // validate the monitoring filter. Range euRange = null; MonitoringFilter filterToUse = null; ServiceResult error = ValidateMonitoringFilter( context, handle, itemToCreate.ItemToMonitor.AttributeId, samplingInterval, queueSize, parameters.Filter, out filterToUse, out euRange, out filterResult); if (ServiceResult.IsBad(error)) { return(error); } // create the item. MonitoredItem datachangeItem = new ComMonitoredItem( Server, this, handle, subscriptionId, monitoredItemId, context.OperationContext.Session, itemToCreate.ItemToMonitor, diagnosticsMasks, timestampsToReturn, itemToCreate.MonitoringMode, itemToCreate.RequestedParameters.ClientHandle, filterToUse, filterToUse, euRange, samplingInterval, queueSize, itemToCreate.RequestedParameters.DiscardOldest, 0); // report the initial value. ReadInitialValue(context, handle, datachangeItem); // update monitored item list. monitoredItem = datachangeItem; // save the monitored item. MonitoredItems.Add(monitoredItemId, datachangeItem); monitoredNode.Add(datachangeItem); // report change. OnMonitoredItemCreated(context, handle, datachangeItem); return(error); }
/// <summary> /// Deletes a monitored item. /// </summary> protected override ServiceResult DeleteMonitoredItem( ISystemContext context, IMonitoredItem monitoredItem, out bool processed) { processed = false; // check for valid handle. MemoryBufferState buffer = monitoredItem.ManagerHandle as MemoryBufferState; if (buffer == null) { return base.DeleteMonitoredItem( context, monitoredItem, out processed); } // owned by this node manager. processed = true; // get the monitored item. MemoryBufferMonitoredItem datachangeItem = monitoredItem as MemoryBufferMonitoredItem; if (datachangeItem == null) { return StatusCodes.BadMonitoredItemIdInvalid; } // delete the item. buffer.DeleteItem(datachangeItem); return ServiceResult.Good; }
/// <summary> /// Changes the monitoring mode for an item. /// </summary> protected override ServiceResult SetMonitoringMode( ISystemContext context, IMonitoredItem monitoredItem, MonitoringMode monitoringMode, out bool processed) { processed = false; // check for valid handle. MemoryBufferState buffer = monitoredItem.ManagerHandle as MemoryBufferState; if (buffer == null) { return base.SetMonitoringMode( context, monitoredItem, monitoringMode, out processed); } // owned by this node manager. processed = true; // get the monitored item. MemoryBufferMonitoredItem datachangeItem = monitoredItem as MemoryBufferMonitoredItem; if (datachangeItem == null) { return StatusCodes.BadMonitoredItemIdInvalid; } // delete the item. MonitoringMode previousMode = datachangeItem.SetMonitoringMode(monitoringMode); // need to provide an immediate update after enabling. if (previousMode == MonitoringMode.Disabled && monitoringMode != MonitoringMode.Disabled) { DataValue initialValue = new DataValue(); initialValue.Value = null; initialValue.ServerTimestamp = DateTime.UtcNow; initialValue.SourceTimestamp = DateTime.MinValue; initialValue.StatusCode = StatusCodes.Good; MemoryTagState tag = new MemoryTagState(buffer, datachangeItem.Offset); ServiceResult error = tag.ReadAttribute( context, datachangeItem.AttributeId, NumericRange.Empty, null, initialValue); datachangeItem.QueueValue(initialValue, error); } return ServiceResult.Good; }
/// <summary> /// Creates a new set of monitored items for a set of variables. /// </summary> /// <remarks> /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. /// </remarks> public override void CreateMonitoredItems( OperationContext context, uint subscriptionId, double publishingInterval, TimestampsToReturn timestampsToReturn, IList <MonitoredItemCreateRequest> itemsToCreate, IList <ServiceResult> errors, IList <MonitoringFilterResult> filterResults, IList <IMonitoredItem> monitoredItems, ref long globalIdCounter) { ServerSystemContext systemContext = _defaultSystemContext.Copy(context); IDictionary <NodeId, NodeState> operationCache = new NodeIdDictionary <NodeState>(); List <NodeHandle> nodesToValidate = new List <NodeHandle>(); List <IMonitoredItem> createdItems = new List <IMonitoredItem>(); lock (Lock) { for (int ii = 0; ii < itemsToCreate.Count; ii++) { MonitoredItemCreateRequest monitoredItemCreateRequest = itemsToCreate[ii]; // skip items that have already been processed. if (monitoredItemCreateRequest.Processed) { continue; } ReadValueId itemToMonitor = monitoredItemCreateRequest.ItemToMonitor; // check for valid handle. NodeHandle handle = GetManagerHandle(systemContext, itemToMonitor.NodeId, operationCache); if (handle == null) { continue; } // owned by this node manager. monitoredItemCreateRequest.Processed = true; // must validate node in a seperate operation. errors[ii] = StatusCodes.BadNodeIdUnknown; handle.Index = ii; nodesToValidate.Add(handle); } // check for nothing to do. if (nodesToValidate.Count == 0) { return; } } // validates the nodes (reads values from the underlying data source if required). for (int ii = 0; ii < nodesToValidate.Count; ii++) { NodeHandle handle = nodesToValidate[ii]; MonitoringFilterResult filterResult = null; IMonitoredItem monitoredItem = null; lock (Lock) { // validate node. NodeState source = ValidateNode(systemContext, handle, operationCache); if (source == null) { continue; } MonitoredItemCreateRequest itemToCreate = itemsToCreate[handle.Index]; // create monitored item. errors[handle.Index] = CreateMonitoredItem( systemContext, handle, subscriptionId, publishingInterval, context.DiagnosticsMask, timestampsToReturn, itemToCreate, ref globalIdCounter, out filterResult, out monitoredItem); } // save any filter error details. filterResults[handle.Index] = filterResult; if (ServiceResult.IsBad(errors[handle.Index])) { continue; } // save the monitored item. monitoredItems[handle.Index] = monitoredItem; createdItems.Add(monitoredItem); } // do any post processing. OnCreateMonitoredItemsComplete(systemContext, createdItems); }
/// <summary> /// Creates a new set of monitored items for a set of variables. /// </summary> /// <remarks> /// This method only handles data change subscriptions. Event subscriptions are created by the SDK. /// </remarks> protected virtual ServiceResult CreateMonitoredItem( ServerSystemContext context, NodeHandle handle, uint subscriptionId, double publishingInterval, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, MonitoredItemCreateRequest itemToCreate, ref long globalIdCounter, out MonitoringFilterResult filterResult, out IMonitoredItem monitoredItem) { filterResult = null; monitoredItem = null; // validate parameters. MonitoringParameters parameters = itemToCreate.RequestedParameters; // validate attribute. if (!Attributes.IsValid(handle.Node.NodeClass, itemToCreate.ItemToMonitor.AttributeId)) { return StatusCodes.BadAttributeIdInvalid; } // check if the node is already being monitored. MonitoredNode monitoredNode = null; if (!m_monitoredNodes.TryGetValue(handle.Node.NodeId, out monitoredNode)) { NodeState cachedNode = AddNodeToComponentCache(context, handle, handle.Node); m_monitoredNodes[handle.Node.NodeId] = monitoredNode = new MonitoredNode(this, cachedNode); } handle.Node = monitoredNode.Node; handle.MonitoredNode = monitoredNode; // create a globally unique identifier. uint monitoredItemId = Utils.IncrementIdentifier(ref globalIdCounter); // determine the sampling interval. double samplingInterval = itemToCreate.RequestedParameters.SamplingInterval; if (samplingInterval < 0) { samplingInterval = publishingInterval; } // ensure minimum sampling interval is not exceeded. if (itemToCreate.ItemToMonitor.AttributeId == Attributes.Value) { BaseVariableState variable = handle.Node as BaseVariableState; if (variable != null && samplingInterval < variable.MinimumSamplingInterval) { samplingInterval = variable.MinimumSamplingInterval; } } // put a large upper limit on sampling. if (samplingInterval == Double.MaxValue) { samplingInterval = 365 * 24 * 3600 * 1000.0; } // put an upper limit on queue size. uint queueSize = itemToCreate.RequestedParameters.QueueSize; if (queueSize > m_maxQueueSize) { queueSize = m_maxQueueSize; } // validate the monitoring filter. Range euRange = null; MonitoringFilter filterToUse = null; ServiceResult error = ValidateMonitoringFilter( context, handle, itemToCreate.ItemToMonitor.AttributeId, samplingInterval, queueSize, parameters.Filter, out filterToUse, out euRange, out filterResult); if (ServiceResult.IsBad(error)) { return error; } // create the item. MonitoredItem datachangeItem = new MonitoredItem( Server, this, handle, subscriptionId, monitoredItemId, context.OperationContext.Session, itemToCreate.ItemToMonitor, diagnosticsMasks, timestampsToReturn, itemToCreate.MonitoringMode, itemToCreate.RequestedParameters.ClientHandle, filterToUse, filterToUse, euRange, samplingInterval, queueSize, itemToCreate.RequestedParameters.DiscardOldest, 0); // report the initial value. ReadInitialValue(context, handle, datachangeItem); // update monitored item list. monitoredItem = datachangeItem; // save the monitored item. m_monitoredItems.Add(monitoredItemId, datachangeItem); monitoredNode.Add(datachangeItem); // report change. OnMonitoredItemCreated(context, handle, datachangeItem); return error; }
/// <summary> /// Modifies the parameters for a monitored item. /// </summary> protected virtual ServiceResult ModifyMonitoredItem( ServerSystemContext context, DiagnosticsMasks diagnosticsMasks, TimestampsToReturn timestampsToReturn, IMonitoredItem monitoredItem, MonitoredItemModifyRequest itemToModify, NodeHandle handle, out MonitoringFilterResult filterResult) { filterResult = null; // check for valid monitored item. MonitoredItem datachangeItem = monitoredItem as MonitoredItem; // validate parameters. MonitoringParameters parameters = itemToModify.RequestedParameters; double previousSamplingInterval = datachangeItem.SamplingInterval; // check if the variable needs to be sampled. double samplingInterval = itemToModify.RequestedParameters.SamplingInterval; if (samplingInterval < 0) { samplingInterval = previousSamplingInterval; } // ensure minimum sampling interval is not exceeded. if (datachangeItem.AttributeId == Attributes.Value) { BaseVariableState variable = handle.Node as BaseVariableState; if (variable != null && samplingInterval < variable.MinimumSamplingInterval) { samplingInterval = variable.MinimumSamplingInterval; } } // put a large upper limit on sampling. if (samplingInterval == Double.MaxValue) { samplingInterval = 365 * 24 * 3600 * 1000.0; } // put an upper limit on queue size. uint queueSize = itemToModify.RequestedParameters.QueueSize; if (queueSize > m_maxQueueSize) { queueSize = m_maxQueueSize; } // validate the monitoring filter. Range euRange = null; MonitoringFilter filterToUse = null; ServiceResult error = ValidateMonitoringFilter( context, handle, datachangeItem.AttributeId, samplingInterval, queueSize, parameters.Filter, out filterToUse, out euRange, out filterResult); if (ServiceResult.IsBad(error)) { return error; } // modify the monitored item parameters. error = datachangeItem.ModifyAttributes( diagnosticsMasks, timestampsToReturn, itemToModify.RequestedParameters.ClientHandle, filterToUse, filterToUse, euRange, samplingInterval, queueSize, itemToModify.RequestedParameters.DiscardOldest); // report change. if (ServiceResult.IsGood(error)) { OnMonitoredItemModified(context, handle, datachangeItem); } return error; }
/// <summary> /// Removes a subscription from the source. /// </summary> public virtual void Unsubscribe(IMonitoredItem monitoredItem) { lock (DataLock) { if (m_monitoredItems != null) { m_monitoredItems.Remove(monitoredItem.Id); } } }
/// <summary> /// Deletes a monitored item. /// </summary> protected virtual ServiceResult DeleteMonitoredItem( ServerSystemContext context, IMonitoredItem monitoredItem, NodeHandle handle) { // check for valid monitored item. MonitoredItem datachangeItem = monitoredItem as MonitoredItem; // check if the node is already being monitored. MonitoredNode monitoredNode = null; if (m_monitoredNodes.TryGetValue(handle.NodeId, out monitoredNode)) { monitoredNode.Remove(datachangeItem); // check if node is no longer being monitored. if (!monitoredNode.HasMonitoredItems) { MonitoredNodes.Remove(handle.NodeId); } } // remove the monitored item. m_monitoredItems.Remove(monitoredItem.Id); // report change. OnMonitoredItemDeleted(context, handle, datachangeItem); return ServiceResult.Good; }
/// <summary> /// Tells the subscription that notifications are available but the item is not ready to publish. /// </summary> public void ItemNotificationsAvailable(IMonitoredItem monitoredItem) { /* lock (m_itemsReadyToPublish) { m_itemsNotificationsAvailable.AddLast(monitoredItem); } */ }
/// <summary> /// Initializes the context with a monitored item. /// </summary> /// <param name="monitoredItem">The monitored item.</param> public OperationContext(IMonitoredItem monitoredItem) { if (monitoredItem == null) throw new ArgumentNullException("monitoredItem"); m_channelContext = null; m_session = monitoredItem.Session; if (m_session != null) { m_identity = m_session.Identity; m_preferredLocales = m_session.PreferredLocales; } m_diagnosticsMask = DiagnosticsMasks.SymbolicId; m_stringTable = new StringTable(); m_auditLogEntryId = null; m_requestId = 0; m_requestType = RequestType.Unknown; m_clientHandle = 0; m_operationDeadline = DateTime.MaxValue; }