laurent@366: import os laurent@654: from PLCControler import UndoBuffer laurent@657: from PythonEditor import PythonEditor laurent@366: laurent@366: from xml.dom import minidom Laurent@1124: from xmlclass import GenerateClassesFromXSD laurent@366: import cPickle laurent@366: Laurent@1097: from CodeFileTreeNode import CodeFile Laurent@1097: Edouard@721: PythonClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) laurent@366: Laurent@1097: class PythonFileCTNMixin(CodeFile): laurent@366: Laurent@1124: CODEFILE_NAME = "PyFile" Laurent@1124: SECTIONS_NAMES = [ Laurent@1124: "globals", Laurent@1124: "init", Laurent@1124: "cleanup", Laurent@1124: "start", Laurent@1124: "stop"] laurent@657: EditorType = PythonEditor laurent@657: laurent@366: def __init__(self): Laurent@1097: CodeFile.__init__(self) laurent@366: laurent@366: filepath = self.PythonFileName() laurent@366: Laurent@1097: python_code = PythonClasses["Python"]() laurent@366: if os.path.isfile(filepath): laurent@366: xmlfile = open(filepath, 'r') laurent@366: tree = minidom.parse(xmlfile) laurent@366: xmlfile.close() laurent@366: laurent@366: for child in tree.childNodes: laurent@366: if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "Python": Laurent@1097: python_code.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"]) Laurent@1097: self.CodeFile.globals.settext(python_code.gettext()) Laurent@1097: os.remove(filepath) Laurent@1097: self.CreateCodeFileBuffer(False) Laurent@1097: self.OnCTNSave() Laurent@1097: Laurent@1097: def CodeFileName(self): Laurent@1097: return os.path.join(self.CTNPath(), "pyfile.xml") Laurent@1097: laurent@366: def PythonFileName(self): Edouard@721: return os.path.join(self.CTNPath(), "py_ext.xml") laurent@366: Edouard@1132: PreSectionsTexts = {} Edouard@1132: PostSectionsTexts = {} Edouard@1132: def GetSection(self,section): Edouard@1132: return self.PreSectionsTexts.get(section,"") + "\n" + \ Edouard@1132: getattr(self.CodeFile, section).gettext() + "\n" + \ Edouard@1132: self.PostSectionsTexts.get(section,"") Edouard@1132: Edouard@1132: Edouard@1132: def CTNGenerate_C(self, buildpath, locations): Edouard@1132: current_location = self.GetCurrentLocation() Edouard@1132: # define a unique name for the generated C file Edouard@1132: location_str = "_".join(map(lambda x:str(x), current_location)) Edouard@1132: Laurent@1097: Laurent@1124: # Generate Beremiz python runtime variables code Laurent@1103: config = self.GetCTRoot().GetProjectConfigNames()[0] Laurent@1124: variables_str = "" Laurent@1097: for variable in self.CodeFile.variables.variable: Laurent@1103: global_name = "%s_%s" % (config.upper(), variable.getname().upper()) Laurent@1124: variables_str += "# global_var:%s python_var:%s type:%s initial:%s\n" % ( Laurent@1103: global_name, Laurent@1103: variable.getname(), Laurent@1103: variable.gettype(), Laurent@1103: str(variable.getinitial())) Edouard@1132: Edouard@1132: # Runtime calls (start, stop, init, and cleanup) Edouard@1132: rtcalls = "" Laurent@1124: for section in self.SECTIONS_NAMES: Laurent@1124: if section != "globals": Edouard@1132: rtcalls += "def _runtime_%s_%s():\n" % (location_str, section) Edouard@1132: sectiontext = self.GetSection(section).strip() Edouard@1132: if sectiontext: Edouard@1132: rtcalls += ' ' + \ Edouard@1132: sectiontext.strip().replace('\n', '\n ')+"\n" Edouard@1132: else: Edouard@1132: rtcalls += " pass\n\n" Edouard@1132: Edouard@1132: text = """\ Edouard@1132: #!/usr/bin/env python Edouard@1132: # -*- coding: utf-8 -*- Edouard@1132: ## Code generated by Beremiz python mixin confnode Edouard@1132: ## Edouard@1132: Edouard@1132: ## Code for PLC global variable access Edouard@1132: %s Edouard@1132: Edouard@1132: ## User code in "global" scope Edouard@1132: %s laurent@366: Edouard@1132: ## Beremiz python runtime calls Edouard@1132: %s Edouard@1132: Edouard@1132: """%( # variables Edouard@1132: variables_str, Edouard@1132: # globals Edouard@1132: self.GetSection("globals"), Edouard@1132: # Beremiz python runtime functions Edouard@1132: rtcalls) Edouard@1132: Edouard@1132: runtimefile_path = os.path.join(buildpath, Edouard@1132: "runtime_%s.py"%location_str) Edouard@1132: runtimefile = open(runtimefile_path, 'w') Edouard@1132: runtimefile.write(text.encode('utf-8')) Edouard@1132: runtimefile.close() Edouard@1132: Edouard@1132: text = """\ Edouard@1132: /* Edouard@1132: * Code generated by Beremiz py_ext confnode Edouard@1132: * for safe global variables access Edouard@1132: */ Edouard@1132: #include "iec_types_all.h" Edouard@1132: """ Edouard@1132: Edouard@1132: # Adding variables Edouard@1132: text += "/* User variables reference */\n" Edouard@1132: for variable in self.CodeFile.variables.variable: Edouard@1132: var_infos = { Edouard@1132: "name": variable.getname(), Edouard@1132: "global": "%s__%s" % (config.upper(), Edouard@1132: variable.getname().upper()), Edouard@1132: "type": "__IEC_%s_t" % variable.gettype()} Edouard@1132: text += "extern %(type)s %(global)s;\n" % var_infos Edouard@1132: text += "%(type)s __buffer_%(name)s;\n" % var_infos Edouard@1132: text += "\n" Edouard@1132: Edouard@1132: # Adding Beremiz confnode functions Edouard@1132: text += "/* Beremiz confnode functions */\n" Edouard@1132: text += "int __init_%s(int argc,char **argv)\n{\n"%location_str Edouard@1132: text += "/*TODO*/\n" Edouard@1132: text += " return 0;\n}\n\n" Edouard@1132: Edouard@1132: text += "void __cleanup_%s(void)\n{\n"%location_str Edouard@1132: text += "/*TODO*/\n" Edouard@1132: text += "\n}\n\n" Edouard@1132: Edouard@1132: text += "void __retrieve_%s(void)\n{\n"%location_str Edouard@1132: text += "/*TODO*/\n" Edouard@1132: text += "\n}\n\n" Edouard@1132: Edouard@1132: text += "void __publish_%s(void)\n{\n"%location_str Edouard@1132: text += "/*TODO*/\n" Edouard@1132: text += "\n}\n\n" Edouard@1132: Edouard@1132: Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c"%location_str) Edouard@1132: pycfile = open(Gen_PyCfile_path,'w') Edouard@1132: pycfile.write(text) Edouard@1132: pycfile.close() Edouard@1132: Edouard@1132: matiec_flags = '"-I%s"'%os.path.abspath( Edouard@1132: self.GetCTRoot().GetIECLibPath()) Edouard@1132: Edouard@1132: return ([(Gen_PyCfile_path, matiec_flags)], Edouard@1132: "", Edouard@1132: False, Edouard@1132: ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))) Edouard@1132: