ProjectController.py
changeset 2485 ef327451d067
parent 2481 6cd7dae360d4
child 2487 6a4f9a061994
equal deleted inserted replaced
2484:2318a7cde101 2485:ef327451d067
   268         self._setBuildPath(None)
   268         self._setBuildPath(None)
   269         self.debug_break = False
   269         self.debug_break = False
   270         self.previous_plcstate = None
   270         self.previous_plcstate = None
   271         # copy StatusMethods so that it can be later customized
   271         # copy StatusMethods so that it can be later customized
   272         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
   272         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
       
   273         self.DebugToken = None
       
   274         self.debug_status = PlcStatus.Stopped
   273 
   275 
   274     def __del__(self):
   276     def __del__(self):
   275         if self.DebugTimer:
   277         if self.DebugTimer:
   276             self.DebugTimer.cancel()
   278             self.DebugTimer.cancel()
   277         self.KillDebugThread()
   279         self.KillDebugThread()
  1477 
  1479 
  1478     def PullPLCStatusProc(self, event):
  1480     def PullPLCStatusProc(self, event):
  1479         self.UpdateMethodsFromPLCStatus()
  1481         self.UpdateMethodsFromPLCStatus()
  1480 
  1482 
  1481     def SnapshotAndResetDebugValuesBuffers(self):
  1483     def SnapshotAndResetDebugValuesBuffers(self):
  1482         if self._connector is not None:
  1484         debug_status = PlcStatus.Disconnected
  1483             plc_status, Traces = self._connector.GetTraceVariables()
  1485         if self._connector is not None and self.DebugToken is not None:
       
  1486             debug_status, Traces = self._connector.GetTraceVariables(self.DebugToken)
  1484             # print [dict.keys() for IECPath, (dict, log, status, fvalue) in
  1487             # print [dict.keys() for IECPath, (dict, log, status, fvalue) in
  1485             # self.IECdebug_datas.items()]
  1488             # self.IECdebug_datas.items()]
  1486             if plc_status == PlcStatus.Started:
  1489             if debug_status == PlcStatus.Started:
  1487                 if len(Traces) > 0:
  1490                 if len(Traces) > 0:
  1488                     for debug_tick, debug_buff in Traces:
  1491                     for debug_tick, debug_buff in Traces:
  1489                         debug_vars = UnpackDebugBuffer(
  1492                         debug_vars = UnpackDebugBuffer(
  1490                             debug_buff, self.TracedIECTypes)
  1493                             debug_buff, self.TracedIECTypes)
  1491                         if debug_vars is not None and len(debug_vars) == len(self.TracedIECPath):
  1494                         if debug_vars is not None and len(debug_vars) == len(self.TracedIECPath):
  1507         buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers,
  1510         buffers, self.DebugValuesBuffers = (self.DebugValuesBuffers,
  1508                                             [list() for dummy in xrange(len(self.TracedIECPath))])
  1511                                             [list() for dummy in xrange(len(self.TracedIECPath))])
  1509 
  1512 
  1510         ticks, self.DebugTicks = self.DebugTicks, []
  1513         ticks, self.DebugTicks = self.DebugTicks, []
  1511 
  1514 
  1512         return ticks, buffers
  1515         return debug_status, ticks, buffers
  1513 
  1516 
  1514     def RegisterDebugVarToConnector(self):
  1517     def RegisterDebugVarToConnector(self):
  1515         self.DebugTimer = None
  1518         self.DebugTimer = None
  1516         Idxs = []
  1519         Idxs = []
  1517         self.TracedIECPath = []
  1520         self.TracedIECPath = []
  1518         self.TracedIECTypes = []
  1521         self.TracedIECTypes = []
  1519         if self._connector is not None:
  1522         if self._connector is not None and self.debug_status != PlcStatus.Broken:
  1520             IECPathsToPop = []
  1523             IECPathsToPop = []
  1521             for IECPath, data_tuple in self.IECdebug_datas.iteritems():
  1524             for IECPath, data_tuple in self.IECdebug_datas.iteritems():
  1522                 WeakCallableDict, _data_log, _status, fvalue, _buffer_list = data_tuple
  1525                 WeakCallableDict, _data_log, _status, fvalue, _buffer_list = data_tuple
  1523                 if len(WeakCallableDict) == 0:
  1526                 if len(WeakCallableDict) == 0:
  1524                     # Callable Dict is empty.
  1527                     # Callable Dict is empty.
  1543             if Idxs:
  1546             if Idxs:
  1544                 Idxs.sort()
  1547                 Idxs.sort()
  1545                 IdxsT = zip(*Idxs)
  1548                 IdxsT = zip(*Idxs)
  1546                 self.TracedIECPath = IdxsT[3]
  1549                 self.TracedIECPath = IdxsT[3]
  1547                 self.TracedIECTypes = IdxsT[1]
  1550                 self.TracedIECTypes = IdxsT[1]
  1548                 self._connector.SetTraceVariablesList(zip(*IdxsT[0:3]))
  1551                 self.DebugToken = self._connector.SetTraceVariablesList(zip(*IdxsT[0:3]))
  1549             else:
  1552             else:
  1550                 self.TracedIECPath = []
  1553                 self.TracedIECPath = []
  1551                 self._connector.SetTraceVariablesList([])
  1554                 self._connector.SetTraceVariablesList([])
  1552             self.SnapshotAndResetDebugValuesBuffers()
  1555                 self.DebugToken = None
       
  1556             self.debug_status, _debug_ticks, _buffers = self.SnapshotAndResetDebugValuesBuffers()
  1553 
  1557 
  1554     def IsPLCStarted(self):
  1558     def IsPLCStarted(self):
  1555         return self.previous_plcstate == PlcStatus.Started
  1559         return self.previous_plcstate == PlcStatus.Started
  1556 
  1560 
  1557     def ReArmDebugRegisterTimer(self):
  1561     def ReArmDebugRegisterTimer(self):
  1663         if self._connector is None:
  1667         if self._connector is None:
  1664             return -1, "No runtime connected!"
  1668             return -1, "No runtime connected!"
  1665         return self._connector.RemoteExec(script, **kwargs)
  1669         return self._connector.RemoteExec(script, **kwargs)
  1666 
  1670 
  1667     def DispatchDebugValuesProc(self, event):
  1671     def DispatchDebugValuesProc(self, event):
  1668         debug_ticks, buffers = self.SnapshotAndResetDebugValuesBuffers()
  1672         self.debug_status, debug_ticks, buffers = self.SnapshotAndResetDebugValuesBuffers()
  1669         start_time = time.time()
  1673         start_time = time.time()
  1670         if len(self.TracedIECPath) == len(buffers):
  1674         if len(self.TracedIECPath) == len(buffers):
  1671             for IECPath, values in zip(self.TracedIECPath, buffers):
  1675             for IECPath, values in zip(self.TracedIECPath, buffers):
  1672                 if len(values) > 0:
  1676                 if len(values) > 0:
  1673                     self.CallWeakcallables(
  1677                     self.CallWeakcallables(
  1674                         IECPath, "NewValues", debug_ticks, values)
  1678                         IECPath, "NewValues", debug_ticks, values)
  1675             if len(debug_ticks) > 0:
  1679             if len(debug_ticks) > 0:
  1676                 self.CallWeakcallables(
  1680                 self.CallWeakcallables(
  1677                     "__tick__", "NewDataAvailable", debug_ticks)
  1681                     "__tick__", "NewDataAvailable", debug_ticks)
  1678 
  1682 
  1679         delay = time.time() - start_time
  1683         if self.debug_status == PlcStatus.Broken:
  1680         next_refresh = max(REFRESH_PERIOD - delay, 0.2 * delay)
  1684             self.logger.write_warning(
  1681         if self.DispatchDebugValuesTimer is not None:
  1685                 _("Debug: token rejected - other debug took over - reconnect to recover\n"))
  1682             self.DispatchDebugValuesTimer.Start(
  1686         else:
  1683                 int(next_refresh * 1000), oneShot=True)
  1687             delay = time.time() - start_time
       
  1688             next_refresh = max(REFRESH_PERIOD - delay, 0.2 * delay)
       
  1689             if self.DispatchDebugValuesTimer is not None:
       
  1690                 self.DispatchDebugValuesTimer.Start(
       
  1691                     int(next_refresh * 1000), oneShot=True)
  1684         event.Skip()
  1692         event.Skip()
  1685 
  1693 
  1686     def KillDebugThread(self):
  1694     def KillDebugThread(self):
  1687         if self.DispatchDebugValuesTimer is not None:
  1695         if self.DispatchDebugValuesTimer is not None:
  1688             self.DispatchDebugValuesTimer.Stop()
  1696             self.DispatchDebugValuesTimer.Stop()
  1689 
  1697 
  1690     def _connect_debug(self):
  1698     def _connect_debug(self):
  1691         self.previous_plcstate = None
  1699         self.previous_plcstate = None
  1692         if self.AppFrame:
  1700         if self.AppFrame:
  1693             self.AppFrame.ResetGraphicViewers()
  1701             self.AppFrame.ResetGraphicViewers()
       
  1702 
       
  1703         self.debug_status = PlcStatus.Started
       
  1704 
  1694         self.RegisterDebugVarToConnector()
  1705         self.RegisterDebugVarToConnector()
  1695         if self.DispatchDebugValuesTimer is not None:
  1706         if self.DispatchDebugValuesTimer is not None:
  1696             self.DispatchDebugValuesTimer.Start(
  1707             self.DispatchDebugValuesTimer.Start(
  1697                 int(REFRESH_PERIOD * 1000), oneShot=True)
  1708                 int(REFRESH_PERIOD * 1000), oneShot=True)
  1698 
  1709 
  1725         if self.AppFrame is not None:
  1736         if self.AppFrame is not None:
  1726             self.AppFrame.LogViewer.SetLogSource(connector)
  1737             self.AppFrame.LogViewer.SetLogSource(connector)
  1727         if connector is not None:
  1738         if connector is not None:
  1728             if self.StatusTimer is not None:
  1739             if self.StatusTimer is not None:
  1729                 # Start the status Timer
  1740                 # Start the status Timer
  1730                 wx.Yield()
       
  1731                 self.StatusTimer.Start(milliseconds=500, oneShot=False)
  1741                 self.StatusTimer.Start(milliseconds=500, oneShot=False)
  1732         else:
  1742         else:
  1733             if self.StatusTimer is not None:
  1743             if self.StatusTimer is not None:
  1734                 # Stop the status Timer
  1744                 # Stop the status Timer
  1735                 self.StatusTimer.Stop()
  1745                 self.StatusTimer.Stop()