ProjectController.py
changeset 2708 ea2aaeaaac4e
parent 2652 269149e78302
child 2712 a00f41d097f3
equal deleted inserted replaced
2707:c26195654ae9 2708:ea2aaeaaac4e
   252         self.SetAppFrame(frame, logger)
   252         self.SetAppFrame(frame, logger)
   253 
   253 
   254         # Setup debug information
   254         # Setup debug information
   255         self.IECdebug_datas = {}
   255         self.IECdebug_datas = {}
   256 
   256 
   257         self.DebugTimer = None
   257         self.DebugUpdatePending = False
   258         self.ResetIECProgramsAndVariables()
   258         self.ResetIECProgramsAndVariables()
   259 
   259 
   260         # In both new or load scenario, no need to save
   260         # In both new or load scenario, no need to save
   261         self.ChangesToSave = False
   261         self.ChangesToSave = False
   262         # root have no parent
   262         # root have no parent
   274         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
   274         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
   275         self.DebugToken = None
   275         self.DebugToken = None
   276         self.debug_status = PlcStatus.Stopped
   276         self.debug_status = PlcStatus.Stopped
   277 
   277 
   278     def __del__(self):
   278     def __del__(self):
   279         if self.DebugTimer:
       
   280             self.DebugTimer.cancel()
       
   281         self.KillDebugThread()
   279         self.KillDebugThread()
   282 
   280 
   283     def LoadLibraries(self):
   281     def LoadLibraries(self):
   284         self.Libraries = []
   282         self.Libraries = []
   285         TypeStack = []
   283         TypeStack = []
  1536         ticks, self.DebugTicks = self.DebugTicks, []
  1534         ticks, self.DebugTicks = self.DebugTicks, []
  1537 
  1535 
  1538         return debug_status, ticks, buffers
  1536         return debug_status, ticks, buffers
  1539 
  1537 
  1540     def RegisterDebugVarToConnector(self):
  1538     def RegisterDebugVarToConnector(self):
  1541         self.DebugTimer = None
       
  1542         Idxs = []
  1539         Idxs = []
  1543         self.TracedIECPath = []
  1540         self.TracedIECPath = []
  1544         self.TracedIECTypes = []
  1541         self.TracedIECTypes = []
  1545         if self._connector is not None and self.debug_status != PlcStatus.Broken:
  1542         if self._connector is not None and self.debug_status != PlcStatus.Broken:
  1546             IECPathsToPop = []
  1543             IECPathsToPop = []
  1575             else:
  1572             else:
  1576                 self.TracedIECPath = []
  1573                 self.TracedIECPath = []
  1577                 self._connector.SetTraceVariablesList([])
  1574                 self._connector.SetTraceVariablesList([])
  1578                 self.DebugToken = None
  1575                 self.DebugToken = None
  1579             self.debug_status, _debug_ticks, _buffers = self.SnapshotAndResetDebugValuesBuffers()
  1576             self.debug_status, _debug_ticks, _buffers = self.SnapshotAndResetDebugValuesBuffers()
       
  1577         self.DebugUpdatePending = False
  1580 
  1578 
  1581     def IsPLCStarted(self):
  1579     def IsPLCStarted(self):
  1582         return self.previous_plcstate == PlcStatus.Started
  1580         return self.previous_plcstate == PlcStatus.Started
  1583 
  1581 
  1584     def ReArmDebugRegisterTimer(self):
  1582     def AppendDebugUpdate(self):
  1585         if self.DebugTimer is not None:
  1583         if not self.DebugUpdatePending :
  1586             self.DebugTimer.cancel()
  1584             wx.CallAfter(self.RegisterDebugVarToConnector)
  1587 
  1585             self.DebugUpdatePending = True
  1588         # Prevent to call RegisterDebugVarToConnector when PLC is not started
       
  1589         # If an output location var is forced it's leads to segmentation fault in runtime
       
  1590         # Links between PLC located variables and real variables are not ready
       
  1591         if self.IsPLCStarted():
       
  1592             # Timer to prevent rapid-fire when registering many variables
       
  1593             # use wx.CallAfter use keep using same thread. TODO : use wx.Timer
       
  1594             # instead
       
  1595             self.DebugTimer = Timer(
       
  1596                 0.5, wx.CallAfter, args=[self.RegisterDebugVarToConnector])
       
  1597             # Rearm anti-rapid-fire timer
       
  1598             self.DebugTimer.start()
       
  1599 
  1586 
  1600     def GetDebugIECVariableType(self, IECPath):
  1587     def GetDebugIECVariableType(self, IECPath):
  1601         _Idx, IEC_Type = self._IECPathToIdx.get(IECPath, (None, None))
  1588         _Idx, IEC_Type = self._IECPathToIdx.get(IECPath, (None, None))
  1602         return IEC_Type
  1589         return IEC_Type
  1603 
  1590 
  1623         else:
  1610         else:
  1624             IECdebug_data[4] |= buffer_list
  1611             IECdebug_data[4] |= buffer_list
  1625 
  1612 
  1626         IECdebug_data[0][callableobj] = buffer_list
  1613         IECdebug_data[0][callableobj] = buffer_list
  1627 
  1614 
  1628         self.ReArmDebugRegisterTimer()
  1615         self.AppendDebugUpdate()
  1629 
  1616 
  1630         return IECdebug_data[1]
  1617         return IECdebug_data[1]
  1631 
  1618 
  1632     def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
  1619     def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
  1633         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1620         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1639                 IECdebug_data[4] = reduce(
  1626                 IECdebug_data[4] = reduce(
  1640                     lambda x, y: x | y,
  1627                     lambda x, y: x | y,
  1641                     IECdebug_data[0].itervalues(),
  1628                     IECdebug_data[0].itervalues(),
  1642                     False)
  1629                     False)
  1643 
  1630 
  1644         self.ReArmDebugRegisterTimer()
  1631         self.AppendDebugUpdate()
  1645 
  1632 
  1646     def UnsubscribeAllDebugIECVariable(self):
  1633     def UnsubscribeAllDebugIECVariable(self):
  1647         self.IECdebug_datas = {}
  1634         self.IECdebug_datas = {}
  1648 
  1635 
  1649         self.ReArmDebugRegisterTimer()
  1636         self.AppendDebugUpdate()
  1650 
  1637 
  1651     def ForceDebugIECVariable(self, IECPath, fvalue):
  1638     def ForceDebugIECVariable(self, IECPath, fvalue):
  1652         if IECPath not in self.IECdebug_datas:
  1639         if IECPath not in self.IECdebug_datas:
  1653             return
  1640             return
  1654 
  1641 
  1655         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1642         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1656         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1643         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1657         IECdebug_data[2] = "Forced"
  1644         IECdebug_data[2] = "Forced"
  1658         IECdebug_data[3] = fvalue
  1645         IECdebug_data[3] = fvalue
  1659 
  1646 
  1660         self.ReArmDebugRegisterTimer()
  1647         self.AppendDebugUpdate()
  1661 
  1648 
  1662     def ReleaseDebugIECVariable(self, IECPath):
  1649     def ReleaseDebugIECVariable(self, IECPath):
  1663         if IECPath not in self.IECdebug_datas:
  1650         if IECPath not in self.IECdebug_datas:
  1664             return
  1651             return
  1665 
  1652 
  1666         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1653         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1667         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1654         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1668         IECdebug_data[2] = "Registered"
  1655         IECdebug_data[2] = "Registered"
  1669         IECdebug_data[3] = None
  1656         IECdebug_data[3] = None
  1670 
  1657 
  1671         self.ReArmDebugRegisterTimer()
  1658         self.AppendDebugUpdate()
  1672 
  1659 
  1673     def CallWeakcallables(self, IECPath, function_name, *cargs):
  1660     def CallWeakcallables(self, IECPath, function_name, *cargs):
  1674         data_tuple = self.IECdebug_datas.get(IECPath, None)
  1661         data_tuple = self.IECdebug_datas.get(IECPath, None)
  1675         if data_tuple is not None:
  1662         if data_tuple is not None:
  1676             WeakCallableDict, _data_log, _status, _fvalue, buffer_list = data_tuple
  1663             WeakCallableDict, _data_log, _status, _fvalue, buffer_list = data_tuple