ua_builtin_types.py 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. #!/usr/bin/env/python
  2. # -*- coding: utf-8 -*-
  3. ###
  4. ### Author: Chris Iatrou (ichrispa@core-vector.net)
  5. ### Version: rev 13
  6. ###
  7. ### This program was created for educational purposes and has been
  8. ### contributed to the open62541 project by the author. All licensing
  9. ### terms for this source is inherited by the terms and conditions
  10. ### specified for by the open62541 project (see the projects readme
  11. ### file for more information on the LGPL terms and restrictions).
  12. ###
  13. ### This program is not meant to be used in a production environment. The
  14. ### author is not liable for any complications arising due to the use of
  15. ### this program.
  16. ###
  17. import xml.dom.minidom as dom
  18. from ua_constants import *
  19. from logger import *
  20. def getNextElementNode(xmlvalue):
  21. if xmlvalue == None:
  22. return None
  23. xmlvalue = xmlvalue.nextSibling
  24. while not xmlvalue == None and not xmlvalue.nodeType == xmlvalue.ELEMENT_NODE:
  25. xmlvalue = xmlvalue.nextSibling
  26. return xmlvalue
  27. class opcua_value_t():
  28. value = None
  29. name = None
  30. __alias__ = None
  31. __binTypeId__ = 0
  32. stringRepresentation = ""
  33. knownTypes = []
  34. parent = None
  35. def __init__(self, parent):
  36. self.value = None
  37. self.parent = parent
  38. self.stringRepresentation = ""
  39. self.setStringReprentation()
  40. self.__binTypeId__ = 0
  41. self.setNumericRepresentation()
  42. self.__alias__ = None
  43. self.knownTypes = ['boolean', 'int32', 'uint32', 'int16', 'uint16', \
  44. 'int64', 'uint64', 'byte', 'sbyte', 'float', 'double', \
  45. 'string', 'bytestring', 'localizedtext', 'statuscode', \
  46. 'diagnosticinfo', 'nodeid', 'guid', 'datetime', \
  47. 'qualifiedname', 'expandednodeid', 'xmlelement']
  48. def alias(self, data=None):
  49. if not data == None:
  50. self.__alias__ = data
  51. return self.__alias__
  52. def isBuiltinByString(self, string):
  53. if str(string).lower() in self.knownTypes:
  54. return True
  55. return False
  56. def value(self, data=None):
  57. if not data==None:
  58. self.__value__ = data
  59. return self.__value__
  60. def getTypeByString(self, stringName):
  61. stringName = str(stringName.lower())
  62. if stringName == 'boolean':
  63. return opcua_BuiltinType_boolean_t(self.parent)
  64. elif stringName == 'int32':
  65. return opcua_BuiltinType_int32_t(self.parent)
  66. elif stringName == 'uint32':
  67. return opcua_BuiltinType_uint32_t(self.parent)
  68. elif stringName == 'int16':
  69. return opcua_BuiltinType_int16_t(self.parent)
  70. elif stringName == 'uint16':
  71. return opcua_BuiltinType_uint16_t(self.parent)
  72. elif stringName == 'int64':
  73. return opcua_BuiltinType_int64_t(self.parent)
  74. elif stringName == 'uint64':
  75. return opcua_BuiltinType_uint64_t(self.parent)
  76. elif stringName == 'byte':
  77. return opcua_BuiltinType_byte_t(self.parent)
  78. elif stringName == 'sbyte':
  79. return opcua_BuiltinType_sbyte_t(self.parent)
  80. elif stringName == 'float':
  81. return opcua_BuiltinType_float_t(self.parent)
  82. elif stringName == 'double':
  83. return opcua_BuiltinType_double_t(self.parent)
  84. elif stringName == 'string':
  85. return opcua_BuiltinType_string_t(self.parent)
  86. elif stringName == 'bytestring':
  87. return opcua_BuiltinType_bytestring_t(self.parent)
  88. elif stringName == 'localizedtext':
  89. return opcua_BuiltinType_localizedtext_t(self.parent)
  90. elif stringName == 'statuscode':
  91. return opcua_BuiltinType_statuscode_t(self.parent)
  92. elif stringName == 'diagnosticinfo':
  93. return opcua_BuiltinType_diagnosticinfo_t(self.parent)
  94. elif stringName == 'nodeid':
  95. return opcua_BuiltinType_nodeid_t(self.parent)
  96. elif stringName == 'guid':
  97. return opcua_BuiltinType_guid_t(self.parent)
  98. elif stringName == 'datetime':
  99. return opcua_BuiltinType_datetime_t(self.parent)
  100. elif stringName == 'qualifiedname':
  101. return opcua_BuiltinType_qualifiedname_t(self.parent)
  102. elif stringName == 'expandednodeid':
  103. return opcua_BuiltinType_expandednodeid_t(self.parent)
  104. elif stringName == 'xmlelement':
  105. return opcua_BuiltinType_xmlelement_t(self.parent)
  106. else:
  107. log(self, "No class representing stringName " + stringName + " was found. Cannot create builtinType.")
  108. return None
  109. def parseXML(self, xmlvalue):
  110. log(self, "parsing xmlvalue for " + self.parent.browseName() + " (" + str(self.parent.id()) + ") according to " + str(self.parent.dataType().target().getEncoding()))
  111. if not "value" in xmlvalue.tagName.lower():
  112. log(self, "Expected <Value> , but found " + xmlvalue.tagName + " instead. Value will not be parsed.", LOG_LEVEL_ERROR)
  113. return
  114. if len(xmlvalue.childNodes) == 0:
  115. log(self, "Expected childnodes for value, but none where found... Value will not be parsed.", LOG_LEVEL_ERROR)
  116. return
  117. for n in xmlvalue.childNodes:
  118. if n.nodeType == n.ELEMENT_NODE:
  119. xmlvalue = n
  120. break
  121. if "ListOf" in xmlvalue.tagName:
  122. self.value = []
  123. for el in xmlvalue.childNodes:
  124. if not el.nodeType == el.ELEMENT_NODE:
  125. continue
  126. self.value.append(self.__parseXMLSingleValue(el))
  127. else:
  128. self.value = [self.__parseXMLSingleValue(xmlvalue)]
  129. log(self, "Parsed Value: " + str(self.value))
  130. def __parseXMLSingleValue(self, xmlvalue, alias=None, encodingPart=None):
  131. # Parse an encoding list such as enc = [[Int32], ['Duration', ['DateTime']]],
  132. # returning a possibly aliased variable or list of variables.
  133. # Keep track of aliases, as ['Duration', ['Hawaii', ['UtcTime', ['DateTime']]]]
  134. # will be of type DateTime, but tagged as <Duration>2013-04-10 12:00 UTC</Duration>,
  135. # and not as <Duration><Hawaii><UtcTime><String>2013-04-10 12:00 UTC</String>...
  136. # Encoding may be partially handed down (iterative call). Only resort to
  137. # type definition if we are not given a specific encoding to match
  138. if encodingPart == None:
  139. enc = self.parent.dataType().target().getEncoding()
  140. else:
  141. enc = encodingPart
  142. # Check the structure of the encoding list to determine if a type is to be
  143. # returned or we need to descend further checking aliases or multipart types
  144. # such as extension Objects.
  145. if len(enc) == 1:
  146. # 0: ['BuiltinType'] either builtin type
  147. # 1: [ [ 'Alias', [...]] ] or single alias for possible multipart
  148. if isinstance(enc[0], str):
  149. # 0: 'BuiltinType'
  150. if alias != None:
  151. if not xmlvalue.tagName == alias:
  152. log(self, "Expected XML element with tag " + alias + " but found " + xmlvalue.tagName + " instead", LOG_LEVEL_ERROR)
  153. return None
  154. else:
  155. t = self.getTypeByString(enc[0])
  156. t.alias(alias)
  157. t.parseXML(xmlvalue)
  158. return t
  159. else:
  160. if not self.isBuiltinByString(xmlvalue.tagName):
  161. log(self, "Expected XML describing builtin type " + enc[0] + " but found " + xmlvalue.tagName + " instead", LOG_LEVEL_ERROR)
  162. else:
  163. t = self.getTypeByString(enc[0])
  164. t.parseXML(xmlvalue)
  165. return t
  166. else:
  167. # 1: ['Alias', [...]]
  168. # Let the next elif handle this
  169. return self.__parseXMLSingleValue(xmlvalue, alias=alias, encodingPart=enc[0])
  170. elif len(enc) == 2 and isinstance(enc[0], str):
  171. # [ 'Alias', [...] ] aliased multipart
  172. if alias == None:
  173. alias = enc[0]
  174. # if we have an alias and the next field is multipart, keep the alias
  175. elif alias != None and len(enc[1]) > 1:
  176. alias = enc[0]
  177. # otherwise drop the alias
  178. return self.__parseXMLSingleValue(xmlvalue, alias=alias, encodingPart=enc[1])
  179. else:
  180. # [ [...], [...], [...]] multifield of unknowns (analyse separately)
  181. # create an extension object to hold multipart type
  182. # FIXME: This implementation expects an extensionobject to be manditory for
  183. # multipart variables. Variants/Structures are not included in the
  184. # OPCUA Namespace 0 nodeset.
  185. # Consider moving this ExtensionObject specific parsing into the
  186. # builtin type and only determining the multipart type at this stage.
  187. if not xmlvalue.tagName == "ExtensionObject":
  188. log(self, "Expected XML tag <ExtensionObject> for multipart type, but found " + xmlvalue.tagName + " instead.", LOG_LEVEL_ERROR)
  189. return None
  190. extobj = opcua_BuiltinType_extensionObject_t(self.parent)
  191. etype = xmlvalue.getElementsByTagName("TypeId")
  192. if len(etype) == 0:
  193. log(self, "Did not find <TypeId> for ExtensionObject", LOG_LEVEL_ERROR)
  194. return None
  195. etype = etype[0].getElementsByTagName("Identifier")
  196. if len(etype) == 0:
  197. log(self, "Did not find <Identifier> for ExtensionObject", LOG_LEVEL_ERROR)
  198. return None
  199. etype = self.parent.getNamespace().getNodeByIDString(etype[0].firstChild.data)
  200. if etype == None:
  201. log(self, "Identifier Node not found in namespace" , LOG_LEVEL_ERROR)
  202. return None
  203. extobj.typeId(etype)
  204. ebody = xmlvalue.getElementsByTagName("Body")
  205. if len(ebody) == 0:
  206. log(self, "Did not find <Body> for ExtensionObject", LOG_LEVEL_ERROR)
  207. return None
  208. ebody = ebody[0]
  209. # Body must contain an Object of type 'DataType' as defined in Variable
  210. ebodypart = ebody.firstChild
  211. if not ebodypart.nodeType == ebodypart.ELEMENT_NODE:
  212. ebodypart = getNextElementNode(ebodypart)
  213. if ebodypart == None:
  214. log(self, "Expected ExtensionObject to hold a variable of type " + str(self.parent.dataType().target().browseName()) + " but found nothing.", LOG_LEVEL_ERROR)
  215. return None
  216. if not ebodypart.tagName == self.parent.dataType().target().browseName():
  217. log(self, "Expected ExtensionObject to hold a variable of type " + str(self.parent.dataType().target().browseName()) + " but found " + str(ebodypart.tagName) + " instead.", LOG_LEVEL_ERROR)
  218. return None
  219. extobj.alias(ebodypart.tagName)
  220. ebodypart = ebodypart.firstChild
  221. if not ebodypart.nodeType == ebodypart.ELEMENT_NODE:
  222. ebodypart = getNextElementNode(ebodypart)
  223. if ebodypart == None:
  224. log(self, "Description of dataType " + str(self.parent.dataType().target().browseName()) + " in ExtensionObject is empty/invalid.", LOG_LEVEL_ERROR)
  225. return None
  226. extobj.value = []
  227. for e in enc:
  228. if not ebodypart == None:
  229. extobj.value.append(extobj.__parseXMLSingleValue(ebodypart, alias=None, encodingPart=e))
  230. else:
  231. log(self, "Expected encoding " + str(e) + " but found none in body.", LOG_LEVEL_ERROR)
  232. ebodypart = getNextElementNode(ebodypart)
  233. return extobj
  234. def setStringReprentation(self):
  235. pass
  236. def setNumericRepresentation(self):
  237. pass
  238. def getNumericRepresentation(self):
  239. return self.__binTypeId__
  240. def __str__(self):
  241. if self.__alias__ != None:
  242. return "'" + self.alias() + "':" + self.stringRepresentation + "(" + str(self.value) + ")"
  243. return self.stringRepresentation + "(" + str(self.value) + ")"
  244. def __repr__(self):
  245. return self.__str__()
  246. def printOpen62541CCode_SubType(self):
  247. return ""
  248. def printOpen62541CCode(self):
  249. code = []
  250. valueName = self.parent.getCodePrintableID() + "_variant_DataContents"
  251. # self.value either contains a list of multiple identical BUILTINTYPES, or it
  252. # contains a single builtintype (which may be a container); choose if we need
  253. # to create an array or a single variable.
  254. if len(self.value) > 1:
  255. # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
  256. if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_GUID:
  257. log(self, "Don't know how to print array of GUID in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  258. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DATETIME:
  259. log(self, "Don't know how to print array of DateTime in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  260. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
  261. log(self, "Don't know how to print array of DiagnosticInfo in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  262. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
  263. log(self, "Don't know how to print array of Extensionobject in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  264. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_STATUSCODE:
  265. log(self, "Don't know how to print array of StatusCode in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  266. else:
  267. code.append("UA_Variant *" + self.parent.getCodePrintableID() + "_variant = UA_Variant_new();")
  268. code.append("UA_" + self.value[0].stringRepresentation + " " + valueName + "[" + str(len(self.value)) + "];")
  269. for v in self.value:
  270. code.append(valueName + "[" + str(self.value.index(v)) + "] = " + v.printOpen62541CCode_SubType() + ";")
  271. code.append("UA_Variant_setArrayCopy(" + self.parent.getCodePrintableID() + "_variant, &" + valueName + ", (UA_Int32) " + str(len(self.value)) + ", &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "]);")
  272. code.append(self.parent.getCodePrintableID() + "->value.variant = *" + self.parent.getCodePrintableID() + "_variant;")
  273. else:
  274. # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
  275. if self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_GUID:
  276. log(self, "Don't know how to print scalar GUID in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  277. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DATETIME:
  278. log(self, "Don't know how to print scalar DateTime in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  279. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
  280. log(self, "Don't know how to print scalar DiagnosticInfo in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  281. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_EXTENSIONOBJECT:
  282. log(self, "Don't know how to print scalar ExtensionObject in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  283. elif self.value[0].__binTypeId__ == BUILTINTYPE_TYPEID_STATUSCODE:
  284. log(self, "Don't know how to print scalar StatusCode in node " + str(self.parent.id()), LOG_LEVEL_WARN)
  285. else:
  286. # The following strategy applies to all other types, in particular strings and numerics.
  287. code.append("UA_Variant *" + self.parent.getCodePrintableID() + "_variant = UA_Variant_new();")
  288. code.append("UA_" + self.value[0].stringRepresentation + " " + valueName + " = " + self.value[0].printOpen62541CCode_SubType() + ";")
  289. code.append("UA_Variant_setScalarCopy(" + self.parent.getCodePrintableID() + "_variant, &" + valueName + ", &UA_TYPES[UA_TYPES_" + self.value[0].stringRepresentation.upper() + "]);")
  290. code.append("UA_" + self.value[0].stringRepresentation + "_deleteMembers(&" + valueName + ");")
  291. code.append(self.parent.getCodePrintableID() + "->value.variant = *" + self.parent.getCodePrintableID() + "_variant;")
  292. return code
  293. ###
  294. ### Actual buitlin types
  295. ###
  296. class opcua_BuiltinType_extensionObject_t(opcua_value_t):
  297. def setStringReprentation(self):
  298. self.stringRepresentation = "ExtensionObject"
  299. self.__typeId__ = None
  300. def setNumericRepresentation(self):
  301. self.__binTypeId__ = BUILTINTYPE_TYPEID_EXTENSIONOBJECT
  302. def typeId(self, data=None):
  303. if not data == None:
  304. self.__typeId__ = data
  305. return self.__typeId__
  306. def __str__(self):
  307. return "'" + self.alias() + "':" + self.stringRepresentation + "(" + str(self.value) + ")"
  308. class opcua_BuiltinType_localizedtext_t(opcua_value_t):
  309. def setStringReprentation(self):
  310. self.stringRepresentation = "LocalizedText"
  311. def setNumericRepresentation(self):
  312. self.__binTypeId__ = BUILTINTYPE_TYPEID_LOCALIZEDTEXT
  313. def parseXML(self, xmlvalue):
  314. # Expect <LocalizedText> or <AliasName>
  315. # <Locale>xx_XX</Locale>
  316. # <Text>TextText</Text>
  317. # <LocalizedText> or </AliasName>
  318. #
  319. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  320. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  321. return
  322. if self.alias() != None:
  323. if not self.alias() == xmlvalue.tagName:
  324. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  325. else:
  326. if not self.stringRepresentation == xmlvalue.tagName:
  327. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  328. if xmlvalue.firstChild == None:
  329. if self.alias() != None:
  330. log(self, "Neither locale nor text in XML description field " + self.alias() + ". Setting to default ['en_US','']")
  331. else:
  332. log(self, "Neither locale nor text in XML description. Setting to default ['en_US','']")
  333. self.value = ['en_US','']
  334. return
  335. self.value = []
  336. tmp = xmlvalue.getElementsByTagName("Locale")
  337. if len(tmp) == 0:
  338. log(self, "Did not find a locale. Setting to en_US per default.", LOG_LEVEL_WARN)
  339. self.value.append('en_US')
  340. else:
  341. if tmp[0].firstChild == None:
  342. log(self, "Locale tag without contents. Setting to en_US per default.", LOG_LEVEL_WARN)
  343. self.value.append('en_US')
  344. else:
  345. self.value.append(tmp[0].firstChild.data)
  346. clean = ""
  347. for s in self.value[0]:
  348. if s in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_":
  349. clean = clean + s
  350. self.value[0] = clean
  351. tmp = xmlvalue.getElementsByTagName("Text")
  352. if len(tmp) == 0:
  353. log(self, "Did not find a Text. Setting to empty string per default.", LOG_LEVEL_WARN)
  354. self.value.append('')
  355. else:
  356. if tmp[0].firstChild == None:
  357. log(self, "Text tag without content. Setting to empty string per default.", LOG_LEVEL_WARN)
  358. self.value.append('')
  359. else:
  360. self.value.append(tmp[0].firstChild.data)
  361. def printOpen62541CCode_SubType(self):
  362. code = "UA_LOCALIZEDTEXT_ALLOC(\"" + str(self.value[0]) + "\", \"" + str(self.value[1].encode('utf-8')) + "\")"
  363. return code
  364. class opcua_BuiltinType_expandednodeid_t(opcua_value_t):
  365. def setStringReprentation(self):
  366. self.stringRepresentation = "ExpandedNodeId"
  367. def setNumericRepresentation(self):
  368. self.__binTypeId__ = BUILTINTYPE_TYPEID_EXPANDEDNODEID
  369. def parseXML(self, xmlvalue):
  370. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  371. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  372. return
  373. log(self, "Not implemented", LOG_LEVEL_ERR)
  374. def printOpen62541CCode_SubType(self):
  375. #FIXME! This one is definetely broken!
  376. code = ""
  377. return code
  378. class opcua_BuiltinType_nodeid_t(opcua_value_t):
  379. def setStringReprentation(self):
  380. self.stringRepresentation = "NodeId"
  381. def setNumericRepresentation(self):
  382. self.__binTypeId__ = BUILTINTYPE_TYPEID_NODEID
  383. def parseXML(self, xmlvalue):
  384. # Expect <NodeId> or <Alias>
  385. # <Identifier> # It is unclear whether or not this is manditory. Identifier tags are used in Namespace 0.
  386. # ns=x;i=y or similar string representation of id()
  387. # </Identifier>
  388. # </NodeId> or </Alias>
  389. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  390. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  391. return
  392. if self.alias() != None:
  393. if not self.alias() == xmlvalue.tagName:
  394. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  395. else:
  396. if not self.stringRepresentation == xmlvalue.tagName:
  397. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  398. # Catch XML <NodeId />
  399. if xmlvalue.firstChild == None :
  400. log(self, "No value is given, which is illegal for Node Types...", LOG_LEVEL_ERROR)
  401. self.value = None
  402. else:
  403. # Check if there is an <Identifier> tag
  404. if len(xmlvalue.getElementsByTagName("Identifier")) != 0:
  405. xmlvalue = xmlvalue.getElementsByTagName("Identifier")[0]
  406. self.value = self.parent.getNamespace().getNodeByIDString(unicode(xmlvalue.firstChild.data))
  407. if self.value == None:
  408. log(self, "Node with id " + str(unicode(xmlvalue.firstChild.data)) + " was not found in namespace.", LOG_LEVEL_ERROR)
  409. class opcua_BuiltinType_datetime_t(opcua_value_t):
  410. def setStringReprentation(self):
  411. self.stringRepresentation = "DateTime"
  412. def setNumericRepresentation(self):
  413. self.__binTypeId__ = BUILTINTYPE_TYPEID_DATETIME
  414. def parseXML(self, xmlvalue):
  415. # Expect <DateTime> or <AliasName>
  416. # 2013-08-13T21:00:05.0000L
  417. # </DateTime> or </AliasName>
  418. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  419. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  420. return
  421. if self.alias() != None:
  422. if not self.alias() == xmlvalue.tagName:
  423. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  424. else:
  425. if not self.stringRepresentation == xmlvalue.tagName:
  426. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  427. # Catch XML <DateTime /> by setting the value to a default
  428. if xmlvalue.firstChild == None :
  429. log(self, "No value is given. Setting to default now()")
  430. self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
  431. else:
  432. timestr = unicode(xmlvalue.firstChild.data)
  433. # .NET tends to create this garbage %Y-%m-%dT%H:%M:%S.0000z
  434. # strip everything after the "." away for a posix time_struct
  435. if "." in timestr:
  436. timestr = timestr[:timestr.index(".")]
  437. # If the last character is not numeric, remove it
  438. while len(timestr)>0 and not timestr[-1] in "0123456789":
  439. timestr = timestr[:-1]
  440. try:
  441. self.value = strptime(timestr, "%Y-%m-%dT%H:%M:%S")
  442. except:
  443. log(self, "Timestring format is illegible. Expected 2001-01-30T21:22:23, but got " + timestr + " instead. Time will be defaultet to now()", LOG_LEVEL_ERROR)
  444. self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
  445. class opcua_BuiltinType_qualifiedname_t(opcua_value_t):
  446. def setStringReprentation(self):
  447. self.stringRepresentation = "QualifiedName"
  448. def setNumericRepresentation(self):
  449. self.__binTypeId__ = BUILTINTYPE_TYPEID_QUALIFIEDNAME
  450. def parseXML(self, xmlvalue):
  451. # Expect <QualifiedName> or <AliasName>
  452. # <NamespaceIndex>Int16<NamespaceIndex> # Optional, apparently ommitted if ns=0 ??? (Not given in OPCUA Nodeset2)
  453. # <Name>SomeString<Name> # Speculation: Manditory if NamespaceIndex is given, omitted otherwise?
  454. # </QualifiedName> or </AliasName>
  455. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  456. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  457. return
  458. if self.alias() != None:
  459. if not self.alias() == xmlvalue.tagName:
  460. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  461. else:
  462. if not self.stringRepresentation == xmlvalue.tagName:
  463. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  464. # Catch XML <Qalified /> by setting the value to a default
  465. if xmlvalue.firstChild == None :
  466. log(self, "No value is given. Setting to default empty string in ns=0: [0, '']")
  467. self.value = [0, '']
  468. else:
  469. # Is a namespace index passed?
  470. if len(xmlvalue.getElementsByTagName("NamespaceIndex")) != 0:
  471. self.value = [int(xmlvalue.getElementsByTagName("NamespaceIndex")[0].firstChild.data)]
  472. # namespace index is passed and <Name> tags are now manditory?
  473. if len(xmlvalue.getElementsByTagName("Name")) != 0:
  474. self.value.append(xmlvalue.getElementsByTagName("Name")[0].firstChild.data)
  475. else:
  476. log(self, "No name is specified, will default to empty string")
  477. self.value.append('')
  478. else:
  479. log(self, "No namespace is specified, will default to 0")
  480. self.value = [0]
  481. self.value.append(unicode(xmlvalue.firstChild.data))
  482. def printOpen62541CCode_SubType(self):
  483. code = "UA_QUALIFIEDNAME_ALLOC(" + str(self.value[0]) + ", \"" + self.value[1].encode('utf-8') + "\")"
  484. return code
  485. class opcua_BuiltinType_statuscode_t(opcua_value_t):
  486. def setStringReprentation(self):
  487. self.stringRepresentation = "StatusCode"
  488. def setNumericRepresentation(self):
  489. self.__binTypeId__ = BUILTINTYPE_TYPEID_STATUSCODE
  490. def parseXML(self, xmlvalue):
  491. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  492. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  493. return
  494. log(self, "Not implemented", LOG_LEVEL_WARN)
  495. class opcua_BuiltinType_diagnosticinfo_t(opcua_value_t):
  496. def setStringReprentation(self):
  497. self.stringRepresentation = "StatusCode"
  498. def setNumericRepresentation(self):
  499. self.__binTypeId__ = BUILTINTYPE_TYPEID_DIAGNOSTICINFO
  500. def parseXML(self, xmlvalue):
  501. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  502. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  503. return
  504. log(self, "Not implemented", LOG_LEVEL_WARN)
  505. class opcua_BuiltinType_guid_t(opcua_value_t):
  506. def setStringReprentation(self):
  507. self.stringRepresentation = "Guid"
  508. def setNumericRepresentation(self):
  509. self.__binTypeId__ = BUILTINTYPE_TYPEID_GUID
  510. def parseXML(self, xmlvalue):
  511. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  512. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  513. return
  514. if self.alias() != None:
  515. if not self.alias() == xmlvalue.tagName:
  516. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  517. else:
  518. if not self.stringRepresentation == xmlvalue.tagName:
  519. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  520. # Catch XML <Guid /> by setting the value to a default
  521. if xmlvalue.firstChild == None:
  522. log(self, "No value is given. Setting to default 0")
  523. self.value = [0,0,0,0]
  524. else:
  525. self.value = unicode(xmlvalue.firstChild.data)
  526. self.value = self.value.replace("{","")
  527. self.value = self.value.replace("}","")
  528. self.value = self.value.split("-")
  529. tmp = []
  530. ok = True
  531. for g in self.value:
  532. try:
  533. tmp.append(int("0x"+g, 16))
  534. except:
  535. log(self, "Invalid formatting of Guid. Expected {01234567-89AB-CDEF-ABCD-0123456789AB}, got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  536. self.value = [0,0,0,0,0]
  537. ok = False
  538. if len(tmp) != 5:
  539. log(self, "Invalid formatting of Guid. Expected {01234567-89AB-CDEF-ABCD-0123456789AB}, got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  540. self.value = [0,0,0,0]
  541. ok = False
  542. self.value = tmp
  543. class opcua_BuiltinType_boolean_t(opcua_value_t):
  544. def setStringReprentation(self):
  545. self.stringRepresentation = "Boolean"
  546. def setNumericRepresentation(self):
  547. self.__binTypeId__ = BUILTINTYPE_TYPEID_BOOLEAN
  548. def parseXML(self, xmlvalue):
  549. # Expect <Boolean>value</Boolean> or
  550. # <Aliasname>value</Aliasname>
  551. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  552. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  553. return
  554. if self.alias() != None:
  555. if not self.alias() == xmlvalue.tagName:
  556. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  557. else:
  558. if not self.stringRepresentation == xmlvalue.tagName:
  559. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  560. # Catch XML <Boolean /> by setting the value to a default
  561. if xmlvalue.firstChild == None:
  562. log(self, "No value is given. Setting to default 0")
  563. self.value = False
  564. else:
  565. if "false" in unicode(xmlvalue.firstChild.data).lower():
  566. self.value = False
  567. else:
  568. self.value = True
  569. def printOpen62541CCode_SubType(self):
  570. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  571. class opcua_BuiltinType_byte_t(opcua_value_t):
  572. def setStringReprentation(self):
  573. self.stringRepresentation = "Byte"
  574. def setNumericRepresentation(self):
  575. self.__binTypeId__ = BUILTINTYPE_TYPEID_BYTE
  576. def parseXML(self, xmlvalue):
  577. # Expect <Byte>value</Byte> or
  578. # <Aliasname>value</Aliasname>
  579. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  580. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  581. return
  582. if self.alias() != None:
  583. if not self.alias() == xmlvalue.tagName:
  584. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  585. else:
  586. if not self.stringRepresentation == xmlvalue.tagName:
  587. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  588. # Catch XML <Byte /> by setting the value to a default
  589. if xmlvalue.firstChild == None:
  590. log(self, "No value is given. Setting to default 0")
  591. self.value = 0
  592. else:
  593. try:
  594. self.value = int(unicode(xmlvalue.firstChild.data))
  595. except:
  596. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  597. def printOpen62541CCode_SubType(self):
  598. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  599. class opcua_BuiltinType_sbyte_t(opcua_value_t):
  600. def setStringReprentation(self):
  601. self.stringRepresentation = "SByte"
  602. def setNumericRepresentation(self):
  603. self.__binTypeId__ = BUILTINTYPE_TYPEID_SBYTE
  604. def parseXML(self, xmlvalue):
  605. # Expect <SByte>value</SByte> or
  606. # <Aliasname>value</Aliasname>
  607. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  608. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  609. return
  610. if self.alias() != None:
  611. if not self.alias() == xmlvalue.tagName:
  612. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  613. else:
  614. if not self.stringRepresentation == xmlvalue.tagName:
  615. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  616. # Catch XML <SByte /> by setting the value to a default
  617. if xmlvalue.firstChild == None:
  618. log(self, "No value is given. Setting to default 0")
  619. self.value = 0
  620. else:
  621. try:
  622. self.value = int(unicode(xmlvalue.firstChild.data))
  623. except:
  624. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  625. def printOpen62541CCode_SubType(self):
  626. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  627. class opcua_BuiltinType_int16_t(opcua_value_t):
  628. def setStringReprentation(self):
  629. self.stringRepresentation = "Int16"
  630. def setNumericRepresentation(self):
  631. self.__binTypeId__ = BUILTINTYPE_TYPEID_INT16
  632. def parseXML(self, xmlvalue):
  633. # Expect <Int16>value</Int16> or
  634. # <Aliasname>value</Aliasname>
  635. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  636. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  637. return
  638. if self.alias() != None:
  639. if not self.alias() == xmlvalue.tagName:
  640. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  641. else:
  642. if not self.stringRepresentation == xmlvalue.tagName:
  643. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  644. # Catch XML <Int16 /> by setting the value to a default
  645. if xmlvalue.firstChild == None:
  646. log(self, "No value is given. Setting to default 0")
  647. self.value = 0
  648. else:
  649. try:
  650. self.value = int(unicode(xmlvalue.firstChild.data))
  651. except:
  652. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  653. def printOpen62541CCode_SubType(self):
  654. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  655. class opcua_BuiltinType_uint16_t(opcua_value_t):
  656. def setStringReprentation(self):
  657. self.stringRepresentation = "UInt16"
  658. def setNumericRepresentation(self):
  659. self.__binTypeId__ = BUILTINTYPE_TYPEID_UINT16
  660. def parseXML(self, xmlvalue):
  661. # Expect <UInt16>value</UInt16> or
  662. # <Aliasname>value</Aliasname>
  663. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  664. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  665. return
  666. if self.alias() != None:
  667. if not self.alias() == xmlvalue.tagName:
  668. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  669. else:
  670. if not self.stringRepresentation == xmlvalue.tagName:
  671. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  672. # Catch XML <UInt16 /> by setting the value to a default
  673. if xmlvalue.firstChild == None:
  674. log(self, "No value is given. Setting to default 0")
  675. self.value = 0
  676. else:
  677. try:
  678. self.value = int(unicode(xmlvalue.firstChild.data))
  679. except:
  680. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  681. def printOpen62541CCode_SubType(self):
  682. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  683. class opcua_BuiltinType_int32_t(opcua_value_t):
  684. def setStringReprentation(self):
  685. self.stringRepresentation = "Int32"
  686. def setNumericRepresentation(self):
  687. self.__binTypeId__ = BUILTINTYPE_TYPEID_INT32
  688. def parseXML(self, xmlvalue):
  689. # Expect <Int32>value</Int32> or
  690. # <Aliasname>value</Aliasname>
  691. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  692. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  693. return
  694. if self.alias() != None:
  695. if not self.alias() == xmlvalue.tagName:
  696. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  697. else:
  698. if not self.stringRepresentation == xmlvalue.tagName:
  699. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  700. # Catch XML <Int32 /> by setting the value to a default
  701. if xmlvalue.firstChild == None:
  702. log(self, "No value is given. Setting to default 0")
  703. self.value = 0
  704. else:
  705. try:
  706. self.value = int(unicode(xmlvalue.firstChild.data))
  707. except:
  708. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  709. def printOpen62541CCode_SubType(self):
  710. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  711. class opcua_BuiltinType_uint32_t(opcua_value_t):
  712. def setStringReprentation(self):
  713. self.stringRepresentation = "UInt32"
  714. def setNumericRepresentation(self):
  715. self.__binTypeId__ = BUILTINTYPE_TYPEID_UINT32
  716. def parseXML(self, xmlvalue):
  717. # Expect <UInt32>value</UInt32> or
  718. # <Aliasname>value</Aliasname>
  719. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  720. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  721. return
  722. if self.alias() != None:
  723. if not self.alias() == xmlvalue.tagName:
  724. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  725. else:
  726. if not self.stringRepresentation == xmlvalue.tagName:
  727. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  728. # Catch XML <UInt32 /> by setting the value to a default
  729. if xmlvalue.firstChild == None:
  730. log(self, "No value is given. Setting to default 0")
  731. self.value = 0
  732. else:
  733. try:
  734. self.value = int(unicode(xmlvalue.firstChild.data))
  735. except:
  736. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  737. def printOpen62541CCode_SubType(self):
  738. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  739. class opcua_BuiltinType_int64_t(opcua_value_t):
  740. def setStringReprentation(self):
  741. self.stringRepresentation = "Int64"
  742. def setNumericRepresentation(self):
  743. self.__binTypeId__ = BUILTINTYPE_TYPEID_INT64
  744. def parseXML(self, xmlvalue):
  745. # Expect <Int64>value</Int64> or
  746. # <Aliasname>value</Aliasname>
  747. if self.alias() != None:
  748. if not self.alias() == xmlvalue.tagName:
  749. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  750. else:
  751. if not self.stringRepresentation == xmlvalue.tagName:
  752. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  753. # Catch XML <Int64 /> by setting the value to a default
  754. if xmlvalue.firstChild == None:
  755. log(self, "No value is given. Setting to default 0")
  756. self.value = 0
  757. else:
  758. try:
  759. self.value = int(unicode(xmlvalue.firstChild.data))
  760. except:
  761. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  762. def printOpen62541CCode_SubType(self):
  763. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  764. class opcua_BuiltinType_uint64_t(opcua_value_t):
  765. def setStringReprentation(self):
  766. self.stringRepresentation = "UInt64"
  767. def setNumericRepresentation(self):
  768. self.__binTypeId__ = BUILTINTYPE_TYPEID_UINT64
  769. def parseXML(self, xmlvalue):
  770. # Expect <UInt16>value</UInt16> or
  771. # <Aliasname>value</Aliasname>
  772. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  773. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  774. return
  775. if self.alias() != None:
  776. if not self.alias() == xmlvalue.tagName:
  777. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  778. else:
  779. if not self.stringRepresentation == xmlvalue.tagName:
  780. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  781. # Catch XML <UInt64 /> by setting the value to a default
  782. if xmlvalue.firstChild == None:
  783. log(self, "No value is given. Setting to default 0")
  784. self.value = 0
  785. else:
  786. try:
  787. self.value = int(unicode(xmlvalue.firstChild.data))
  788. except:
  789. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  790. def printOpen62541CCode_SubType(self):
  791. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  792. class opcua_BuiltinType_float_t(opcua_value_t):
  793. def setStringReprentation(self):
  794. self.stringRepresentation = "Float"
  795. def setNumericRepresentation(self):
  796. self.__binTypeId__ = BUILTINTYPE_TYPEID_FLOAT
  797. def parseXML(self, xmlvalue):
  798. # Expect <Float>value</Float> or
  799. # <Aliasname>value</Aliasname>
  800. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  801. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  802. return
  803. if self.alias() != None:
  804. if not self.alias() == xmlvalue.tagName:
  805. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  806. else:
  807. if not self.stringRepresentation == xmlvalue.tagName:
  808. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  809. # Catch XML <Float /> by setting the value to a default
  810. if xmlvalue.firstChild == None:
  811. log(self, "No value is given. Setting to default 0")
  812. self.value = 0.0
  813. else:
  814. try:
  815. self.value = float(unicode(xmlvalue.firstChild.data))
  816. except:
  817. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  818. def printOpen62541CCode_SubType(self):
  819. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  820. class opcua_BuiltinType_double_t(opcua_value_t):
  821. def setStringReprentation(self):
  822. self.stringRepresentation = "Double"
  823. def setNumericRepresentation(self):
  824. self.__binTypeId__ = BUILTINTYPE_TYPEID_DOUBLE
  825. def parseXML(self, xmlvalue):
  826. # Expect <Double>value</Double> or
  827. # <Aliasname>value</Aliasname>
  828. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  829. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  830. return
  831. if self.alias() != None:
  832. if not self.alias() == xmlvalue.tagName:
  833. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  834. else:
  835. if not self.stringRepresentation == xmlvalue.tagName:
  836. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  837. # Catch XML <Double /> by setting the value to a default
  838. if xmlvalue.firstChild == None:
  839. log(self, "No value is given. Setting to default 0")
  840. self.value = 0.0
  841. else:
  842. try:
  843. self.value = float(unicode(xmlvalue.firstChild.data))
  844. except:
  845. log(self, "Error parsing integer. Expected " + self.stringRepresentation + " but got " + unicode(xmlvalue.firstChild.data), LOG_LEVEL_ERROR)
  846. def printOpen62541CCode_SubType(self):
  847. return "(UA_" + self.stringRepresentation + ") " + str(self.value)
  848. class opcua_BuiltinType_string_t(opcua_value_t):
  849. def setStringReprentation(self):
  850. self.stringRepresentation = "String"
  851. def setNumericRepresentation(self):
  852. self.__binTypeId__ = BUILTINTYPE_TYPEID_STRING
  853. def pack(self):
  854. bin = structpack("I", len(unicode(self.value)))
  855. bin = bin + str(self.value)
  856. return bin
  857. def parseXML(self, xmlvalue):
  858. # Expect <String>value</String> or
  859. # <Aliasname>value</Aliasname>
  860. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  861. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  862. return
  863. if self.alias() != None:
  864. if not self.alias() == xmlvalue.tagName:
  865. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  866. else:
  867. if not self.stringRepresentation == xmlvalue.tagName:
  868. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  869. # Catch XML <String /> by setting the value to a default
  870. if xmlvalue.firstChild == None:
  871. log(self, "No value is given. Setting to default 0")
  872. self.value = ""
  873. else:
  874. self.value = str(unicode(xmlvalue.firstChild.data))
  875. def printOpen62541CCode_SubType(self):
  876. code = "UA_STRING_ALLOC(\"" + self.value.encode('utf-8') + "\")"
  877. return code
  878. class opcua_BuiltinType_xmlelement_t(opcua_BuiltinType_string_t):
  879. def setStringReprentation(self):
  880. self.stringRepresentation = "XmlElement"
  881. def setNumericRepresentation(self):
  882. self.__binTypeId__ = BUILTINTYPE_TYPEID_XMLELEMENT
  883. def printOpen62541CCode_SubType(self):
  884. code = "UA_XMLELEMENT_ALLOC(\"" + self.value.encode('utf-8') + "\")"
  885. return code
  886. class opcua_BuiltinType_bytestring_t(opcua_value_t):
  887. def setStringReprentation(self):
  888. self.stringRepresentation = "ByteString"
  889. def setNumericRepresentation(self):
  890. self.__binTypeId__ = BUILTINTYPE_TYPEID_BYTESTRING
  891. def parseXML(self, xmlvalue):
  892. # Expect <ByteString>value</ByteString> or
  893. # <Aliasname>value</Aliasname>
  894. if xmlvalue == None or xmlvalue.nodeType != xmlvalue.ELEMENT_NODE:
  895. log(self, "Expected XML Element, but got junk...", LOG_LEVEL_ERROR)
  896. return
  897. if self.alias() != None:
  898. if not self.alias() == xmlvalue.tagName:
  899. log(self, "Expected an aliased XML field called " + self.alias() + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  900. else:
  901. if not self.stringRepresentation == xmlvalue.tagName:
  902. log(self, "Expected XML field " + self.stringRepresentation + " but got " + xmlvalue.tagName + " instead. This is a parsing error of opcua_value_t.__parseXMLSingleValue(), will try to continue anyway.", LOG_LEVEL_WARN)
  903. # Catch XML <ByteString /> by setting the value to a default
  904. if xmlvalue.firstChild == None:
  905. log(self, "No value is given. Setting to default 0")
  906. self.value = ""
  907. else:
  908. self.value = str(unicode(xmlvalue.firstChild.data))
  909. def printOpen62541CCode_SubType(self):
  910. bs = ""
  911. for line in self.value:
  912. bs = bs + str(line).replace("\n","");
  913. outs = bs
  914. log(self, "Encoded Bytestring: " + outs, LOG_LEVEL_DEBUG)
  915. # bs = bs.decode('base64')
  916. # outs = ""
  917. # for s in bs:
  918. # outs = outs + hex(ord(s)).upper().replace("0X", "\\x")
  919. code = "UA_STRING_ALLOC(\"" + outs + "\")"
  920. return code