runtime/PLCObject.py
changeset 1742 92932cd370a4
parent 1741 dd94b9a68c61
child 1743 c3c3d1318130
equal deleted inserted replaced
1741:dd94b9a68c61 1742:92932cd370a4
    44 def get_last_traceback(tb):
    44 def get_last_traceback(tb):
    45     while tb.tb_next:
    45     while tb.tb_next:
    46         tb = tb.tb_next
    46         tb = tb.tb_next
    47     return tb
    47     return tb
    48 
    48 
    49 lib_ext ={
    49 lib_ext = {
    50      "linux2": ".so",
    50      "linux2": ".so",
    51      "win32":  ".dll",
    51      "win32":  ".dll",
    52      }.get(sys.platform, "")
    52      }.get(sys.platform, "")
    53 
    53 
    54 
    54 
    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)