# HG changeset patch # User greg # Date 1243510829 -7200 # Node ID a3a5561bde1d81f410696999d5741552e0c5888b # Parent 24d4e48714edb523dc745f499b7952d14c954ad5 - now call load, start, free PLC from the python Thread - add a wx timer (500ms) that pull the plc state to refresh Beremiz icons (fix problem when command PLC with the TaskBar icon) diff -r 24d4e48714ed -r a3a5561bde1d plugger.py --- a/plugger.py Thu May 28 13:29:23 2009 +0200 +++ b/plugger.py Thu May 28 13:40:29 2009 +0200 @@ -708,12 +708,17 @@ self.DebugTimer=None self.ResetIECProgramsAndVariables() + # Timer to pull PLC status + ID_STATUSTIMER = wx.NewId() + self.StatusTimer = wx.Timer(self.AppFrame, ID_STATUSTIMER) + self.AppFrame.Bind(wx.EVT_TIMER, self.PullPLCStatusProc, self.StatusTimer) + #This method are not called here... but in NewProject and OpenProject #self._AddParamsMembers() #self.PluggedChilds = {} # In both new or load scenario, no need to save - self.ChangesToSave = False + self.ChangesToSave = False # root have no parent self.PlugParent = None # Keep track of the plugin type name @@ -725,6 +730,9 @@ self.PLCDebug = None self.DebugThread = None self.debug_break = False + self.previous_plcstate = None + self.StatusPrint = {"Broken": self.logger.write_error, + None: lambda x: None} # copy PluginMethods so that it can be later customized self.PluginMethods = [dic.copy() for dic in self.PluginMethods] self.LoadSTLibrary() @@ -1399,7 +1407,6 @@ # TODO : use explicit status instead of boolean if self._connector is not None: status = self._connector.GetPLCstatus() - self.logger.write("PLC is %s\n"%status) else: status = "Disconnected" for args in { @@ -1415,20 +1422,28 @@ "Dirty": [("_Run", True), ("_Debug", True), ("_Stop", False)], + "Broken": [("_Run", True), + ("_Debug", True), + ("_Stop", False)], "Disconnected": [("_Run", False), ("_Debug", False), ("_Stop", False)], }.get(status,[]): self.ShowMethod(*args) - + return status + + def PullPLCStatusProc(self, event): + current_status = self.UpdateMethodsFromPLCStatus() + if current_status != self.previous_plcstate: + self.previous_plcstate = current_status + self.StatusPrint.get(current_status, self.logger.write)("PLC is %s\n"%current_status) + self.AppFrame.RefreshAll() + def _Run(self): """ Start PLC """ - if self._connector.StartPLC(): - self.logger.write("Starting PLC\n") - else: - self.logger.write_error("Couldn't start PLC !\n") + self._connector.StartPLC() self.UpdateMethodsFromPLCStatus() def RegisterDebugVarToConnector(self): @@ -1569,8 +1584,8 @@ """ Start PLC (Debug Mode) """ - if self.GetIECProgramsAndVariables() and \ - self._connector.StartPLC(debug=True): + if self.GetIECProgramsAndVariables(): + self._connector.StartPLC(debug=True) self.logger.write("Starting PLC (debug mode)\n") if self.PLCDebug is None: self.RefreshPluginsBlockLists() @@ -1613,9 +1628,7 @@ self.logger.write("Stopping debug\n") self.KillDebugThread() - if self._connector.StopPLC(): - self.logger.write("Stopping PLC\n") - else: + if not self._connector.StopPLC(): self.logger.write_error("Couldn't stop PLC !\n") self.UpdateMethodsFromPLCStatus() @@ -1662,7 +1675,13 @@ self.ShowMethod("_Transfer", True) self.CompareLocalAndRemotePLC() - self.UpdateMethodsFromPLCStatus() + + # Init with actual PLC status and print it + self.previous_plcstate = self.UpdateMethodsFromPLCStatus() + self.logger.write("PLC is %s\n"%self.previous_plcstate) + + # Start the status Timer + self.StatusTimer.Start(milliseconds=500, oneShot=False) def CompareLocalAndRemotePLC(self): if self._connector is None: @@ -1691,6 +1710,7 @@ self.ShowMethod("_Transfer", False) self.ShowMethod("_Connect", True) self.ShowMethod("_Disconnect", False) + self.StatusTimer.Stop() self.UpdateMethodsFromPLCStatus() def _Transfer(self): diff -r 24d4e48714ed -r a3a5561bde1d runtime/PLCObject.py --- a/runtime/PLCObject.py Thu May 28 13:29:23 2009 +0200 +++ b/runtime/PLCObject.py Thu May 28 13:40:29 2009 +0200 @@ -237,57 +237,62 @@ self.hmi_frame.Destroy() self.python_threads_vars = None - def PythonThreadProc(self): + def PythonThreadProc(self, debug): PLCprint("PythonThreadProc started") - self.evaluator(self.PrepareRuntimePy) - res,cmd = "None","None" - while self.PLCStatus == "Started": - #print "_PythonIterator(", res, ")", - cmd = self._PythonIterator(res) - #print " -> ", cmd - if cmd is None: - break - try : - res = str(self.evaluator(eval,cmd,self.python_threads_vars)) - except Exception,e: - res = "#EXCEPTION : "+str(e) - PLCprint(res) - self.evaluator(self.FinishRuntimePy) - PLCprint("PythonThreadProc interrupted") - - def StartPLC(self, debug=False): - PLCprint("StartPLC") - if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": - c_argv = ctypes.c_char_p * len(self.argv) - if self._LoadNewPLC() and self._startPLC(len(self.argv),c_argv(*self.argv)) == 0: + c_argv = ctypes.c_char_p * len(self.argv) + error = None + if self._LoadNewPLC(): + if self._startPLC(len(self.argv),c_argv(*self.argv)) == 0: if debug: for idx in self._Idxs: self._RegisterDebugVariable(idx) self._resumeDebug() self.PLCStatus = "Started" self.StatusChange() - self.PythonThread = Thread(target=self.PythonThreadProc) - self.PythonThread.start() - return True + self.evaluator(self.PrepareRuntimePy) + res,cmd = "None","None" + while self.PLCStatus == "Started": + #print "_PythonIterator(", res, ")", + cmd = self._PythonIterator(res) + #print " -> ", cmd + if cmd is None: + break + try : + res = str(self.evaluator(eval,cmd,self.python_threads_vars)) + except Exception,e: + res = "#EXCEPTION : "+str(e) + PLCprint(res) + self.PLCStatus = "Stopped" + self.StatusChange() + self.evaluator(self.FinishRuntimePy) else: - PLCprint("Problem starting PLC") - self._DoStopPLC() - return False + error = "starting" + else: + error = "loading" + if error is not None: + PLCprint("Problem %s PLC"%error) + self.PLCStatus = "Broken" + self._DoStopPLC() + self._FreePLC() + PLCprint("PythonThreadProc interrupted") + + def StartPLC(self, debug=False): + PLCprint("StartPLC") + if self.CurrentPLCFilename is not None and self.PLCStatus == "Stopped": + self.PythonThread = Thread(target=self.PythonThreadProc, args=[debug]) + self.PythonThread.start() def _DoStopPLC(self): - self.PLCStatus = "Stopped" self.StatusChange() self._stopPLC() - if self.PythonThread.isAlive(): - self.PythonThread.join() - if self._FreePLC(): - self.PLCStatus = "Dirty" self.StatusChange() return True def StopPLC(self): + PLCprint("StopPLC") if self.PLCStatus == "Started": self._DoStopPLC() + self.PLCStatus = "Stopped" return True return False @@ -308,7 +313,7 @@ def NewPLC(self, md5sum, data, extrafiles): PLCprint("NewPLC (%s)"%md5sum) - if self.PLCStatus in ["Stopped", "Empty", "Dirty"]: + if self.PLCStatus in ["Stopped", "Empty", "Dirty", "Broken"]: NewFileName = md5sum + lib_ext extra_files_log = os.path.join(self.workingdir,"extra_files.txt") try: