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() |