Bläddra i källkod

Support DateTime as value and fix parsing of date values

Stefan Profanter 6 år sedan
förälder
incheckning
bcd3e49656

+ 2 - 2
tools/nodeset_compiler/backend_open62541_datatypes.py

@@ -68,8 +68,8 @@ def generateExpandedNodeIdCode(value):
 
 def generateDateTimeCode(value):
     epoch = datetime.datetime.utcfromtimestamp(0)
-    mSecsSinceEpoch = (value - epoch).total_seconds() * 1000.0
-    return "( (" + str(mSecsSinceEpoch) + "f * UA_MSEC_TO_DATETIME) + UA_DATETIME_UNIX_EPOCH)"
+    mSecsSinceEpoch = int((value - epoch).total_seconds() * 1000.0)
+    return "( (UA_DateTime)(" + str(mSecsSinceEpoch) + " * UA_MSEC_TO_DATETIME) + UA_DATETIME_UNIX_EPOCH)"
 
 def generateNodeValueCode(node, instanceName, asIndirect=False, max_string_length=0):
     if type(node) in [Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float, Double]:

+ 1 - 5
tools/nodeset_compiler/backend_open62541_nodes.py

@@ -311,7 +311,7 @@ def generateValueCodeDummy(dataTypeNode, parentNode, nodeset, bootstrapping=True
 
 def getTypesArrayForValue(nodeset, value):
     typeNode = nodeset.getNodeByBrowseName(value.__class__.__name__)
-    if typeNode is None:
+    if typeNode is None or value.isInternal:
         typesArray = "UA_TYPES"
     else:
         typesArray = typeNode.typesArray
@@ -345,8 +345,6 @@ def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_
         # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
         if node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_GUID:
             logger.warn("Don't know how to print array of GUID in node " + str(parentNode.id))
-        elif node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_DATETIME:
-            logger.warn("Don't know how to print array of DateTime in node " + str(parentNode.id))
         elif node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
             logger.warn("Don't know how to print array of DiagnosticInfo in node " + str(parentNode.id))
         elif node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_STATUSCODE:
@@ -379,8 +377,6 @@ def generateValueCode(node, parentNode, nodeset, bootstrapping=True, max_string_
         # User the following strategy for all directly mappable values a la 'UA_Type MyInt = (UA_Type) 23;'
         if node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_GUID:
             logger.warn("Don't know how to print scalar GUID in node " + str(parentNode.id))
-        elif node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_DATETIME:
-            logger.warn("Don't know how to print scalar DateTime in node " + str(parentNode.id))
         elif node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_DIAGNOSTICINFO:
             logger.warn("Don't know how to print scalar DiagnosticInfo in node " + str(parentNode.id))
         elif node.value[0].numericRepresentation == BUILTINTYPE_TYPEID_STATUSCODE:

+ 7 - 5
tools/nodeset_compiler/datatypes.py

@@ -17,8 +17,8 @@
 ###
 
 import sys
-from time import strftime, strptime
 import logging
+from datetime import datetime
 
 logger = logging.getLogger(__name__)
 import xml.dom.minidom as dom
@@ -56,6 +56,7 @@ class Value(object):
         self.alias = None
         self.dataType = None
         self.encodingRule = []
+        self.isInternal = False
         if xmlelement:
             self.parseXML(xmlelement)
 
@@ -197,6 +198,7 @@ class Value(object):
                     else:
                         t = self.getTypeByString(enc[0], enc)
                         t.parseXML(xmlvalue)
+                        t.isInternal = True
                         return t
             else:
                 # 1: ['Alias', [...], n]
@@ -624,7 +626,7 @@ class DateTime(Value):
         self.checkXML(xmlvalue)
         if xmlvalue.firstChild == None:
             # Catch XML <DateTime /> by setting the value to a default
-            self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
+            self.value = datetime(2001, 1, 1)
         else:
             timestr = unicode(xmlvalue.firstChild.data)
             # .NET tends to create this garbage %Y-%m-%dT%H:%M:%S.0000z
@@ -635,14 +637,14 @@ class DateTime(Value):
             while len(timestr) > 0 and not timestr[-1] in "0123456789":
                 timestr = timestr[:-1]
             try:
-                self.value = strptime(timestr, "%Y-%m-%dT%H:%M:%S")
+                self.value = datetime.strptime(timestr, "%Y-%m-%dT%H:%M:%S")
             except:
                 try:
-                    self.value = strptime(timestr, "%Y-%m-%d")
+                    self.value = datetime.strptime(timestr, "%Y-%m-%d")
                 except:
                     logger.error("Timestring format is illegible. Expected 2001-01-30T21:22:23 or 2001-01-30, but got " + \
                                  timestr + " instead. Time will be defaultet to now()")
-                    self.value = strptime(strftime("%Y-%m-%dT%H:%M%S"), "%Y-%m-%dT%H:%M%S")
+                    self.value = datetime(2001, 1, 1)
 
 class QualifiedName(Value):
     def __init__(self, xmlelement=None):

+ 2 - 0
tools/nodeset_compiler/nodes.py

@@ -537,6 +537,8 @@ class DataTypeNode(Node):
                 for at,av in x.attributes.items():
                     if at == "DataType":
                         fdtype = str(av)
+                        if fdtype in nodeset.aliases:
+                            fdtype = nodeset.aliases[fdtype]
                         isEnum = False
                     elif at == "Name":
                         fname = str(av)