--- a/ConfigTreeNode.py Tue Jun 16 11:12:36 2020 +0200
+++ b/ConfigTreeNode.py Tue Jun 16 15:53:52 2020 +0200
@@ -678,6 +678,3 @@
raise UserAddressedException(message)
-class UserAddressedException(Exception):
--- a/POULibrary.py Tue Jun 16 11:12:36 2020 +0200
+++ b/POULibrary.py Tue Jun 16 15:53:52 2020 +0200
@@ -26,6 +26,10 @@
from __future__ import absolute_import
+# Exception type for problems that user has to take action in order to fix +class UserAddressedException(Exception): class POULibrary(object):
def __init__(self, CTR, LibName, TypeStack):
@@ -59,6 +63,11 @@
# Pure python or IEC libs doesn't produce C code
return ((""), [], False), ""
+ def FatalError(self, message): + """ Raise an exception that will trigger error message intended to + the user, but without backtrace since it is not a software error """ + raise UserAddressedException(message) def SimplePOULibraryFactory(path):
class SimplePOULibrary(POULibrary):
--- a/ProjectController.py Tue Jun 16 11:12:36 2020 +0200
+++ b/ProjectController.py Tue Jun 16 15:53:52 2020 +0200
@@ -63,7 +63,8 @@
from runtime.typemapping import DebugTypesSize, UnpackDebugBuffer
from runtime import PlcStatus
-from ConfigTreeNode import ConfigTreeNode, XSDSchemaErrorMessage, UserAddressedException
+from ConfigTreeNode import ConfigTreeNode, XSDSchemaErrorMessage +from POULibrary import UserAddressedException base_folder = paths.AbsParentDir(__file__)
@@ -1441,7 +1442,8 @@
PlcStatus.Stopped: {"_Run": True,
PlcStatus.Empty: {"_Transfer": True,
@@ -1978,6 +1980,13 @@
+ "bitmap": "Disconnect", + "name": _("Disconnect"), + "tooltip": _("Disconnect from PLC"), + "method": "_Disconnect", "tooltip": _("Repair broken PLC"),
@@ -1985,13 +1994,6 @@
- "bitmap": "Disconnect",
- "name": _("Disconnect"),
- "tooltip": _("Disconnect from PLC"),
- "method": "_Disconnect",
"tooltip": _("Manage secure connection identities"),
--- a/runtime/PLCObject.py Tue Jun 16 11:12:36 2020 +0200
+++ b/runtime/PLCObject.py Tue Jun 16 15:53:52 2020 +0200
@@ -451,17 +451,27 @@
self.PythonThreadCond.notify()
self.PythonThreadCondLock.release()
+ self.LogMessage(0, msg) + self.PLCStatus = PlcStatus.Broken + Here goes actions to be taken just before PLC starts, + with all libraries and python object already created. + For example : restore saved proprietary parameters
- self.LogMessage(0, msg)
- self.PLCStatus = PlcStatus.Broken
if self.PLClibraryHandle is None:
- fail(_("Problem starting PLC : can't load PLC"))
+ self._fail(_("Problem starting PLC : can't load PLC")) if self.CurrentPLCFilename is not None and self.PLCStatus == PlcStatus.Stopped:
c_argv = ctypes.c_char_p * len(self.argv)
@@ -472,7 +482,7 @@
self.PythonThreadCommand("Activate")
self.LogMessage("PLC started")
- fail(_("Problem starting PLC : error %d" % res))
+ self._fail(_("Problem starting PLC : error %d" % res)) @@ -510,7 +520,7 @@
def SeedBlob(self, seed):
blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),))
- _fobj, _path, md5sum = blob
+ _fd, _path, md5sum = blob newBlobID = md5sum.digest()
self.blobs[newBlobID] = blob
@@ -523,17 +533,17 @@
- fobj, _path, md5sum = blob
+ fd, _path, md5sum = blob newBlobID = md5sum.digest()
self.blobs[newBlobID] = blob
- for fobj, _path, _md5sum in self.blobs.values():
+ for fd, _path, _md5sum in self.blobs.values(): def _BlobAsFile(self, blobID, newpath):
@@ -542,8 +552,11 @@
raise Exception(_("Missing data to create file: {}").format(newpath))
- fobj, path, _md5sum = blob
+ fd, path, _md5sum = blob shutil.move(path, newpath)
def _extra_files_log_path(self):
@@ -599,9 +612,6 @@
self._BlobAsFile(plc_object, new_PLC_filename)
- # Store new PLC filename based on md5 key
- open(self._GetMD5FileName(), "w").write(md5sum)
log = open(extra_files_log, "w")
for fname, blobID in extrafiles:
@@ -609,6 +619,12 @@
self._BlobAsFile(blobID, fpath)
+ # Store new PLC filename based on md5 key + with open(self._GetMD5FileName(), "w") as f: self.CurrentPLCFilename = NewFileName