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 { |