--- a/py_ext/PythonFileCTNMixin.py Tue May 14 18:42:29 2013 +0200
+++ b/py_ext/PythonFileCTNMixin.py Tue May 14 18:43:52 2013 +0200
@@ -46,7 +46,19 @@
def PythonFileName(self):
return os.path.join(self.CTNPath(), "py_ext.xml")
- def GetSectionsCode(self):
+ PreSectionsTexts = {}
+ PostSectionsTexts = {}
+ def GetSection(self,section):
+ return self.PreSectionsTexts.get(section,"") + "\n" + \
+ getattr(self.CodeFile, section).gettext() + "\n" + \
+ self.PostSectionsTexts.get(section,"")
+
+
+ def CTNGenerate_C(self, buildpath, locations):
+ current_location = self.GetCurrentLocation()
+ # define a unique name for the generated C file
+ location_str = "_".join(map(lambda x:str(x), current_location))
+
# Generate Beremiz python runtime variables code
config = self.GetCTRoot().GetProjectConfigNames()[0]
@@ -58,23 +70,95 @@
variable.getname(),
variable.gettype(),
str(variable.getinitial()))
-
- sections_code = {
- "variables": variables_str,
- "globals": self.CodeFile.globals.gettext().strip()
- }
-
- # Generate Beremiz python runtime functions code
+
+ # Runtime calls (start, stop, init, and cleanup)
+ rtcalls = ""
for section in self.SECTIONS_NAMES:
if section != "globals":
- code_object = getattr(self.CodeFile, section)
- section_str = ""
- lines = code_object.gettext().strip().splitlines()
- if len(lines) > 0:
- for line in lines:
- section_str += " " + line + "\n"
- section_str += "\n"
- sections_code[section] = section_str
-
- return sections_code
+ rtcalls += "def _runtime_%s_%s():\n" % (location_str, section)
+ sectiontext = self.GetSection(section).strip()
+ if sectiontext:
+ rtcalls += ' ' + \
+ sectiontext.strip().replace('\n', '\n ')+"\n"
+ else:
+ rtcalls += " pass\n\n"
+
+ text = """\
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## Code generated by Beremiz python mixin confnode
+##
+
+## Code for PLC global variable access
+%s
+
+## User code in "global" scope
+%s
+## Beremiz python runtime calls
+%s
+
+"""%( # variables
+ variables_str,
+ # globals
+ self.GetSection("globals"),
+ # Beremiz python runtime functions
+ rtcalls)
+
+ runtimefile_path = os.path.join(buildpath,
+ "runtime_%s.py"%location_str)
+ runtimefile = open(runtimefile_path, 'w')
+ runtimefile.write(text.encode('utf-8'))
+ runtimefile.close()
+
+ text = """\
+/*
+ * Code generated by Beremiz py_ext confnode
+ * for safe global variables access
+ */
+#include "iec_types_all.h"
+"""
+
+ # Adding variables
+ text += "/* User variables reference */\n"
+ for variable in self.CodeFile.variables.variable:
+ var_infos = {
+ "name": variable.getname(),
+ "global": "%s__%s" % (config.upper(),
+ variable.getname().upper()),
+ "type": "__IEC_%s_t" % variable.gettype()}
+ text += "extern %(type)s %(global)s;\n" % var_infos
+ text += "%(type)s __buffer_%(name)s;\n" % var_infos
+ text += "\n"
+
+ # Adding Beremiz confnode functions
+ text += "/* Beremiz confnode functions */\n"
+ text += "int __init_%s(int argc,char **argv)\n{\n"%location_str
+ text += "/*TODO*/\n"
+ text += " return 0;\n}\n\n"
+
+ text += "void __cleanup_%s(void)\n{\n"%location_str
+ text += "/*TODO*/\n"
+ text += "\n}\n\n"
+
+ text += "void __retrieve_%s(void)\n{\n"%location_str
+ text += "/*TODO*/\n"
+ text += "\n}\n\n"
+
+ text += "void __publish_%s(void)\n{\n"%location_str
+ text += "/*TODO*/\n"
+ text += "\n}\n\n"
+
+ Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c"%location_str)
+ pycfile = open(Gen_PyCfile_path,'w')
+ pycfile.write(text)
+ pycfile.close()
+
+ matiec_flags = '"-I%s"'%os.path.abspath(
+ self.GetCTRoot().GetIECLibPath())
+
+ return ([(Gen_PyCfile_path, matiec_flags)],
+ "",
+ False,
+ ("runtime_%s.py"%location_str, file(runtimefile_path,"rb")))
+
--- a/py_ext/py_ext.py Tue May 14 18:42:29 2013 +0200
+++ b/py_ext/py_ext.py Tue May 14 18:43:52 2013 +0200
@@ -8,18 +8,21 @@
def Generate_C(self, buildpath, varlist, IECCFLAGS):
- plc_python_filepath = os.path.join(os.path.split(__file__)[0], "plc_python.c")
+ plc_python_filepath = os.path.join(
+ os.path.split(__file__)[0], "plc_python.c")
plc_python_file = open(plc_python_filepath, 'r')
plc_python_code = plc_python_file.read()
plc_python_file.close()
python_eval_fb_list = []
for v in varlist:
- if v["vartype"] == "FB" and v["type"] in ["PYTHON_EVAL","PYTHON_POLL"]:
+ if v["vartype"] == "FB" and v["type"] in ["PYTHON_EVAL",
+ "PYTHON_POLL"]:
python_eval_fb_list.append(v)
python_eval_fb_count = max(1, len(python_eval_fb_list))
# prepare python code
- plc_python_code = plc_python_code % { "python_eval_fb_count": python_eval_fb_count }
+ plc_python_code = plc_python_code % {
+ "python_eval_fb_count": python_eval_fb_count }
Gen_Pythonfile_path = os.path.join(buildpath, "py_ext.c")
pythonfile = open(Gen_Pythonfile_path,'w')
@@ -33,41 +36,4 @@
def GetIconName(self):
return "Pyfile"
- def CTNGenerate_C(self, buildpath, locations):
- current_location = self.GetCurrentLocation()
- # define a unique name for the generated C file
- location_str = "_".join(map(lambda x:str(x), current_location))
-
- sections_code = self.GetSectionsCode()
-
- text = "## Code generated by Beremiz python mixin confnode\n\n"
-
- # Adding variables
- text += "## User variables reference\n"
- text += sections_code["variables"]
- text += "\n"
-
- # Adding user global variables and routines
- text += "## User internal user variables and routines\n"
- text += sections_code["globals"]
- text += "\n"
-
- # Adding Beremiz python runtime functions
- text += "## Beremiz python runtime functions\n"
- for section in self.SECTIONS_NAMES:
- if section != "globals":
- code_object = getattr(self.CodeFile, section)
- text += "def _runtime_%s_%s():\n" % (location_str, section)
- section_code = sections_code.get(section)
- if section_code:
- text += section_code
- else:
- text += " pass\n\n"
-
- runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
- runtimefile = open(runtimefile_path, 'w')
- runtimefile.write(text)
- runtimefile.close()
-
- return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
--- a/runtime/PLCObject.py Tue May 14 18:42:29 2013 +0200
+++ b/runtime/PLCObject.py Tue May 14 18:43:52 2013 +0200
@@ -264,7 +264,6 @@
self.python_runtime_vars["_runtime_%s"%methodname] = []
self.python_runtime_vars["PLCObject"] = self
self.python_runtime_vars["PLCBinary"] = self.PLClibraryHandle
-
try:
for filename in os.listdir(self.workingdir):
name, ext = os.path.splitext(filename)
@@ -274,7 +273,6 @@
method = self.python_runtime_vars.get("_%s_%s" % (name, methodname), None)
if method is not None:
self.python_runtime_vars["_runtime_%s"%methodname].append(method)
-
except:
self.LogMessage(0,traceback.format_exc())
raise
--- a/wxglade_hmi/wxglade_hmi.py Tue May 14 18:42:29 2013 +0200
+++ b/wxglade_hmi/wxglade_hmi.py Tue May 14 18:43:52 2013 +0200
@@ -38,19 +38,6 @@
return PythonFileCTNMixin.OnCTNSave(self, from_project_path)
def CTNGenerate_C(self, buildpath, locations):
- """
- Return C code generated by iec2c compiler
- when _generate_softPLC have been called
- @param locations: ignored
- @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
- """
-
- current_location = self.GetCurrentLocation()
- # define a unique name for the generated C file
- location_str = "_".join(map(lambda x:str(x), current_location))
-
- runtimefile_path = os.path.join(buildpath, "runtime_%s.py"%location_str)
- runtimefile = open(runtimefile_path, 'w')
hmi_frames = {}
@@ -73,65 +60,32 @@
self.launch_wxglade(['-o', wxghmipyfile_path, '-g', 'python', wxgfile_path], wait=True)
hmipyfile = open(hmipyfile_path, 'r')
- runtimefile.write(hmipyfile.read())
+ define_hmi = hmipyfile.read().decode('utf-8')
hmipyfile.close()
- sections_code = self.GetSectionsCode()
+ declare_hmi = "\n".join(map(lambda x:"%s = None" % x,
+ hmi_frames.keys()))
+ global_hmi = "global "+",".join(hmi_frames.keys())
+ init_hmi = "\n".join(map(lambda x: """\
+def OnCloseFrame(evt):
+ wx.MessageBox(_("Please stop PLC to close"))
+
+%(name)s = %(class)s(None)
+%(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
+%(name)s.Show()
+""" % {"name": x[0], "class": x[1]}, hmi_frames.items()))
+ cleanup_hmi = "\n".join(map(lambda x:"if %s is not None: %s.Destroy()" % (x,x), hmi_frames.keys()))
- # Adding variables
- runtimefile.write("## User variables reference\n" +
- sections_code["variables"] + "\n")
-
- # Adding user global variables and routines
- runtimefile.write("## User internal user variables and routines\n" +
- sections_code["globals"] + "\n")
-
- for section in ["init", "cleanup"]:
- if not sections_code[section]:
- sections_code[section] = " pass"
-
- sections_code.update({
- "location": location_str,
- "declare_hmi": "\n".join(map(lambda x:"%s = None" % x, hmi_frames.keys())),
- "global_hmi": ",".join(hmi_frames.keys()),
- "init_hmi": "\n".join(map(lambda x: """
- %(name)s = %(class)s(None)
- %(name)s.Bind(wx.EVT_CLOSE, OnCloseFrame)
- %(name)s.Show()
-""" % {"name": x[0], "class": x[1]},
- hmi_frames.items())),
- "cleanup_hmi": "\n ".join(map(lambda x:"if %s is not None: %s.Destroy()" % (x,x), hmi_frames.keys()))})
-
- runtimefile.write("""
-%(declare_hmi)s
+ self.PreSectionsTexts = {
+ "globals":define_hmi + declare_hmi,
+ "start":global_hmi,
+ "stop":global_hmi
+ }
+ self.PostSectionsTexts = {
+ "start":init_hmi,
+ }
-def _runtime_%(location)s_init():
-%(init)s
-
-def _runtime_%(location)s_cleanup():
-%(cleanup)s
-
-def _runtime_%(location)s_start():
- global %(global_hmi)s
-
-%(start)s
-
- def OnCloseFrame(evt):
- wx.MessageBox(_("Please stop PLC to close"))
-
- %(init_hmi)s
-
-def _runtime_%(location)s_stop():
- global %(global_hmi)s
-
- %(cleanup_hmi)s
-
-%(stop)s
-
-""" % sections_code)
- runtimefile.close()
-
- return [], "", False, ("runtime_%s.py"%location_str, file(runtimefile_path,"rb"))
+ return PythonFileCTNMixin.CTNGenerate_C(self, buildpath, locations)
def _editWXGLADE(self):
wxg_filename = self._getWXGLADEpath()