def _create_monitored_item(self, params):
        with self._lock:
            result = ua.MonitoredItemCreateResult()
            result.RevisedSamplingInterval = self.isub.data.RevisedPublishingInterval
            result.RevisedQueueSize = params.RequestedParameters.QueueSize
            result.FilterResult = ua.downcast_extobject(params.RequestedParameters.Filter)
            self._monitored_item_counter += 1
            result.MonitoredItemId = self._monitored_item_counter
            self.logger.debug("Creating MonitoredItem with id %s", result.MonitoredItemId)

            mdata = MonitoredItemData()
            mdata.parameters = result
            mdata.mode = params.MonitoringMode
            mdata.client_handle = params.RequestedParameters.ClientHandle
            mdata.monitored_item_id = result.MonitoredItemId

            self._monitored_items[result.MonitoredItemId] = mdata

            if params.ItemToMonitor.AttributeId == ua.AttributeIds.EventNotifier:
                self.logger.info("request to subscribe to events for node %s and attribute %s", params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId)
                self._monitored_events[params.ItemToMonitor.NodeId] = result.MonitoredItemId
            else:
                self.logger.info("request to subscribe to datachange for node %s and attribute %s", params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId)
                result.StatusCode, handle = self.aspace.add_datachange_callback(params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId, self.datachange_callback)
                self.logger.debug("adding callback return status %s and handle %s", result.StatusCode, handle)
                mdata.callback_handle = handle
                self._monitored_datachange[handle] = result.MonitoredItemId
                # force data change event generation
                self.trigger_datachange(handle, params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId)

            return result
예제 #2
0
    def _create_monitored_item(self, params):
        with self._lock:
            result = ua.MonitoredItemCreateResult()
            result.RevisedSamplingInterval = self.data.RevisedPublishingInterval
            result.RevisedQueueSize = params.RequestedParameters.QueueSize #FIXME check and use value
            result.FilterResult = ua.downcast_extobject(params.RequestedParameters.Filter)
            self._monitored_item_counter += 1
            result.MonitoredItemId = self._monitored_item_counter
            self.logger.debug("Creating MonitoredItem with id %s", result.MonitoredItemId)

            mdata = MonitoredItemData()
            mdata.parameters = result
            mdata.mode = params.MonitoringMode
            mdata.client_handle = params.RequestedParameters.ClientHandle
            mdata.monitored_item_id = result.MonitoredItemId 

            self._monitored_items[result.MonitoredItemId] = mdata

            if params.ItemToMonitor.AttributeId == ua.AttributeIds.EventNotifier:
                self.logger.info("request to subscribe to events for node %s and attribute %s", params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId)
                self._monitored_events[params.ItemToMonitor.NodeId] = result.MonitoredItemId
            else:
                self.logger.info("request to subscribe to datachange for node %s and attribute %s", params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId)
                result.StatusCode, handle = self.aspace.add_datachange_callback(params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId, self.datachange_callback)
                self.logger.debug("adding callback return status %s and handle %s", result.StatusCode, handle)
                mdata.callback_handle = handle
                self._monitored_datachange[handle] = result.MonitoredItemId
                #force data change event generation
                self.trigger_datachange(handle, params.ItemToMonitor.NodeId, params.ItemToMonitor.AttributeId)

            return result
예제 #3
0
 def _add_nodeattributes(self, item, nodedata):
     item = ua.downcast_extobject(item)
     self._add_node_attr(item, nodedata, "AccessLevel", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "ArrayDimensions", ua.VariantType.Int32)
     self._add_node_attr(item, nodedata, "BrowseName", ua.VariantType.QualifiedName)
     self._add_node_attr(item, nodedata, "ContainsNoLoops", ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "DataType", ua.VariantType.NodeId)
     self._add_node_attr(item, nodedata, "Description", ua.VariantType.LocalizedText)
     self._add_node_attr(item, nodedata, "DisplayName", ua.VariantType.LocalizedText)
     self._add_node_attr(item, nodedata, "EventNotifier", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "Executable", ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "Historizing", ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "InverseName", ua.VariantType.LocalizedText)
     self._add_node_attr(item, nodedata, "IsAbstract", ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "MinimumSamplingInterval", ua.VariantType.Double)
     self._add_node_attr(item, nodedata, "NodeClass", ua.VariantType.UInt32)
     self._add_node_attr(item, nodedata, "NodeId", ua.VariantType.NodeId)
     self._add_node_attr(item, nodedata, "Symmetric", ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "UserAccessLevel", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "UserExecutable", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "UserWriteMask", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "ValueRank", ua.VariantType.Int32)
     self._add_node_attr(item, nodedata, "WriteMask", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "UserWriteMask", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "Value")
예제 #4
0
    def create_monitored_items(self, monitored_items):
        """
        low level method to have full control over subscription parameters
        Client handle must be unique since it will be used as key for internal registration of data
        """
        params = ua.CreateMonitoredItemsParameters()
        params.SubscriptionId = self.subscription_id
        params.ItemsToCreate = monitored_items
        params.TimestampsToReturn = ua.TimestampsToReturn.Neither
        
        mids = []
        results = self.server.create_monitored_items(params)
        # FIXME: Race condition here
        # We lock as early as possible. But in some situation, a notification may arrives before
        # locking and we will not be able to prosess it. To avoid issues, users should subscribe 
        # to all nodes at once
        with self._lock:  
            for idx, result in enumerate(results):
                mi = params.ItemsToCreate[idx]
                if not result.StatusCode.is_good():
                    mids.append(result.StatusCode)
                    continue
                data = SubscriptionItemData()
                data.client_handle = mi.RequestedParameters.ClientHandle
                data.node = Node(self.server, mi.ItemToMonitor.NodeId)
                data.attribute = mi.ItemToMonitor.AttributeId
                data.server_handle = result.MonitoredItemId
                data.mfilter = ua.downcast_extobject(result.FilterResult)
                self._monitoreditems_map[mi.RequestedParameters.ClientHandle] = data

                mids.append(result.MonitoredItemId)
        return mids
 def _modify_monitored_item(self, params):
     with self._lock:
         for mdata in self._monitored_items.values():
             result = ua.MonitoredItemCreateResult()
             if mdata.monitored_item_id == params.MonitoredItemId:
                 result.RevisedSamplingInterval = self.isub.data.RevisedPublishingInterval
                 result.RevisedQueueSize = ua.downcast_extobject(params.RequestedParameters.QueueSize)
                 result.FilterResult = params.RequestedParameters.Filter
                 mdata.parameters = result
                 return result
         # FIXME modify event subscriptions
         result = ua.MonitoredItemCreateResult()
         result.StatusCode(ua.StatusCodes.BadMonitoredItemIdInvalid)
         return result
예제 #6
0
 def _modify_monitored_item(self, params):
     with self._lock:
         for mdata in self._monitored_items.values():
             result = ua.MonitoredItemCreateResult()
             if mdata.monitored_item_id == params.MonitoredItemId:
                 result.RevisedSamplingInterval = self.isub.data.RevisedPublishingInterval
                 result.RevisedQueueSize = ua.downcast_extobject(params.RequestedParameters.QueueSize)
                 result.FilterResult = params.RequestedParameters.Filter
                 mdata.parameters = result
                 return result
         # FIXME modify event subscriptions
         result = ua.MonitoredItemCreateResult()
         result.StatusCode(ua.StatusCodes.BadMonitoredItemIdInvalid)
         return result
예제 #7
0
 def activate_session(self, params):
     self.logger.info("activate session")
     result = ua.ActivateSessionResult()
     if not self.state == SessionState.Created:
         raise utils.ServiceError(ua.StatusCodes.BadSessionIdInvalid)
     result.ServerNonce = self.nonce
     for _ in params.ClientSoftwareCertificates:
         result.Results.append(ua.StatusCode())
     self.state = SessionState.Activated
     id_token = ua.downcast_extobject(params.UserIdentityToken)
     if id_token.TypeId == ua.FourByteNodeId(ua.ObjectIds.UserNameIdentityToken_Encoding_DefaultBinary):
         if self.iserver.allow_remote_admin and id_token.UserName in ("admin", "Admin"):
             self.user = User.Admin
     return result
예제 #8
0
 def activate_session(self, params):
     self.logger.info("activate session")
     result = ua.ActivateSessionResult()
     if not self.state == SessionState.Created:
         raise utils.ServiceError(ua.StatusCodes.BadSessionIdInvalid)
     result.ServerNonce = self.nonce
     for _ in params.ClientSoftwareCertificates:
         result.Results.append(ua.StatusCode())
     self.state = SessionState.Activated
     id_token = ua.downcast_extobject(params.UserIdentityToken)
     if id_token.TypeId == ua.FourByteNodeId(
             ua.ObjectIds.UserNameIdentityToken_Encoding_DefaultBinary):
         if self.iserver.allow_remote_admin and id_token.UserName in (
                 "admin", "Admin"):
             self.user = User.Admin
     return result
예제 #9
0
 def _add_nodeattributes(self, item, nodedata):
     item = ua.downcast_extobject(item)
     if item.SpecifiedAttributes & ua.NodeAttributesMask.AccessLevel:
         nodedata.attributes[ua.AttributeIds.AccessLevel] = AttributeValue(ua.DataValue(ua.Variant(item.AccessLevel, ua.VariantType.Byte)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.ArrayDimensions:
         nodedata.attributes[ua.AttributeIds.ArrayDimensions] = AttributeValue(ua.DataValue(ua.Variant(item.ArrayDimensions, ua.VariantType.Int32)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.BrowseName:
         nodedata.attributes[ua.AttributeIds.BrowseName] = AttributeValue(ua.DataValue(ua.Variant(item.BrowseName, ua.VariantType.QualifiedName)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.ContainsNoLoops:
         nodedata.attributes[ua.AttributeIds.ContainsNoLoops] = AttributeValue(ua.DataValue(ua.Variant(item.ContainsNoLoops, ua.VariantType.Boolean)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.DataType:
         nodedata.attributes[ua.AttributeIds.DataType] = AttributeValue(ua.DataValue(ua.Variant(item.DataType, ua.VariantType.NodeId)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.Description:
         nodedata.attributes[ua.AttributeIds.Description] = AttributeValue(ua.DataValue(ua.Variant(item.Description, ua.VariantType.LocalizedText)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.DisplayName:
         nodedata.attributes[ua.AttributeIds.DisplayName] = AttributeValue(ua.DataValue(ua.Variant(item.DisplayName, ua.VariantType.LocalizedText)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.EventNotifier:
         nodedata.attributes[ua.AttributeIds.EventNotifier] = AttributeValue(ua.DataValue(ua.Variant(item.EventNotifier, ua.VariantType.Byte)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.Executable:
         nodedata.attributes[ua.AttributeIds.Executable] = AttributeValue(ua.DataValue(ua.Variant(item.Executable, ua.VariantType.Boolean)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.Historizing:
         nodedata.attributes[ua.AttributeIds.Historizing] = AttributeValue(ua.DataValue(ua.Variant(item.Historizing, ua.VariantType.Boolean)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.InverseName:
         nodedata.attributes[ua.AttributeIds.InverseName] = AttributeValue(ua.DataValue(ua.Variant(item.InverseName, ua.VariantType.LocalizedText)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.IsAbstract:
         nodedata.attributes[ua.AttributeIds.IsAbstract] = AttributeValue(ua.DataValue(ua.Variant(item.IsAbstract, ua.VariantType.Boolean)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.MinimumSamplingInterval:
         nodedata.attributes[ua.AttributeIds.MinimumSamplingInterval] = AttributeValue(ua.DataValue(ua.Variant(item.MinimumSamplingInterval, ua.VariantType.Double)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.NodeClass:
         nodedata.attributes[ua.AttributeIds.NodeClass] = AttributeValue(ua.DataValue(ua.Variant(item.NodeClass, ua.VariantType.UInt32)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.NodeId:
         nodedata.attributes[ua.AttributeIds.NodeId] = AttributeValue(ua.DataValue(ua.Variant(item.NodeId, ua.VariantType.NodeId)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.Symmetric:
         nodedata.attributes[ua.AttributeIds.Symmetric] = AttributeValue(ua.DataValue(ua.Variant(item.Symmetric, ua.VariantType.Boolean)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.UserAccessLevel:
         nodedata.attributes[ua.AttributeIds.UserAccessLevel] = AttributeValue(ua.DataValue(ua.Variant(item.UserAccessLevel, ua.VariantType.Byte)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.UserExecutable:
         nodedata.attributes[ua.AttributeIds.UserExecutable] = AttributeValue(ua.DataValue(ua.Variant(item.UserExecutable, ua.VariantType.Boolean)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.UserWriteMask:
         nodedata.attributes[ua.AttributeIds.UserWriteMask] = AttributeValue(ua.DataValue(ua.Variant(item.UserWriteMask, ua.VariantType.Byte)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.ValueRank:
         nodedata.attributes[ua.AttributeIds.ValueRank] = AttributeValue(ua.DataValue(ua.Variant(item.ValueRank, ua.VariantType.Int32)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.WriteMask:
         nodedata.attributes[ua.AttributeIds.WriteMask] = AttributeValue(ua.DataValue(ua.Variant(item.WriteMask, ua.VariantType.Byte)))
     if item.SpecifiedAttributes & ua.NodeAttributesMask.Value:
         nodedata.attributes[ua.AttributeIds.Value] = AttributeValue(ua.DataValue(item.Value))
예제 #10
0
 def _add_nodeattributes(self, item, nodedata):
     item = ua.downcast_extobject(item)
     self._add_node_attr(item, nodedata, "AccessLevel", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "ArrayDimensions",
                         ua.VariantType.Int32)
     self._add_node_attr(item, nodedata, "BrowseName",
                         ua.VariantType.QualifiedName)
     self._add_node_attr(item, nodedata, "ContainsNoLoops",
                         ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "DataType", ua.VariantType.NodeId)
     self._add_node_attr(item, nodedata, "Description",
                         ua.VariantType.LocalizedText)
     self._add_node_attr(item, nodedata, "DisplayName",
                         ua.VariantType.LocalizedText)
     self._add_node_attr(item, nodedata, "EventNotifier",
                         ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "Executable",
                         ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "Historizing",
                         ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "InverseName",
                         ua.VariantType.LocalizedText)
     self._add_node_attr(item, nodedata, "IsAbstract",
                         ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "MinimumSamplingInterval",
                         ua.VariantType.Double)
     self._add_node_attr(item, nodedata, "NodeClass", ua.VariantType.UInt32)
     self._add_node_attr(item, nodedata, "NodeId", ua.VariantType.NodeId)
     self._add_node_attr(item, nodedata, "Symmetric",
                         ua.VariantType.Boolean)
     self._add_node_attr(item, nodedata, "UserAccessLevel",
                         ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "UserExecutable",
                         ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "UserWriteMask",
                         ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "ValueRank", ua.VariantType.Int32)
     self._add_node_attr(item, nodedata, "WriteMask", ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "UserWriteMask",
                         ua.VariantType.Byte)
     self._add_node_attr(item, nodedata, "Value")
예제 #11
0
    def _subscribe(self, node, attr, mfilter=None, queuesize=0):
        rv = ua.ReadValueId()
        rv.NodeId = node.nodeid
        rv.AttributeId = attr
        # rv.IndexRange //We leave it null, then the entire array is returned
        mparams = ua.MonitoringParameters()
        self._client_handle += 1
        mparams.ClientHandle = self._client_handle
        mparams.SamplingInterval = self.parameters.RequestedPublishingInterval
        mparams.QueueSize = queuesize
        mparams.DiscardOldest = True
        if mfilter:
            mparams.Filter = mfilter

        mir = ua.MonitoredItemCreateRequest()
        mir.ItemToMonitor = rv
        mir.MonitoringMode = ua.MonitoringMode.Reporting
        mir.RequestedParameters = mparams

        params = ua.CreateMonitoredItemsParameters()
        params.SubscriptionId = self.subscription_id
        params.ItemsToCreate.append(mir)
        params.TimestampsToReturn = ua.TimestampsToReturn.Neither

        results = self.server.create_monitored_items(params)
        result = results[0]
        result.StatusCode.check()

        data = SubscriptionItemData()
        data.client_handle = mparams.ClientHandle
        data.node = node
        data.attribute = attr
        data.server_handle = result.MonitoredItemId
        data.mfilter = ua.downcast_extobject(result.FilterResult)
        with self._lock:
            self._monitoreditems_map[mparams.ClientHandle] = data

        return result.MonitoredItemId
예제 #12
0
    def _subscribe(self, node, attr, mfilter=None, queuesize=0):
        rv = ua.ReadValueId()
        rv.NodeId = node.nodeid
        rv.AttributeId = attr
        # rv.IndexRange //We leave it null, then the entire array is returned
        mparams = ua.MonitoringParameters()
        self._client_handle += 1
        mparams.ClientHandle = self._client_handle
        mparams.SamplingInterval = self.parameters.RequestedPublishingInterval
        mparams.QueueSize = queuesize
        mparams.DiscardOldest = True
        if mfilter:
            mparams.Filter = mfilter

        mir = ua.MonitoredItemCreateRequest()
        mir.ItemToMonitor = rv
        mir.MonitoringMode = ua.MonitoringMode.Reporting
        mir.RequestedParameters = mparams

        params = ua.CreateMonitoredItemsParameters()
        params.SubscriptionId = self.subscription_id
        params.ItemsToCreate.append(mir)
        params.TimestampsToReturn = ua.TimestampsToReturn.Neither

        with self._lock:
            results = self.server.create_monitored_items(params)
            result = results[0]
            result.StatusCode.check()

            data = SubscriptionItemData()
            data.client_handle = mparams.ClientHandle
            data.node = node
            data.attribute = attr
            data.server_handle = result.MonitoredItemId
            data.mfilter = ua.downcast_extobject(result.FilterResult)
            self._monitoreditems_map[mparams.ClientHandle] = data

        return result.MonitoredItemId