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;
}
NodeState cachedNode = AddNodeToComponentCache(context, handle, handle.Node);
// check if the node is already being monitored.
MonitoredNode2 monitoredNode = null;
if (!m_monitoredNodes.TryGetValue(handle.Node.NodeId, out monitoredNode))
{
m_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 > 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;
}