--- a/ProjectController.py Tue Aug 07 13:35:28 2018 +0200
+++ b/ProjectController.py Wed Aug 08 10:15:51 2018 +0200
@@ -65,7 +65,8 @@
base_folder = paths.AbsParentDir(__file__)
-MATIEC_ERROR_MODEL = re.compile(".*\.st:(\d+)-(\d+)\.\.(\d+)-(\d+): (?:error)|(?:warning) : (.*)$")
+MATIEC_ERROR_MODEL = re.compile(
+ ".*\.st:(\d+)-(\d+)\.\.(\d+)-(\d+): (?:error)|(?:warning) : (.*)$")
def ExtractChildrenTypesFromCatalog(catalog):
@@ -94,6 +95,7 @@
class Iec2CSettings(object):
+
def __init__(self):
self.iec2c = None
self.iec2c_buildopts = None
@@ -109,11 +111,12 @@
return path
def findCmd(self):
- cmd = "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else "")
+ cmd = "iec2c" + (".exe" if wx.Platform == '__WXMSW__' else "")
paths = [
os.path.join(base_folder, "matiec")
]
- path = self.findObject(paths, lambda p: os.path.isfile(os.path.join(p, cmd)))
+ path = self.findObject(
+ paths, lambda p: os.path.isfile(os.path.join(p, cmd)))
# otherwise use iec2c from PATH
if path is not None:
@@ -126,7 +129,8 @@
os.path.join(base_folder, "matiec", "lib"),
"/usr/lib/matiec"
]
- path = self.findObject(paths, lambda p: os.path.isfile(os.path.join(p, "ieclib.txt")))
+ path = self.findObject(
+ paths, lambda p: os.path.isfile(os.path.join(p, "ieclib.txt")))
return path
def findLibCPath(self):
@@ -146,7 +150,8 @@
buildopt = ""
try:
- # Invoke compiler. Output files are listed to stdout, errors to stderr
+ # Invoke compiler.
+ # Output files are listed to stdout, errors to stderr
_status, result, _err_result = ProcessLogger(None, buildcmd,
no_stdout=True,
no_stderr=True).spin()
@@ -186,17 +191,17 @@
<xsd:element name="TargetType">
<xsd:complexType>
<xsd:choice minOccurs="0">
- """+targets.GetTargetChoices()+"""
+ """ + targets.GetTargetChoices() + """
</xsd:choice>
</xsd:complexType>
- </xsd:element>"""+(("""
+ </xsd:element>""" + (("""
<xsd:element name="Libraries" minOccurs="0">
<xsd:complexType>
- """+"\n".join(['<xsd:attribute name=' +
- '"Enable_' + libname + '_Library" ' +
- 'type="xsd:boolean" use="optional" default="' +
- ('true' if default else 'false') + '"/>'
- for libname, _lib, default in features.libraries])+"""
+ """ + "\n".join(['<xsd:attribute name=' +
+ '"Enable_' + libname + '_Library" ' +
+ 'type="xsd:boolean" use="optional" default="' +
+ ('true' if default else 'false') + '"/>'
+ for libname, _lib, default in features.libraries]) + """
</xsd:complexType>
</xsd:element>""") if len(features.libraries) > 0 else '') + """
</xsd:sequence>
@@ -206,11 +211,11 @@
</xsd:element>
</xsd:schema>
"""
- print XSD
return XSD
class ProjectController(ConfigTreeNode, PLCControler):
+
"""
This class define Root object of the confnode tree.
It is responsible of :
@@ -221,7 +226,8 @@
- ...
"""
- # For root object, available Children Types are modules of the confnode packages.
+ # For root object, available Children Types are modules of the confnode
+ # packages.
CTNChildrenTypes = ExtractChildrenTypesFromCatalog(features.catalog)
XSD = GetProjectControllerXSD()
EditorType = ProjectNodeEditor
@@ -272,8 +278,10 @@
def LoadLibraries(self):
self.Libraries = []
TypeStack = []
- for libname, clsname, default in features.libraries:
- if self.BeremizRoot.Libraries is not None and getattr(self.BeremizRoot.Libraries, "Enable_"+libname+"_Library"):
+ for libname, clsname, _default in features.libraries:
+ if self.BeremizRoot.Libraries is not None and \
+ getattr(self.BeremizRoot.Libraries,
+ "Enable_" + libname + "_Library"):
Lib = GetClassImporter(clsname)()(self, libname, TypeStack)
TypeStack.append(Lib.GetTypes())
self.Libraries.append(Lib)
@@ -363,7 +371,8 @@
target = self.Parser.CreateElement("TargetType", "BeremizRoot")
temp_root.setTargetType(target)
target_name = self.GetDefaultTargetName()
- target.setcontent(self.Parser.CreateElement(target_name, "TargetType"))
+ target.setcontent(
+ self.Parser.CreateElement(target_name, "TargetType"))
return target
def GetParamsAttributes(self, path=None):
@@ -371,7 +380,8 @@
if params[0]["name"] == "BeremizRoot":
for child in params[0]["children"]:
if child["name"] == "TargetType" and child["value"] == '':
- child.update(self.GetTarget().getElementInfos("TargetType"))
+ child.update(
+ self.GetTarget().getElementInfos("TargetType"))
return params
def SetParamsAttribute(self, path, value):
@@ -405,7 +415,8 @@
def _getProjectFilesPath(self, project_path=None):
if project_path is not None:
return os.path.join(project_path, "project_files")
- projectfiles_path = os.path.join(self.GetProjectPath(), "project_files")
+ projectfiles_path = os.path.join(
+ self.GetProjectPath(), "project_files")
if not os.path.exists(projectfiles_path):
os.mkdir(projectfiles_path)
return projectfiles_path
@@ -416,7 +427,8 @@
def SetProjectDefaultConfiguration(self):
# Sets default task and instance for new project
- config = self.Project.getconfiguration(self.GetProjectMainConfigurationName())
+ config = self.Project.getconfiguration(
+ self.GetProjectMainConfigurationName())
resource = config.getresource()[0].getname()
config = config.getname()
resource_tagname = ComputeConfigurationResourceName(config, resource)
@@ -473,7 +485,8 @@
if error is not None:
if self.Project is not None:
(fname_err, lnum, src) = (("PLC",) + error)
- self.logger.write_warning(XSDSchemaErrorMessage.format(a1=fname_err, a2=lnum, a3=src))
+ self.logger.write_warning(
+ XSDSchemaErrorMessage.format(a1=fname_err, a2=lnum, a3=src))
else:
return error, False
if len(self.GetProjectConfigNames()) == 0:
@@ -530,14 +543,17 @@
def CheckNewProjectPath(self, old_project_path, new_project_path):
if old_project_path == new_project_path:
message = (_("Save path is the same as path of a project! \n"))
- dialog = wx.MessageDialog(self.AppFrame, message, _("Error"), wx.OK | wx.ICON_ERROR)
+ dialog = wx.MessageDialog(
+ self.AppFrame, message, _("Error"), wx.OK | wx.ICON_ERROR)
dialog.ShowModal()
return False
else:
plc_file = os.path.join(new_project_path, "plc.xml")
if os.path.isfile(plc_file):
- message = (_("Selected directory already contains another project. Overwrite? \n"))
- dialog = wx.MessageDialog(self.AppFrame, message, _("Error"), wx.YES_NO | wx.ICON_ERROR)
+ message = (
+ _("Selected directory already contains another project. Overwrite? \n"))
+ dialog = wx.MessageDialog(
+ self.AppFrame, message, _("Error"), wx.YES_NO | wx.ICON_ERROR)
answer = dialog.ShowModal()
return answer == wx.ID_YES
return True
@@ -545,7 +561,8 @@
def SaveProject(self, from_project_path=None):
if self.CheckProjectPathPerm(False):
if from_project_path is not None:
- old_projectfiles_path = self._getProjectFilesPath(from_project_path)
+ old_projectfiles_path = self._getProjectFilesPath(
+ from_project_path)
if os.path.isdir(old_projectfiles_path):
shutil.copytree(old_projectfiles_path,
self._getProjectFilesPath(self.ProjectPath))
@@ -560,7 +577,8 @@
path = os.getenv("USERPROFILE")
else:
path = os.getenv("HOME")
- dirdialog = wx.DirDialog(self.AppFrame, _("Choose a directory to save project"), path, wx.DD_NEW_DIR_BUTTON)
+ dirdialog = wx.DirDialog(
+ self.AppFrame, _("Choose a directory to save project"), path, wx.DD_NEW_DIR_BUTTON)
answer = dirdialog.ShowModal()
dirdialog.Destroy()
if answer == wx.ID_OK:
@@ -584,7 +602,8 @@
if len(self.Libraries) == 0:
return [], [], ()
self.GetIECProgramsAndVariables()
- LibIECCflags = '"-I%s" -Wno-unused-function' % os.path.abspath(self.GetIECLibPath())
+ LibIECCflags = '"-I%s" -Wno-unused-function' % os.path.abspath(
+ self.GetIECLibPath())
LocatedCCodeAndFlags = []
Extras = []
for lib in self.Libraries:
@@ -592,7 +611,7 @@
LocatedCCodeAndFlags.append(res[:2])
if len(res) > 2:
Extras.extend(res[2:])
- return map(list, zip(*LocatedCCodeAndFlags))+[tuple(Extras)]
+ return map(list, zip(*LocatedCCodeAndFlags)) + [tuple(Extras)]
# Update PLCOpenEditor ConfNode Block types from loaded confnodes
def RefreshConfNodesBlockLists(self):
@@ -658,7 +677,8 @@
self.DefaultBuildPath = os.path.join(self.ProjectPath, "build")
# Create a build path in temp folder
else:
- self.DefaultBuildPath = os.path.join(tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build")
+ self.DefaultBuildPath = os.path.join(
+ tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build")
if not os.path.exists(self.DefaultBuildPath):
os.makedirs(self.DefaultBuildPath)
@@ -683,19 +703,23 @@
locations = []
filepath = os.path.join(self._getBuildPath(), "LOCATED_VARIABLES.h")
if os.path.isfile(filepath):
- # IEC2C compiler generate a list of located variables : LOCATED_VARIABLES.h
- location_file = open(os.path.join(self._getBuildPath(), "LOCATED_VARIABLES.h"))
+ # IEC2C compiler generate a list of located variables :
+ # LOCATED_VARIABLES.h
+ location_file = open(
+ os.path.join(self._getBuildPath(), "LOCATED_VARIABLES.h"))
# each line of LOCATED_VARIABLES.h declares a located variable
lines = [line.strip() for line in location_file.readlines()]
# This regular expression parses the lines genereated by IEC2C
- LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWDL]))?,(?P<LOC>[,0-9]*)\)")
+ LOCATED_MODEL = re.compile(
+ "__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWDL]))?,(?P<LOC>[,0-9]*)\)")
for line in lines:
# If line match RE,
result = LOCATED_MODEL.match(line)
if result:
# Get the resulting dict
resdict = result.groupdict()
- # rewrite string for variadic location as a tuple of integers
+ # rewrite string for variadic location as a tuple of
+ # integers
resdict['LOC'] = tuple(map(int, resdict['LOC'].split(',')))
# set located size to 'X' if not given
if not resdict['SIZE']:
@@ -721,16 +745,20 @@
# Update PLCOpenEditor ConfNode Block types before generate ST code
self.RefreshConfNodesBlockLists()
- self.logger.write(_("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n"))
+ self.logger.write(
+ _("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n"))
# ask PLCOpenEditor controller to write ST/IL/SFC code file
- _program, errors, warnings = self.GenerateProgram(self._getIECgeneratedcodepath())
+ _program, errors, warnings = self.GenerateProgram(
+ self._getIECgeneratedcodepath())
if len(warnings) > 0:
- self.logger.write_warning(_("Warnings in ST/IL/SFC code generator :\n"))
+ self.logger.write_warning(
+ _("Warnings in ST/IL/SFC code generator :\n"))
for warning in warnings:
self.logger.write_warning("%s\n" % warning)
if len(errors) > 0:
# Failed !
- self.logger.write_error(_("Error in ST/IL/SFC code generator :\n%s\n") % errors[0])
+ self.logger.write_error(
+ _("Error in ST/IL/SFC code generator :\n%s\n") % errors[0])
return False
plc_file = open(self._getIECcodepath(), "w")
# Add ST Library from confnodes
@@ -765,9 +793,11 @@
self._getIECcodepath())
try:
- # Invoke compiler. Output files are listed to stdout, errors to stderr
+ # Invoke compiler.
+ # Output files are listed to stdout, errors to stderr
status, result, err_result = ProcessLogger(self.logger, buildcmd,
- no_stdout=True, no_stderr=True).spin()
+ no_stdout=True,
+ no_stderr=True).spin()
except Exception, e:
self.logger.write_error(buildcmd + "\n")
self.logger.write_error(repr(e) + "\n")
@@ -796,29 +826,36 @@
if first_line <= i <= last_line:
if last_section is not None:
- self.logger.write_warning("In section: " + last_section)
+ self.logger.write_warning(
+ "In section: " + last_section)
last_section = None # only write section once
self.logger.write_warning("%04d: %s" % (i, line))
f.close()
- self.logger.write_error(_("Error : IEC to C compiler returned %d\n") % status)
+ self.logger.write_error(
+ _("Error : IEC to C compiler returned %d\n") % status)
return False
# Now extract C files of stdout
- C_files = [fname for fname in result.splitlines() if fname[-2:] == ".c" or fname[-2:] == ".C"]
+ C_files = [fname for fname in result.splitlines() if fname[
+ -2:] == ".c" or fname[-2:] == ".C"]
# remove those that are not to be compiled because included by others
C_files.remove("POUS.c")
if not C_files:
- self.logger.write_error(_("Error : At least one configuration and one resource must be declared in PLC !\n"))
+ self.logger.write_error(
+ _("Error : At least one configuration and one resource must be declared in PLC !\n"))
return False
# transform those base names to full names with path
- C_files = map(lambda filename: os.path.join(buildpath, filename), C_files)
+ C_files = map(
+ lambda filename: os.path.join(buildpath, filename), C_files)
# prepend beremiz include to configuration header
- H_files = [fname for fname in result.splitlines() if fname[-2:] == ".h" or fname[-2:] == ".H"]
+ H_files = [fname for fname in result.splitlines() if fname[
+ -2:] == ".h" or fname[-2:] == ".H"]
H_files.remove("LOCATED_VARIABLES.h")
- H_files = map(lambda filename: os.path.join(buildpath, filename), H_files)
+ H_files = map(
+ lambda filename: os.path.join(buildpath, filename), H_files)
for H_file in H_files:
with file(H_file, 'r') as original:
data = original.read()
@@ -826,7 +863,8 @@
modified.write('#include "beremiz.h"\n' + data)
self.logger.write(_("Extracting Located Variables...\n"))
- # Keep track of generated located variables for later use by self._Generate_C
+ # Keep track of generated located variables for later use by
+ # self._Generate_C
self.PLCGeneratedLocatedVars = self.GetLocations()
# Keep track of generated C files for later use by self.CTNGenerate_C
self.PLCGeneratedCFiles = C_files
@@ -861,11 +899,11 @@
else:
return None
- #######################################################################
+ #
#
# C CODE GENERATION METHODS
#
- #######################################################################
+ #
def CTNGenerate_C(self, buildpath, locations):
"""
@@ -904,7 +942,8 @@
csvfile = os.path.join(self._getBuildPath(), "VARIABLES.csv")
# describes CSV columns
ProgramsListAttributeName = ["num", "C_path", "type"]
- VariablesListAttributeName = ["num", "vartype", "IEC_path", "C_path", "type"]
+ VariablesListAttributeName = [
+ "num", "vartype", "IEC_path", "C_path", "type"]
self._ProgramList = []
self._VariablesList = []
self._DbgVariablesList = []
@@ -924,9 +963,11 @@
# first section contains programs
for line in ListGroup[0]:
# Split and Maps each field to dictionnary entries
- attrs = dict(zip(ProgramsListAttributeName, line.strip().split(';')))
+ attrs = dict(
+ zip(ProgramsListAttributeName, line.strip().split(';')))
# Truncate "C_path" to remove conf an resources names
- attrs["C_path"] = '__'.join(attrs["C_path"].split(".", 2)[1:])
+ attrs["C_path"] = '__'.join(
+ attrs["C_path"].split(".", 2)[1:])
# Push this dictionnary into result.
self._ProgramList.append(attrs)
@@ -935,7 +976,8 @@
Idx = 0
for line in ListGroup[1]:
# Split and Maps each field to dictionnary entries
- attrs = dict(zip(VariablesListAttributeName, line.strip().split(';')))
+ attrs = dict(
+ zip(VariablesListAttributeName, line.strip().split(';')))
# Truncate "C_path" to remove conf an resources names
parts = attrs["C_path"].split(".", 2)
if len(parts) > 2:
@@ -966,7 +1008,8 @@
self._Ticktime = int(ListGroup[2][0])
except Exception:
- self.logger.write_error(_("Cannot open/parse VARIABLES.csv!\n"))
+ self.logger.write_error(
+ _("Cannot open/parse VARIABLES.csv!\n"))
self.logger.write_error(traceback.format_exc())
self.ResetIECProgramsAndVariables()
return False
@@ -1036,16 +1079,16 @@
"retrieve_calls": "\n ".join([
"__retrieve_%s();" % locstr for locstr in locstrs]),
"publish_calls": "\n ".join([ # Call publish in reverse order
- "__publish_%s();" % locstrs[i-1] for i in xrange(len(locstrs), 0, -1)]),
+ "__publish_%s();" % locstrs[i - 1] for i in xrange(len(locstrs), 0, -1)]),
"init_calls": "\n ".join([
- "init_level=%d; " % (i+1) +
+ "init_level=%d; " % (i + 1) +
"if((res = __init_%s(argc,argv))){" % locstr +
# "printf(\"%s\"); "%locstr + #for debug
"return res;}" for i, locstr in enumerate(locstrs)]),
"cleanup_calls": "\n ".join([
"if(init_level >= %d) " % i +
- "__cleanup_%s();" % locstrs[i-1] for i in xrange(len(locstrs), 0, -1)])
- }
+ "__cleanup_%s();" % locstrs[i - 1] for i in xrange(len(locstrs), 0, -1)])
+ }
else:
plc_main_code = targets.GetCode("plc_main_head.c") % {
"calls_prototypes": "\n",
@@ -1054,7 +1097,8 @@
"init_calls": "\n",
"cleanup_calls": "\n"
}
- plc_main_code += targets.GetTargetCode(self.GetTarget().getcontent().getLocalTag())
+ plc_main_code += targets.GetTargetCode(
+ self.GetTarget().getcontent().getLocalTag())
plc_main_code += targets.GetCode("plc_main_tail.c")
return plc_main_code
@@ -1126,21 +1170,25 @@
buildpath,
self.PLCGeneratedLocatedVars)
except Exception:
- self.logger.write_error(_("Runtime IO extensions C code generation failed !\n"))
+ self.logger.write_error(
+ _("Runtime IO extensions C code generation failed !\n"))
self.logger.write_error(traceback.format_exc())
self.ResetBuildMD5()
return False
# Generate C code and compilation params from liraries
try:
- LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(buildpath)
+ LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(
+ buildpath)
except Exception:
- self.logger.write_error(_("Runtime library extensions C code generation failed !\n"))
+ self.logger.write_error(
+ _("Runtime library extensions C code generation failed !\n"))
self.logger.write_error(traceback.format_exc())
self.ResetBuildMD5()
return False
- self.LocationCFilesAndCFLAGS = LibCFilesAndCFLAGS + CTNLocationCFilesAndCFLAGS
+ self.LocationCFilesAndCFLAGS = LibCFilesAndCFLAGS + \
+ CTNLocationCFilesAndCFLAGS
self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS
ExtraFiles = CTNExtraFiles + LibExtraFiles
@@ -1159,7 +1207,8 @@
del ExtraFiles
# Header file for extensions
- open(os.path.join(buildpath, "beremiz.h"), "w").write(targets.GetHeader())
+ open(os.path.join(buildpath, "beremiz.h"), "w").write(
+ targets.GetHeader())
# Template based part of C code generation
# files are stacked at the beginning, as files of confnode tree root
@@ -1178,10 +1227,12 @@
raise Exception
code_path = os.path.join(buildpath, filename)
open(code_path, "w").write(code)
- # Insert this file as first file to be compiled at root confnode
- self.LocationCFilesAndCFLAGS[0][1].insert(0, (code_path, self.plcCFLAGS))
+ # Insert this file as first file to be compiled at root
+ # confnode
+ self.LocationCFilesAndCFLAGS[0][1].insert(
+ 0, (code_path, self.plcCFLAGS))
except Exception:
- self.logger.write_error(name+_(" generation failed !\n"))
+ self.logger.write_error(name + _(" generation failed !\n"))
self.logger.write_error(traceback.format_exc())
self.ResetBuildMD5()
return False
@@ -1191,12 +1242,16 @@
def ShowError(self, logger, from_location, to_location):
chunk_infos = self.GetChunkInfos(from_location, to_location)
for infos, (start_row, start_col) in chunk_infos:
- row = 1 if from_location[0] < start_row else (from_location[0] - start_row)
- col = 1 if (start_row != from_location[0]) else (from_location[1] - start_col)
+ row = 1 if from_location[0] < start_row else (
+ from_location[0] - start_row)
+ col = 1 if (start_row != from_location[0]) else (
+ from_location[1] - start_col)
start = (row, col)
- row = 1 if to_location[0] < start_row else (to_location[0] - start_row)
- col = 1 if (start_row != to_location[0]) else (to_location[1] - start_col)
+ row = 1 if to_location[0] < start_row else (
+ to_location[0] - start_row)
+ col = 1 if (start_row != to_location[0]) else (
+ to_location[1] - start_col)
end = (row, col)
if self.AppFrame is not None:
@@ -1227,7 +1282,8 @@
if self._IECCodeView is None:
plc_file = self._getIECcodepath()
- self._IECCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, None, instancepath=name)
+ self._IECCodeView = IECCodeViewer(
+ self.AppFrame.TabsOpened, "", self.AppFrame, None, instancepath=name)
self._IECCodeView.SetTextSyntax("ALL")
self._IECCodeView.SetKeywords(IEC_KEYWORDS)
try:
@@ -1248,7 +1304,8 @@
if self._IECRawCodeView is None:
controler = MiniTextControler(self._getIECrawcodepath(), self)
- self._IECRawCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, controler, instancepath=name)
+ self._IECRawCodeView = IECCodeViewer(
+ self.AppFrame.TabsOpened, "", self.AppFrame, controler, instancepath=name)
self._IECRawCodeView.SetTextSyntax("ALL")
self._IECRawCodeView.SetKeywords(IEC_KEYWORDS)
self._IECRawCodeView.RefreshView()
@@ -1262,7 +1319,8 @@
elif name == "Project Files":
if self._ProjectFilesView is None:
- self._ProjectFilesView = FileManagementPanel(self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True)
+ self._ProjectFilesView = FileManagementPanel(
+ self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True)
extensions = []
for extension, name, editor in features.file_editors:
@@ -1304,7 +1362,8 @@
name = "::".join([filepath, editor_name])
editor = editors[editor_name]()
- self._FileEditors[filepath] = editor(self.AppFrame.TabsOpened, self, name, self.AppFrame)
+ self._FileEditors[filepath] = editor(
+ self.AppFrame.TabsOpened, self, name, self.AppFrame)
self._FileEditors[filepath].SetIcon(GetBitmap("FILE"))
if isinstance(self._FileEditors[filepath], DebugViewer):
self._FileEditors[filepath].SetDataProducer(self)
@@ -1395,18 +1454,20 @@
allmethods.update(
self.MethodsFromStatus.get(status, {}))
for method, active in allmethods.items():
- self.ShowMethod(method,active)
+ self.ShowMethod(method, active)
self.previous_plcstate = status
if self.AppFrame is not None:
updated = True
self.AppFrame.RefreshStatusToolBar()
if status == "Disconnected":
- self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 1)
+ self.AppFrame.ConnectionStatusBar.SetStatusText(
+ self.GetTextStatus(status), 1)
self.AppFrame.ConnectionStatusBar.SetStatusText('', 2)
else:
self.AppFrame.ConnectionStatusBar.SetStatusText(
_("Connected to URI: %s") % self.BeremizRoot.getURI_location().strip(), 1)
- self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 2)
+ self.AppFrame.ConnectionStatusBar.SetStatusText(
+ self.GetTextStatus(status), 2)
return updated
def GetTextStatus(self, status):
@@ -1416,12 +1477,13 @@
"Empty": _("Empty"),
"Broken": _("Broken"),
"Disconnected": _("Disconnected")
- }
+ }
return msgs.get(status, status)
def ShowPLCProgress(self, status="", progress=0):
self.AppFrame.ProgressStatusBar.Show()
- self.AppFrame.ConnectionStatusBar.SetStatusText(self.GetTextStatus(status), 1)
+ self.AppFrame.ConnectionStatusBar.SetStatusText(
+ self.GetTextStatus(status), 1)
self.AppFrame.ProgressStatusBar.SetValue(progress)
def HidePLCProgress(self):
@@ -1437,19 +1499,23 @@
def SnapshotAndResetDebugValuesBuffers(self):
if self._connector is not None:
plc_status, Traces = self._connector.GetTraceVariables()
- # print [dict.keys() for IECPath, (dict, log, status, fvalue) in self.IECdebug_datas.items()]
+ # print [dict.keys() for IECPath, (dict, log, status, fvalue) in
+ # self.IECdebug_datas.items()]
if plc_status == "Started":
if len(Traces) > 0:
for debug_tick, debug_buff in Traces:
- debug_vars = UnpackDebugBuffer(debug_buff, self.TracedIECTypes)
+ debug_vars = UnpackDebugBuffer(
+ debug_buff, self.TracedIECTypes)
if debug_vars is not None and len(debug_vars) == len(self.TracedIECPath):
for IECPath, values_buffer, value in izip(
self.TracedIECPath,
self.DebugValuesBuffers,
debug_vars):
- IECdebug_data = self.IECdebug_datas.get(IECPath, None)
+ IECdebug_data = self.IECdebug_datas.get(
+ IECPath, None)
if IECdebug_data is not None and value is not None:
- forced = IECdebug_data[2:4] == ["Forced", value]
+ forced = IECdebug_data[2:4] == [
+ "Forced", value]
if not IECdebug_data[4] and len(values_buffer) > 0:
values_buffer[-1] = (value, forced)
else:
@@ -1478,14 +1544,17 @@
IECPathsToPop.append(IECPath)
elif IECPath != "__tick__":
# Convert
- Idx, IEC_Type = self._IECPathToIdx.get(IECPath, (None, None))
+ Idx, IEC_Type = self._IECPathToIdx.get(
+ IECPath, (None, None))
if Idx is not None:
if IEC_Type in DebugTypesSize:
Idxs.append((Idx, IEC_Type, fvalue, IECPath))
else:
- self.logger.write_warning(_("Debug: Unsupported type to debug '%s'\n") % IEC_Type)
+ self.logger.write_warning(
+ _("Debug: Unsupported type to debug '%s'\n") % IEC_Type)
else:
- self.logger.write_warning(_("Debug: Unknown variable '%s'\n") % IECPath)
+ self.logger.write_warning(
+ _("Debug: Unknown variable '%s'\n") % IECPath)
for IECPathToPop in IECPathsToPop:
self.IECdebug_datas.pop(IECPathToPop)
@@ -1512,8 +1581,10 @@
# Links between PLC located variables and real variables are not ready
if self.IsPLCStarted():
# Timer to prevent rapid-fire when registering many variables
- # use wx.CallAfter use keep using same thread. TODO : use wx.Timer instead
- self.DebugTimer = Timer(0.5, wx.CallAfter, args=[self.RegisterDebugVarToConnector])
+ # use wx.CallAfter use keep using same thread. TODO : use wx.Timer
+ # instead
+ self.DebugTimer = Timer(
+ 0.5, wx.CallAfter, args=[self.RegisterDebugVarToConnector])
# Rearm anti-rapid-fire timer
self.DebugTimer.start()
@@ -1617,9 +1688,11 @@
if len(self.TracedIECPath) == len(buffers):
for IECPath, values in izip(self.TracedIECPath, buffers):
if len(values) > 0:
- self.CallWeakcallables(IECPath, "NewValues", debug_ticks, values)
+ self.CallWeakcallables(
+ IECPath, "NewValues", debug_ticks, values)
if len(debug_ticks) > 0:
- self.CallWeakcallables("__tick__", "NewDataAvailable", debug_ticks)
+ self.CallWeakcallables(
+ "__tick__", "NewDataAvailable", debug_ticks)
delay = time.time() - start_time
next_refresh = max(REFRESH_PERIOD - delay, 0.2 * delay)
@@ -1684,7 +1757,8 @@
def _Connect(self):
# don't accept re-connetion if already connected
if self._connector is not None:
- self.logger.write_error(_("Already connected. Please disconnect\n"))
+ self.logger.write_error(
+ _("Already connected. Please disconnect\n"))
return
# Get connector uri
@@ -1722,7 +1796,8 @@
try:
self._SetConnector(connectors.ConnectorFactory(uri, self))
except Exception:
- self.logger.write_error(_("Exception while connecting %s!\n") % uri)
+ self.logger.write_error(
+ _("Exception while connecting %s!\n") % uri)
self.logger.write_error(traceback.format_exc())
# Did connection success ?
@@ -1739,7 +1814,8 @@
self.logger.write(_("Debugger ready\n"))
self._connect_debug()
else:
- self.logger.write_warning(_("Debug does not match PLC - stop/transfert/start to re-enable\n"))
+ self.logger.write_warning(
+ _("Debug does not match PLC - stop/transfert/start to re-enable\n"))
def CompareLocalAndRemotePLC(self):
if self._connector is None:
@@ -1750,7 +1826,8 @@
if MD5 is not None:
if not self._connector.MatchMD5(MD5):
# self.logger.write_warning(
- # _("Latest build does not match with target, please transfer.\n"))
+ # _("Latest build does not match with target, please
+ # transfer.\n"))
self.EnableMethod("_Transfer", True)
else:
# self.logger.write(
@@ -1783,7 +1860,8 @@
# Check if md5 file is empty : ask user to build PLC
if MD5 is None:
- self.logger.write_error(_("Failed : Must build before transfer.\n"))
+ self.logger.write_error(
+ _("Failed : Must build before transfer.\n"))
return False
# Compare PLC project with PLC on target
@@ -1818,7 +1896,8 @@
self.logger.write_error(_("Transfer failed\n"))
self.HidePLCProgress()
else:
- self.logger.write_error(_("No PLC to transfer (did build succeed ?)\n"))
+ self.logger.write_error(
+ _("No PLC to transfer (did build succeed ?)\n"))
wx.CallAfter(self.UpdateMethodsFromPLCStatus)
--- a/runtime/WampClient.py Tue Aug 07 13:35:28 2018 +0200
+++ b/runtime/WampClient.py Wed Aug 08 10:15:51 2018 +0200
@@ -67,9 +67,9 @@
# de-activated dumb wamp config
defaultWampConfig = {
- "ID": "wamptest",
- "active": False,
- "realm": "Automation",
+ "ID": "wamptest",
+ "active": False,
+ "realm": "Automation",
"url": "ws://127.0.0.1:8888"
}
@@ -84,6 +84,7 @@
lastKnownConfig = None
+
def GetCallee(name):
""" Get Callee or Subscriber corresponding to '.' spearated object path """
names = name.split('.')
@@ -94,6 +95,7 @@
class WampSession(wamp.ApplicationSession):
+
def onConnect(self):
if "secret" in self.config.extra:
user = self.config.extra["ID"]
@@ -105,12 +107,14 @@
if challenge.method == u"wampcra":
if "secret" in self.config.extra:
secret = self.config.extra["secret"].encode('utf8')
- signature = auth.compute_wcs(secret, challenge.extra['challenge'].encode('utf8'))
+ signature = auth.compute_wcs(
+ secret, challenge.extra['challenge'].encode('utf8'))
return signature.decode("ascii")
else:
raise Exception("no secret given for authentication")
else:
- raise Exception("don't know how to handle authmethod {}".format(challenge.method))
+ raise Exception(
+ "don't know how to handle authmethod {}".format(challenge.method))
@inlineCallbacks
def onJoin(self, details):
@@ -144,6 +148,7 @@
class ReconnectingWampWebSocketClientFactory(WampWebSocketClientFactory, ReconnectingClientFactory):
+
def __init__(self, config, *args, **kwargs):
global _transportFactory
WampWebSocketClientFactory.__init__(self, *args, **kwargs)
@@ -163,15 +168,19 @@
def clientConnectionFailed(self, connector, reason):
if self.continueTrying:
- print(_("WAMP Client connection failed (%s) .. retrying ..") % time.ctime())
- super(ReconnectingWampWebSocketClientFactory, self).clientConnectionFailed(connector, reason)
+ print(_("WAMP Client connection failed (%s) .. retrying ..") %
+ time.ctime())
+ super(ReconnectingWampWebSocketClientFactory,
+ self).clientConnectionFailed(connector, reason)
else:
del connector
def clientConnectionLost(self, connector, reason):
if self.continueTrying:
- print(_("WAMP Client connection lost (%s) .. retrying ..") % time.ctime())
- super(ReconnectingWampWebSocketClientFactory, self).clientConnectionFailed(connector, reason)
+ print(_("WAMP Client connection lost (%s) .. retrying ..") %
+ time.ctime())
+ super(ReconnectingWampWebSocketClientFactory,
+ self).clientConnectionFailed(connector, reason)
else:
del connector
@@ -180,20 +189,22 @@
url = WampClientConf["url"]
if not IsCorrectUri(url):
raise annotate.ValidateError(
- {"url":"Invalid URL: {}".format(url)},
+ {"url": "Invalid URL: {}".format(url)},
_("WAMP configuration error:"))
+
def GetConfiguration():
global lastKnownConfig
if os.path.exists(_WampConf):
WampClientConf = json.load(open(_WampConf))
- else:
+ else:
WampClientConf = defaultWampConfig.copy()
for itemName in mandatoryConfigItems:
- if WampClientConf.get(itemName, None) is None :
- raise Exception(_("WAMP configuration error : missing '{}' parameter.").format(itemName))
+ if WampClientConf.get(itemName, None) is None:
+ raise Exception(
+ _("WAMP configuration error : missing '{}' parameter.").format(itemName))
CheckConfiguration(WampClientConf)
@@ -205,13 +216,14 @@
with open(os.path.realpath(_WampSecret), 'w') as f:
f.write(wampSecret)
+
def SetConfiguration(WampClientConf):
global lastKnownConfig
CheckConfiguration(WampClientConf)
lastKnownConfig = WampClientConf.copy()
-
+
with open(os.path.realpath(_WampConf), 'w') as f:
json.dump(WampClientConf, f, sort_keys=True, indent=4)
if 'active' in WampClientConf and WampClientConf['active']:
@@ -226,7 +238,7 @@
def LoadWampSecret(secretfname):
WSClientWampSecret = open(secretfname, 'rb').read()
- if len(WSClientWampSecret) == 0 :
+ if len(WSClientWampSecret) == 0:
raise Exception(_("WAMP secret empty"))
return WSClientWampSecret
@@ -252,7 +264,8 @@
# set secret file path only if not already set
if _WampSecret is None:
- # default project's wamp secret also has precedance over commandline given
+ # default project's wamp secret also
+ # has precedance over commandline given
if os.path.exists(_WampSecretDefault):
_WampSecret = _WampSecretDefault
else:
@@ -260,7 +273,7 @@
if _WampSecret is not None:
WampClientConf["secret"] = LoadWampSecret(_WampSecret)
- else :
+ else:
print(_("WAMP authentication has no secret configured"))
_WampSecret = _WampSecretDefault
@@ -285,7 +298,7 @@
# start the client from a Twisted endpoint
if _transportFactory:
- conn = connectWS(_transportFactory)
+ connectWS(_transportFactory)
print(_("WAMP client connecting to :"), WampClientConf["url"])
return True
else:
@@ -294,9 +307,9 @@
def StopReconnectWampClient():
- if _transportFactory is not None :
+ if _transportFactory is not None:
_transportFactory.stopTrying()
- if _WampSession is not None :
+ if _WampSession is not None:
_WampSession.leave()
@@ -314,10 +327,11 @@
def GetSession():
return _WampSession
+
def getWampStatus():
- if _transportFactory is not None :
- if _WampSession is not None :
- if _WampSession.is_attached() :
+ if _transportFactory is not None:
+ if _WampSession is not None:
+ if _WampSession.is_attached():
return "Attached"
return "Established"
return "Connecting"
@@ -328,14 +342,16 @@
_PySrv = pysrv
-#### WEB CONFIGURATION INTERFACE ####
+# WEB CONFIGURATION INTERFACE
WAMP_SECRET_URL = "secret"
webExposedConfigItems = ['active', 'url', 'ID']
-def wampConfigDefault(ctx,argument):
- if lastKnownConfig is not None :
+
+def wampConfigDefault(ctx, argument):
+ if lastKnownConfig is not None:
return lastKnownConfig.get(argument.name, None)
+
def wampConfig(**kwargs):
secretfile_field = kwargs["secretfile"]
if secretfile_field is not None:
@@ -347,69 +363,73 @@
newConfig = lastKnownConfig.copy()
for argname in webExposedConfigItems:
arg = kwargs.get(argname, None)
- if arg is not None :
+ if arg is not None:
newConfig[argname] = arg
SetConfiguration(newConfig)
+
class FileUploadDownload(annotate.FileUpload):
pass
class FileUploadDownloadRenderer(webform.FileUploadRenderer):
+
def input(self, context, slot, data, name, value):
+ # pylint: disable=expression-not-assigned
slot[_("Upload:")]
- slot = webform.FileUploadRenderer.input(self, context, slot, data, name, value)
+ slot = webform.FileUploadRenderer.input(
+ self, context, slot, data, name, value)
download_url = data.typedValue.getAttribute('download_url')
return slot[tags.a(href=download_url)[_("Download")]]
-registerAdapter(FileUploadDownloadRenderer, FileUploadDownload, formless.iformless.ITypedRenderer)
-
+registerAdapter(FileUploadDownloadRenderer, FileUploadDownload,
+ formless.iformless.ITypedRenderer)
+
+
def getDownloadUrl(ctx, argument):
- if lastKnownConfig is not None :
+ if lastKnownConfig is not None:
return url.URL.fromContext(ctx).\
child(WAMP_SECRET_URL).\
- child(lastKnownConfig["ID"]+".secret")
+ child(lastKnownConfig["ID"] + ".secret")
webFormInterface = [
("status",
- annotate.String(label=_("Current status"),
- immutable = True,
- default = lambda *k:getWampStatus())),
+ annotate.String(label=_("Current status"),
+ immutable=True,
+ default=lambda *k:getWampStatus())),
("ID",
- annotate.String(label=_("ID"),
- default = wampConfigDefault)),
+ annotate.String(label=_("ID"),
+ default=wampConfigDefault)),
("secretfile",
- FileUploadDownload(
- label = _("File containing secret for that ID"),
- download_url = getDownloadUrl,
- )),
+ FileUploadDownload(label=_("File containing secret for that ID"),
+ download_url=getDownloadUrl)),
("active",
- annotate.Boolean(label=_("Enable WAMP connection"),
- default=wampConfigDefault)),
+ annotate.Boolean(label=_("Enable WAMP connection"),
+ default=wampConfigDefault)),
("url",
- annotate.String(label=_("WAMP Server URL"),
- default=wampConfigDefault))]
+ annotate.String(label=_("WAMP Server URL"),
+ default=wampConfigDefault))]
def deliverWampSecret(ctx, segments):
- filename = segments[1].decode('utf-8')
+ # filename = segments[1].decode('utf-8')
+
# FIXME: compare filename to ID+".secret"
# for now all url under /secret returns the secret
- # TODO: make beutifull message in case of exception
+ # TODO: make beautifull message in case of exception
# while loading secret (if empty or dont exist)
secret = LoadWampSecret(_WampSecret)
- return static.Data(secret, 'application/octet-stream'),()
+ return static.Data(secret, 'application/octet-stream'), ()
+
def RegisterWebSettings(NS):
NS.ConfigurableSettings.addExtension(
- "wamp",
+ "wamp",
_("Wamp Settings"),
webFormInterface,
_("Set"),
wampConfig)
-
NS.customSettingsURLs[WAMP_SECRET_URL] = deliverWampSecret
-