81 self.Traces = [] |
81 self.Traces = [] |
82 |
82 |
83 def AutoLoad(self): |
83 def AutoLoad(self): |
84 # Get the last transfered PLC if connector must be restart |
84 # Get the last transfered PLC if connector must be restart |
85 try: |
85 try: |
86 self.CurrentPLCFilename=open( |
86 self.CurrentPLCFilename = open( |
87 self._GetMD5FileName(), |
87 self._GetMD5FileName(), |
88 "r").read().strip() + lib_ext |
88 "r").read().strip() + lib_ext |
89 if self.LoadPLC(): |
89 if self.LoadPLC(): |
90 self.PLCStatus = "Stopped" |
90 self.PLCStatus = "Stopped" |
91 except Exception, e: |
91 except Exception, e: |
92 self.PLCStatus = "Empty" |
92 self.PLCStatus = "Empty" |
93 self.CurrentPLCFilename=None |
93 self.CurrentPLCFilename = None |
94 |
94 |
95 def StatusChange(self): |
95 def StatusChange(self): |
96 if self.statuschange is not None: |
96 if self.statuschange is not None: |
97 for callee in self.statuschange: |
97 for callee in self.statuschange: |
98 callee(self.PLCStatus) |
98 callee(self.PLCStatus) |
110 self._ResetLogCount() |
110 self._ResetLogCount() |
111 |
111 |
112 def GetLogCount(self, level): |
112 def GetLogCount(self, level): |
113 if self._GetLogCount is not None: |
113 if self._GetLogCount is not None: |
114 return int(self._GetLogCount(level)) |
114 return int(self._GetLogCount(level)) |
115 elif self._loading_error is not None and level==0: |
115 elif self._loading_error is not None and level == 0: |
116 return 1 |
116 return 1 |
117 |
117 |
118 def GetLogMessage(self, level, msgid): |
118 def GetLogMessage(self, level, msgid): |
119 tick = ctypes.c_uint32() |
119 tick = ctypes.c_uint32() |
120 tv_sec = ctypes.c_uint32() |
120 tv_sec = ctypes.c_uint32() |
127 ctypes.byref(tv_sec), |
127 ctypes.byref(tv_sec), |
128 ctypes.byref(tv_nsec)) |
128 ctypes.byref(tv_nsec)) |
129 if sz and sz <= maxsz: |
129 if sz and sz <= maxsz: |
130 self._log_read_buffer[sz] = '\x00' |
130 self._log_read_buffer[sz] = '\x00' |
131 return self._log_read_buffer.value, tick.value, tv_sec.value, tv_nsec.value |
131 return self._log_read_buffer.value, tick.value, tv_sec.value, tv_nsec.value |
132 elif self._loading_error is not None and level==0: |
132 elif self._loading_error is not None and level == 0: |
133 return self._loading_error, 0, 0, 0 |
133 return self._loading_error, 0, 0, 0 |
134 return None |
134 return None |
135 |
135 |
136 def _GetMD5FileName(self): |
136 def _GetMD5FileName(self): |
137 return os.path.join(self.workingdir, "lasttransferedPLC.md5") |
137 return os.path.join(self.workingdir, "lasttransferedPLC.md5") |
327 self.python_runtime_vars = None |
327 self.python_runtime_vars = None |
328 |
328 |
329 def PythonThreadProc(self): |
329 def PythonThreadProc(self): |
330 self.StartSem.release() |
330 self.StartSem.release() |
331 res, cmd, blkid = "None", "None", ctypes.c_void_p() |
331 res, cmd, blkid = "None", "None", ctypes.c_void_p() |
332 compile_cache={} |
332 compile_cache = {} |
333 while True: |
333 while True: |
334 # print "_PythonIterator(", res, ")", |
334 # print "_PythonIterator(", res, ")", |
335 cmd = self._PythonIterator(res, blkid) |
335 cmd = self._PythonIterator(res, blkid) |
336 FBID = blkid.value |
336 FBID = blkid.value |
337 # print " -> ", cmd, blkid |
337 # print " -> ", cmd, blkid |
338 if cmd is None: |
338 if cmd is None: |
339 break |
339 break |
340 try: |
340 try: |
341 self.python_runtime_vars["FBID"]=FBID |
341 self.python_runtime_vars["FBID"] = FBID |
342 ccmd, AST =compile_cache.get(FBID, (None, None)) |
342 ccmd, AST = compile_cache.get(FBID, (None, None)) |
343 if ccmd is None or ccmd!=cmd: |
343 if ccmd is None or ccmd != cmd: |
344 AST = compile(cmd, '<plc>', 'eval') |
344 AST = compile(cmd, '<plc>', 'eval') |
345 compile_cache[FBID]=(cmd, AST) |
345 compile_cache[FBID] = (cmd, AST) |
346 result, exp = self.evaluator(eval, AST, self.python_runtime_vars) |
346 result, exp = self.evaluator(eval, AST, self.python_runtime_vars) |
347 if exp is not None: |
347 if exp is not None: |
348 res = "#EXCEPTION : "+str(exp[1]) |
348 res = "#EXCEPTION : "+str(exp[1]) |
349 self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, |
349 self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, |
350 '\n'.join(traceback.format_exception(*exp)))) |
350 '\n'.join(traceback.format_exception(*exp)))) |
351 else: |
351 else: |
352 res=str(result) |
352 res = str(result) |
353 self.python_runtime_vars["FBID"]=None |
353 self.python_runtime_vars["FBID"] = None |
354 except Exception, e: |
354 except Exception, e: |
355 res = "#EXCEPTION : "+str(e) |
355 res = "#EXCEPTION : "+str(e) |
356 self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, str(e))) |
356 self.LogMessage(1, ('PyEval@0x%x(Code="%s") Exception "%s"') % (FBID, cmd, str(e))) |
357 |
357 |
358 def StartPLC(self): |
358 def StartPLC(self): |
362 res = self._startPLC(len(self.argv), c_argv(*self.argv)) |
362 res = self._startPLC(len(self.argv), c_argv(*self.argv)) |
363 if res == 0: |
363 if res == 0: |
364 self.PLCStatus = "Started" |
364 self.PLCStatus = "Started" |
365 self.StatusChange() |
365 self.StatusChange() |
366 self.PythonRuntimeCall("start") |
366 self.PythonRuntimeCall("start") |
367 self.StartSem=Semaphore(0) |
367 self.StartSem = Semaphore(0) |
368 self.PythonThread = Thread(target=self.PythonThreadProc) |
368 self.PythonThread = Thread(target=self.PythonThreadProc) |
369 self.PythonThread.start() |
369 self.PythonThread.start() |
370 self.StartSem.acquire() |
370 self.StartSem.acquire() |
371 self.LogMessage("PLC started") |
371 self.LogMessage("PLC started") |
372 else: |
372 else: |
475 # suspend but dont disable |
475 # suspend but dont disable |
476 if self._suspendDebug(False) == 0: |
476 if self._suspendDebug(False) == 0: |
477 # keep a copy of requested idx |
477 # keep a copy of requested idx |
478 self._ResetDebugVariables() |
478 self._ResetDebugVariables() |
479 for idx, iectype, force in idxs: |
479 for idx, iectype, force in idxs: |
480 if force !=None: |
480 if force != None: |
481 c_type, unpack_func, pack_func = \ |
481 c_type, unpack_func, pack_func = \ |
482 TypeTranslator.get(iectype, |
482 TypeTranslator.get(iectype, |
483 (None, None, None)) |
483 (None, None, None)) |
484 force = ctypes.byref(pack_func(c_type, force)) |
484 force = ctypes.byref(pack_func(c_type, force)) |
485 self._RegisterDebugVariable(idx, force) |
485 self._RegisterDebugVariable(idx, force) |