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