runtime/PLCObject.py
changeset 972 659198075ce4
parent 971 c4550f76ae05
child 1011 388777d307de
equal deleted inserted replaced
971:c4550f76ae05 972:659198075ce4
   238         self.python_threads_vars["_runtime_begin"] = []
   238         self.python_threads_vars["_runtime_begin"] = []
   239         self.python_threads_vars["_runtime_cleanup"] = []
   239         self.python_threads_vars["_runtime_cleanup"] = []
   240         self.python_threads_vars["PLCObject"] = self
   240         self.python_threads_vars["PLCObject"] = self
   241         self.python_threads_vars["PLCBinary"] = self.PLClibraryHandle
   241         self.python_threads_vars["PLCBinary"] = self.PLClibraryHandle
   242         
   242         
   243         for filename in os.listdir(self.workingdir):
   243         try:
   244             name, ext = os.path.splitext(filename)
   244             for filename in os.listdir(self.workingdir):
   245             if name.upper().startswith("RUNTIME") and ext.upper() == ".PY":
   245                 name, ext = os.path.splitext(filename)
   246                 try:
   246                 if name.upper().startswith("RUNTIME") and ext.upper() == ".PY":
   247                     # TODO handle exceptions in runtime.py
       
   248                     # pyfile may redefine _runtime_cleanup
       
   249                     # or even call _PythonThreadProc itself.
       
   250                     execfile(os.path.join(self.workingdir, filename), self.python_threads_vars)
   247                     execfile(os.path.join(self.workingdir, filename), self.python_threads_vars)
   251                 except:
   248                     runtime_begin = self.python_threads_vars.get("_%s_begin" % name, None)
   252                     PLCprint(traceback.format_exc())
   249                     if runtime_begin is not None:
   253                 runtime_begin = self.python_threads_vars.get("_%s_begin" % name, None)
   250                         self.python_threads_vars["_runtime_begin"].append(runtime_begin)
   254                 if runtime_begin is not None:
   251                     runtime_cleanup = self.python_threads_vars.get("_%s_cleanup" % name, None)
   255                     self.python_threads_vars["_runtime_begin"].append(runtime_begin)
   252                     if runtime_cleanup is not None:
   256                 runtime_cleanup = self.python_threads_vars.get("_%s_cleanup" % name, None)
   253                         self.python_threads_vars["_runtime_cleanup"].append(runtime_cleanup)
   257                 if runtime_cleanup is not None:
   254             
   258                     self.python_threads_vars["_runtime_cleanup"].append(runtime_cleanup)
   255             for runtime_begin in self.python_threads_vars.get("_runtime_begin", []):
   259         
   256                 runtime_begin()
   260         for runtime_begin in self.python_threads_vars.get("_runtime_begin", []):
   257         except:
   261             runtime_begin()
   258             self.LogMessage(0,traceback.format_exc())
       
   259             raise
   262             
   260             
   263         if self.website is not None:
   261         if self.website is not None:
   264             self.website.PLCStarted()
   262             self.website.PLCStarted()
   265 
   263 
   266     def FinishRuntimePy(self):
   264     def FinishRuntimePy(self):
   272 
   270 
   273     def PythonThreadProc(self):
   271     def PythonThreadProc(self):
   274         self.PLCStatus = "Started"
   272         self.PLCStatus = "Started"
   275         self.StatusChange()
   273         self.StatusChange()
   276         self.StartSem.release()
   274         self.StartSem.release()
   277         self.evaluator(self.PrepareRuntimePy)
   275         res,exp = self.evaluator(self.PrepareRuntimePy)
       
   276         if exp is not None: raise(exp)
   278         res,cmd,blkid = "None","None",ctypes.c_void_p()
   277         res,cmd,blkid = "None","None",ctypes.c_void_p()
   279         compile_cache={}
   278         compile_cache={}
   280         while True:
   279         while True:
   281             # print "_PythonIterator(", res, ")",
   280             # print "_PythonIterator(", res, ")",
   282             cmd = self._PythonIterator(res,blkid)
   281             cmd = self._PythonIterator(res,blkid)
   296                 else:
   295                 else:
   297                     res=str(result)
   296                     res=str(result)
   298                 self.python_threads_vars["FBID"]=None
   297                 self.python_threads_vars["FBID"]=None
   299             except Exception,e:
   298             except Exception,e:
   300                 res = "#EXCEPTION : "+str(e)
   299                 res = "#EXCEPTION : "+str(e)
   301                 PLCprint(('*** Python eval EXCEPTION ***\n'+
   300                 self.LogMessage(1,('PyEval@0x%x(Code="%s") Exception "%s"')%(FBID,cmd,str(e)))
   302                           '| Function Block ID: %d\n'+
       
   303                           '| Command : "%s"\n'+
       
   304                           '| Exception : "%s"')%(FBID,cmd,str(e)))
       
   305         self.PLCStatus = "Stopped"
   301         self.PLCStatus = "Stopped"
   306         self.StatusChange()
   302         self.StatusChange()
   307         self.evaluator(self.FinishRuntimePy)
   303         exp,res = self.evaluator(self.FinishRuntimePy)
       
   304         if exp is not None: raise(exp)
   308     
   305     
   309     def StartPLC(self):
   306     def StartPLC(self):
   310         if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
   307         if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped":
   311             c_argv = ctypes.c_char_p * len(self.argv)
   308             c_argv = ctypes.c_char_p * len(self.argv)
   312             error = None
   309             error = None
   316                 self.PythonThread = Thread(target=self.PythonThreadProc)
   313                 self.PythonThread = Thread(target=self.PythonThreadProc)
   317                 self.PythonThread.start()
   314                 self.PythonThread.start()
   318                 self.StartSem.acquire()
   315                 self.StartSem.acquire()
   319                 self.LogMessage("PLC started")
   316                 self.LogMessage("PLC started")
   320             else:
   317             else:
   321                 self.LogMessage(_("Problem starting PLC : error %d" % res))
   318                 self.LogMessage(0,_("Problem starting PLC : error %d" % res))
   322                 self.PLCStatus = "Broken"
   319                 self.PLCStatus = "Broken"
   323                 self.StatusChange()
   320                 self.StatusChange()
   324             
   321             
   325     def StopPLC(self):
   322     def StopPLC(self):
   326         if self.PLCStatus == "Started":
   323         if self.PLCStatus == "Started":