Adding support for debugging and forcing DATE, DT and TOD in Beremiz interface
authorlaurent
Tue, 05 Apr 2011 19:06:00 +0200
changeset 525 e8d5ab0855d3
parent 524 9a5fa6679a94
child 526 79900abdfa3c
Adding support for debugging and forcing DATE, DT and TOD in Beremiz interface
dialogs/ForceVariableDialog.py
graphics/GraphicCommons.py
--- a/dialogs/ForceVariableDialog.py	Tue Apr 05 19:01:51 2011 +0200
+++ b/dialogs/ForceVariableDialog.py	Tue Apr 05 19:06:00 2011 +0200
@@ -51,7 +51,11 @@
 MINUTE = 60 * SECOND
 HOUR = 60 * MINUTE
 DAY = 24 * HOUR
-IEC_TIME_MODEL = re.compile("(?:T|TIME)#(-)?(?:(%(float)s)D_?)?(?:(%(float)s)H_?)?(?:(%(float)s)M_?)?(?:(%(float)s)S_?)?(?:(%(float)s)MS)?" % {"float": "[0-9]+(?:\.[0-9]+)?"})
+
+IEC_TIME_MODEL = re.compile("(?:(?:T|TIME)#)?(-)?(?:(%(float)s)D_?)?(?:(%(float)s)H_?)?(?:(%(float)s)M_?)?(?:(%(float)s)S_?)?(?:(%(float)s)MS)?" % {"float": "[0-9]+(?:\.[0-9]+)?"})
+IEC_DATE_MODEL = re.compile("(?:(?:D|DATE)#)?([0-9]{4})-([0-9]{2})-([0-9]{2})")
+IEC_DATETIME_MODEL = re.compile("(?:(?:DT|DATE_AND_TIME)#)?([0-9]{4})-([0-9]{2})-([0-9]{2})-([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)")
+IEC_TIMEOFDAY_MODEL = re.compile("(?:(?:TOD|TIME_OF_DAY)#)?([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)")
 
 def gettime(v):    
     result = IEC_TIME_MODEL.match(v.upper())
@@ -76,6 +80,44 @@
     else: 
         return None
 
+def getdate(v):
+    result = IEC_DATE_MODEL.match(v.upper())
+    if result is not None:
+        year, month, day = result.groups()
+        try:
+            date = datetime.datetime(int(year), int(month), int(day))
+        except ValueError, e:
+            return None
+        base_date = datetime.datetime(1970, 1, 1)
+        return date - base_date
+    else: 
+        return None
+
+def getdatetime(v):
+    result = IEC_DATETIME_MODEL.match(v.upper())
+    if result is not None:
+        year, month, day, hours, minutes, seconds = result.groups()
+        try:
+            date = datetime.datetime(int(year), int(month), int(day), int(hours), int(minutes), int(float(seconds)), int((float(second) * SECOND) % SECOND))
+        except ValueError, e:
+            return None
+        base_date = datetime.datetime(1970, 1, 1)
+        return date - base_date
+    else: 
+        return None
+
+def gettimeofday(v):
+    result = IEC_TIMEOFDAY_MODEL.match(v.upper())
+    if result is not None:
+        hours, minutes, seconds = result.groups()
+        microseconds = 0
+        for value, factor in [(hours, HOUR),
+                              (minutes, MINUTE),
+                              (seconds, SECOND)]:
+            microseconds += float(value) * factor
+        return datetime.timedelta(microseconds=microseconds)
+    else:
+        return None
 
 GetTypeValue = {"BOOL": lambda x: {"TRUE": True, "FALSE": False}.get(x.upper(), None),
                 "SINT": getinteger,
@@ -94,7 +136,10 @@
                 "LREAL": getfloat,
                 "STRING": getstring,
                 "WSTRING": getstring,
-                "TIME": gettime}
+                "TIME": gettime,
+                "DATE": getdate,
+                "DT": getdatetime,
+                "TOD": gettimeofday}
 
 
 class ForceVariableDialog(wx.TextEntryDialog):
--- a/graphics/GraphicCommons.py	Tue Apr 05 19:01:51 2011 +0200
+++ b/graphics/GraphicCommons.py	Tue Apr 05 19:06:00 2011 +0200
@@ -26,6 +26,7 @@
 from time import time as gettime
 from math import *
 from types import *
+import datetime
 
 #-------------------------------------------------------------------------------
 #                               Common constants
@@ -198,7 +199,32 @@
     data += "%gms" % (microseconds % SECOND / 1000.)
     return data
 
-TYPE_TRANSLATOR = {"TIME": generate_time}
+def generate_date(value):
+    base_date = datetime.datetime(1970, 1, 1)
+    date = base_date + value 
+    return date.strftime("DATE#%Y-%m-%d")
+
+def generate_datetime(value):
+    base_date = datetime.datetime(1970, 1, 1)
+    date_time = base_date + value 
+    return date_time.strftime("DT#%Y-%m-%d-%H:%M:%S.%f")
+
+def generate_timeofday(value):
+    microseconds = float(value.days * DAY + value.seconds * SECOND + value.microseconds)
+    negative = microseconds < 0
+    microseconds = abs(microseconds)
+    data = "TOD#"
+    for val, format in [(int(microseconds) / HOUR, "%2.2d:"),
+                        ((int(microseconds) % HOUR) / MINUTE, "%2.2d:"),
+                        ((int(microseconds) % MINUTE) / SECOND, "%2.2d."),
+                        (microseconds % SECOND, "%6.6d")]:
+        data += format % val
+    return data
+
+TYPE_TRANSLATOR = {"TIME": generate_time,
+                   "DATE": generate_date,
+                   "DT": generate_datetime,
+                   "TOD": generate_timeofday}
 
 #-------------------------------------------------------------------------------
 #                            Debug Data Consumer Class
@@ -2596,31 +2622,27 @@
             connector = self.Parent.FindBlockConnector(new_pos, self.GetConnectionDirection())
             if connector:
                 if handle == 0 and self.EndConnected != connector:
-                    if connector.IsCompatible(self.GetEndConnectedType()):
-                        connector.HighlightParentBlock(True)
-                        connector.Connect((self, handle))
-                        self.SetStartPointDirection(connector.GetDirection())
-                        self.ConnectStartPoint(connector.GetPosition(), connector)
-                        pos = connector.GetPosition()
-                        movex = pos.x - self.oldPos.x
-                        movey = pos.y - self.oldPos.y
-                        self.Dragging = False
-                    else:
+                    connector.HighlightParentBlock(True)
+                    connector.Connect((self, handle))
+                    self.SetStartPointDirection(connector.GetDirection())
+                    self.ConnectStartPoint(connector.GetPosition(), connector)
+                    pos = connector.GetPosition()
+                    movex = pos.x - self.oldPos.x
+                    movey = pos.y - self.oldPos.y
+                    if not connector.IsCompatible(self.GetEndConnectedType()):
                         self.SetValid(False)
-                        self.MoveStartPoint(new_pos)
+                    self.Dragging = False
                 elif handle != 0 and self.StartConnected != connector:
-                    if connector.IsCompatible(self.GetStartConnectedType()):
-                        connector.HighlightParentBlock(True)
-                        connector.Connect((self, handle))
-                        self.SetEndPointDirection(connector.GetDirection())
-                        self.ConnectEndPoint(connector.GetPosition(), connector)
-                        pos = connector.GetPosition()
-                        movex = pos.x - self.oldPos.x
-                        movey = pos.y - self.oldPos.y
-                        self.Dragging = False
-                    else:
+                    connector.HighlightParentBlock(True)
+                    connector.Connect((self, handle))
+                    self.SetEndPointDirection(connector.GetDirection())
+                    self.ConnectEndPoint(connector.GetPosition(), connector)
+                    pos = connector.GetPosition()
+                    movex = pos.x - self.oldPos.x
+                    movey = pos.y - self.oldPos.y
+                    if not connector.IsCompatible(self.GetStartConnectedType()):
                         self.SetValid(False)
-                        self.MoveEndPoint(new_pos)
+                    self.Dragging = False
                 elif handle == 0:
                     self.MoveStartPoint(new_pos)
                 else: