dialogs/ForceVariableDialog.py
changeset 814 5743cbdff669
child 878 37256069baed
equal deleted inserted replaced
813:1460273f40ed 814:5743cbdff669
       
     1 # -*- coding: utf-8 -*-
       
     2 
       
     3 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     4 #based on the plcopen standard. 
       
     5 #
       
     6 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     7 #
       
     8 #See COPYING file for copyrights details.
       
     9 #
       
    10 #This library is free software; you can redistribute it and/or
       
    11 #modify it under the terms of the GNU General Public
       
    12 #License as published by the Free Software Foundation; either
       
    13 #version 2.1 of the License, or (at your option) any later version.
       
    14 #
       
    15 #This library is distributed in the hope that it will be useful,
       
    16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    18 #General Public License for more details.
       
    19 #
       
    20 #You should have received a copy of the GNU General Public
       
    21 #License along with this library; if not, write to the Free Software
       
    22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    23 
       
    24 import re
       
    25 import datetime
       
    26 
       
    27 import wx
       
    28 
       
    29 #-------------------------------------------------------------------------------
       
    30 #                                Helpers
       
    31 #-------------------------------------------------------------------------------
       
    32 
       
    33 LOCATIONDATATYPES = {"X" : ["BOOL"],
       
    34                      "B" : ["SINT", "USINT", "BYTE", "STRING"],
       
    35                      "W" : ["INT", "UINT", "WORD", "WSTRING"],
       
    36                      "D" : ["DINT", "UDINT", "REAL", "DWORD"],
       
    37                      "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
       
    38 
       
    39 def gen_get_function(f):
       
    40     def get_function(v):
       
    41         try:
       
    42             return f(v)
       
    43         except:
       
    44             return None
       
    45     return get_function
       
    46 
       
    47 getinteger = gen_get_function(int)
       
    48 getfloat = gen_get_function(float)
       
    49 getstring = gen_get_function(str)
       
    50 
       
    51 SECOND = 1000000
       
    52 MINUTE = 60 * SECOND
       
    53 HOUR = 60 * MINUTE
       
    54 DAY = 24 * HOUR
       
    55 
       
    56 IEC_TIME_MODEL = re.compile("(?:(?:T|TIME)#)?(-)?(?:(%(float)s)D_?)?(?:(%(float)s)H_?)?(?:(%(float)s)M(?!S)_?)?(?:(%(float)s)S_?)?(?:(%(float)s)MS)?" % {"float": "[0-9]+(?:\.[0-9]+)?"})
       
    57 IEC_DATE_MODEL = re.compile("(?:(?:D|DATE)#)?([0-9]{4})-([0-9]{2})-([0-9]{2})")
       
    58 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]+)?)")
       
    59 IEC_TIMEOFDAY_MODEL = re.compile("(?:(?:TOD|TIME_OF_DAY)#)?([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)")
       
    60 
       
    61 def gettime(v):    
       
    62     result = IEC_TIME_MODEL.match(v.upper())
       
    63     if result is not None:
       
    64         negative, days, hours, minutes, seconds, milliseconds = result.groups()
       
    65         microseconds = 0
       
    66         not_null = False
       
    67         for value, factor in [(days, DAY),
       
    68                               (hours, HOUR),
       
    69                               (minutes, MINUTE),
       
    70                               (seconds, SECOND),
       
    71                               (milliseconds, 1000)]:
       
    72             if value is not None:
       
    73                 microseconds += float(value) * factor
       
    74                 not_null = True
       
    75         if not not_null:
       
    76             return None
       
    77         if negative is not None:
       
    78             microseconds = -microseconds
       
    79         return datetime.timedelta(microseconds=microseconds)
       
    80     
       
    81     else: 
       
    82         return None
       
    83 
       
    84 def getdate(v):
       
    85     result = IEC_DATE_MODEL.match(v.upper())
       
    86     if result is not None:
       
    87         year, month, day = result.groups()
       
    88         try:
       
    89             date = datetime.datetime(int(year), int(month), int(day))
       
    90         except ValueError, e:
       
    91             return None
       
    92         base_date = datetime.datetime(1970, 1, 1)
       
    93         return date - base_date
       
    94     else: 
       
    95         return None
       
    96 
       
    97 def getdatetime(v):
       
    98     result = IEC_DATETIME_MODEL.match(v.upper())
       
    99     if result is not None:
       
   100         year, month, day, hours, minutes, seconds = result.groups()
       
   101         try:
       
   102             date = datetime.datetime(int(year), int(month), int(day), int(hours), int(minutes), int(float(seconds)), int((float(second) * SECOND) % SECOND))
       
   103         except ValueError, e:
       
   104             return None
       
   105         base_date = datetime.datetime(1970, 1, 1)
       
   106         return date - base_date
       
   107     else: 
       
   108         return None
       
   109 
       
   110 def gettimeofday(v):
       
   111     result = IEC_TIMEOFDAY_MODEL.match(v.upper())
       
   112     if result is not None:
       
   113         hours, minutes, seconds = result.groups()
       
   114         microseconds = 0
       
   115         for value, factor in [(hours, HOUR),
       
   116                               (minutes, MINUTE),
       
   117                               (seconds, SECOND)]:
       
   118             microseconds += float(value) * factor
       
   119         return datetime.timedelta(microseconds=microseconds)
       
   120     else:
       
   121         return None
       
   122 
       
   123 GetTypeValue = {"BOOL": lambda x: {"TRUE": True, "FALSE": False, "0": False, "1": True}.get(x.upper(), None),
       
   124                 "SINT": getinteger,
       
   125                 "INT": getinteger,
       
   126                 "DINT": getinteger,
       
   127                 "LINT": getinteger,
       
   128                 "USINT": getinteger,
       
   129                 "UINT": getinteger,
       
   130                 "UDINT": getinteger,
       
   131                 "ULINT": getinteger,
       
   132                 "BYTE": getinteger,
       
   133                 "WORD": getinteger,
       
   134                 "DWORD": getinteger,
       
   135                 "LWORD": getinteger,
       
   136                 "REAL": getfloat,
       
   137                 "LREAL": getfloat,
       
   138                 "STRING": getstring,
       
   139                 "WSTRING": getstring,
       
   140                 "TIME": gettime,
       
   141                 "DATE": getdate,
       
   142                 "DT": getdatetime,
       
   143                 "TOD": gettimeofday}
       
   144 
       
   145 #-------------------------------------------------------------------------------
       
   146 #                            Force Variable Dialog
       
   147 #-------------------------------------------------------------------------------
       
   148 
       
   149 class ForceVariableDialog(wx.TextEntryDialog):
       
   150 
       
   151     def __init__(self, parent, iec_type, defaultValue=""):
       
   152         wx.TextEntryDialog.__init__(self, parent, message = _("Forcing Variable Value"), 
       
   153                 caption = _("Please enter value for a \"%s\" variable:") % iec_type, defaultValue = defaultValue, 
       
   154                 style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition)
       
   155         
       
   156         self.IEC_Type = iec_type 
       
   157         
       
   158         self.Bind(wx.EVT_BUTTON, self.OnOK, 
       
   159               self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
       
   160         
       
   161     def OnOK(self, event):
       
   162         message = None
       
   163         value = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
   164         if value == "":
       
   165             message = _("You must type a value!")
       
   166         elif GetTypeValue[self.IEC_Type](value) is None:
       
   167             message = _("Invalid value \"%s\" for \"%s\" variable!") % (value, self.IEC_Type)
       
   168         if message is not None:
       
   169             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
       
   170             dialog.ShowModal()
       
   171             dialog.Destroy()
       
   172         else:
       
   173             self.EndModal(wx.ID_OK)
       
   174         event.Skip()
       
   175 
       
   176     def GetValue(self):
       
   177         return GetTypeValue[self.IEC_Type](wx.TextEntryDialog.GetValue(self))