runtime/PLCObject.py
changeset 366 cd90e4c10261
parent 365 a7f58414dea0
child 368 86ecd8374dae
equal deleted inserted replaced
365:a7f58414dea0 366:cd90e4c10261
    51         self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
    51         self.argv = [workingdir] + argv # force argv[0] to be "path" to exec...
    52         self.workingdir = workingdir
    52         self.workingdir = workingdir
    53         self.PLCStatus = "Stopped"
    53         self.PLCStatus = "Stopped"
    54         self.PLClibraryHandle = None
    54         self.PLClibraryHandle = None
    55         self.PLClibraryLock = Lock()
    55         self.PLClibraryLock = Lock()
       
    56         self.DummyIteratorLock = None
    56         # Creates fake C funcs proxies
    57         # Creates fake C funcs proxies
    57         self._FreePLC()
    58         self._FreePLC()
    58         self.daemon = daemon
    59         self.daemon = daemon
    59         self.statuschange = statuschange
    60         self.statuschange = statuschange
    60         self.hmi_frame = None
    61         self.hmi_frame = None
    91     
    92     
    92             self._startPLC = self.PLClibraryHandle.startPLC
    93             self._startPLC = self.PLClibraryHandle.startPLC
    93             self._startPLC.restype = ctypes.c_int
    94             self._startPLC.restype = ctypes.c_int
    94             self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
    95             self._startPLC.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)]
    95             
    96             
    96             def StopPLCLock():
    97             self.DummyIteratorLock = Lock()
    97                 self.PLClibraryLock.acquire()
    98             self.DummyIteratorLock.acquire()
    98                 self.PLClibraryHandle.stopPLC()
    99             
    99                 self.PLClibraryLock.release()
   100             self._PythonIterator = getattr(self.PLClibraryHandle, "PythonIterator", None)
       
   101             if self._PythonIterator is not None:
       
   102                 self._PythonIterator.restype = ctypes.c_char_p
       
   103                 self._PythonIterator.argtypes = [ctypes.c_char_p]
       
   104                 
       
   105                 def StopPLCLock():
       
   106                     self.PLClibraryLock.acquire()
       
   107                     self.PLClibraryHandle.stopPLC()
       
   108                     self.PLClibraryLock.release()
       
   109                 
       
   110             else:
       
   111                 def DummyIterator(res):
       
   112                     self.DummyIteratorLock.acquire()
       
   113                     return None
       
   114                 self._PythonIterator = DummyIterator
       
   115                 
       
   116                 def StopPLCLock():
       
   117                     self.PLClibraryLock.acquire()
       
   118                     self.PLClibraryHandle.stopPLC()
       
   119                     self.DummyIteratorLock.release()
       
   120                     self.PLClibraryLock.release()
   100             
   121             
   101             self._stopPLC = StopPLCLock
   122             self._stopPLC = StopPLCLock
   102             self._stopPLC.restype = None
   123             self._stopPLC.restype = None
   103     
   124     
   104             self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
   125             self._ResetDebugVariables = self.PLClibraryHandle.ResetDebugVariables
   121             self._suspendDebug = self.PLClibraryHandle.suspendDebug
   142             self._suspendDebug = self.PLClibraryHandle.suspendDebug
   122             self._suspendDebug.restype = None
   143             self._suspendDebug.restype = None
   123 
   144 
   124             self._resumeDebug = self.PLClibraryHandle.resumeDebug
   145             self._resumeDebug = self.PLClibraryHandle.resumeDebug
   125             self._resumeDebug.restype = None
   146             self._resumeDebug.restype = None
   126 
       
   127             self._PythonIterator = self.PLClibraryHandle.PythonIterator
       
   128             self._PythonIterator.restype = ctypes.c_char_p
       
   129             self._PythonIterator.argtypes = [ctypes.c_char_p]
       
   130             
   147             
   131             return True
   148             return True
   132         except:
   149         except:
   133             PLCprint(traceback.format_exc())
   150             PLCprint(traceback.format_exc())
   134             return False
   151             return False
   186         return False
   203         return False
   187 
   204 
   188     def PrepareRuntimePy(self):
   205     def PrepareRuntimePy(self):
   189         self.python_threads_vars = globals().copy()
   206         self.python_threads_vars = globals().copy()
   190         self.python_threads_vars["WorkingDir"] = self.workingdir
   207         self.python_threads_vars["WorkingDir"] = self.workingdir
   191         pyfile = os.path.join(self.workingdir, "runtime.py")
   208         self.python_threads_vars["_runtime_begin"] = []
   192         hmifile = os.path.join(self.workingdir, "hmi.py")
   209         self.python_threads_vars["_runtime_cleanup"] = []
   193         if os.path.exists(hmifile):
   210 #        pyfile = os.path.join(self.workingdir, "runtime.py")
   194             try:
   211 #        hmifile = os.path.join(self.workingdir, "hmi.py")
   195                 execfile(hmifile, self.python_threads_vars)
   212 #        if os.path.exists(hmifile):
   196                 if os.path.exists(pyfile):
   213 #            try:
   197                     try:
   214 #                execfile(hmifile, self.python_threads_vars)
   198                         # TODO handle exceptions in runtime.py
   215 #                if os.path.exists(pyfile):
   199                         # pyfile may redefine _runtime_cleanup
   216 #                    try:
   200                         # or even call _PythonThreadProc itself.
   217 #                        # TODO handle exceptions in runtime.py
   201                         execfile(pyfile, self.python_threads_vars)
   218 #                        # pyfile may redefine _runtime_cleanup
   202                     except:
   219 #                        # or even call _PythonThreadProc itself.
   203                         PLCprint(traceback.format_exc())
   220 #                        execfile(pyfile, self.python_threads_vars)
   204                 if self.python_threads_vars.has_key('wx'):
   221 #                    except:
   205                     wx = self.python_threads_vars['wx']
   222 #                        PLCprint(traceback.format_exc())
   206                     # try to instanciate the first frame found.
   223 #                if self.python_threads_vars.has_key('wx'):
   207                     for name, obj in self.python_threads_vars.iteritems():
   224 #                    wx = self.python_threads_vars['wx']
   208                         # obj is a class
   225 #                    # try to instanciate the first frame found.
   209                         if type(obj)==type(type) and issubclass(obj,wx.Frame):
   226 #                    for name, obj in self.python_threads_vars.iteritems():
   210                             def create_frame():
   227 #                        # obj is a class
   211                                 self.hmi_frame = obj(None)
   228 #                        if type(obj)==type(type) and issubclass(obj,wx.Frame):
   212                                 self.python_threads_vars[name] = self.hmi_frame
   229 #                            def create_frame():
   213                                 # keep track of class... never know
   230 #                                self.hmi_frame = obj(None)
   214                                 self.python_threads_vars['Class_'+name] = obj
   231 #                                self.python_threads_vars[name] = self.hmi_frame
   215                                 self.hmi_frame.Bind(wx.EVT_CLOSE, OnCloseFrame)
   232 #                                # keep track of class... never know
   216                                 self.hmi_frame.Show()
   233 #                                self.python_threads_vars['Class_'+name] = obj
   217                             
   234 #                                self.hmi_frame.Bind(wx.EVT_CLOSE, OnCloseFrame)
   218                             def OnCloseFrame(evt):
   235 #                                self.hmi_frame.Show()
   219                                 wx.MessageBox(_("Please stop PLC to close"))
   236 #                            
   220                             create_frame()
   237 #                            def OnCloseFrame(evt):
   221                             break
   238 #                                wx.MessageBox(_("Please stop PLC to close"))
   222             except:
   239 #                            create_frame()
   223                 PLCprint(traceback.format_exc())
   240 #                            break
   224         elif os.path.exists(pyfile):
   241 #            except:
   225             try:
   242 #                PLCprint(traceback.format_exc())
   226                 # TODO handle exceptions in runtime.py
   243 #        elif os.path.exists(pyfile):
   227                 # pyfile may redefine _runtime_cleanup
   244 #            try:
   228                 # or even call _PythonThreadProc itself.
   245 #                # TODO handle exceptions in runtime.py
   229                 execfile(pyfile, self.python_threads_vars)
   246 #                # pyfile may redefine _runtime_cleanup
   230             except:
   247 #                # or even call _PythonThreadProc itself.
   231                 PLCprint(traceback.format_exc())
   248 #                execfile(pyfile, self.python_threads_vars)
   232         runtime_begin = self.python_threads_vars.get("_runtime_begin",None)
   249 #            except:
   233         if runtime_begin is not None:
   250 #                PLCprint(traceback.format_exc())
       
   251         for filename in os.listdir(self.workingdir):
       
   252             name, ext = os.path.splitext(filename)
       
   253             if name.startswith("runtime") and ext == ".py":
       
   254                 try:
       
   255                     # TODO handle exceptions in runtime.py
       
   256                     # pyfile may redefine _runtime_cleanup
       
   257                     # or even call _PythonThreadProc itself.
       
   258                     execfile(os.path.join(self.workingdir, filename), self.python_threads_vars)
       
   259                 except:
       
   260                     PLCprint(traceback.format_exc())
       
   261                 runtime_begin = self.python_threads_vars.get("_%s_begin" % name, None)
       
   262                 if runtime_begin is not None:
       
   263                     self.python_threads_vars["_runtime_begin"].append(runtime_begin)
       
   264                 runtime_cleanup = self.python_threads_vars.get("_%s_cleanup" % name, None)
       
   265                 if runtime_cleanup is not None:
       
   266                     self.python_threads_vars["_runtime_cleanup"].append(runtime_cleanup)
       
   267         
       
   268         for runtime_begin in self.python_threads_vars.get("_runtime_begin", []):
   234             runtime_begin()
   269             runtime_begin()
   235 
   270 
   236     def FinishRuntimePy(self):
   271     def FinishRuntimePy(self):
   237         runtime_cleanup = None
   272         for runtime_cleanup in self.python_threads_vars.get("_runtime_cleanup", []):
   238         if self.python_threads_vars is not None:
   273             runtime_cleanup()    
   239             runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
   274 #        if self.python_threads_vars is not None:
   240         if runtime_cleanup is not None:
   275 #            runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None)
   241             runtime_cleanup()
   276 #        if runtime_cleanup is not None:
   242         if self.hmi_frame is not None:
   277 #            runtime_cleanup()
   243             self.hmi_frame.Destroy()
   278 #        if self.hmi_frame is not None:
       
   279 #            self.hmi_frame.Destroy()
   244         self.python_threads_vars = None
   280         self.python_threads_vars = None
   245 
   281 
   246     def PythonThreadProc(self, debug):
   282     def PythonThreadProc(self, debug):
   247         PLCprint("PythonThreadProc started")
   283         PLCprint("PythonThreadProc started")
   248         c_argv = ctypes.c_char_p * len(self.argv)
   284         c_argv = ctypes.c_char_p * len(self.argv)