2 Generate address space c++ code from xml file specification 6 import xml.etree.ElementTree
as ET
55 self.
part = self.input_path.split(
".")[-2]
59 if sys.version_info < (3,):
65 tree = ET.parse(xmlpath)
68 if child.tag[51:] ==
'UAObject':
71 elif child.tag[51:] ==
'UAObjectType':
74 elif child.tag[51:] ==
'UAVariable':
77 elif child.tag[51:] ==
'UAVariableType':
80 elif child.tag[51:] ==
'UAReferenceType':
83 elif child.tag[51:] ==
'UADataType':
87 sys.stderr.write(
"Not implemented node type: " + child.tag[51:] +
"\n")
89 void CreateAddressSpace%s(OpcUa::NodeManagementServices & registry) 92 if child.tag[51:] ==
'UAObject':
94 elif child.tag[51:] ==
'UAObjectType':
96 elif child.tag[51:] ==
'UAVariable':
98 elif child.tag[51:] ==
'UAVariableType':
100 elif child.tag[51:] ==
'UAReferenceType':
102 elif child.tag[51:] ==
'UADataType':
111 self.output_file.write(
" ".join(args) +
"\n")
115 // DO NOT EDIT THIS FILE! 116 // It is automatically generated from opcfoundation.org schemas. 119 #include "standard_address_space_parts.h" 120 #include <opc/ua/protocol/string_utils.h> 121 #include <opc/common/addons_core/addon.h> 122 #include <opc/ua/protocol/strings.h> 123 #include <opc/ua/protocol/variable_access_level.h> 124 #include <opc/ua/services/node_management.h> 143 obj.nodetype = child.tag[53:]
144 for key, val
in child.attrib.items():
147 elif key ==
"BrowseName":
149 elif key ==
"SymbolicName":
151 elif key ==
"ParentNodeId":
153 elif key ==
"DataType":
155 elif key ==
"IsAbstract":
157 elif key ==
"EventNotifier":
158 obj.eventnotifier = val
159 elif key ==
"ValueRank":
161 elif key ==
"ArrayDimensions":
163 elif key ==
"MinimumSamplingInterval":
165 elif key ==
"AccessLevel":
166 obj.accesslevel = val
167 elif key ==
"UserAccessLevel":
168 obj.useraccesslevel = val
169 elif key ==
"Symmetric":
172 sys.stderr.write(
"Attribute not implemented: " + key +
" " + val +
"\n")
174 obj.displayname = obj.browsename
178 if tag ==
"DisplayName":
179 obj.displayname = el.text
180 elif tag ==
"Description":
182 elif tag ==
"References":
185 if ref.attrib[
"ReferenceType"] ==
"HasTypeDefinition":
186 obj.typedef = ref.text
187 elif "IsForward" in ref.attrib
and ref.attrib[
"IsForward"] ==
"false":
190 obj.parent = ref.text
191 obj.parentlink = ref.attrib[
"ReferenceType"]
194 if "IsForward" in ref.attrib: struct.forward = ref.attrib[
"IsForward"]
195 struct.target = ref.text
196 struct.reftype = ref.attrib[
"ReferenceType"]
197 obj.refs.append(struct)
202 obj.value.append(
"(int32_t) " + val.text)
203 elif ntag ==
"UInt32":
204 obj.value.append(
"(uint32_t) " + val.text)
205 elif ntag
in (
'ByteString',
'String'):
206 mytext = val.text.replace(
'\r',
'')
207 if len(mytext) < 65535:
208 mytext = [
'"{}"'.
format(x)
for x
in val.text.replace(
'\r',
'').splitlines()]
209 mytext =
'\n'.join(mytext)
210 obj.value.append(
'+{}'.
format(mytext))
212 def batch_gen(data, batch_size):
213 for i
in range(0, len(data), batch_size):
214 yield data[i:i+batch_size]
215 mytext =
'({}).c_str()'.
format(
217 [
'std::string({})'.
format(
219 [
'"{}"'.
format(x)
for x
in segment.splitlines()]
221 )
for segment
in batch_gen(mytext, 65000)
225 elif ntag ==
"ListOfExtensionObject":
227 elif ntag ==
"ListOfLocalizedText":
231 elif tag ==
"InverseName":
232 obj.inversename = el.text
233 elif tag ==
"Definition":
235 obj.definition.append(field)
237 sys.stderr.write(
"Not implemented tag: "+ str(el) +
"\n")
241 self.
writecode(indent,
'AddNodesItem node;')
242 self.
writecode(indent,
'node.RequestedNewNodeId = ToNodeId("{}");'.
format(obj.nodeid))
243 self.
writecode(indent,
'node.BrowseName = ToQualifiedName("{}");'.
format(obj.browsename))
244 self.
writecode(indent,
'node.Class = NodeClass::{};'.
format(obj.nodetype))
245 if obj.parent: self.
writecode(indent,
'node.ParentNodeId = ToNodeId("{}");'.
format(obj.parent))
247 if obj.typedef: self.
writecode(indent,
'node.TypeDefinition = ToNodeId("{}");'.
format(obj.typedef))
250 s =
"std::vector<uint32_t> {" 251 s += dims.replace(
',',
', ')
257 return "ObjectId::String" 259 return 'ToNodeId("{}")'.
format(nodeid)
261 return 'ObjectId::{}'.
format(nodeid)
265 return 'ToNodeId("{}")'.
format(nodeid)
267 return 'ReferenceId::{}'.
format(nodeid)
272 self.
writecode(
'static void create_{}(OpcUa::NodeManagementServices & registry)'.
format(obj.nodeid[2:]))
275 self.
writecode(indent,
'ObjectAttributes attrs;')
276 if obj.desc: self.
writecode(indent,
'attrs.Description = LocalizedText("{}");'.
format(obj.desc))
277 self.
writecode(indent,
'attrs.DisplayName = LocalizedText("{}");'.
format(obj.displayname))
278 self.
writecode(indent,
'attrs.EventNotifier = {};'.
format(obj.eventnotifier))
279 self.
writecode(indent,
'node.Attributes = attrs;')
280 self.
writecode(indent,
'registry.AddNodes(std::vector<AddNodesItem> {node});')
287 self.
writecode(
'static void create_{}(OpcUa::NodeManagementServices & registry)'.
format(obj.nodeid[2:]))
290 self.
writecode(indent,
'ObjectTypeAttributes attrs;')
291 if obj.desc: self.
writecode(indent,
'attrs.Description = LocalizedText("{}");'.
format(obj.desc))
292 self.
writecode(indent,
'attrs.DisplayName = LocalizedText("{}");'.
format(obj.displayname))
294 self.
writecode(indent,
'node.Attributes = attrs;')
295 self.
writecode(indent,
'registry.AddNodes(std::vector<AddNodesItem> {node});')
303 self.
writecode(
'static void create_{}(OpcUa::NodeManagementServices & registry)'.
format(obj.nodeid[2:]))
306 self.
writecode(indent,
'VariableAttributes attrs;')
307 if obj.desc: self.
writecode(indent,
'attrs.Description = LocalizedText("{}");'.
format(obj.desc))
308 self.
writecode(indent,
'attrs.DisplayName = LocalizedText("{}");'.
format(obj.displayname))
310 if obj.value
and len(obj.value) == 1: self.
writecode(indent,
'attrs.Value = {};'.
format(obj.value[0]))
311 if obj.rank: self.
writecode(indent,
'attrs.Rank = {};'.
format(obj.rank))
312 if obj.accesslevel: self.
writecode(indent,
'attrs.AccessLevel = (VariableAccessLevel) {};'.
format(obj.accesslevel))
313 if obj.useraccesslevel: self.
writecode(indent,
'attrs.UserAccessLevel = (VariableAccessLevel) {};'.
format(obj.useraccesslevel))
314 if obj.minsample: self.
writecode(indent,
'attrs.MinimumSamplingInterval = {};'.
format(obj.minsample))
316 self.
writecode(indent,
'node.Attributes = attrs;')
317 self.
writecode(indent,
'registry.AddNodes(std::vector<AddNodesItem> {node});')
324 self.
writecode(
'static void create_{}(OpcUa::NodeManagementServices & registry)'.
format(obj.nodeid[2:]))
327 self.
writecode(indent,
'VariableTypeAttributes attrs;')
328 if obj.desc: self.
writecode(indent,
'attrs.Description = LocalizedText("{}");'.
format(obj.desc))
329 self.
writecode(indent,
'attrs.DisplayName = LocalizedText("{}");'.
format(obj.displayname))
331 if obj.value
and len(obj.value) == 1: self.
writecode(indent,
'attrs.Value = {};'.
format(obj.value[0]))
332 if obj.rank: self.
writecode(indent,
'attrs.Rank = {};'.
format(obj.rank))
333 if obj.abstract: self.
writecode(indent,
'attrs.IsAbstract = {};'.
format(obj.abstract))
335 self.
writecode(indent,
'node.Attributes = attrs;')
336 self.
writecode(indent,
'registry.AddNodes(std::vector<AddNodesItem> {node});')
345 self.
writecode(
'static void create_{}(OpcUa::NodeManagementServices & registry)'.
format(obj.nodeid[2:]))
348 self.
writecode(indent,
'ReferenceTypeAttributes attrs;')
349 if obj.desc: self.
writecode(indent,
'attrs.Description = LocalizedText("{}");'.
format(obj.desc))
350 self.
writecode(indent,
'attrs.DisplayName = LocalizedText("{}");'.
format(obj.displayname))
351 if obj. inversename: self.
writecode(indent,
'attrs.InverseName = LocalizedText("{}");'.
format(obj.inversename))
352 if obj.abstract: self.
writecode(indent,
'attrs.IsAbstract = {};'.
format(obj.abstract))
353 if obj.symmetric: self.
writecode(indent,
'attrs.Symmetric = {};'.
format(obj.symmetric))
354 self.
writecode(indent,
'node.Attributes = attrs;')
355 self.
writecode(indent,
'registry.AddNodes(std::vector<AddNodesItem> {node});')
362 self.
writecode(
'static void create_{}(OpcUa::NodeManagementServices & registry)'.
format(obj.nodeid[2:]))
365 self.
writecode(indent,
'DataTypeAttributes attrs;')
366 if obj.desc: self.
writecode(indent,
u'attrs.Description = LocalizedText("{}");'.
format(obj.desc))
367 self.
writecode(indent,
'attrs.DisplayName = LocalizedText("{}");'.
format(obj.displayname))
368 if obj.abstract: self.
writecode(indent,
'attrs.IsAbstract = {};'.
format(obj.abstract))
369 self.
writecode(indent,
'node.Attributes = attrs;')
370 self.
writecode(indent,
'registry.AddNodes(std::vector<AddNodesItem> {node});')
377 self.
writecode(indent,
"std::vector<AddReferencesItem> refs;")
380 localIndent = indent +
" " 381 self.
writecode(localIndent,
'AddReferencesItem ref;')
382 self.
writecode(localIndent,
'ref.IsForward = true;')
384 self.
writecode(localIndent,
'ref.SourceNodeId = ToNodeId("{}");'.
format(obj.nodeid))
385 self.
writecode(localIndent,
'ref.TargetNodeClass = NodeClass::DataType;')
386 self.
writecode(localIndent,
'ref.TargetNodeId = ToNodeId("{}");'.
format(ref.target))
387 self.
writecode(localIndent,
"refs.push_back(ref);")
389 self.
writecode(indent,
'registry.AddReferences(refs);')
392 if __name__ ==
"__main__":
393 if len(sys.argv) == 2
and sys.argv[1] ==
"all":
394 for i
in (3, 4, 5, 8, 9, 10, 11, 13):
395 xmlpath =
"Opc.Ua.NodeSet2.Part{}.xml".
format(str(i))
396 cpppath =
"../src/server/standard_address_space_part{}.cpp".
format(str(i))
401 elif len(sys.argv) != 3:
403 print(
"usage: generate_address_space.py xml_input_file cpp_output_file")
404 print(
" or generate_address_space.py all")
407 xmlpath = sys.argv[1]
408 cpppath = sys.argv[2]
def parse_node(self, child)
FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args)
def make_object_code(self, obj)
std::string format(CStringRef format_str, ArgList args)
def to_vector(self, dims)
def make_object_type_code(self, obj)
def make_variable_code(self, obj)
def __init__(self, input_path, output_path)
def make_node_code(self, obj, indent)
def make_refs_code(self, obj, indent)
def to_ref_type(self, nodeid)
def writecode(self, args)
def make_datatype_code(self, obj)
def make_reference_code(self, obj)
def to_data_type(self, nodeid)
def make_variable_type_code(self, obj)