6 import plugins |
6 import plugins |
7 import types |
7 import types |
8 import shutil |
8 import shutil |
9 from xml.dom import minidom |
9 from xml.dom import minidom |
10 import wx |
10 import wx |
11 import subprocess, ctypes, time, shutil |
|
12 |
11 |
13 #Quick hack to be able to find Beremiz IEC tools. Should be config params. |
12 #Quick hack to be able to find Beremiz IEC tools. Should be config params. |
14 base_folder = os.path.split(sys.path[0])[0] |
13 base_folder = os.path.split(sys.path[0])[0] |
15 sys.path.append(os.path.join(base_folder, "plcopeneditor")) |
14 sys.path.append(os.path.join(base_folder, "plcopeneditor")) |
16 |
15 |
17 from xmlclass import GenerateClassesFromXSDstring |
16 from xmlclass import GenerateClassesFromXSDstring |
|
17 from wxPopen import ProcessLogger |
18 |
18 |
19 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?> |
19 _BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?> |
20 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
20 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
21 <xsd:element name="BaseParams"> |
21 <xsd:element name="BaseParams"> |
22 <xsd:complexType> |
22 <xsd:complexType> |
858 plc_file.write(open(self._getIECgeneratedcodepath(), "r").read()) |
861 plc_file.write(open(self._getIECgeneratedcodepath(), "r").read()) |
859 plc_file.close() |
862 plc_file.close() |
860 logger.write("Compiling IEC Program in to C code...\n") |
863 logger.write("Compiling IEC Program in to C code...\n") |
861 # Now compile IEC code into many C files |
864 # Now compile IEC code into many C files |
862 # files are listed to stdout, and errors to stderr. |
865 # files are listed to stdout, and errors to stderr. |
863 status, result, err_result = logger.LogCommand("%s \"%s\" -I \"%s\" \"%s\""%(iec2c_path, self._getIECcodepath(), ieclib_path, buildpath), no_stdout=True) |
866 status, result, err_result = ProcessLogger( |
|
867 logger, |
|
868 "%s \"%s\" -I \"%s\" \"%s\""%( |
|
869 iec2c_path, |
|
870 self._getIECcodepath(), |
|
871 ieclib_path, buildpath), |
|
872 no_stdout=True).spin() |
864 if status: |
873 if status: |
865 # Failed ! |
874 # Failed ! |
866 logger.write_error("Error : IEC to C compiler returned %d\n"%status) |
875 logger.write_error("Error : IEC to C compiler returned %d\n"%status) |
867 return False |
876 return False |
868 # Now extract C files of stdout |
877 # Now extract C files of stdout |
891 if not os.path.exists(buildpath): |
900 if not os.path.exists(buildpath): |
892 os.mkdir(buildpath) |
901 os.mkdir(buildpath) |
893 |
902 |
894 logger.flush() |
903 logger.flush() |
895 logger.write("Start build in %s\n" % buildpath) |
904 logger.write("Start build in %s\n" % buildpath) |
|
905 |
|
906 self.EnableMethod("_Clean", True) |
|
907 self.EnableMethod("_showIECcode", True) |
896 |
908 |
897 # Generate SoftPLC code |
909 # Generate SoftPLC code |
898 if not self._Generate_SoftPLC(logger): |
910 if not self._Generate_SoftPLC(logger): |
899 logger.write_error("SoftPLC code generation failed !\n") |
911 logger.write_error("SoftPLC code generation failed !\n") |
900 return False |
912 return False |
|
913 |
901 |
914 |
902 #logger.write("SoftPLC code generation successfull\n") |
915 #logger.write("SoftPLC code generation successfull\n") |
903 |
916 |
904 logger.write("Generating plugins code ...\n") |
917 logger.write("Generating plugins code ...\n") |
905 |
918 |
958 bn = os.path.basename(CFile) |
971 bn = os.path.basename(CFile) |
959 obn = os.path.splitext(bn)[0]+".o" |
972 obn = os.path.splitext(bn)[0]+".o" |
960 obns.append(obn) |
973 obns.append(obn) |
961 logger.write(" [CC] "+bn+" -> "+obn+"\n") |
974 logger.write(" [CC] "+bn+" -> "+obn+"\n") |
962 objectfilename = os.path.splitext(CFile)[0]+".o" |
975 objectfilename = os.path.splitext(CFile)[0]+".o" |
963 status, result, err_result = logger.LogCommand("\"%s\" -c \"%s\" -o \"%s\" %s %s"%(compiler, CFile, objectfilename, _CFLAGS, CFLAGS)) |
976 |
|
977 status, result, err_result = ProcessLogger( |
|
978 logger, |
|
979 "\"%s\" -c \"%s\" -o \"%s\" %s %s"% |
|
980 (compiler, CFile, objectfilename, _CFLAGS, CFLAGS) |
|
981 ).spin() |
|
982 |
964 if status != 0: |
983 if status != 0: |
965 logger.write_error("Build failed\n") |
984 logger.write_error("Build failed\n") |
966 return False |
985 return False |
967 objs.append(objectfilename) |
986 objs.append(objectfilename) |
968 # Link all the object files into one executable |
987 # Link all the object files into one executable |
970 exe = self.GetProjectName() |
989 exe = self.GetProjectName() |
971 if target_name == "Win32": |
990 if target_name == "Win32": |
972 exe += ".exe" |
991 exe += ".exe" |
973 exe_path = os.path.join(buildpath, exe) |
992 exe_path = os.path.join(buildpath, exe) |
974 logger.write(" [CC] " + ' '.join(obns)+" -> " + exe + "\n") |
993 logger.write(" [CC] " + ' '.join(obns)+" -> " + exe + "\n") |
975 status, result, err_result = logger.LogCommand("\"%s\" \"%s\" -o \"%s\" %s"%(linker, '" "'.join(objs), exe_path, ' '.join(LDFLAGS+[_LDFLAGS]))) |
994 status, result, err_result = ProcessLogger( |
|
995 logger, |
|
996 "\"%s\" \"%s\" -o \"%s\" %s"% |
|
997 (linker, |
|
998 '" "'.join(objs), |
|
999 exe_path, |
|
1000 ' '.join(LDFLAGS+[_LDFLAGS])) |
|
1001 ).spin() |
976 if status != 0: |
1002 if status != 0: |
977 logger.write_error("Build failed\n") |
1003 logger.write_error("Build failed\n") |
978 self.EnableMethod("_Run", False) |
1004 self.EnableMethod("_Run", False) |
979 return False |
1005 return False |
980 |
1006 |
1032 if os.path.isdir(os.path.join(self._getBuildPath())): |
1058 if os.path.isdir(os.path.join(self._getBuildPath())): |
1033 logger.write("Cleaning the build directory\n") |
1059 logger.write("Cleaning the build directory\n") |
1034 shutil.rmtree(os.path.join(self._getBuildPath())) |
1060 shutil.rmtree(os.path.join(self._getBuildPath())) |
1035 else: |
1061 else: |
1036 logger.write_error("Build directory already clean\n") |
1062 logger.write_error("Build directory already clean\n") |
|
1063 self.EnableMethod("_showIECcode", False) |
|
1064 self.EnableMethod("_Clean", False) |
|
1065 self.EnableMethod("_Run", False) |
1037 |
1066 |
1038 def _Run(self, logger): |
1067 def _Run(self, logger): |
1039 logger.write("\n") |
|
1040 self.pid_plc = 0 |
|
1041 command_start_plc = os.path.join(self._getBuildPath(),self.GetProjectName() + exe_ext) |
1068 command_start_plc = os.path.join(self._getBuildPath(),self.GetProjectName() + exe_ext) |
1042 if os.path.isfile(command_start_plc): |
1069 if os.path.isfile(command_start_plc): |
1043 logger.write("\nStarting PLC\n") |
1070 logger.write("Starting PLC\n") |
1044 self.pid_plc = subprocess.Popen(command_start_plc).pid |
1071 def this_plc_finish_callback(*args): |
|
1072 if self.runningPLC is not None: |
|
1073 self.runningPLC = None |
|
1074 self._Stop(logger) |
|
1075 self.runningPLC = ProcessLogger( |
|
1076 logger, |
|
1077 command_start_plc, |
|
1078 finish_callback = this_plc_finish_callback) |
|
1079 self.EnableMethod("_Clean", False) |
|
1080 self.EnableMethod("_Run", False) |
|
1081 self.EnableMethod("_Stop", True) |
|
1082 self.EnableMethod("_build", False) |
1045 else: |
1083 else: |
1046 logger.write_error("%s doesn't exist\n" %command_start_plc) |
1084 logger.write_error("%s doesn't exist\n" %command_start_plc) |
1047 |
1085 |
|
1086 def reset_finished(self): |
|
1087 self.EnableMethod("_Clean", True) |
|
1088 self.EnableMethod("_Run", True) |
|
1089 self.EnableMethod("_Stop", False) |
|
1090 self.EnableMethod("_build", True) |
|
1091 |
1048 def _Stop(self, logger): |
1092 def _Stop(self, logger): |
1049 PROCESS_TERMINATE = 1 |
1093 if self.runningPLC is not None: |
1050 if self.pid_plc != 0: |
|
1051 logger.write("Stopping PLC\n") |
1094 logger.write("Stopping PLC\n") |
1052 handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.pid_plc) |
1095 was_runningPLC = self.runningPLC |
1053 ctypes.windll.kernel32.TerminateProcess(handle, -1) |
1096 self.runningPLC = None |
1054 ctypes.windll.kernel32.CloseHandle(handle) |
1097 was_runningPLC.kill() |
|
1098 self.reset_finished() |
1055 |
1099 |
1056 PluginMethods = [ |
1100 PluginMethods = [ |
1057 {"bitmap" : os.path.join("images", "editPLC"), |
1101 {"bitmap" : os.path.join("images", "editPLC"), |
1058 "name" : "Edit PLC", |
1102 "name" : "Edit PLC", |
1059 "tooltip" : "Edit PLC program with PLCOpenEditor", |
1103 "tooltip" : "Edit PLC program with PLCOpenEditor", |
1076 "enabled" : False, |
1120 "enabled" : False, |
1077 "tooltip" : "Stop Running PLC", |
1121 "tooltip" : "Stop Running PLC", |
1078 "method" : "_Stop"}, |
1122 "method" : "_Stop"}, |
1079 {"bitmap" : os.path.join("images", "ShowIECcode"), |
1123 {"bitmap" : os.path.join("images", "ShowIECcode"), |
1080 "name" : "Show IEC code", |
1124 "name" : "Show IEC code", |
|
1125 "enabled" : False, |
1081 "tooltip" : "Show IEC code generated by PLCGenerator", |
1126 "tooltip" : "Show IEC code generated by PLCGenerator", |
1082 "method" : "_showIECcode"}, |
1127 "method" : "_showIECcode"}, |
1083 {"name" : "Edit raw IEC code", |
1128 {"name" : "Edit raw IEC code", |
1084 "tooltip" : "Edit raw IEC code added to code generated by PLCGenerator", |
1129 "tooltip" : "Edit raw IEC code added to code generated by PLCGenerator", |
1085 "method" : "_editIECrawcode"} |
1130 "method" : "_editIECrawcode"} |
1086 ] |
1131 ] |
1087 |
|