runtime/PLCObject.py
author lbessard
Tue, 09 Jun 2009 10:10:34 +0200
changeset 356 e9698d0ee5f3
parent 353 c68fc75ebb06
child 361 331d698e1118
permissions -rwxr-xr-x
Adding support for printing lines where matiec failed in Log console (thanks to Brendan)
Bug that prevent to see errors in editor with double click fixed.
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     1
#!/usr/bin/env python
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     2
# -*- coding: utf-8 -*-
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     3
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     4
#This file is part of Beremiz, a Integrated Development Environment for
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     5
#programming IEC 61131-3 automates supporting plcopen standard and CanFestival. 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     6
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     7
#Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     8
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
     9
#See COPYING file for copyrights details.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    10
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    11
#This library is free software; you can redistribute it and/or
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    12
#modify it under the terms of the GNU General Public
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    13
#License as published by the Free Software Foundation; either
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    14
#version 2.1 of the License, or (at your option) any later version.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    15
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    16
#This library is distributed in the hope that it will be useful,
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    17
#but WITHOUT ANY WARRANTY; without even the implied warranty of
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    18
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    19
#General Public License for more details.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    20
#
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    21
#You should have received a copy of the GNU General Public
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    22
#License along with this library; if not, write to the Free Software
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    23
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    24
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    25
import Pyro.core as pyro
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    26
from threading import Timer, Thread, Lock
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    27
import ctypes, os, commands, types, sys
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    28
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    29
if os.name in ("nt", "ce"):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    30
    from _ctypes import LoadLibrary as dlopen
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    31
    from _ctypes import FreeLibrary as dlclose
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    32
elif os.name == "posix":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    33
    from _ctypes import dlopen, dlclose
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    34
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
    35
import traceback
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    36
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    37
lib_ext ={
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    38
     "linux2":".so",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    39
     "win32":".dll",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    40
     }.get(sys.platform, "")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    41
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    42
def PLCprint(message):
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    43
    sys.stdout.write("PLCobject : "+message+"\n")
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    44
    sys.stdout.flush()
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    45
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    46
class PLCObject(pyro.ObjBase):
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
    47
    _Idxs = []
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
    48
    def __init__(self, workingdir, daemon, argv, statuschange, evaluator):
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    49
        pyro.ObjBase.__init__(self)
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    50
        self.evaluator = evaluator
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    51
        self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    52
        self.workingdir = workingdir
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    53
        self.PLCStatus = "Stopped"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    54
        self.PLClibraryHandle = None
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    55
        self.PLClibraryLock = Lock()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    56
        # Creates fake C funcs proxies
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    57
        self._FreePLC()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    58
        self.daemon = daemon
269
d29c5f71574f add a TaskBarIcon to configure beremiz_service and display plc states (started, stopped)
greg
parents: 239
diff changeset
    59
        self.statuschange = statuschange
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
    60
        self.hmi_frame = None
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    61
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    62
        # Get the last transfered PLC if connector must be restart
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    63
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    64
            self.CurrentPLCFilename=open(
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    65
                             self._GetMD5FileName(),
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    66
                             "r").read().strip() + lib_ext
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    67
        except Exception, e:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    68
            self.PLCStatus = "Empty"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    69
            self.CurrentPLCFilename=None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    70
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    71
    def StatusChange(self):
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    72
        if self.statuschange is not None:
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    73
            self.statuschange(self.PLCStatus)
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
    74
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    75
    def _GetMD5FileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    76
        return os.path.join(self.workingdir, "lasttransferedPLC.md5")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    77
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    78
    def _GetLibFileName(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    79
        return os.path.join(self.workingdir,self.CurrentPLCFilename)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    80
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    81
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    82
    def _LoadNewPLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    83
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    84
        Load PLC library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    85
        Declare all functions, arguments and return values
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    86
        """
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
    87
        PLCprint("Load PLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    88
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    89
            self._PLClibraryHandle = dlopen(self._GetLibFileName())
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    90
            self.PLClibraryHandle = ctypes.CDLL(self.CurrentPLCFilename, handle=self._PLClibraryHandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    91
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    92
            self._startPLC = self.PLClibraryHandle.startPLC
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    93
            self._startPLC.restype = ctypes.c_int
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    94
            self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
    95
            
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    96
            def StopPLCLock():
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    97
                self.PLClibraryLock.acquire()
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    98
                self.PLClibraryHandle.stopPLC()
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
    99
                self.PLClibraryLock.release()
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   100
            
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   101
            self._stopPLC = StopPLCLock
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   102
            self._stopPLC.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   103
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   104
            self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   105
            self._ResetDebugVariables.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   106
    
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   107
            self._RegisterDebugVariable = self.PLClibraryHandle.RegisterDebugVariable
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   108
            self._RegisterDebugVariable.restype = None
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   109
            self._RegisterDebugVariable.argtypes = [ctypes.c_int]
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   110
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   111
            self._IterDebugData = self.PLClibraryHandle.IterDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   112
            self._IterDebugData.restype = ctypes.c_void_p
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   113
            self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   114
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   115
            self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   116
            self._FreeDebugData.restype = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   117
            
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   118
            self._WaitDebugData = self.PLClibraryHandle.WaitDebugData
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   119
            self._WaitDebugData.restype = ctypes.c_int  
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   120
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   121
            self._suspendDebug = self.PLClibraryHandle.suspendDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   122
            self._suspendDebug.restype = None
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   123
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   124
            self._resumeDebug = self.PLClibraryHandle.resumeDebug
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   125
            self._resumeDebug.restype = None
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   126
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   127
            self._PythonIterator = self.PLClibraryHandle.PythonIterator
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   128
            self._PythonIterator.restype = ctypes.c_char_p
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   129
            self._PythonIterator.argtypes = [ctypes.c_char_p]
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   130
            
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   131
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   132
        except:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   133
            PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   134
            return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   135
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   136
    def _FreePLC(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   137
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   138
        Unload PLC library.
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   139
        This is also called by __init__ to create dummy C func proxies
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   140
        """
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   141
        self.PLClibraryLock.acquire()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   142
        # Forget all refs to library
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   143
        self._startPLC = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   144
        self._stopPLC = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   145
        self._ResetDebugVariables = lambda:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   146
        self._RegisterDebugVariable = lambda x:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   147
        self._IterDebugData = lambda x,y:None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   148
        self._FreeDebugData = lambda:None
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   149
        self._WaitDebugData = lambda:-1
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   150
        self._suspendDebug = lambda:None
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   151
        self._resumeDebug = lambda:None
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   152
        self._PythonIterator = lambda:""
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   153
        self.PLClibraryHandle = None
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   154
        # Unload library explicitely
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   155
        if getattr(self,"_PLClibraryHandle",None) is not None:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   156
            PLCprint("Unload PLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   157
            dlclose(self._PLClibraryHandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   158
            res = self._DetectDirtyLibs()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   159
        else:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   160
            res = False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   161
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   162
        self._PLClibraryHandle = None
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   163
        self.PLClibraryLock.release()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   164
        return res
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   165
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   166
    def _DetectDirtyLibs(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   167
        # Detect dirty libs
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   168
        # Get lib dependencies (for dirty lib detection)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   169
        if os.name == "posix":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   170
            # parasiting libs listed with ldd
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   171
            badlibs = [ toks.split()[0] for toks in commands.getoutput(
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   172
                            "ldd "+self._GetLibFileName()).splitlines() ]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   173
            for badlib in badlibs:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   174
                if badlib[:6] in ["libwx_",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   175
                                  "libwxs",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   176
                                  "libgtk",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   177
                                  "libgdk",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   178
                                  "libatk",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   179
                                  "libpan",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   180
                                  "libX11",
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   181
                                  ]:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   182
                    #badhandle = dlopen(badlib, dl.RTLD_NOLOAD)
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   183
                    PLCprint("Dirty lib detected :" + badlib)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   184
                    #dlclose(badhandle)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   185
                    return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   186
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   187
299
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   188
    def PrepareRuntimePy(self):
290
3bd617ae7a05 Local Runtime (LOCAL://) now launched "on demand"
etisserant
parents: 286
diff changeset
   189
        self.python_threads_vars = globals().copy()
344
25b7b7f854bc Wait the debug thread has terminated before freeing PLC to avoid random segmentation fault.
greg
parents: 339
diff changeset
   190
        self.python_threads_vars["WorkingDir"] = self.workingdir
283
d0e6fc0701fb Added "runtime.py", a file that is executed in python thread in runtime, before handling python_eval FBs requests. Added small python editor taken from wxPython demo, and appropriate icon and button to launch it.
etisserant
parents: 280
diff changeset
   191
        pyfile = os.path.join(self.workingdir, "runtime.py")
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
   192
        hmifile = os.path.join(self.workingdir, "hmi.py")
322
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   193
        if os.path.exists(hmifile):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   194
            try:
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   195
                execfile(hmifile, self.python_threads_vars)
332
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   196
                if os.path.exists(pyfile):
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   197
                    try:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   198
                        # TODO handle exceptions in runtime.py
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   199
                        # pyfile may redefine _runtime_cleanup
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   200
                        # or even call _PythonThreadProc itself.
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   201
                        execfile(pyfile, self.python_threads_vars)
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   202
                    except:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   203
                        PLCprint(traceback.format_exc())
322
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   204
                if self.python_threads_vars.has_key('wx'):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   205
                    wx = self.python_threads_vars['wx']
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   206
                    # try to instanciate the first frame found.
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   207
                    for name, obj in self.python_threads_vars.iteritems():
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   208
                        # obj is a class
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   209
                        if type(obj)==type(type) and issubclass(obj,wx.Frame):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   210
                            def create_frame():
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   211
                                self.hmi_frame = obj(None)
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   212
                                self.python_threads_vars[name] = self.hmi_frame
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   213
                                # keep track of class... never know
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   214
                                self.python_threads_vars['Class_'+name] = obj
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   215
                                self.hmi_frame.Bind(wx.EVT_CLOSE, OnCloseFrame)
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   216
                                self.hmi_frame.Show()
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   217
                            
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   218
                            def OnCloseFrame(evt):
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   219
                                wx.MessageBox("Please stop PLC to close")
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   220
                            create_frame()
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   221
                            break
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   222
            except:
b8ae0580565c Make 'runtime.py' and 'hmi.py' executed independantly
lbessard
parents: 319
diff changeset
   223
                PLCprint(traceback.format_exc())
332
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   224
        elif os.path.exists(pyfile):
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   225
            try:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   226
                # TODO handle exceptions in runtime.py
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   227
                # pyfile may redefine _runtime_cleanup
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   228
                # or even call _PythonThreadProc itself.
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   229
                execfile(pyfile, self.python_threads_vars)
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   230
            except:
4f0e1d66bba5 add utf-8 and save shortcut support in PythonST
greg
parents: 331
diff changeset
   231
                PLCprint(traceback.format_exc())
299
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   232
        runtime_begin = self.python_threads_vars.get("_runtime_begin",None)
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   233
        if runtime_begin is not None:
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   234
            runtime_begin()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   235
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   236
    def FinishRuntimePy(self):
336
ae3488c79283 Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
greg
parents: 332
diff changeset
   237
        runtime_cleanup = None
ae3488c79283 Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
greg
parents: 332
diff changeset
   238
        if self.python_threads_vars is not None:
ae3488c79283 Fixed bug : Segmentation fault or locks when stop PLC if no CAN network.
greg
parents: 332
diff changeset
   239
            runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
299
d7f8ffe18017 Enhanced the way "runtime.py" is executed,
etisserant
parents: 291
diff changeset
   240
        if runtime_cleanup is not None:
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   241
            runtime_cleanup()
301
87c925eaaa3a Added support for wxglade GUIs.
etisserant
parents: 299
diff changeset
   242
        if self.hmi_frame is not None:
329
22e65b8e20f4 add autostart plc feature for beremiz_service
greg
parents: 327
diff changeset
   243
            self.hmi_frame.Destroy()
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   244
        self.python_threads_vars = None
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   245
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   246
    def PythonThreadProc(self, debug):
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   247
        PLCprint("PythonThreadProc started")
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   248
        c_argv = ctypes.c_char_p * len(self.argv)
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   249
        error = None
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   250
        if self._LoadNewPLC():
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   251
            if self._startPLC(len(self.argv),c_argv(*self.argv)) == 0:
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   252
                if debug:
327
e82c422ad811 Register the current watched variable in Debug Window before starting
lbessard
parents: 322
diff changeset
   253
                    for idx in self._Idxs:
e82c422ad811 Register the current watched variable in Debug Window before starting
lbessard
parents: 322
diff changeset
   254
                        self._RegisterDebugVariable(idx)
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   255
                    self._resumeDebug()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   256
                self.PLCStatus = "Started"
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   257
                self.StatusChange()
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   258
                self.evaluator(self.PrepareRuntimePy)
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   259
                res,cmd = "None","None"
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   260
                while True:
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   261
                    #print "_PythonIterator(", res, ")",
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   262
                    cmd = self._PythonIterator(res)
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   263
                    #print " -> ", cmd
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   264
                    if cmd is None:
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   265
                        break
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   266
                    try :
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   267
                        res = str(self.evaluator(eval,cmd,self.python_threads_vars))
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   268
                    except Exception,e:
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   269
                        res = "#EXCEPTION : "+str(e)
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   270
                        PLCprint(res)
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   271
                self.PLCStatus = "Stopped"
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   272
                self.StatusChange()
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   273
                self.evaluator(self.FinishRuntimePy)
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   274
            else:
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   275
                error = "starting"
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   276
        else:
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   277
            error = "loading"
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   278
        if error is not None:
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   279
            PLCprint("Problem %s PLC"%error)
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   280
            self.PLCStatus = "Broken"
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   281
        self._FreePLC()
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   282
        PLCprint("PythonThreadProc interrupted")
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   283
    
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   284
    def StartPLC(self, debug=False):
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   285
        PLCprint("StartPLC")
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   286
        if self.CurrentPLCFilename is not None:
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   287
            self.PythonThread = Thread(target=self.PythonThreadProc, args=[debug])
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   288
            self.PythonThread.start()
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   289
            
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   290
    def StopPLC(self):
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   291
        PLCprint("StopPLC")
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   292
        if self.PLCStatus == "Started":
352
81777d4e379c fixed bug : Lock _FreePLC until _stopPLC finish
greg
parents: 350
diff changeset
   293
            self._stopPLC()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   294
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   295
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   296
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   297
    def _Reload(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   298
        self.daemon.shutdown(True)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   299
        self.daemon.sock.close()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   300
        os.execv(sys.executable,[sys.executable]+sys.argv[:])
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   301
        # never reached
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   302
        return 0
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   303
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   304
    def ForceReload(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   305
        # respawn python interpreter
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   306
        Timer(0.1,self._Reload).start()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   307
        return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   308
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   309
    def GetPLCstatus(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   310
        return self.PLCStatus
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   311
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   312
    def NewPLC(self, md5sum, data, extrafiles):
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   313
        PLCprint("NewPLC (%s)"%md5sum)
350
a3a5561bde1d - now call load, start, free PLC from the python Thread
greg
parents: 344
diff changeset
   314
        if self.PLCStatus in ["Stopped", "Empty", "Dirty", "Broken"]:
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   315
            NewFileName = md5sum + lib_ext
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   316
            extra_files_log = os.path.join(self.workingdir,"extra_files.txt")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   317
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   318
                os.remove(os.path.join(self.workingdir,
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   319
                                       self.CurrentPLCFilename))
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   320
                for filename in file(extra_files_log, "r").readlines() + extra_files_log:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   321
                    try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   322
                        os.remove(os.path.join(self.workingdir, filename))
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   323
                    except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   324
                        pass
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   325
            except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   326
                pass
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   327
                        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   328
            try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   329
                # Create new PLC file
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   330
                open(os.path.join(self.workingdir,NewFileName),
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   331
                     'wb').write(data)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   332
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   333
                # Store new PLC filename based on md5 key
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   334
                open(self._GetMD5FileName(), "w").write(md5sum)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   335
        
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   336
                # Then write the files
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   337
                log = file(extra_files_log, "w")
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   338
                for fname,fdata in extrafiles:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   339
                    fpath = os.path.join(self.workingdir,fname)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   340
                    open(fpath, "wb").write(fdata)
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   341
                    log.write(fname+'\n')
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   342
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   343
                # Store new PLC filename
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   344
                self.CurrentPLCFilename = NewFileName
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   345
            except:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   346
                PLCprint(traceback.format_exc())
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   347
                return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   348
            if self.PLCStatus == "Empty":
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   349
                self.PLCStatus = "Stopped"
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   350
            return True
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   351
        return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   352
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   353
    def MatchMD5(self, MD5):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   354
        try:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   355
            last_md5 = open(self._GetMD5FileName(), "r").read()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   356
            return last_md5 == MD5
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   357
        except:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   358
            return False
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   359
    
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   360
    def SetTraceVariablesList(self, idxs):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   361
        """
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   362
        Call ctype imported function to append 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   363
        these indexes to registred variables in PLC debugger
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   364
        """
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   365
        self._suspendDebug()
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   366
        # keep a copy of requested idx
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   367
        self._Idxs = idxs[:]
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   368
        self._ResetDebugVariables()
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   369
        for idx in idxs:
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   370
            self._RegisterDebugVariable(idx)
235
a66e150f2888 Improved debug data feedback.
etisserant
parents: 229
diff changeset
   371
        self._resumeDebug()
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   372
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   373
    class IEC_STRING(ctypes.Structure):
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   374
        """
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   375
        Must be changed according to changes in iec_types.h
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   376
        """
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   377
        _fields_ = [("len", ctypes.c_uint8),
302
d962b3d503b5 Enhanced wxGlade GUI creation.
etisserant
parents: 301
diff changeset
   378
                    ("body", ctypes.c_char * 127)] 
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   379
    
238
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   380
    TypeTranslator = {"BOOL" :       (ctypes.c_uint8, lambda x:x.value!=0),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   381
                      "STEP" :       (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   382
                      "TRANSITION" : (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   383
                      "ACTION" :     (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   384
                      "SINT" :       (ctypes.c_int8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   385
                      "USINT" :      (ctypes.c_uint8, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   386
                      "BYTE" :       (ctypes.c_uint8, lambda x:x.value),
280
f2ef79f3dba0 Added native (not a plugin) asynchronous python eval function block - Beta. Code cleanup in C code templates.
etisserant
parents: 269
diff changeset
   387
                      "STRING" :     (IEC_STRING, lambda x:x.body[:x.len]),
238
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   388
                      "INT" :        (ctypes.c_int16, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   389
                      "UINT" :       (ctypes.c_uint16, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   390
                      "WORD" :       (ctypes.c_uint16, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   391
                      "WSTRING" :    (None, None),#TODO
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   392
                      "DINT" :       (ctypes.c_int32, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   393
                      "UDINT" :      (ctypes.c_uint32, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   394
                      "DWORD" :      (ctypes.c_uint32, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   395
                      "LINT" :       (ctypes.c_int64, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   396
                      "ULINT" :      (ctypes.c_uint64, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   397
                      "LWORD" :      (ctypes.c_uint64, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   398
                      "REAL" :       (ctypes.c_float, lambda x:x.value),
02d0daed3e46 Debugger now reports BOOL as booleans
etisserant
parents: 237
diff changeset
   399
                      "LREAL" :      (ctypes.c_double, lambda x:x.value),
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   400
                      } 
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   401
                           
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   402
    def GetTraceVariables(self):
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   403
        """
339
6dbde4a0c31d Adding support for updating PLC status when stopping
greg
parents: 336
diff changeset
   404
        Return a list of variables, corresponding to the list of required idx
229
8bc65076e290 add tests for win32
greg
parents: 227
diff changeset
   405
        """
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   406
        if self.PLCStatus == "Started":
353
c68fc75ebb06 Adding Lock around C code called by Debug thread
greg
parents: 352
diff changeset
   407
            self.PLClibraryLock.acquire()
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   408
            tick = self._WaitDebugData()
353
c68fc75ebb06 Adding Lock around C code called by Debug thread
greg
parents: 352
diff changeset
   409
            #PLCprint("Debug tick : %d"%tick)
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   410
            if tick == -1:
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   411
                res = None
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   412
            else:
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   413
                idx = ctypes.c_int()
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   414
                typename = ctypes.c_char_p()
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   415
                res = []
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   416
        
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   417
                for given_idx in self._Idxs:
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   418
                    buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   419
                    c_type,unpack_func = self.TypeTranslator.get(typename.value, (None,None))
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   420
                    if c_type is not None and given_idx == idx.value:
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   421
                        res.append(unpack_func(ctypes.cast(buffer,
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   422
                                                           ctypes.POINTER(c_type)).contents))
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   423
                    else:
291
701c0601db02 Added systematic stdout.flush runtime side, so that results appear in log window
etisserant
parents: 290
diff changeset
   424
                        PLCprint("Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value))
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   425
                        res.append(None)
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   426
            self._FreeDebugData()
353
c68fc75ebb06 Adding Lock around C code called by Debug thread
greg
parents: 352
diff changeset
   427
            self.PLClibraryLock.release()
286
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   428
            return tick, res
a2a8a52b0d4f Minor changes to get better cleanup of debug and python_eval threads, accross multiple debug sessions and PLC runs.
etisserant
parents: 283
diff changeset
   429
        return -1, None
353
c68fc75ebb06 Adding Lock around C code called by Debug thread
greg
parents: 352
diff changeset
   430