plugger.py
changeset 578 6f5795bdee49
parent 544 064165a5276a
child 579 554ba6df4ee0
equal deleted inserted replaced
577:04baf6607a44 578:6f5795bdee49
   706 import connectors
   706 import connectors
   707 from discovery import DiscoveryDialog
   707 from discovery import DiscoveryDialog
   708 from weakref import WeakKeyDictionary
   708 from weakref import WeakKeyDictionary
   709 
   709 
   710 MATIEC_ERROR_MODEL = re.compile(".*\.st:(\d+)-(\d+)\.\.(\d+)-(\d+): error : (.*)$")
   710 MATIEC_ERROR_MODEL = re.compile(".*\.st:(\d+)-(\d+)\.\.(\d+)-(\d+): error : (.*)$")
       
   711 
       
   712 DEBUG_RETRIES_WARN = 3
       
   713 DEBUG_RETRIES_REREGISTER = 4
   711 
   714 
   712 class PluginsRoot(PlugTemplate, PLCControler):
   715 class PluginsRoot(PlugTemplate, PLCControler):
   713     """
   716     """
   714     This class define Root object of the plugin tree. 
   717     This class define Root object of the plugin tree. 
   715     It is responsible of :
   718     It is responsible of :
  1729 
  1732 
  1730     def DebugThreadProc(self):
  1733     def DebugThreadProc(self):
  1731         """
  1734         """
  1732         This thread waid PLC debug data, and dispatch them to subscribers
  1735         This thread waid PLC debug data, and dispatch them to subscribers
  1733         """
  1736         """
  1734         # This lock is used to avoid flooding wx event stack calling callafter
       
  1735         self.debug_break = False
  1737         self.debug_break = False
  1736         debug_getvar_retry = 0
  1738         debug_getvar_retry = 0
  1737         while (not self.debug_break) and (self._connector is not None):
  1739         while (not self.debug_break) and (self._connector is not None):
  1738             plc_status, debug_tick, debug_vars = self._connector.GetTraceVariables()
  1740             plc_status, debug_tick, debug_vars = self._connector.GetTraceVariables()
       
  1741             debug_getvar_retry += 1
  1739             #print debug_tick, debug_vars
  1742             #print debug_tick, debug_vars
  1740             self.IECdebug_lock.acquire()
  1743             if plc_status == "Started":
  1741             if debug_vars is not None:
  1744                 self.IECdebug_lock.acquire()
  1742                 debug_getvar_retry = 0
       
  1743                 if len(debug_vars) == len(self.TracedIECPath):
  1745                 if len(debug_vars) == len(self.TracedIECPath):
       
  1746                     if debug_getvar_retry > DEBUG_RETRIES_WARN:
       
  1747                         wx.CallAfter(self.logger.write, 
       
  1748                                  _("... debugger recovered\n"))
       
  1749                     debug_getvar_retry = 0
  1744                     for IECPath,value in zip(self.TracedIECPath, debug_vars):
  1750                     for IECPath,value in zip(self.TracedIECPath, debug_vars):
  1745                         if value is not None:
  1751                         if value is not None:
  1746                             self.CallWeakcallables(IECPath, "NewValue", debug_tick, value)
  1752                             self.CallWeakcallables(IECPath, "NewValue", debug_tick, value)
  1747                     self.CallWeakcallables("__tick__", "NewDataAvailable")
  1753                     self.CallWeakcallables("__tick__", "NewDataAvailable")
  1748                 else :
  1754                 self.IECdebug_lock.release()
  1749                     wx.CallAfter(self.logger.write_warning, 
  1755                 if debug_getvar_retry == DEBUG_RETRIES_WARN:
  1750                                  _("Debug data do not match requested variable count %d != %d\n")%(len(debug_vars), len(self.TracedIECPath)))
  1756                     wx.CallAfter(self.logger.write, 
  1751             else:
  1757                              _("Waiting debugger to recover...\n"))
  1752                 if plc_status == "Started":
  1758                 if debug_getvar_retry == DEBUG_RETRIES_REREGISTER:
  1753                     # Just in case, re-register debug registry to PLC
  1759                     # re-register debug registry to PLC
  1754                     if debug_getvar_retry == 0:
  1760                     wx.CallAfter(self.RegisterDebugVarToConnector)
  1755                         wx.CallAfter(self.RegisterDebugVarToConnector)
  1761                 if debug_getvar_retry != 0:
  1756                         wx.CallAfter(self.logger.write_warning, 
       
  1757                                  _("Waiting debugger to recover...\n"))
       
  1758                     debug_getvar_retry += 1
       
  1759                     # Be patient, tollerate PLC to come up before debugging
  1762                     # Be patient, tollerate PLC to come up before debugging
  1760                     time.sleep(0.1)
  1763                     time.sleep(0.1)
  1761                 else:
  1764             else:
  1762                     wx.CallAfter(self.logger.write, _("Debugger disabled\n"))
  1765                 self.debug_break = True
  1763                     self.debug_break = True
  1766         wx.CallAfter(self.logger.write, _("Debugger disabled\n"))
  1764             self.IECdebug_lock.release()
       
  1765 
  1767 
  1766     def KillDebugThread(self):
  1768     def KillDebugThread(self):
  1767         self.debug_break = True
  1769         self.debug_break = True
  1768         if self.DebugThread is not None:
  1770         if self.DebugThread is not None:
  1769             self.DebugThread.join(timeout=1)
  1771             self.logger.writeyield(_("Stopping debug ... "))
       
  1772             self.DebugThread.join(timeout=5)
  1770             if self.DebugThread.isAlive() and self.logger:
  1773             if self.DebugThread.isAlive() and self.logger:
  1771                 self.logger.write_warning(_("Debug Thread couldn't be killed"))
  1774                 self.logger.write_warning(_("Debug Thread couldn't be killed"))
       
  1775             else:
       
  1776                 self.logger.write(_("success\n"))
  1772         self.DebugThread = None
  1777         self.DebugThread = None
  1773 
  1778 
  1774     def _connect_debug(self): 
  1779     def _connect_debug(self): 
  1775         if self.AppFrame:
  1780         if self.AppFrame:
  1776             self.AppFrame.ResetGraphicViewers()
  1781             self.AppFrame.ResetGraphicViewers()
  1777         self.RegisterDebugVarToConnector()
  1782         self.RegisterDebugVarToConnector()
  1778         self.DebugThread = Thread(target=self.DebugThreadProc)
  1783         if self.DebugThread is None:
  1779         self.DebugThread.start()
  1784             self.DebugThread = Thread(target=self.DebugThreadProc)
       
  1785             self.DebugThread.start()
  1780     
  1786     
  1781     def _Run(self):
  1787     def _Run(self):
  1782         """
  1788         """
  1783         Start PLC
  1789         Start PLC
  1784         """
  1790         """
  1813         Stop PLC
  1819         Stop PLC
  1814         """
  1820         """
  1815         if self._connector is not None and not self._connector.StopPLC():
  1821         if self._connector is not None and not self._connector.StopPLC():
  1816             self.logger.write_error(_("Couldn't stop PLC !\n"))
  1822             self.logger.write_error(_("Couldn't stop PLC !\n"))
  1817 
  1823 
  1818         if self.DebugThread is not None:
  1824         self.KillDebugThread()
  1819             self.logger.write(_("Stopping debug\n"))
       
  1820             self.KillDebugThread()
       
  1821         
  1825         
  1822         self.UpdateMethodsFromPLCStatus()
  1826         self.UpdateMethodsFromPLCStatus()
  1823 
  1827 
  1824     def _Connect(self):
  1828     def _Connect(self):
  1825         # don't accept re-connetion is already connected
  1829         # don't accept re-connetion is already connected