ProjectController.py
changeset 2463 8742337a9fe3
parent 2462 ed6b0e905fcb
child 2464 10437c6c294e
equal deleted inserted replaced
2462:ed6b0e905fcb 2463:8742337a9fe3
   889         if self._builder is None or not isinstance(self._builder, targetclass):
   889         if self._builder is None or not isinstance(self._builder, targetclass):
   890             # Get classname instance
   890             # Get classname instance
   891             self._builder = targetclass(self)
   891             self._builder = targetclass(self)
   892         return self._builder
   892         return self._builder
   893 
   893 
   894     def ResetBuildMD5(self):
       
   895         builder = self.GetBuilder()
       
   896         if builder is not None:
       
   897             builder.ResetBinaryCodeMD5()
       
   898         self.EnableMethod("_Transfer", False)
       
   899 
       
   900     def GetLastBuildMD5(self):
       
   901         builder = self.GetBuilder()
       
   902         if builder is not None:
       
   903             return builder.GetBinaryCodeMD5()
       
   904         else:
       
   905             return None
       
   906 
       
   907     #
   894     #
   908     #
   895     #
   909     #                C CODE GENERATION METHODS
   896     #                C CODE GENERATION METHODS
   910     #
   897     #
   911     #
   898     #
  1129         self.UpdateButtons()
  1116         self.UpdateButtons()
  1130 
  1117 
  1131         # If IEC code gen fail, bail out.
  1118         # If IEC code gen fail, bail out.
  1132         if not IECGenRes:
  1119         if not IECGenRes:
  1133             self.logger.write_error(_("PLC code generation failed !\n"))
  1120             self.logger.write_error(_("PLC code generation failed !\n"))
  1134             self.ResetBuildMD5()
       
  1135             return False
  1121             return False
  1136 
  1122 
  1137         # Reset variable and program list that are parsed from
  1123         # Reset variable and program list that are parsed from
  1138         # CSV file generated by IEC2C compiler.
  1124         # CSV file generated by IEC2C compiler.
  1139         self.ResetIECProgramsAndVariables()
  1125         self.ResetIECProgramsAndVariables()
  1145 
  1131 
  1146         # Get current or fresh builder
  1132         # Get current or fresh builder
  1147         builder = self.GetBuilder()
  1133         builder = self.GetBuilder()
  1148         if builder is None:
  1134         if builder is None:
  1149             self.logger.write_error(_("Fatal : cannot get builder.\n"))
  1135             self.logger.write_error(_("Fatal : cannot get builder.\n"))
  1150             self.ResetBuildMD5()
       
  1151             return False
  1136             return False
  1152 
  1137 
  1153         # Build
  1138         # Build
  1154         try:
  1139         try:
  1155             if not builder.build():
  1140             if not builder.build():
  1156                 self.logger.write_error(_("C Build failed.\n"))
  1141                 self.logger.write_error(_("C Build failed.\n"))
  1157                 return False
  1142                 return False
  1158         except Exception:
  1143         except Exception:
       
  1144             builder.ResetBinaryMD5()
  1159             self.logger.write_error(_("C Build crashed !\n"))
  1145             self.logger.write_error(_("C Build crashed !\n"))
  1160             self.logger.write_error(traceback.format_exc())
  1146             self.logger.write_error(traceback.format_exc())
  1161             self.ResetBuildMD5()
       
  1162             return False
  1147             return False
  1163 
  1148 
  1164         self.logger.write(_("Successfully built.\n"))
  1149         self.logger.write(_("Successfully built.\n"))
  1165         # Update GUI status about need for transfer
  1150         # Update GUI status about need for transfer
  1166         self.CompareLocalAndRemotePLC()
  1151         self.CompareLocalAndRemotePLC()
  1176                 self.PLCGeneratedLocatedVars)
  1161                 self.PLCGeneratedLocatedVars)
  1177         except Exception:
  1162         except Exception:
  1178             self.logger.write_error(
  1163             self.logger.write_error(
  1179                 _("Runtime IO extensions C code generation failed !\n"))
  1164                 _("Runtime IO extensions C code generation failed !\n"))
  1180             self.logger.write_error(traceback.format_exc())
  1165             self.logger.write_error(traceback.format_exc())
  1181             self.ResetBuildMD5()
       
  1182             return False
  1166             return False
  1183 
  1167 
  1184         # Generate C code and compilation params from liraries
  1168         # Generate C code and compilation params from liraries
  1185         try:
  1169         try:
  1186             LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(
  1170             LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(
  1187                 buildpath)
  1171                 buildpath)
  1188         except Exception:
  1172         except Exception:
  1189             self.logger.write_error(
  1173             self.logger.write_error(
  1190                 _("Runtime library extensions C code generation failed !\n"))
  1174                 _("Runtime library extensions C code generation failed !\n"))
  1191             self.logger.write_error(traceback.format_exc())
  1175             self.logger.write_error(traceback.format_exc())
  1192             self.ResetBuildMD5()
       
  1193             return False
  1176             return False
  1194 
  1177 
  1195         self.LocationCFilesAndCFLAGS = LibCFilesAndCFLAGS + \
  1178         self.LocationCFilesAndCFLAGS = LibCFilesAndCFLAGS + \
  1196             CTNLocationCFilesAndCFLAGS
  1179             CTNLocationCFilesAndCFLAGS
  1197         self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS
  1180         self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS
  1237                 self.LocationCFilesAndCFLAGS[0][1].insert(
  1220                 self.LocationCFilesAndCFLAGS[0][1].insert(
  1238                     0, (code_path, self.plcCFLAGS))
  1221                     0, (code_path, self.plcCFLAGS))
  1239             except Exception:
  1222             except Exception:
  1240                 self.logger.write_error(name + _(" generation failed !\n"))
  1223                 self.logger.write_error(name + _(" generation failed !\n"))
  1241                 self.logger.write_error(traceback.format_exc())
  1224                 self.logger.write_error(traceback.format_exc())
  1242                 self.ResetBuildMD5()
       
  1243                 return False
  1225                 return False
  1244         self.logger.write(_("C code generated successfully.\n"))
  1226         self.logger.write(_("C code generated successfully.\n"))
  1245         return True
  1227         return True
  1246 
  1228 
  1247     def ShowError(self, logger, from_location, to_location):
  1229     def ShowError(self, logger, from_location, to_location):
  1818                         _("Debug does not match PLC - stop/transfert/start to re-enable\n"))
  1800                         _("Debug does not match PLC - stop/transfert/start to re-enable\n"))
  1819 
  1801 
  1820     def CompareLocalAndRemotePLC(self):
  1802     def CompareLocalAndRemotePLC(self):
  1821         if self._connector is None:
  1803         if self._connector is None:
  1822             return
  1804             return
  1823         # We are now connected. Update button status
  1805         builder = self.GetBuilder()
  1824         MD5 = self.GetLastBuildMD5()
  1806         if builder is None :
       
  1807             return
       
  1808         MD5 = builder.GetBinaryMD5()
       
  1809         if MD5 is None:
       
  1810             return
  1825         # Check remote target PLC correspondance to that md5
  1811         # Check remote target PLC correspondance to that md5
  1826         if MD5 is not None:
  1812         if self._connector.MatchMD5(MD5):
  1827             if not self._connector.MatchMD5(MD5):
  1813             self.ProgramTransferred()
  1828                 # self.logger.write_warning(
       
  1829                 # _("Latest build does not match with target, please
       
  1830                 # transfer.\n"))
       
  1831                 self.EnableMethod("_Transfer", True)
       
  1832             else:
       
  1833                 # self.logger.write(
       
  1834                 #     _("Latest build matches target, no transfer needed.\n"))
       
  1835                 self.EnableMethod("_Transfer", True)
       
  1836                 # warns controller that program match
       
  1837                 self.ProgramTransferred()
       
  1838                 # self.EnableMethod("_Transfer", False)
       
  1839         else:
  1814         else:
  1840             # self.logger.write_warning(
  1815             self.logger.write(
  1841             #     _("Cannot compare latest build to target. Please build.\n"))
  1816                 _("Latest build does not match with connected target.\n"))
  1842             self.EnableMethod("_Transfer", False)
       
  1843 
  1817 
  1844     def _Disconnect(self):
  1818     def _Disconnect(self):
  1845         self._SetConnector(None)
  1819         self._SetConnector(None)
  1846 
  1820 
  1847     def _Transfer(self):
  1821     def _Transfer(self):
  1853             if dialog.ShowModal() == wx.ID_YES:
  1827             if dialog.ShowModal() == wx.ID_YES:
  1854                 self._Stop()
  1828                 self._Stop()
  1855             else:
  1829             else:
  1856                 return
  1830                 return
  1857 
  1831 
  1858         # Get the last build PLC's
  1832         builder = self.GetBuilder()
  1859         MD5 = self.GetLastBuildMD5()
  1833         if builder is None:
       
  1834             self.logger.write_error(_("Fatal : cannot get builder.\n"))
       
  1835             return False
       
  1836 
       
  1837         # recover md5 from last build 
       
  1838         MD5 = builder.GetBinaryMD5()
  1860 
  1839 
  1861         # Check if md5 file is empty : ask user to build PLC
  1840         # Check if md5 file is empty : ask user to build PLC
  1862         if MD5 is None:
  1841         if MD5 is None:
  1863             self.logger.write_error(
  1842             self.logger.write_error(
  1864                 _("Failed : Must build before transfer.\n"))
  1843                 _("Failed : Must build before transfer.\n"))
  1867         # Compare PLC project with PLC on target
  1846         # Compare PLC project with PLC on target
  1868         if self._connector.MatchMD5(MD5):
  1847         if self._connector.MatchMD5(MD5):
  1869             self.logger.write(
  1848             self.logger.write(
  1870                 _("Latest build already matches current target. Transfering anyway...\n"))
  1849                 _("Latest build already matches current target. Transfering anyway...\n"))
  1871 
  1850 
  1872         # Get temprary directory path
  1851         # purge any non-finished transfer
       
  1852         # note: this would abord any runing transfer with error
       
  1853         self._connector.PurgeBlobs()
       
  1854 
       
  1855         # transfer extra files
  1873         extrafiles = []
  1856         extrafiles = []
  1874         for extrafilespath in [self._getExtraFilesPath(),
  1857         for extrafilespath in [self._getExtraFilesPath(),
  1875                                self._getProjectFilesPath()]:
  1858                                self._getProjectFilesPath()]:
  1876 
  1859 
  1877             extrafiles.extend(
  1860             for name in os.listdir(extrafilespath):
  1878                 [(name, open(os.path.join(extrafilespath, name),
  1861                 extrafiles.append((
  1879                              'rb').read())
  1862                     name, 
  1880                  for name in os.listdir(extrafilespath)])
  1863                     self._connector.BlobFromFile(
       
  1864                         os.path.join(extrafilespath, name))))
  1881 
  1865 
  1882         # Send PLC on target
  1866         # Send PLC on target
  1883         builder = self.GetBuilder()
  1867         object_path = builder.GetBinaryPath()
  1884         if builder is not None:
  1868         object_blob = self._connector.BlobFromFile(object_path)
  1885             data = builder.GetBinaryCode()
  1869 
  1886             if data is not None:
  1870         if self._connector.NewPLC(MD5, object_blob, extrafiles):
  1887                 if self._connector.NewPLC(MD5, data, extrafiles) and self.GetIECProgramsAndVariables():
  1871             self.ProgramTransferred()
  1888                     self.UnsubscribeAllDebugIECVariable()
  1872             self.AppFrame.CloseObsoleteDebugTabs()
  1889                     self.ProgramTransferred()
  1873             self.AppFrame.LogViewer.ResetLogCounters()
  1890                     if self.AppFrame is not None:
  1874             if self.GetIECProgramsAndVariables():
  1891                         self.AppFrame.CloseObsoleteDebugTabs()
  1875                 self.UnsubscribeAllDebugIECVariable()
  1892                         self.AppFrame.RefreshPouInstanceVariablesPanel()
  1876                 self.AppFrame.RefreshPouInstanceVariablesPanel()
  1893                     self.logger.write(_("Transfer completed successfully.\n"))
  1877             self.logger.write(_("Transfer completed successfully.\n"))
  1894                     self.AppFrame.LogViewer.ResetLogCounters()
  1878         else:
  1895                 else:
  1879             self.logger.write_error(_("Transfer failed\n"))
  1896                     self.logger.write_error(_("Transfer failed\n"))
  1880 
  1897                 self.HidePLCProgress()
  1881         self.HidePLCProgress()
  1898             else:
       
  1899                 self.logger.write_error(
       
  1900                     _("No PLC to transfer (did build succeed ?)\n"))
       
  1901 
  1882 
  1902         wx.CallAfter(self.UpdateMethodsFromPLCStatus)
  1883         wx.CallAfter(self.UpdateMethodsFromPLCStatus)
  1903 
  1884 
  1904     StatusMethods = [
  1885     StatusMethods = [
  1905         {
  1886         {