Example #1
0
    async def read_node_attribute(self, nodeId, attribute):
        """
        Read node attribute based on given arguments.
        Giving correct dataType for value and node speeds
        up the write operation.

        Arguments                               Example
        nodeId:     Target nodeId               "ns=2;i=2"
        attribute:  Target attribute of node    "Value"

        Results
        OPCUAVar:   OPC UA variable object      <object>
        readTime:   Time taken for read (ns)    12345678
        """

        rv = ua.ReadValueId()
        if nodeId == "":
            rv.NodeId = ua.NodeId.from_string(server.rootNodeId)
        else:
            rv.NodeId = ua.NodeId.from_string(nodeId)
        rv.AttributeId = ua.AttributeIds[attribute]

        params = ua.ReadParameters()
        params.NodesToRead.append(rv)

        result, readTime = await self.read(params)
        if attribute == "Value":
            return result[0], readTime
        else:
            return result[0]
Example #2
0
 def get_attributes(self, nodes, attr):
     self.logger.info("get_attribute")
     request = ua.ReadRequest()
     for node in nodes:
         rv = ua.ReadValueId()
         rv.NodeId = node
         rv.AttributeId = attr
         request.Parameters.NodesToRead.append(rv)
     data = self._uasocket.send_request(request)
     response = struct_from_binary(ua.ReadResponse, data)
     response.ResponseHeader.ServiceResult.check()
     return response.Results
Example #3
0
def create_monitored_items(sub, dirty_nodes, attr):
	mirs = []
	for dirty_node in dirty_nodes:
		try:
			node_var = Node(sub.server, NodeId().from_string(dirty_node["node"]))
			rv = ua.ReadValueId()
			rv.NodeId = node_var.nodeid
			rv.AttributeId = attr
			# rv.IndexRange //We leave it null, then the entire array is returned
			mparams = ua.MonitoringParameters()
			with sub._lock:
				sub._client_handle += 1
				mparams.ClientHandle = sub._client_handle
			mparams.SamplingInterval = dirty_node["samplingInterval"]
			mparams.QueueSize = dirty_node["queueSize"]
			mparams.DiscardOldest = dirty_node["queueDiscardOldest"] == "True"
			
			if dirty_node["filter"] != "None":
				try:
					mfilter = DataChangeFilter()
					#DataChangeTrigger(0) = Status, DataChangeTrigger(1) = StatusValue, DataChangeTrigger(2) = StatusValueTimestamp
					mfilter.Trigger = DataChangeTrigger[dirty_node["filter"]["Trigger"]]
					# DeadbandType(0) = None, DeadbandType(1) = Absolute, DeadbandType(2) = Percent
					mfilter.DeadbandType = DeadbandType[dirty_node["filter"]["DeadbandType"]]
					mfilter.DeadbandValue = dirty_node["filter"]["DeadbandValue"]
				except:
					mfilter = None
					print(f"\n\nWARNING: Can't apply filter on node {dirty_node['node']}")
			else:
				mfilter = None
			
			if mfilter:
				mparams.Filter = mfilter	
			
			mir = ua.MonitoredItemCreateRequest()
			mir.ItemToMonitor = rv
			mir.MonitoringMode = ua.MonitoringMode.Disabled if dirty_node["monitoringMode"] == "Disabled" else ua.MonitoringMode.Sampling if dirty_node["monitoringMode"] == "Sampling" else ua.MonitoringMode.Reporting
			mir.RequestedParameters = mparams
			mirs.append(mir)
		except:
			print("\nUnable to create monitored item for node {dirty_node['node']}")		
		
	mids, results = sub_monitored_items_creation(sub, mirs)
	
	for i, r in enumerate(results):
		if dirty_node["samplingInterval"] != r.RevisedSamplingInterval or dirty_node["queueSize"] != r.RevisedQueueSize:
			print(f"\nServer has changed monitored item properties for node {dirty_node['node']}")
			print(f"Monitored item id: {r.MonitoredItemId}")
			print(f"Revised SamplingInterval: {r.RevisedSamplingInterval}")
			print(f"Revised QueueSize: {r.RevisedQueueSize}")
			print(f"Filter Result: {r.FilterResult}\n")
		
	return mids	
Example #4
0
 def get_attribute(self, attr):
     """
     Read one attribute of a node
     result code from server is checked and an exception is raised in case of error
     """
     rv = ua.ReadValueId()
     rv.NodeId = self.nodeid
     rv.AttributeId = attr
     params = ua.ReadParameters()
     params.NodesToRead.append(rv)
     result = self.server.read(params)
     result[0].StatusCode.check()
     return result[0]
Example #5
0
    def get_attributes(self, attrs):
        """
        Read several attributes of a node
        list of DataValue is returned
        """
        params = ua.ReadParameters()
        for attr in attrs:
            rv = ua.ReadValueId()
            rv.NodeId = self.nodeid
            rv.AttributeId = attr
            params.NodesToRead.append(rv)

        results = self.server.read(params)
        return results
Example #6
0
    async def batch_load_fn(self, attributeKeys):
        """
        Iterates through the attributeKeys and retrieves data
        from OPC UA servers based on the attributeKey values.

        Arguments
        attributeKeys:  List of strings with required infromation
                        to retrieve the attributes from OPC UA servers.
        Template:       "Server/NodeId/Attribute"
        Example:        "TestServer/ns=2;i=2/Value"

        Results
        sortedResults:  List of values returned by the OPC UA server
                        for each attribute. Also includes OPC UA read
                        time with each attribute.
                        In same order as attributeKeys.
        Example:        [<opcua_object>, readTime]
        """

        servers = defaultdict(list)
        i = 0
        for attribute in attributeKeys:
            info = attribute.split("/")
            servers[info[0]].append([i, info[1], info[2]])
            i += 1

        sortedResults = [None] * len(attributeKeys)
        for serverName, attributes in servers.items():
            params = ua.ReadParameters()
            server = getServer(serverName)
            for info in attributes:
                rv = ua.ReadValueId()
                if info[1] == "":
                    rv.NodeId = ua.NodeId.from_string(server.rootNodeId)
                else:
                    rv.NodeId = ua.NodeId.from_string(info[1])
                rv.AttributeId = ua.AttributeIds[info[2]]
                params.NodesToRead.append(rv)

            results, readTime = await server.read(params)

            i = 0
            for info in attributes:
                sortedResults[info[0]] = [results[i], readTime]
                i += 1

        return sortedResults
 def make_monitored_item_request(self, subscription, node, attr, sampling_interval, client_handle, filter, queuesize, discard_oldest):
     rv = ua.ReadValueId()
     rv.NodeId = node.nodeid
     rv.AttributeId = attr
     mparams = ua.MonitoringParameters()
     with subscription._lock:
         subscription._client_handle = client_handle
         mparams.ClientHandle = subscription._client_handle
     mparams.SamplingInterval = sampling_interval
     mparams.QueueSize = queuesize
     mparams.DiscardOldest = discard_oldest
     if filter:
         mparams.Filter = filter
     mir = ua.MonitoredItemCreateRequest() #stack request
     mir.ItemToMonitor = rv
     mir.MonitoringMode = ua.MonitoringMode.Reporting
     mir.RequestedParameters = mparams
     return mir
Example #8
0
 def _make_monitored_item_request(self, node, attr, mfilter, queuesize):
     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()
     with self._lock:
         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
     return mir
Example #9
0
    async def get_variable_nodes(self,
                                 node,
                                 nodeClass=2,
                                 variableList=None,
                                 depth=0,
                                 maxDepth=10):
        """
        Eats a list of node object(s).
        Recursively finds nodes under given nodes that have given nodeClass.
        Returns node objects in a list.
        """

        if variableList is None:
            variableList = []

        depth += 1
        if depth >= maxDepth:
            return variableList

        nodes = node.get_children()
        params = ua.ReadParameters()
        for node in nodes:
            rv = ua.ReadValueId()
            rv.NodeId = node.nodeid
            rv.AttributeId = ua.AttributeIds.NodeClass
            params.NodesToRead.append(rv)

        results = []
        if len(params.NodesToRead) > 0:
            results, readTime = await self.read(params)

        for i in range(len(results)):
            if nodeClass == results[i].Value.Value:
                variableList.append(nodes[i])
            await self.get_variable_nodes(node=nodes[i],
                                          nodeClass=nodeClass,
                                          variableList=variableList,
                                          depth=depth)

        return variableList
Example #10
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
Example #11
0
 def add(self, attr):
     rv = ua.ReadValueId()
     rv.NodeId = self.nodeid
     rv.AttributeId = attr
     self.params.NodesToRead.append(rv)
     self._debug_attr.append(attr)
Example #12
0
 def create_monitored_items(self, nodes, index):
     monitored_items = []
     if not isinstance(nodes, list):
         nodes = [nodes]
     for node in nodes:
         # Set item to monitor
         rv = ua.ReadValueId()
         rv.NodeId = node.nodeid
         rv.AttributeId = ua.AttributeIds.Value
         # Set monitoring parameters
         mparams = ua.MonitoringParameters()
         self._client_handle += 1
         mparams.ClientHandle = self._client_handle
         mparams.SamplingInterval = self.samplingInterval
         mparams.QueueSize = self.queueSize
         mparams.DiscardOldest = self.discardOldest
         # Create monitored item filter
         if self.dataChangeFilter:
             mfilter = ua.DataChangeFilter()
             mfilter.Trigger = ua.DataChangeTrigger(self.dataChangeTrigger)
             if self.deadbandType == ua.DeadbandType.Absolute:
                 if node.get_data_value(
                 ).Value.VariantType in self.numericTypes:
                     mfilter.DeadbandType = self.deadbandType
                     mfilter.DeadbandValue = self.deadbandValue  # absolute float value or from 0 to 100 for percentage deadband
                 else:
                     self.deadbandType = ua.DeadbandType.None_
                     mfilter.DeadbandType = self.deadbandType
             elif self.deadbandType == ua.DeadbandType.Percent:
                 has_EURange = False
                 if node.get_type_definition(
                 ).Identifier == ua.object_ids.ObjectIds.AnalogItemType:
                     # Get node properties
                     descriptions = node.get_references(
                         ua.ObjectIds.HasProperty,
                         ua.BrowseDirection.Forward, ua.NodeClass.Variable,
                         False)
                     for desc in descriptions:
                         if desc.BrowseName.Name == "EURange" and self.get_node(
                                 desc.NodeId).get_value() is not None:
                             has_EURange = True
                 if has_EURange:
                     mfilter.DeadbandType = self.deadbandType
                     mfilter.DeadbandValue = self.deadbandValue  # absolute float value or from 0 to 100 for percentage deadband
                 else:
                     self.deadbandType = ua.DeadbandType.None_
                     mfilter.DeadbandType = self.deadbandType
         else:
             mfilter = None
         mparams.Filter = mfilter
         # Create monitored item request
         mir = ua.MonitoredItemCreateRequest()
         mir.ItemToMonitor = rv
         mir.MonitoringMode = ua.MonitoringMode.Reporting
         mir.RequestedParameters = mparams
         # Append to list
         monitored_items.append(mir)
     sub, monitored_items_handles = self._datachange_subs[index]
     handles = sub.create_monitored_items(monitored_items)
     for i in range(len(handles)):
         handle = handles[i]
         if type(handle) == ua.StatusCode:
             handle.check()
         monitored_items_handles[nodes[i].nodeid] = handle