def _create_method(parent, nodeid, qname, callback, inputs, outputs): node = ua.AddNodesItem() node.RequestedNewNodeId = nodeid node.BrowseName = qname node.NodeClass = ua.NodeClass.Method node.ParentNodeId = parent.nodeid node.ReferenceTypeId = ua.NodeId.from_string("i=47") #node.TypeDefinition = ua.NodeId(ua.ObjectIds.BaseObjectType) attrs = ua.MethodAttributes() attrs.Description = ua.LocalizedText(qname.Name) attrs.DisplayName = ua.LocalizedText(qname.Name) attrs.WriteMask = ua.OpenFileMode.Read attrs.UserWriteMask = ua.OpenFileMode.Read attrs.Executable = True attrs.UserExecutable = True node.NodeAttributes = attrs results = parent.server.add_nodes([node]) results[0].StatusCode.check() method = Node(parent.server, nodeid) if inputs: create_property(method, ua.generate_nodeid(qname.NamespaceIndex), ua.QualifiedName("InputArguments", 0), [_vtype_to_argument(vtype) for vtype in inputs]) if outputs: create_property(method, ua.generate_nodeid(qname.NamespaceIndex), ua.QualifiedName("OutputArguments", 0), [_vtype_to_argument(vtype) for vtype in outputs]) parent.server.add_method_callback(method.nodeid, callback) return nodeid
def _recursive_create_items(self, parent, idx, topic_name, type_name, message, top_level=False): topic_text = topic_name.split('/')[-1] if '[' in topic_text: topic_text = topic_text[topic_text.index('['):] # This here are 'complex datatypes' if hasattr(message, '__slots__') and hasattr(message, '_slot_types'): complex_type = True new_node = parent.add_object( ua.NodeId(topic_name, parent.nodeid.NamespaceIndex, ua.NodeIdType.String), ua.QualifiedName(topic_name, parent.nodeid.NamespaceIndex)) new_node.add_property( ua.NodeId(topic_name + ".Type", idx), ua.QualifiedName("Type", parent.nodeid.NamespaceIndex), type_name) if top_level: new_node.add_method( ua.NodeId(topic_name + ".Update", parent.nodeid.NamespaceIndex), ua.QualifiedName("Update", parent.nodeid.NamespaceIndex), self.opcua_update_callback, [], []) for slot_name, type_name_child in zip(message.__slots__, message._slot_types): self._recursive_create_items(new_node, idx, topic_name + '/' + slot_name, type_name_child, getattr(message, slot_name)) self._nodes[topic_name] = new_node else: # This are arrays base_type_str, array_size = _extract_array_info(type_name) try: base_instance = roslib.message.get_message_class( base_type_str)() except (ValueError, TypeError): base_instance = None if array_size is not None and hasattr(base_instance, '__slots__'): for index in range(array_size): self._recursive_create_items(parent, idx, topic_name + '[%d]' % index, base_type_str, base_instance) else: new_node = _create_node_with_type(parent, idx, topic_name, topic_text, type_name, array_size) self._nodes[topic_name] = new_node if topic_name in self._nodes and self._nodes[ topic_name].get_node_class() == ua.NodeClass.Variable: self._nodes[topic_name].set_writable(True) return
def _create_method(parent, nodeid, qname, callback, inputs, outputs): addnode = ua.AddNodesItem() addnode.RequestedNewNodeId = nodeid addnode.BrowseName = qname addnode.NodeClass = ua.NodeClass.Method addnode.ParentNodeId = parent.nodeid addnode.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasComponent) #node.TypeDefinition = ua.NodeId(ua.ObjectIds.BaseObjectType) attrs = ua.MethodAttributes() attrs.Description = ua.LocalizedText(qname.Name) attrs.DisplayName = ua.LocalizedText(qname.Name) attrs.WriteMask = 0 attrs.UserWriteMask = 0 attrs.Executable = True attrs.UserExecutable = True addnode.NodeAttributes = attrs results = parent.server.add_nodes([addnode]) results[0].StatusCode.check() method = node.Node(parent.server, results[0].AddedNodeId) create_property(method, ua.NodeId(), ua.QualifiedName("InputArguments", 0), [_vtype_to_argument(vtype) for vtype in inputs], varianttype=ua.VariantType.ExtensionObject, datatype=ua.ObjectIds.Argument) create_property(method, ua.NodeId(), ua.QualifiedName("OutputArguments", 0), [_vtype_to_argument(vtype) for vtype in outputs], varianttype=ua.VariantType.ExtensionObject, datatype=ua.ObjectIds.Argument) parent.server.add_method_callback(method.nodeid, callback) return results[0].AddedNodeId
def recursive_create_objects(self, topic_name, idx, parent): rospy.logdebug("reached parent object creation! current parent: " + str(parent)) hierachy = topic_name.split('/') rospy.logdebug("Current hierachy: " + str(hierachy)) if len(hierachy) == 0 or len(hierachy) == 1: return parent for name in hierachy: rospy.logdebug("current name: " + str(name)) if name != '': try: nodewithsamename = self.server.find_action_node_with_same_name(name, idx) if nodewithsamename is not None: rospy.logdebug("Found node with same name, is now new parent") return self.recursive_create_objects(ros_server.nextname(hierachy, hierachy.index(name)), idx, nodewithsamename) else: # if for some reason 2 services with exactly same name are created use hack>: add random int, prob to hit two # same ints 1/10000, should be sufficient newparent = parent.add_object( ua.NodeId(name, parent.nodeid.NamespaceIndex, ua.NodeIdType.String), ua.QualifiedName(name, parent.nodeid.NamespaceIndex)) return self.recursive_create_objects(ros_server.nextname(hierachy, hierachy.index(name)), idx, newparent) # thrown when node with parent name is not existent in server except IndexError, UaError: newparent = parent.add_object( ua.NodeId(name + str(random.randint(0, 10000)), parent.nodeid.NamespaceIndex, ua.NodeIdType.String), ua.QualifiedName(name, parent.nodeid.NamespaceIndex)) return self.recursive_create_objects(ros_server.nextname(hierachy, hierachy.index(name)), idx, newparent)
def add_server_methods(srv): @uamethod def func(parent, value): return value * 2 o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethod", 2), ua.QualifiedName('ServerMethod', 2), func, [ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func2(parent, methodname, value): return math.sin(value) o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodArray", 2), ua.QualifiedName('ServerMethodArray', 2), func2, [ua.VariantType.String, ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func3(parent, mylist): return [i * 2 for i in mylist] o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodArray2", 2), ua.QualifiedName('ServerMethodArray2', 2), func3, [ua.VariantType.Int64], [ua.VariantType.Int64])
def recursive_create_objects(self, topic_name, parent): hierachy = topic_name.split('/') if len(hierachy) == 0 or len(hierachy) == 1: return parent for name in hierachy: if name != '': # skip empty names (e.g. the first slash) try: nodewithsamename = self.server.find_topics_node_with_same_name(name, self.idx) if nodewithsamename is not None: return self.recursive_create_objects(common.nextname(hierachy, hierachy.index(name)), nodewithsamename) else: # if for some reason 2 services with exactly same name are created use hack>: add random int, prob to hit two # same ints 1/10000, should be sufficient newparent = parent.add_object( ua.NodeId(name, parent.nodeid.NamespaceIndex, ua.NodeIdType.String), ua.QualifiedName(name, parent.nodeid.NamespaceIndex)) return self.recursive_create_objects(common.nextname(hierachy, hierachy.index(name)), newparent) # thrown when node with parent name is not existent in server or when nodeid already exists (perhaps that error should be unrecoverable) except (IndexError, opcua.ua.uaerrors._auto.BadNodeIdExists): newparent = parent.add_object( ua.NodeId(name + str(random.randint(0, 10000)), parent.nodeid.NamespaceIndex, ua.NodeIdType.String), ua.QualifiedName(name, parent.nodeid.NamespaceIndex)) return self.recursive_create_objects(common.nextname(hierachy, hierachy.index(name)), newparent) return parent
def get_sensor_node(client, macId, browseName): nsIdx = client.get_namespace_index( 'http://www.iqunet.com') # iQunet namespace index bpath = [ ua.QualifiedName(name=macId, namespaceidx=nsIdx), ua.QualifiedName(name=browseName, namespaceidx=nsIdx) ] sensorNode = client.objectsNode.get_child(bpath) return sensorNode
def _create_data_type(self, type_name): name = _to_camel_case(type_name) # apply for new node id data_type_node_id = self._nodeid_generator() description_node_id = self._nodeid_generator() bind_obj_node_id = self._nodeid_generator() # create data type node dt_node = ua.AddNodesItem() dt_node.RequestedNewNodeId = data_type_node_id dt_node.BrowseName = ua.QualifiedName(name, self._idx) dt_node.NodeClass = ua.NodeClass.DataType dt_node.ParentNodeId = ua.NodeId(ua.ObjectIds.Structure, 0) dt_node.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasSubtype, 0) dt_attributes = ua.DataTypeAttributes() dt_attributes.DisplayName = ua.LocalizedText(type_name) dt_node.NodeAttributes = dt_attributes # create description node desc_node = ua.AddNodesItem() desc_node.RequestedNewNodeId = description_node_id desc_node.BrowseName = ua.QualifiedName(name, self._idx) desc_node.NodeClass = ua.NodeClass.Variable desc_node.ParentNodeId = self.dict_id desc_node.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasComponent, 0) desc_node.TypeDefinition = ua.NodeId( ua.ObjectIds.DataTypeDescriptionType, 0) desc_attributes = ua.VariableAttributes() desc_attributes.DisplayName = ua.LocalizedText(type_name) desc_attributes.DataType = ua.NodeId(ua.ObjectIds.String) desc_attributes.Value = ua.Variant(name, ua.VariantType.String) desc_attributes.ValueRank = -1 desc_node.NodeAttributes = desc_attributes # create object node which the loaded python class should link to obj_node = ua.AddNodesItem() obj_node.RequestedNewNodeId = bind_obj_node_id obj_node.BrowseName = ua.QualifiedName('Default Binary', 0) obj_node.NodeClass = ua.NodeClass.Object obj_node.ParentNodeId = data_type_node_id obj_node.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasEncoding, 0) obj_node.TypeDefinition = ua.NodeId(ua.ObjectIds.DataTypeEncodingType, 0) obj_attributes = ua.ObjectAttributes() obj_attributes.DisplayName = ua.LocalizedText('Default Binary') obj_attributes.EventNotifier = 0 obj_node.NodeAttributes = obj_attributes self._session_server.add_nodes([dt_node, desc_node, obj_node]) self._link_nodes(bind_obj_node_id, data_type_node_id, description_node_id) self._type_dictionary.append_struct(type_name) return StructNode(self, data_type_node_id, type_name)
def test_data_type_dict_create_data_type(self): type_name = 'CustomizedStruct2' created_type = self.dict_builder.create_data_type(type_name) self.assertTrue(isinstance(created_type, StructNode)) # Test data type node type_node = self.srv.get_node(created_type.data_type) self.assertEqual(type_node.get_browse_name(), ua.QualifiedName(type_name, self.idx)) self.assertEqual(type_node.get_node_class(), ua.NodeClass.DataType) self.assertEqual(type_node.get_parent().nodeid, ua.NodeId(ua.ObjectIds.Structure, 0)) self.assertEqual(ua.NodeId(ua.ObjectIds.HasSubtype, 0), type_node.get_references(refs=ua.ObjectIds.HasSubtype)[0].ReferenceTypeId) self.assertEqual(type_node.get_display_name(), ua.LocalizedText(type_name)) # Test description node desc_node = self.srv.get_node(self.dict_builder.dict_id).get_child("2:{}".format(type_name)) self.assertEqual(desc_node.get_browse_name(), ua.QualifiedName(type_name, self.idx)) self.assertEqual(desc_node.get_node_class(), ua.NodeClass.Variable) self.assertEqual(desc_node.get_parent().nodeid, self.dict_builder.dict_id) self.assertEqual(ua.NodeId(ua.ObjectIds.HasComponent, 0), desc_node.get_references(refs=ua.ObjectIds.HasComponent)[0].ReferenceTypeId) self.assertEqual(desc_node.get_type_definition(), ua.NodeId(ua.ObjectIds.DataTypeDescriptionType, 0)) self.assertEqual(desc_node.get_display_name(), ua.LocalizedText(type_name)) self.assertEqual(desc_node.get_data_type(), ua.NodeId(ua.ObjectIds.String)) self.assertEqual(desc_node.get_value(), type_name) self.assertEqual(desc_node.get_value_rank(), -1) # Test object node obj_node = type_node.get_children(refs=ua.ObjectIds.HasEncoding)[0] self.assertEqual(obj_node.get_browse_name(), ua.QualifiedName('Default Binary', 0)) self.assertEqual(obj_node.get_node_class(), ua.NodeClass.Object) self.assertEqual(obj_node.get_references(refs=ua.ObjectIds.HasEncoding)[0].NodeId, type_node.nodeid) self.assertEqual(ua.NodeId(ua.ObjectIds.HasEncoding, 0), obj_node.get_references(refs=ua.ObjectIds.HasEncoding)[0].ReferenceTypeId) self.assertEqual(obj_node.get_type_definition(), ua.NodeId(ua.ObjectIds.DataTypeEncodingType, 0)) self.assertEqual(obj_node.get_display_name(), ua.LocalizedText('Default Binary')) self.assertEqual(len(obj_node.get_event_notifier()), 0) # Test links, three were tested above struct_node = self.srv.get_node(ua.NodeId(ua.ObjectIds.Structure, 0)) struct_children = struct_node.get_children(refs=ua.ObjectIds.HasSubtype) self.assertTrue(type_node in struct_children) dict_node = self.srv.get_node(self.dict_builder.dict_id) dict_children = dict_node.get_children(refs=ua.ObjectIds.HasComponent) self.assertTrue(desc_node in dict_children) self.assertTrue(obj_node in type_node.get_children(ua.ObjectIds.HasEncoding)) self.assertTrue(desc_node in obj_node.get_children(refs=ua.ObjectIds.HasDescription)) self.assertEqual(obj_node.nodeid, desc_node.get_references(refs=ua.ObjectIds.HasDescription, direction=ua.BrowseDirection.Inverse)[0].NodeId)
def test_add_read_node(self): objects = self.opc.get_objects_node() o = objects.add_object('ns=2;i=102;', '2:AddReadObject') nid = ua.NodeId(102, 2) self.assertEqual(o.nodeid, nid) qn = ua.QualifiedName('AddReadObject', 2) self.assertEqual(o.get_browse_name(), qn)
async def task(loop): # setup our server server = Server() await server.init() server.set_endpoint('opc.tcp://0.0.0.0:4840/freeopcua/server/') #4840 # setup our own namespace, not really necessary but should as spec uri = 'http://examples.freeopcua.github.io' idx = await server.register_namespace(uri) # get Objects node, this is where we should put our nodes objects = server.get_objects_node() await objects.add_method(ua.NodeId("ServerMethod", 2), ua.QualifiedName('ServerMethod', 2), func, [ua.VariantType.Int64], [ua.VariantType.Int64]) # populating our address space myobj = await objects.add_object(idx, 'MyObject') myvar = await myobj.add_variable(idx, 'MyVariable', 6.7) await myvar.set_writable() # Set MyVariable to be writable by clients # starting! async with server: count = 0 while True: await asyncio.sleep(1) count += 0.1 await myvar.set_value(count)
def endnodes_path_generator(sensorNode): for (axis, ordinate, domain) in \ itertools.product(DataAcquisition.AXES, DataAcquisition.ORDINATES, DataAcquisition.DOMAINS): # browseName: e.g. xAccelTime browseName = ''.join( [axis, ordinate.capitalize(), domain.capitalize()]) nsIdx = sensorNode.nodeid.NamespaceIndex # iQunet namespace index path = [ ua.QualifiedName(axis, nsIdx), # e.g. 'x' ua.QualifiedName(ordinate, nsIdx), # e.g. 'accel' ua.QualifiedName(browseName, nsIdx), # e.g. 'xAccelTime' ] yield path
def _add_dictionary(self, name): try: node = self._server.nodes.opc_binary.get_child("{}:{}".format( self._idx, name)) except ua.uaerrors.BadNoMatch: node = ua.AddNodesItem() node.RequestedNewNodeId = ua.NodeId(0, self._idx) node.BrowseName = ua.QualifiedName(name, self._idx) node.NodeClass = ua.NodeClass.Variable node.ParentNodeId = ua.NodeId( ua.ObjectIds.OPCBinarySchema_TypeSystem, 0) node.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasComponent, 0) node.TypeDefinition = ua.NodeId( ua.ObjectIds.DataTypeDictionaryType, 0) attrs = ua.VariableAttributes() attrs.DisplayName = ua.LocalizedText(name) attrs.DataType = ua.NodeId(ua.ObjectIds.ByteString) # Value should be set after all data types created by calling set_dict_byte_string attrs.Value = ua.Variant(None, ua.VariantType.Null) attrs.ValueRank = -1 node.NodeAttributes = attrs res = self._session_server.add_nodes([node]) return res[0].AddedNodeId logger.warning( "Making %s object for node %s which already exist, its data will be overriden", self, node) #FIXME: we have an issue return node.nodeid
def where_clause_from_evtype(evtypes): cf = ua.ContentFilter() el = ua.ContentFilterElement() # operands can be ElementOperand, LiteralOperand, AttributeOperand, SimpleAttribute # Create a clause where the generate event type property EventType # must be a subtype of events in evtypes argument # the first operand is the attribute event type op = ua.SimpleAttributeOperand() # op.TypeDefinitionId = evtype.nodeid op.BrowsePath.append(ua.QualifiedName("EventType", 0)) op.AttributeId = ua.AttributeIds.Value el.FilterOperands.append(op) # now create a list of all subtypes we want to accept subtypes = [] for evtype in evtypes: subtypes += [st.nodeid for st in ua_utils.get_node_subtypes(evtype)] subtypes = list(set(subtypes)) # remove duplicates for subtypeid in subtypes: op = ua.LiteralOperand() op.Value = ua.Variant(subtypeid) el.FilterOperands.append(op) el.FilterOperator = ua.FilterOperator.InList cf.Elements.append(el) return cf
def test_add_string_node(self): objects = self.opc.get_objects_node() qn = ua.QualifiedName('AddNodeVar2', 3) nid = ua.NodeId('AddNodeVar2Id', 3) v2 = objects.add_variable(nid, qn, 0) self.assertEqual(nid, v2.nodeid) self.assertEqual(qn, v2.get_browse_name())
def __init__(self): self.BooleanValue = True self.SByteValue = 0 self.ByteValue = 0 self.Int16Value = 0 self.UInt16Value = 0 self.Int32Value = 0 self.UInt32Value = 0 self.Int64Value = 0 self.UInt64Value = 0 self.FloatValue = 0 self.DoubleValue = 0 self.StringValue = '' self.DateTimeValue = datetime.utcnow() self.GuidValue = uuid.uuid4() self.ByteStringValue = b'' self.XmlElementValue = ua.XmlElement() self.NodeIdValue = ua.NodeId() self.ExpandedNodeIdValue = ua.ExpandedNodeId() self.QualifiedNameValue = ua.QualifiedName() self.LocalizedTextValue = ua.LocalizedText() self.StatusCodeValue = ua.StatusCode() self.VariantValue = ua.Variant() self.EnumerationValue = 0 self.StructureValue = ua.ExtensionObject() self.Number = ua.Variant() self.Integer = ua.Variant() self.UInteger = ua.Variant()
def test_add_string_variable(self): objects = self.opc.get_objects_node() v = objects.add_variable('ns=3;s=stringid;', '3:stringnodefromstring', [68]) nid = ua.NodeId('stringid', 3) qn = ua.QualifiedName('stringnodefromstring', 3) self.assertEqual(nid, v.nodeid) self.assertEqual(qn, v.get_browse_name())
def test_add_numeric_node(self): objects = self.opc.get_objects_node() nid = ua.NodeId(9999, 3) qn = ua.QualifiedName('AddNodeVar1', 3) v1 = objects.add_variable(nid, qn, 0) self.assertEqual(nid, v1.nodeid) self.assertEqual(qn, v1.get_browse_name())
def test_add_numeric_variable(self): objects = self.opc.get_objects_node() v = objects.add_variable('ns=3;i=888;', '3:numericnodefromstring', 99) nid = ua.NodeId(888, 3) qn = ua.QualifiedName('numericnodefromstring', 3) self.assertEqual(nid, v.nodeid) self.assertEqual(qn, v.get_browse_name())
def _parse_nodeid_qname(*args): try: if isinstance(args[0], int): nodeid = ua.NodeId(0, int(args[0])) qname = ua.QualifiedName(args[1], int(args[0])) return nodeid, qname if isinstance(args[0], ua.NodeId): nodeid = args[0] elif isinstance(args[0], str): nodeid = ua.NodeId.from_string(args[0]) else: raise RuntimeError() if isinstance(args[1], ua.QualifiedName): qname = args[1] elif isinstance(args[1], str): qname = ua.QualifiedName.from_string(args[1]) else: raise RuntimeError() return nodeid, qname except ua.UaError: raise except Exception as ex: raise TypeError( "This method takes either a namespace index and a string as argument or a nodeid and a qualifiedname. Received arguments {0} and got exception {1}" .format(args, ex))
def provision_node_instance(self, instance_id: str, service_id: str, plan_id: str, parameters: dict=None) -> ProvisionedServiceSpec: url = parameters.get("url") if not url: print("Error: {0}\n".format("url not contained in provision parameters!")) return ProvisionedServiceSpec(state="failed") nodes_to_add = parameters.get("nodesToAdd") if not nodes_to_add: print("Error: {0}\n".format("nodes_to_add not contained in provision parameters!")) return ProvisionedServiceSpec(state="failed") add_nodes_items = [] for node_to_add in nodes_to_add: add_nodes_item = ua.AddNodesItem() if "parentNodeId" in node_to_add: add_nodes_item.ParentNodeId = ua.ExpandedNodeId(node_to_add.get("parentNodeId")) if "referenceTypeId" in node_to_add: add_nodes_item.ReferenceTypeId = ua.NodeId(node_to_add.get("referenceTypeId")) if "requestedNewNodeId" in node_to_add: add_nodes_item.RequestedNewNodeId = ua.ExpandedNodeId(node_to_add.get("requestedNewNodeId")) if "browseName" in node_to_add: add_nodes_item.BrowseName = ua.QualifiedName(node_to_add.get("browseName")) if "nodeClass" in node_to_add: add_nodes_item.NodeClass = ua.NodeClass(node_to_add.get("nodeClass")) add_nodes_items.append(add_nodes_item) print(add_nodes_items) client = Client(url) try: client.connect() nodes = [] for add_nodes_item in add_nodes_items: parent_node = client.get_node(add_nodes_item.ParentNodeId) if add_nodes_item.NodeClass == 1: obj = parent_node.add_object(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName) nodes.append(obj) elif add_nodes_item.NodeClass == 2: var = parent_node.add_variable(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName) nodes.append(var) elif add_nodes_item.NodeClass == 4: method = parent_node.add_method() nodes.append(method) else: folder = parent_node.add_folder(add_nodes_item.RequestedNewNodeId, add_nodes_item.BrowseName) nodes.append(folder) service_instance = OpcuaServiceInstance(instance_id, service_id, plan_id, parameters) service_instance.params["nodes"] = nodes service_instance_map = dict() service_instance_map[instance_id] = service_instance self.service_instance_map = service_instance_map except Exception as e: print("Error: {0}\n".format(e)) return ProvisionedServiceSpec(state="failed") print("Node management service instance {0} is provisioned successfully\n".format(instance_id)) return ProvisionedServiceSpec()
def add_server_methods(srv): @uamethod def func(parent, value): return value * 2 o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethod", 2), ua.QualifiedName('ServerMethod', 2), func, [ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func2(parent, methodname, value): if methodname == "panic": return ua.StatusCode(ua.StatusCodes.BadOutOfMemory) if methodname != "sin": res = ua.CallMethodResult() res.StatusCode = ua.StatusCode(ua.StatusCodes.BadInvalidArgument) res.InputArgumentResults = [ua.StatusCode(ua.StatusCodes.BadNotSupported), ua.StatusCode()] return res return math.sin(value) o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodArray", 2), ua.QualifiedName('ServerMethodArray', 2), func2, [ua.VariantType.String, ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func3(parent, mylist): return [i * 2 for i in mylist] o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodArray2", 2), ua.QualifiedName('ServerMethodArray2', 2), func3, [ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func4(parent): return None base_otype= srv.get_node(ua.ObjectIds.BaseObjectType) custom_otype = base_otype.add_object_type(2, 'ObjectWithMethodsType') custom_otype.add_method(2, 'ServerMethodDefault', func4) custom_otype.add_method(2, 'ServerMethodMandatory', func4).set_modelling_rule(True) custom_otype.add_method(2, 'ServerMethodOptional', func4).set_modelling_rule(False) custom_otype.add_method(2, 'ServerMethodNone', func4).set_modelling_rule(None) o.add_object(2, 'ObjectWithMethods', custom_otype) @uamethod def func5(parent): return 1,2,3 o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodTuple", 2), ua.QualifiedName('ServerMethodTuple', 2), func5, [], [ua.VariantType.Int64, ua.VariantType.Int64, ua.VariantType.Int64])
def load_type_definitions(server, nodes=None): """ Download xml from given variable node defining custom structures. If no node is given, attemps to import variables from all nodes under "0:OPC Binary" the code is generated and imported on the fly. If you know the structures are not going to be modified it might be interresting to copy the generated files and include them in you code """ if nodes is None: nodes = [] for desc in server.nodes.opc_binary.get_children_descriptions(): if desc.BrowseName != ua.QualifiedName("Opc.Ua"): nodes.append(server.get_node(desc.NodeId)) structs_dict = {} generators = [] for node in nodes: xml = node.get_value() xml = xml.decode("utf-8") generator = StructGenerator() generators.append(generator) generator.make_model_from_string(xml) # generate and execute new code on the fly generator.get_python_classes(structs_dict) # same but using a file that is imported. This can be usefull for debugging library #name = node.get_browse_name().Name # Make sure structure names do not contain charaters that cannot be used in Python class file names #name = _clean_name(name) #name = "structures_" + node.get_browse_name().Name #generator.save_and_import(name + ".py", append_to=structs_dict) # register classes # every children of our node should represent a class for ndesc in node.get_children_descriptions(): ndesc_node = server.get_node(ndesc.NodeId) ref_desc_list = ndesc_node.get_references( refs=ua.ObjectIds.HasDescription, direction=ua.BrowseDirection.Inverse) if ref_desc_list: #some server put extra things here name = _clean_name(ndesc.BrowseName.Name) if not name in structs_dict: logger.warning( "Error {} is found as child of binary definition node but is not found in xml" .format(name)) continue nodeid = ref_desc_list[0].NodeId ua.register_extension_object(name, nodeid, structs_dict[name]) # save the typeid if user want to create static file for type definitnion generator.set_typeid(name, nodeid.to_string()) for key in structs_dict.keys(): if type(structs_dict[key]) is EnumMeta and key is not "IntEnum": import opcua.ua setattr(opcua.ua, key, structs_dict[key]) return generators, structs_dict
def _parse_add_args(*args): if isinstance(args[0], ua.NodeId): return args[0], args[1] elif isinstance(args[0], str): return ua.NodeId.from_string(args[0]), ua.QualifiedName.from_string(args[1]) elif isinstance(args[0], int): return ua.generate_nodeid(args[0]), ua.QualifiedName(args[1], args[0]) else: raise TypeError("Add methods takes a nodeid and a qualifiedname as argument, received %s" % args)
def test_add_string_array_variable(self): objects = self.opc.get_objects_node() v = objects.add_variable('ns=3;s=stringarrayid;', '9:stringarray', ['l', 'b']) nid = ua.NodeId('stringarrayid', 3) qn = ua.QualifiedName('stringarray', 9) self.assertEqual(nid, v.nodeid) self.assertEqual(qn, v.get_browse_name()) val = v.get_value() self.assertEqual(['l', 'b'], val)
def get_nodeid_and_bname(self): ns = self.nsComboBox.currentIndex() name = self.nameLabel.text() bname = ua.QualifiedName(name, ns) if self.nodeidCheckBox.isChecked(): nodeid = ua.NodeId(namespaceidx=ns) else: nodeid = ua.NodeId.from_string(self.nodeidLineEdit.text()) return nodeid, bname
def add_matrix_variable(server): objects = server.get_objects_node() my_integer_node_id = ua.NodeId("double.matrix", 1) matrix = ua.Variant([[1.5, 4.0], [2.5, 0.0]], ua.VariantType.Double) matrix_var = objects.add_variable(nodeid=my_integer_node_id, bname=ua.QualifiedName( "double.matrix", 1), val=matrix) matrix_var.set_writable()
def add_server_methods(srv): @uamethod def func(parent, value): return value * 2 o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethod", 2), ua.QualifiedName('ServerMethod', 2), func, [ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func2(parent, methodname, value): return math.sin(value) o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodArray", 2), ua.QualifiedName('ServerMethodArray', 2), func2, [ua.VariantType.String, ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func3(parent, mylist): return [i * 2 for i in mylist] o = srv.get_objects_node() v = o.add_method(ua.NodeId("ServerMethodArray2", 2), ua.QualifiedName('ServerMethodArray2', 2), func3, [ua.VariantType.Int64], [ua.VariantType.Int64]) @uamethod def func4(parent): return [] base_otype = srv.get_node(ua.ObjectIds.BaseObjectType) custom_otype = base_otype.add_object_type(2, 'ObjectWithMethodsType') custom_otype.add_method(2, 'ServerMethodDefault', func4) custom_otype.add_method(2, 'ServerMethodMandatory', func4).set_modelling_rule(True) custom_otype.add_method(2, 'ServerMethodOptional', func4).set_modelling_rule(False) custom_otype.add_method(2, 'ServerMethodNone', func4).set_modelling_rule(None) o.add_object(2, 'ObjectWithMethods', custom_otype)
def get_ns_and_name(self): args = [] ns = self.nsComboBox.currentIndex() name = self.nameLabel.text() if self.nodeidCheckBox.isChecked(): args.append(ns) args.append(name) else: nodeid = ua.NodeId.from_string(self.nodeidLineEdit.text()) args.append(nodeid) args.append(ua.QualifiedName(name, ns)) return args
def test_utf8(self): objects = self.opc.get_objects_node() utf_string = "æøå@%&" bn = ua.QualifiedName(utf_string, 3) nid = ua.NodeId("æølå", 3) val = "æøå" v = objects.add_variable(nid, bn, val) self.assertEqual(nid, v.nodeid) val2 = v.get_value() self.assertEqual(val, val2) bn2 = v.get_browse_name() self.assertEqual(bn, bn2)