More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
authorEdouard Tisserant
Tue, 29 Jan 2013 21:34:43 +1100
changeset 914 94436558f0ce
parent 913 5d6a04abab3c
child 915 8dc28b21bdac
More stable logging. Added small one-entry log for loading errors. Test now include python side concurrent logging
ProjectController.py
runtime/PLCObject.py
tests/logging/plc.xml
tests/logging/py_ext_0@py_ext/baseconfnode.xml
tests/logging/py_ext_0@py_ext/py_ext.xml
--- a/ProjectController.py	Tue Jan 29 16:22:04 2013 +1100
+++ b/ProjectController.py	Tue Jan 29 21:34:43 2013 +1100
@@ -942,7 +942,6 @@
         for infos, (start_row, start_col) in chunk_infos:
             start = (from_location[0] - start_row, from_location[1] - start_col)
             end = (to_location[0] - start_row, to_location[1] - start_col)
-            #print from_location, to_location, start_row, start_col, start, end
             if self.AppFrame is not None:
                 self.AppFrame.ShowError(infos, start, end)
     
@@ -1079,14 +1078,19 @@
 
     def UpdatePLCLog(self, log_count):
         if log_count and self.previous_log_count != log_count:
-            #self.logger.write("Now log count is "+repr(log_count)+"\n")
+            # XXX replace dump to console with dedicated log panel.
             to_console = ['']
-            for msgidx in xrange(log_count-1, self.previous_log_count - 1 if self.previous_log_count is not None else 0,-1): 
+            dump_end = max( # request message sent after the last one we already got
+                self.previous_log_count - 1 if self.previous_log_count is not None else -1,
+                log_count - 100) # 100 is purely arbitrary number
+                # dedicated panel should only ask for a small range, 
+                # depending on how user navigate in the panel
+                # and only ask for last one in follow mode
+            for msgidx in xrange(log_count-1, dump_end,-1):
                 msg = self._connector.GetLogMessage(msgidx)
                 if msg is not None :
                     to_console.insert(0, '#' + repr(msgidx) + ": " + msg)
                 else:
-                    #self.logger.write(repr(msgidx) + " : GetLogMessage returned None\n")
                     to_console.insert(0, 'No log before #'+repr(msgidx))
                     break;
             self.logger.write("\n".join(to_console))
@@ -1143,7 +1147,6 @@
                 if len(WeakCallableDict) == 0:
                     # Callable Dict is empty.
                     # This variable is not needed anymore!
-                    #print "Unused : " + IECPath
                     IECPathsToPop.append(IECPath)
                 elif IECPath != "__tick__":
                     # Convert 
@@ -1166,9 +1169,6 @@
                 self.TracedIECPath = []
                 self._connector.SetTraceVariablesList([])
             self.IECdebug_lock.release()
-            
-            #for IEC_path, IECdebug_data in self.IECdebug_datas.iteritems():
-            #    print IEC_path, IECdebug_data[0].keys()
 
     def ReArmDebugRegisterTimer(self):
         if self.DebugTimer is not None:
@@ -1213,7 +1213,6 @@
         return IECdebug_data[1]
 
     def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
-        #print "Unsubscribe", IECPath, callableobj
         self.IECdebug_lock.acquire()
         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
         if IECdebug_data is not None:
@@ -1265,7 +1264,6 @@
             WeakCallableDict, data_log, status, fvalue = data_tuple
             #data_log.append((debug_tick, value))
             for weakcallable,(args,kwargs) in WeakCallableDict.iteritems():
-                #print weakcallable, value, args, kwargs
                 function = getattr(weakcallable, function_name, None)
                 if function is not None:
                     if status == "Forced" and cargs[1] == fvalue:
@@ -1295,7 +1293,6 @@
             else:
                 plc_status = None
             debug_getvar_retry += 1
-            #print debug_tick, debug_vars
             if plc_status == "Started":
                 self.IECdebug_lock.acquire()
                 if len(debug_vars) == len(self.TracedIECPath):
@@ -1333,6 +1330,8 @@
         self.DebugThread = None
 
     def _connect_debug(self): 
+        self.previous_plcstate = None
+        self.previous_log_count = None
         if self.AppFrame:
             self.AppFrame.ResetGraphicViewers()
         self.RegisterDebugVarToConnector()
@@ -1512,6 +1511,8 @@
             else:
                 self.logger.write_error(_("No PLC to transfer (did build succeed ?)\n"))
 
+        self.previous_log_count = None
+
         wx.CallAfter(self.UpdateMethodsFromPLCStatus)
 
     StatusMethods = [
--- a/runtime/PLCObject.py	Tue Jan 29 16:22:04 2013 +1100
+++ b/runtime/PLCObject.py	Tue Jan 29 21:34:43 2013 +1100
@@ -65,6 +65,7 @@
         self.statuschange = statuschange
         self.hmi_frame = None
         self.website = website
+        self._loading_error = None
         
         # Get the last transfered PLC if connector must be restart
         try:
@@ -86,15 +87,20 @@
     def GetLogCount(self):
         if self._GetLogCount is not None :
             return int(self._GetLogCount())
+        elif self._loading_error is not None:
+            return 1;
+
 
     def GetLogMessage(self, msgid):
-        maxsz = len(self._log_read_buffer)-1
-        sz = self._GetLogMessage(msgid, self._log_read_buffer, maxsz)
-        if sz and sz <= maxsz:
-            self._log_read_buffer[sz] = '\x00'
-            return self._log_read_buffer.value
-        else :
-            return None
+        if self._GetLogMessage is not None:
+            maxsz = len(self._log_read_buffer)-1
+            sz = self._GetLogMessage(msgid, self._log_read_buffer, maxsz)
+            if sz and sz <= maxsz:
+                self._log_read_buffer[sz] = '\x00'
+                return self._log_read_buffer.value
+        elif self._loading_error is not None :
+            return self._loading_error
+        return None
 
     def _GetMD5FileName(self):
         return os.path.join(self.workingdir, "lasttransferedPLC.md5")
@@ -175,9 +181,11 @@
             self._GetLogMessage.restype = ctypes.c_uint32
             self._GetLogMessage.argtypes = [ctypes.c_uint32, ctypes.c_char_p, ctypes.c_uint32]
 
+            self._loading_error = None
             return True
         except:
-            PLCprint(traceback.format_exc())
+            self._loading_error = traceback.format_exc()
+            PLCprint(self._loading_error)
             return False
 
     def _FreePLC(self):
@@ -199,7 +207,7 @@
         self._PythonIterator = lambda:""
         self._GetLogCount = None 
         self._LogMessage = lambda m,s:PLCprint("OFF LOG :"+m)
-        self._GetLogMessage = lambda i,b,s:None
+        self._GetLogMessage = None
         self.PLClibraryHandle = None
         # Unload library explicitely
         if getattr(self,"_PLClibraryHandle",None) is not None:
--- a/tests/logging/plc.xml	Tue Jan 29 16:22:04 2013 +1100
+++ b/tests/logging/plc.xml	Tue Jan 29 21:34:43 2013 +1100
@@ -8,7 +8,7 @@
               productVersion="1"
               creationDateTime="2013-01-29T14:01:00"/>
   <contentHeader name="Unnamed"
-                 modificationDateTime="2013-01-29T15:56:10">
+                 modificationDateTime="2013-01-29T21:30:36">
     <coordinateInfo>
       <fbd>
         <scaling x="0" y="0"/>
@@ -301,7 +301,7 @@
     <configurations>
       <configuration name="config">
         <resource name="resource1">
-          <task name="blob" interval="T#1ms" priority="0">
+          <task name="blob" interval="T#10ms" priority="0">
             <pouInstance name="blub" typeName="program0"/>
           </task>
         </resource>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/logging/py_ext_0@py_ext/baseconfnode.xml	Tue Jan 29 21:34:43 2013 +1100
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<BaseParams Name="py_ext_0" IEC_Channel="0"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/logging/py_ext_0@py_ext/py_ext.xml	Tue Jan 29 21:34:43 2013 +1100
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<Python xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="py_ext_xsd.xsd">
+<![CDATA[import threading
+
+MyT = None
+Stop = False
+
+def DoLog():
+    global MyT,Stop
+    MyT=threading.Timer(0.03, DoLog)
+    if not Stop : MyT.start()
+    Stop = False
+    PLCObject.LogMessage("Python side Logging")
+
+def StopLog():
+    global MyT,Stop
+    Stop=True
+    if MyT is not None: MyT.cancel()
+
+_runtime_begin.append(DoLog)
+_runtime_cleanup.append(StopLog)
+]]>
+</Python>