2 add nodes defined in XML to address space 3 format is the one from opc-ua specification 18 self.
logger = logging.getLogger(__name__)
26 creates a mapping between the namespaces in the xml file and in the server. 27 if not present the namespace is registered. 30 for ns_index, ns_uri
in enumerate(namespaces_uris):
31 ns_server_index = self.server.register_namespace(ns_uri)
32 namespaces[ns_index + 1] = ns_server_index
37 maps the import aliases to the correct namespaces 40 for alias, node_id
in aliases.items():
46 import xml and return added nodes 48 self.logger.info(
"Importing XML file %s", xmlpath)
51 dnodes = self.parser.get_node_datas()
60 for nodedata
in nodes_parsed:
61 if nodedata.nodetype ==
'UAObject':
63 elif nodedata.nodetype ==
'UAObjectType':
65 elif nodedata.nodetype ==
'UAVariable':
67 elif nodedata.nodetype ==
'UAVariableType':
69 elif nodedata.nodetype ==
'UAReferenceType':
71 elif nodedata.nodetype ==
'UADataType':
73 elif nodedata.nodetype ==
'UAMethod':
76 self.logger.warning(
"Not implemented node type: %s ", nodedata.nodetype)
83 for ndata
in node_datas:
84 ndata.nodeid = ua.NodeId.from_string(ndata.nodeid)
85 ndata.browsename = ua.QualifiedName.from_string(ndata.browsename)
87 ndata.parent = ua.NodeId.from_string(ndata.parent)
89 ndata.parentlink = self.
to_nodeid(ndata.parentlink)
91 ndata.typedef = self.
to_nodeid(ndata.typedef)
92 new_nodes.append(ndata)
97 Check if the index of nodeid or browsename given in the xml model file 98 must be converted to a already existing namespace id based on the files 101 :returns: NodeId (str) 104 nodeid = copy(nodeid)
105 nodeid.NamespaceIndex = self.
namespaces[nodeid.NamespaceIndex]
110 node.RequestedNewNodeId = self.
_migrate_ns(obj.nodeid)
112 self.logger.info(
"Importing xml node (%s, %s) as (%s %s)", obj.browsename, obj.nodeid, node.BrowseName, node.RequestedNewNodeId)
113 node.NodeClass = getattr(
ua.NodeClass, obj.nodetype[2:])
117 node.ReferenceTypeId = self.
_migrate_ns(obj.parentlink)
119 node.TypeDefinition = self.
_migrate_ns(obj.typedef)
128 return ua.NodeId.from_string(nodeid)
143 attrs.EventNotifier = obj.eventnotifier
144 node.NodeAttributes = attrs
145 res = self.server.iserver.isession.add_nodes([node])
147 res[0].StatusCode.check()
148 return res[0].AddedNodeId
156 attrs.IsAbstract = obj.abstract
157 node.NodeAttributes = attrs
158 res = self.server.iserver.isession.add_nodes([node])
160 res[0].StatusCode.check()
161 return res[0].AddedNodeId
169 attrs.DataType = self.
to_nodeid(obj.datatype)
170 if obj.value
is not None:
173 attrs.ValueRank = obj.rank
175 attrs.AccessLevel = obj.accesslevel
176 if obj.useraccesslevel:
177 attrs.UserAccessLevel = obj.useraccesslevel
179 attrs.MinimumSamplingInterval = obj.minsample
181 attrs.ArrayDimensions = obj.dimensions
182 node.NodeAttributes = attrs
183 res = self.server.iserver.isession.add_nodes([node])
185 res[0].StatusCode.check()
186 return res[0].AddedNodeId
189 ext = getattr(ua, obj.objname)()
190 for name, val
in obj.body:
191 if isinstance(val, str):
192 raise Exception(
"Error val should a dict", name, val)
194 for attname, v
in val:
202 if isinstance(val, str):
203 pval = xmlparser.ua_type_to_python(val, obj.ua_types[attname])
204 setattr(obj, attname, pval)
207 obj2 = getattr(obj, attname)
209 for attname2, v2
in val:
210 if attname2 ==
"Identifier":
211 obj2 = ua.NodeId.from_string(v2)
212 setattr(obj, attname, obj2)
214 elif not isinstance(obj2,
ua.NodeId)
and not hasattr(obj2,
"ua_types"):
217 for vtype, v2
in val:
218 my_list.append(xmlparser.ua_type_to_python(v2, vtype))
219 setattr(obj, attname, my_list)
221 for attname2, v2
in val:
223 setattr(obj, attname, obj2)
227 Returns the value for a Variable based on the objects value type. 229 self.logger.debug(
"Setting value with type %s and value %s", obj.valuetype, obj.value)
230 if obj.valuetype ==
'ListOfExtensionObject':
232 for ext
in obj.value:
234 values.append(extobj)
236 elif obj.valuetype.startswith(
"ListOf"):
237 vtype = obj.valuetype[6:]
241 return [getattr(ua, vtype)(v)
for v
in obj.value]
242 elif obj.valuetype ==
'ExtensionObject':
245 elif obj.valuetype ==
'DateTime':
247 elif obj.valuetype ==
'Guid':
249 elif obj.valuetype ==
'LocalizedText':
251 for name, val
in obj.value:
253 ltext.Text = val.encode(
"utf-8")
255 self.logger.warning(
"While parsing localizedText value, unkown element: %s with val: %s", name, val)
256 return ua.Variant(ltext, ua.VariantType.LocalizedText)
257 elif obj.valuetype ==
'NodeId':
258 return ua.Variant(ua.NodeId.from_string(obj.value))
268 attrs.DataType = self.
to_nodeid(obj.datatype)
269 if obj.value
and len(obj.value) == 1:
270 attrs.Value = obj.value[0]
272 attrs.ValueRank = obj.rank
274 attrs.IsAbstract = obj.abstract
276 attrs.ArrayDimensions = obj.dimensions
277 node.NodeAttributes = attrs
278 res = self.server.iserver.isession.add_nodes([node])
280 res[0].StatusCode.check()
281 return res[0].AddedNodeId
290 attrs.AccessLevel = obj.accesslevel
291 if obj.useraccesslevel:
292 attrs.UserAccessLevel = obj.useraccesslevel
294 attrs.MinimumSamplingInterval = obj.minsample
296 attrs.ArrayDimensions = obj.dimensions
297 node.NodeAttributes = attrs
298 res = self.server.iserver.isession.add_nodes([node])
300 res[0].StatusCode.check()
301 return res[0].AddedNodeId
312 attrs.IsAbstract = obj.abstract
314 attrs.Symmetric = obj.symmetric
315 node.NodeAttributes = attrs
316 res = self.server.iserver.isession.add_nodes([node])
318 res[0].StatusCode.check()
319 return res[0].AddedNodeId
328 attrs.IsAbstract = obj.abstract
329 node.NodeAttributes = attrs
330 res = self.server.iserver.isession.add_nodes([node])
332 res[0].StatusCode.check()
333 return res[0].AddedNodeId
339 for data
in obj.refs:
342 ref.ReferenceTypeId = self.
to_nodeid(data.reftype)
344 ref.TargetNodeClass = ua.NodeClass.DataType
347 self.server.iserver.isession.add_references(refs)
351 Sort the list of nodes according their parent node in order to respect 352 the dependency between nodes. 354 :param nodes: list of NodeDataObjects 355 :returns: list of sorted nodes 357 _ndatas = list(ndatas)
359 sorted_nodes_ids = []
362 all_node_ids = [data.nodeid
for data
in ndatas]
368 while len(_ndatas) > 0:
370 for ndata
in _ndatas:
374 if ndata.nodeid.NamespaceIndex
not in self.
namespaces or \
375 ndata.parent
is None or \
376 ndata.parent
not in all_node_ids:
377 sorted_ndatas.append(ndata)
378 sorted_nodes_ids.append(ndata.nodeid)
379 pop_nodes.append(ndata)
383 if ndata.parent
in sorted_nodes_ids:
384 sorted_ndatas.append(ndata)
385 sorted_nodes_ids.append(ndata.nodeid)
386 pop_nodes.append(ndata)
388 for ndata
in pop_nodes:
389 _ndatas.pop(_ndatas.index(ndata))
def add_reference_type(self, obj)
def to_nodeid(self, nodeid)
def _sort_nodes_by_parentid(self, ndatas)
def add_datatype(self, obj)
def add_object_type(self, obj)
def add_variable_type(self, obj)
def make_objects(self, node_datas)
def __init__(self, server)
def add_variable(self, obj)
def add_object(self, obj)
def _set_attr(self, obj, attname, val)
def _add_variable_value(self, obj)
def _make_ext_obj(self, obj)
def add_method(self, obj)
def _migrate_ns(self, nodeid)
def _map_namespaces(self, namespaces_uris)
def _map_aliases(self, aliases)
def import_xml(self, xmlpath)