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": |