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 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("%s is found as child of binary definition node but is not found in xml", 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, val in structs_dict.items(): if isinstance(val, EnumMeta) and key is not "IntEnum": setattr(ua, key, val) return generators, structs_dict
def import_and_register_structures(self, nodes=None): """ Download xml from given variable node defining custom structures. If no 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 self.nodes.opc_binary.get_children_descriptions(): if desc.BrowseName != ua.QualifiedName("Opc.Ua"): nodes.append(self.get_node(desc.NodeId)) self.logger.info("Importing structures from nodes: %s", nodes) structs_dict = {} for node in nodes: xml = node.get_value() xml = xml.decode("utf-8") name = "structures_" + node.get_browse_name().Name gen = StructGenerator() gen.make_model_from_string(xml) gen.save_and_import(name + ".py", append_to=structs_dict) # register classes for desc in self.nodes.base_structure_type.get_children_descriptions(): # FIXME: maybe we should look recursively at children # FIXME: we should get enoding and description but this is too # expensive. we take a shorcut and assume that browsename of struct # is the same as the name of the data type structure if desc.BrowseName.Name in structs_dict: struct_node = self.get_node(desc.NodeId) refs = struct_node.get_references(ua.ObjectIds.HasEncoding, ua.BrowseDirection.Forward) for ref in refs: if "Binary" in ref.BrowseName.Name: ua.register_extension_object( desc.BrowseName.Name, ref.NodeId, structs_dict[desc.BrowseName.Name])
('Letter', 'Byte'), ] def __str__(self): vals = [name + ": " + str(val) for name, val in self.__dict__.items()] return self.__class__.__name__ + "(" + ", ".join(vals) + ")" __repr__ = __str__ def __init__(self): self.Number = 0 self.Number2 = 0 self.Letter = 0 ua.register_extension_object('ChannelType', ua.NodeId.from_string('ns=0;i=1'), ChannelType) ua.register_extension_object('InputSignalCategory', ua.NodeId.from_string('ns=0;i=2'), InputSignalCategory) ua.register_extension_object('MoldTypeEnumeration', ua.NodeId.from_string('ns=0;i=3'), MoldTypeEnumeration) ua.register_extension_object('SetupChangeType', ua.NodeId.from_string('ns=0;i=4'), SetupChangeType) ua.register_extension_object('StopConditionType', ua.NodeId.from_string('ns=0;i=5'), StopConditionType) ua.register_extension_object('ChannelIdDataType', ua.NodeId.from_string('ns=0;i=6'), ChannelIdDataType)