plugger.py
changeset 366 cd90e4c10261
parent 363 e0c4d3549369
child 382 37f870528def
equal deleted inserted replaced
365:a7f58414dea0 366:cd90e4c10261
   908     
   908     
   909     def _getIECrawcodepath(self):
   909     def _getIECrawcodepath(self):
   910         # define name for IEC raw code file
   910         # define name for IEC raw code file
   911         return os.path.join(self.PlugPath(), "raw_plc.st")
   911         return os.path.join(self.PlugPath(), "raw_plc.st")
   912     
   912     
   913     def _getPYTHONcodepath(self):
       
   914         # define name for IEC raw code file
       
   915         return os.path.join(self.PlugPath(), "runtime.py")
       
   916 
       
   917     def _getWXGLADEpath(self):
       
   918         # define name for IEC raw code file
       
   919         return os.path.join(self.PlugPath(), "hmi.wxg")
       
   920 
       
   921     def GetLocations(self):
   913     def GetLocations(self):
   922         locations = []
   914         locations = []
   923         filepath = os.path.join(self._getBuildPath(),"LOCATED_VARIABLES.h")
   915         filepath = os.path.join(self._getBuildPath(),"LOCATED_VARIABLES.h")
   924         if os.path.isfile(filepath):
   916         if os.path.isfile(filepath):
   925             # IEC2C compiler generate a list of located variables : LOCATED_VARIABLES.h
   917             # IEC2C compiler generate a list of located variables : LOCATED_VARIABLES.h
  1071         if builder is not None:
  1063         if builder is not None:
  1072             return builder.GetBinaryCodeMD5()
  1064             return builder.GetBinaryCodeMD5()
  1073         else:
  1065         else:
  1074             return None
  1066             return None
  1075 
  1067 
  1076     def launch_wxglade(self, options, wait=False):
       
  1077         from wxglade import __file__ as fileName
       
  1078         path = os.path.dirname(fileName)
       
  1079         glade = os.path.join(path, 'wxglade.py')
       
  1080         if wx.Platform == '__WXMSW__':
       
  1081             glade = "\"%s\""%glade
       
  1082         mode = {False:os.P_NOWAIT, True:os.P_WAIT}[wait]
       
  1083         os.spawnv(mode, sys.executable, ["\"%s\""%sys.executable] + [glade] + options)
       
  1084 
       
  1085     #######################################################################
  1068     #######################################################################
  1086     #
  1069     #
  1087     #                C CODE GENERATION METHODS
  1070     #                C CODE GENERATION METHODS
  1088     #
  1071     #
  1089     #######################################################################
  1072     #######################################################################
  1094         when _generate_softPLC have been called
  1077         when _generate_softPLC have been called
  1095         @param locations: ignored
  1078         @param locations: ignored
  1096         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
  1079         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
  1097         """
  1080         """
  1098 
  1081 
  1099         res = ([(C_file_name, self.plcCFLAGS) 
  1082         return ([(C_file_name, self.plcCFLAGS) 
  1100                 for C_file_name in self.PLCGeneratedCFiles ], 
  1083                 for C_file_name in self.PLCGeneratedCFiles ], 
  1101                "", # no ldflags
  1084                "", # no ldflags
  1102                False) # do not expose retreive/publish calls
  1085                False) # do not expose retreive/publish calls
  1103         
       
  1104         pyfile=self._getPYTHONcodepath()
       
  1105         if os.path.exists(pyfile):
       
  1106             res += (("runtime.py", file(pyfile,"rb")),)
       
  1107         wxgfile=self._getWXGLADEpath()
       
  1108         if os.path.exists(wxgfile):
       
  1109             hmipyfile=os.path.join(self._getBuildPath(),"hmi.py")
       
  1110             if wx.Platform == '__WXMSW__':
       
  1111                 wxgfile = "\"%s\""%wxgfile
       
  1112                 _hmipyfile = "\"%s\""%hmipyfile
       
  1113             else:
       
  1114                 _hmipyfile = hmipyfile
       
  1115             self.launch_wxglade(['-o', _hmipyfile, '-g', 'python', wxgfile], wait=True)
       
  1116             res += (("hmi.py", file(hmipyfile,"rb")),)
       
  1117 
       
  1118         return res
       
  1119 
       
  1120     
  1086     
  1121     def ResetIECProgramsAndVariables(self):
  1087     def ResetIECProgramsAndVariables(self):
  1122         """
  1088         """
  1123         Reset variable and program list that are parsed from
  1089         Reset variable and program list that are parsed from
  1124         CSV file generated by IEC2C compiler.
  1090         CSV file generated by IEC2C compiler.
  1208                 "VAR":"    variable_table[%(num)s].ptrvalue = (void*)(&%(C_path)s);\n"}[v["vartype"]]%v + 
  1174                 "VAR":"    variable_table[%(num)s].ptrvalue = (void*)(&%(C_path)s);\n"}[v["vartype"]]%v + 
  1209                 "    variable_table[%(num)s].type = %(type)s_ENUM;\n"%v
  1175                 "    variable_table[%(num)s].type = %(type)s_ENUM;\n"%v
  1210                 for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypes ])}
  1176                 for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypes ])}
  1211         
  1177         
  1212         return debug_code
  1178         return debug_code
  1213         
       
  1214     def Generate_plc_python(self):
       
  1215         """
       
  1216         Generate trace/debug code out of PLC variable list
       
  1217         """
       
  1218         self.GetIECProgramsAndVariables()
       
  1219 
       
  1220         python_eval_fb_list = []
       
  1221         for v in self._VariablesList :
       
  1222             if v["vartype"] == "FB" and v["type"] in ["PYTHON_EVAL","PYTHON_POLL"]:
       
  1223                 python_eval_fb_list.append(v)
       
  1224         python_eval_fb_count = max(1, len(python_eval_fb_list))
       
  1225         
       
  1226         # prepare debug code
       
  1227         python_code = targets.code("plc_python") % {
       
  1228            "python_eval_fb_count": python_eval_fb_count}
       
  1229         return python_code
       
  1230         
  1179         
  1231     def Generate_plc_common_main(self):
  1180     def Generate_plc_common_main(self):
  1232         """
  1181         """
  1233         Use plugins layout given in LocationCFilesAndCFLAGS to
  1182         Use plugins layout given in LocationCFilesAndCFLAGS to
  1234         generate glue code that dispatch calls to all plugins
  1183         generate glue code that dispatch calls to all plugins
  1332         # Template based part of C code generation
  1281         # Template based part of C code generation
  1333         # files are stacked at the beginning, as files of plugin tree root
  1282         # files are stacked at the beginning, as files of plugin tree root
  1334         for generator, filename, name in [
  1283         for generator, filename, name in [
  1335            # debugger code
  1284            # debugger code
  1336            (self.Generate_plc_debugger, "plc_debugger.c", "Debugger"),
  1285            (self.Generate_plc_debugger, "plc_debugger.c", "Debugger"),
  1337            # IEC<->python gateway code
       
  1338            (self.Generate_plc_python, "plc_python.c", "IEC-Python gateway"),
       
  1339            # init/cleanup/retrieve/publish, run and align code
  1286            # init/cleanup/retrieve/publish, run and align code
  1340            (self.Generate_plc_common_main,"plc_common_main.c","Common runtime")]:
  1287            (self.Generate_plc_common_main,"plc_common_main.c","Common runtime")]:
  1341             try:
  1288             try:
  1342                 # Do generate
  1289                 # Do generate
  1343                 code = generator()
  1290                 code = generator()
  1405         ST_viewer.SetKeywords(IEC_KEYWORDS)
  1352         ST_viewer.SetKeywords(IEC_KEYWORDS)
  1406         ST_viewer.RefreshView()
  1353         ST_viewer.RefreshView()
  1407             
  1354             
  1408         new_dialog.Show()
  1355         new_dialog.Show()
  1409 
  1356 
  1410     def _editPYTHONcode(self):
       
  1411         from PythonSTC import PythonCodePanel
       
  1412         new_dialog = wx.Frame(self.AppFrame)
       
  1413         
       
  1414         PYTHON_viewer = PythonCodePanel(new_dialog, self.AppFrame)
       
  1415         #ST_viewer.Enable(False)
       
  1416         pyfile=self._getPYTHONcodepath()
       
  1417         PYTHON_viewer.LoadSourceFile(pyfile)
       
  1418             
       
  1419         new_dialog.Show()
       
  1420 
       
  1421     def _editWXGLADE(self):
       
  1422         wxg_filename = self._getWXGLADEpath()
       
  1423         if not os.path.exists(wxg_filename):
       
  1424             open(wxg_filename,"w").write("""<?xml version="1.0"?>
       
  1425 <application path="" name="" class="" option="0" language="python" top_window="frame_1" encoding="UTF-8" use_gettext="0" overwrite="0" use_new_namespace="1" for_version="2.8" is_template="0">
       
  1426     <object class="HMIFrame" name="frame_1" base="EditFrame">
       
  1427         <style>wxDEFAULT_FRAME_STYLE</style>
       
  1428         <title>frame_1</title>
       
  1429     </object>
       
  1430 </application>
       
  1431 """)
       
  1432         if wx.Platform == '__WXMSW__':
       
  1433             wxg_filename = "\"%s\""%wxg_filename
       
  1434         self.launch_wxglade([wxg_filename])
       
  1435         
       
  1436     def _EditPLC(self):
  1357     def _EditPLC(self):
  1437         if self.PLCEditor is None:
  1358         if self.PLCEditor is None:
  1438             self.RefreshPluginsBlockLists()
  1359             self.RefreshPluginsBlockLists()
  1439             def _onclose():
  1360             def _onclose():
  1440                 self.PLCEditor = None
  1361                 self.PLCEditor = None
  1871          "method" : "_showIECcode"},
  1792          "method" : "_showIECcode"},
  1872         {"bitmap" : opjimg("editIECrawcode"),
  1793         {"bitmap" : opjimg("editIECrawcode"),
  1873          "name" : _("Raw IEC code"),
  1794          "name" : _("Raw IEC code"),
  1874          "tooltip" : _("Edit raw IEC code added to code generated by PLCGenerator"),
  1795          "tooltip" : _("Edit raw IEC code added to code generated by PLCGenerator"),
  1875          "method" : "_editIECrawcode"},
  1796          "method" : "_editIECrawcode"},
  1876         {"bitmap" : opjimg("editPYTHONcode"),
       
  1877          "name" : "Python code",
       
  1878          "tooltip" : "Write Python runtime code, for use with python_eval FBs",
       
  1879          "method" : "_editPYTHONcode"},
       
  1880         {"bitmap" : opjimg("editWXGLADE"),
       
  1881          "name" : "WXGLADE GUI",
       
  1882          "tooltip" : "Edit a WxWidgets GUI with WXGlade",
       
  1883          "method" : "_editWXGLADE"},
       
  1884     ]
  1797     ]