44 sys.stdout.write("PLCobject : "+message+"\n") |
44 sys.stdout.write("PLCobject : "+message+"\n") |
45 sys.stdout.flush() |
45 sys.stdout.flush() |
46 |
46 |
47 class PLCObject(pyro.ObjBase): |
47 class PLCObject(pyro.ObjBase): |
48 _Idxs = [] |
48 _Idxs = [] |
49 def __init__(self, workingdir, daemon, argv, statuschange=None, evaluator=eval): |
49 def __init__(self, workingdir, daemon, argv, statuschange, evaluator): |
50 pyro.ObjBase.__init__(self) |
50 pyro.ObjBase.__init__(self) |
51 self.evaluator = evaluator |
51 self.evaluator = evaluator |
52 self.argv = [workingdir] + argv # force argv[0] to be "path" to exec... |
52 self.argv = [workingdir] + argv # force argv[0] to be "path" to exec... |
53 self.workingdir = workingdir |
53 self.workingdir = workingdir |
54 self.PLCStatus = "Stopped" |
54 self.PLCStatus = "Stopped" |
55 self.PLClibraryHandle = None |
55 self.PLClibraryHandle = None |
56 # Creates fake C funcs proxies |
56 # Creates fake C funcs proxies |
57 self._FreePLC() |
57 self._FreePLC() |
58 self.daemon = daemon |
58 self.daemon = daemon |
59 self.statuschange = statuschange |
59 self.statuschange = statuschange |
60 self.python_threads_vars = None |
|
61 self.hmi_frame = None |
60 self.hmi_frame = None |
62 |
61 |
63 # Get the last transfered PLC if connector must be restart |
62 # Get the last transfered PLC if connector must be restart |
64 try: |
63 try: |
65 self.CurrentPLCFilename=open( |
64 self.CurrentPLCFilename=open( |
218 #evt.Skip() |
217 #evt.Skip() |
219 create_frame() |
218 create_frame() |
220 break |
219 break |
221 except: |
220 except: |
222 PLCprint(traceback.format_exc()) |
221 PLCprint(traceback.format_exc()) |
223 |
|
224 def BeginRuntimePy(self): |
|
225 runtime_begin = self.python_threads_vars.get("_runtime_begin",None) |
222 runtime_begin = self.python_threads_vars.get("_runtime_begin",None) |
226 if runtime_begin is not None: |
223 if runtime_begin is not None: |
227 self.evaluator(runtime_begin) |
224 runtime_begin() |
228 |
225 |
229 def FinishRuntimePy(self): |
226 def FinishRuntimePy(self): |
230 runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None) |
227 runtime_cleanup = self.python_threads_vars.get("_runtime_cleanup",None) |
231 if runtime_cleanup is not None: |
228 if runtime_cleanup is not None: |
232 self.evaluator(runtime_cleanup) |
229 runtime_cleanup() |
233 if self.hmi_frame is not None: |
230 if self.hmi_frame is not None: |
234 self.evaluator(self.hmi_frame.Destroy) |
231 self.hmi_frame.Destroy() |
235 self.python_threads_vars = None |
232 self.python_threads_vars = None |
236 |
233 |
237 def PythonThreadProc(self): |
234 def PythonThreadProc(self): |
238 PLCprint("PythonThreadProc started") |
235 PLCprint("PythonThreadProc started") |
239 self.BeginRuntimePy() |
236 self.evaluator(self.PrepareRuntimePy) |
240 res,cmd = "None","None" |
237 res,cmd = "None","None" |
241 while self.PLCStatus == "Started": |
238 while self.PLCStatus == "Started": |
242 #print "_PythonIterator(", res, ")", |
239 #print "_PythonIterator(", res, ")", |
243 cmd = self._PythonIterator(res) |
240 cmd = self._PythonIterator(res) |
244 #print " -> ", cmd |
241 #print " -> ", cmd |
247 try : |
244 try : |
248 res = str(self.evaluator(eval,cmd,self.python_threads_vars)) |
245 res = str(self.evaluator(eval,cmd,self.python_threads_vars)) |
249 except Exception,e: |
246 except Exception,e: |
250 res = "#EXCEPTION : "+str(e) |
247 res = "#EXCEPTION : "+str(e) |
251 PLCprint(res) |
248 PLCprint(res) |
|
249 self.evaluator(self.FinishRuntimePy) |
252 PLCprint("PythonThreadProc interrupted") |
250 PLCprint("PythonThreadProc interrupted") |
253 |
251 |
254 def StartPLC(self, debug=False): |
252 def StartPLC(self, debug=False): |
255 PLCprint("StartPLC") |
253 PLCprint("StartPLC") |
256 if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": |
254 if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": |
260 for idx in self._Idxs: |
258 for idx in self._Idxs: |
261 self._RegisterDebugVariable(idx) |
259 self._RegisterDebugVariable(idx) |
262 self._resumeDebug() |
260 self._resumeDebug() |
263 self.PLCStatus = "Started" |
261 self.PLCStatus = "Started" |
264 self.StatusChange() |
262 self.StatusChange() |
265 self.evaluator(self.PrepareRuntimePy) |
|
266 self.PythonThread = Thread(target=self.PythonThreadProc) |
263 self.PythonThread = Thread(target=self.PythonThreadProc) |
267 self.PythonThread.start() |
264 self.PythonThread.start() |
268 return True |
265 return True |
269 else: |
266 else: |
270 PLCprint("Problem starting PLC") |
267 PLCprint("Problem starting PLC") |
271 self._DoStopPLC() |
268 self._DoStopPLC() |
272 return False |
269 return False |
273 |
270 |
274 def _DoStopPLC(self): |
271 def _DoStopPLC(self): |
|
272 self.PLCStatus = "Stopped" |
275 self._stopPLC() |
273 self._stopPLC() |
276 self.PLCStatus = "Stopped" |
|
277 self.PythonThread.join(timeout=1) |
|
278 if self.PythonThread.isAlive(): |
|
279 PLCprint("Python thread couldn't be killed") |
|
280 self.FinishRuntimePy() |
|
281 if self._FreePLC(): |
274 if self._FreePLC(): |
282 self.PLCStatus = "Dirty" |
275 self.PLCStatus = "Dirty" |
283 self.StatusChange() |
276 self.StatusChange() |
284 return True |
277 return True |
285 |
278 |