- now call load, start, free PLC from the python Thread
authorgreg
Thu, 28 May 2009 13:40:29 +0200
changeset 350 a3a5561bde1d
parent 349 24d4e48714ed
child 351 89eca146bee0
- 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)
plugger.py
runtime/PLCObject.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):
--- 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: