/// <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> /// 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> /// 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> /// 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 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> /// Validates the monitoring filter specified by the client. /// </summary> protected virtual StatusCode ValidateMonitoringFilter( ServerSystemContext context, NodeHandle handle, uint attributeId, double samplingInterval, uint queueSize, ExtensionObject filter, out MonitoringFilter filterToUse, out Range range, out MonitoringFilterResult result) { range = null; filterToUse = null; result = null; // nothing to do if the filter is not specified. if (ExtensionObject.IsNull(filter)) { return StatusCodes.Good; } // extension objects wrap any data structure. must check that the client provided the correct structure. DataChangeFilter deadbandFilter = ExtensionObject.ToEncodeable(filter) as DataChangeFilter; if (deadbandFilter == null) { AggregateFilter aggregateFilter = ExtensionObject.ToEncodeable(filter) as AggregateFilter; if (aggregateFilter == null || attributeId != Attributes.Value) { return StatusCodes.BadFilterNotAllowed; } if (!Server.AggregateManager.IsSupported(aggregateFilter.AggregateType)) { return StatusCodes.BadAggregateNotSupported; } ServerAggregateFilter revisedFilter = new ServerAggregateFilter(); revisedFilter.AggregateType = aggregateFilter.AggregateType; revisedFilter.StartTime = aggregateFilter.StartTime; revisedFilter.ProcessingInterval = aggregateFilter.ProcessingInterval; revisedFilter.AggregateConfiguration = aggregateFilter.AggregateConfiguration; revisedFilter.Stepped = false; StatusCode error = ReviseAggregateFilter(context, handle, samplingInterval, queueSize, revisedFilter); if (StatusCode.IsBad(error)) { return error; } AggregateFilterResult aggregateFilterResult = new AggregateFilterResult(); aggregateFilterResult.RevisedProcessingInterval = aggregateFilter.ProcessingInterval; aggregateFilterResult.RevisedStartTime = aggregateFilter.StartTime; aggregateFilterResult.RevisedAggregateConfiguration = aggregateFilter.AggregateConfiguration; filterToUse = revisedFilter; result = aggregateFilterResult; return StatusCodes.Good; } // deadband filters only allowed for variable values. if (attributeId != Attributes.Value) { return StatusCodes.BadFilterNotAllowed; } BaseVariableState variable = handle.Node as BaseVariableState; if (variable == null) { return StatusCodes.BadFilterNotAllowed; } // check for status filter. if (deadbandFilter.DeadbandType == (uint)DeadbandType.None) { filterToUse = deadbandFilter; return StatusCodes.Good; } // deadband filters can only be used for numeric values. if (!Server.TypeTree.IsTypeOf(variable.DataType, DataTypeIds.Number)) { return StatusCodes.BadFilterNotAllowed; } // nothing more to do for absolute filters. if (deadbandFilter.DeadbandType == (uint)DeadbandType.Absolute) { filterToUse = deadbandFilter; return StatusCodes.Good; } // need to look up the EU range if a percent filter is requested. if (deadbandFilter.DeadbandType == (uint)DeadbandType.Percent) { PropertyState property = handle.Node.FindChild(context, Opc.Ua.BrowseNames.EURange) as PropertyState; if (property == null) { return StatusCodes.BadFilterNotAllowed; } range = property.Value as Range; if (range == null) { return StatusCodes.BadFilterNotAllowed; } filterToUse = deadbandFilter; return StatusCodes.Good; } // no other type of filter supported. return StatusCodes.BadFilterNotAllowed; }
/// <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> /// 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> /// 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> /// 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> /// 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; }