ProjectController.py
changeset 2719 745b64e7c695
parent 2712 a00f41d097f3
child 2729 4e0cd7806776
child 3163 7cf38cd0d820
equal deleted inserted replaced
2718:76e8ec46828a 2719:745b64e7c695
   157             # Output files are listed to stdout, errors to stderr
   157             # Output files are listed to stdout, errors to stderr
   158             _status, result, _err_result = ProcessLogger(None, buildcmd,
   158             _status, result, _err_result = ProcessLogger(None, buildcmd,
   159                                                          no_stdout=True,
   159                                                          no_stdout=True,
   160                                                          no_stderr=True).spin()
   160                                                          no_stderr=True).spin()
   161         except Exception:
   161         except Exception:
       
   162             self.logger.write_error(_("Couldn't launch IEC compiler to determine compatible options.\n"))
   162             return buildopt
   163             return buildopt
   163 
   164 
   164         for opt in options:
   165         for opt in options:
   165             if opt in result:
   166             if opt in result:
   166                 buildopt = buildopt + " " + opt
   167                 buildopt = buildopt + " " + opt
   252         self.SetAppFrame(frame, logger)
   253         self.SetAppFrame(frame, logger)
   253 
   254 
   254         # Setup debug information
   255         # Setup debug information
   255         self.IECdebug_datas = {}
   256         self.IECdebug_datas = {}
   256 
   257 
   257         self.DebugTimer = None
   258         self.DebugUpdatePending = False
   258         self.ResetIECProgramsAndVariables()
   259         self.ResetIECProgramsAndVariables()
   259 
   260 
   260         # In both new or load scenario, no need to save
   261         # In both new or load scenario, no need to save
   261         self.ChangesToSave = False
   262         self.ChangesToSave = False
   262         # root have no parent
   263         # root have no parent
   274         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
   275         self.StatusMethods = [dic.copy() for dic in self.StatusMethods]
   275         self.DebugToken = None
   276         self.DebugToken = None
   276         self.debug_status = PlcStatus.Stopped
   277         self.debug_status = PlcStatus.Stopped
   277 
   278 
   278     def __del__(self):
   279     def __del__(self):
   279         if self.DebugTimer:
       
   280             self.DebugTimer.cancel()
       
   281         self.KillDebugThread()
   280         self.KillDebugThread()
   282 
   281 
   283     def LoadLibraries(self):
   282     def LoadLibraries(self):
   284         self.Libraries = []
   283         self.Libraries = []
   285         TypeStack = []
   284         TypeStack = []
  1536         ticks, self.DebugTicks = self.DebugTicks, []
  1535         ticks, self.DebugTicks = self.DebugTicks, []
  1537 
  1536 
  1538         return debug_status, ticks, buffers
  1537         return debug_status, ticks, buffers
  1539 
  1538 
  1540     def RegisterDebugVarToConnector(self):
  1539     def RegisterDebugVarToConnector(self):
  1541         self.DebugTimer = None
       
  1542         Idxs = []
  1540         Idxs = []
  1543         self.TracedIECPath = []
  1541         self.TracedIECPath = []
  1544         self.TracedIECTypes = []
  1542         self.TracedIECTypes = []
  1545         if self._connector is not None and self.debug_status != PlcStatus.Broken:
  1543         if self._connector is not None and self.debug_status != PlcStatus.Broken:
  1546             IECPathsToPop = []
  1544             IECPathsToPop = []
  1575             else:
  1573             else:
  1576                 self.TracedIECPath = []
  1574                 self.TracedIECPath = []
  1577                 self._connector.SetTraceVariablesList([])
  1575                 self._connector.SetTraceVariablesList([])
  1578                 self.DebugToken = None
  1576                 self.DebugToken = None
  1579             self.debug_status, _debug_ticks, _buffers = self.SnapshotAndResetDebugValuesBuffers()
  1577             self.debug_status, _debug_ticks, _buffers = self.SnapshotAndResetDebugValuesBuffers()
       
  1578         self.DebugUpdatePending = False
  1580 
  1579 
  1581     def IsPLCStarted(self):
  1580     def IsPLCStarted(self):
  1582         return self.previous_plcstate == PlcStatus.Started
  1581         return self.previous_plcstate == PlcStatus.Started
  1583 
  1582 
  1584     def ReArmDebugRegisterTimer(self):
  1583     def AppendDebugUpdate(self):
  1585         if self.DebugTimer is not None:
  1584         if not self.DebugUpdatePending :
  1586             self.DebugTimer.cancel()
  1585             wx.CallAfter(self.RegisterDebugVarToConnector)
  1587 
  1586             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 
  1587 
  1600     def GetDebugIECVariableType(self, IECPath):
  1588     def GetDebugIECVariableType(self, IECPath):
  1601         _Idx, IEC_Type = self._IECPathToIdx.get(IECPath, (None, None))
  1589         _Idx, IEC_Type = self._IECPathToIdx.get(IECPath, (None, None))
  1602         return IEC_Type
  1590         return IEC_Type
  1603 
  1591 
  1623         else:
  1611         else:
  1624             IECdebug_data[4] |= buffer_list
  1612             IECdebug_data[4] |= buffer_list
  1625 
  1613 
  1626         IECdebug_data[0][callableobj] = buffer_list
  1614         IECdebug_data[0][callableobj] = buffer_list
  1627 
  1615 
  1628         self.ReArmDebugRegisterTimer()
  1616         self.AppendDebugUpdate()
  1629 
  1617 
  1630         return IECdebug_data[1]
  1618         return IECdebug_data[1]
  1631 
  1619 
  1632     def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
  1620     def UnsubscribeDebugIECVariable(self, IECPath, callableobj):
  1633         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1621         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1639                 IECdebug_data[4] = reduce(
  1627                 IECdebug_data[4] = reduce(
  1640                     lambda x, y: x | y,
  1628                     lambda x, y: x | y,
  1641                     IECdebug_data[0].itervalues(),
  1629                     IECdebug_data[0].itervalues(),
  1642                     False)
  1630                     False)
  1643 
  1631 
  1644         self.ReArmDebugRegisterTimer()
  1632         self.AppendDebugUpdate()
  1645 
  1633 
  1646     def UnsubscribeAllDebugIECVariable(self):
  1634     def UnsubscribeAllDebugIECVariable(self):
  1647         self.IECdebug_datas = {}
  1635         self.IECdebug_datas = {}
  1648 
  1636 
  1649         self.ReArmDebugRegisterTimer()
  1637         self.AppendDebugUpdate()
  1650 
  1638 
  1651     def ForceDebugIECVariable(self, IECPath, fvalue):
  1639     def ForceDebugIECVariable(self, IECPath, fvalue):
  1652         if IECPath not in self.IECdebug_datas:
  1640         if IECPath not in self.IECdebug_datas:
  1653             return
  1641             return
  1654 
  1642 
  1655         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1643         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1656         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1644         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1657         IECdebug_data[2] = "Forced"
  1645         IECdebug_data[2] = "Forced"
  1658         IECdebug_data[3] = fvalue
  1646         IECdebug_data[3] = fvalue
  1659 
  1647 
  1660         self.ReArmDebugRegisterTimer()
  1648         self.AppendDebugUpdate()
  1661 
  1649 
  1662     def ReleaseDebugIECVariable(self, IECPath):
  1650     def ReleaseDebugIECVariable(self, IECPath):
  1663         if IECPath not in self.IECdebug_datas:
  1651         if IECPath not in self.IECdebug_datas:
  1664             return
  1652             return
  1665 
  1653 
  1666         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1654         # If no entry exist, create a new one with a fresh WeakKeyDictionary
  1667         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1655         IECdebug_data = self.IECdebug_datas.get(IECPath, None)
  1668         IECdebug_data[2] = "Registered"
  1656         IECdebug_data[2] = "Registered"
  1669         IECdebug_data[3] = None
  1657         IECdebug_data[3] = None
  1670 
  1658 
  1671         self.ReArmDebugRegisterTimer()
  1659         self.AppendDebugUpdate()
  1672 
  1660 
  1673     def CallWeakcallables(self, IECPath, function_name, *cargs):
  1661     def CallWeakcallables(self, IECPath, function_name, *cargs):
  1674         data_tuple = self.IECdebug_datas.get(IECPath, None)
  1662         data_tuple = self.IECdebug_datas.get(IECPath, None)
  1675         if data_tuple is not None:
  1663         if data_tuple is not None:
  1676             WeakCallableDict, _data_log, _status, _fvalue, buffer_list = data_tuple
  1664             WeakCallableDict, _data_log, _status, _fvalue, buffer_list = data_tuple