From 2dbd37f2e7ce135b2d0abdfeff8e7e810b6e16d2 Mon Sep 17 00:00:00 2001 From: NaruX Date: Sun, 16 Jun 2019 13:44:59 +0200 Subject: [PATCH] =?UTF-8?q?Parameter=20replace=5Fio=5Ffile=20hinzugef?= =?UTF-8?q?=C3=BCgt=20f=C3=BCr=20IO=20replacement=20Wenn=20replace=5Fio=5F?= =?UTF-8?q?file=20verwendet=20wird,=20ist=20.replace=5Fio=20gesperrt=20Ver?= =?UTF-8?q?arbeitung=20der=20Datei=20direkt=20beim=20Instanziieren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/revpimodio2.modio.html | 42 +++++----- doc/revpimodio2.netio.html | 9 +- eric-revpimodio2.api | 14 ++-- revpimodio2/io.py | 7 ++ revpimodio2/modio.py | 163 +++++++++++++++++++++++-------------- revpimodio2/netio.py | 18 ++-- 6 files changed, 154 insertions(+), 99 deletions(-) diff --git a/doc/revpimodio2.modio.html b/doc/revpimodio2.modio.html index b7ce297..2841f45 100644 --- a/doc/revpimodio2.modio.html +++ b/doc/revpimodio2.modio.html @@ -77,6 +77,9 @@ Methods _configure Verarbeitet die piCtory Konfigurationsdatei. +_configure_replace_io +Importiert ersetzte IOs in diese Instanz. + _create_myfh Erstellt FileObject mit Pfad zum procimg. @@ -134,9 +137,6 @@ Methods handlesignalend Signalhandler fuer Programmende verwalten. -import_replaced_ios -Importiert ersetzte IOs in diese Instanz. - mainloop Startet den Mainloop mit Eventueberwachung. @@ -164,7 +164,7 @@ Static Methods

RevPiModIO (Constructor)

-RevPiModIO(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False) +RevPiModIO(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None)

Instantiiert die Grundfunktionen.

@@ -189,6 +189,9 @@ Laedt das Modul als Simulator und vertauscht IOs
debug
Gibt bei allen Fehlern komplette Meldungen aus +
replace_io_file
+
+Replace IO Konfiguration aus Datei laden

@@ -216,6 +219,18 @@ RevPiModIO._configure

_configure(jconfigrsc)

Verarbeitet die piCtory Konfigurationsdatei. +

+

+RevPiModIO._configure_replace_io

+_configure_replace_io() +

+Importiert ersetzte IOs in diese Instanz. +

+ Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...) + in eine Datei exportiert worden sind. Diese IOs werden in dieser + Instanz wiederhergestellt. +

+

RevPiModIO._create_myfh

@@ -471,21 +486,6 @@ Signalhandler fuer Programmende verwalten. Funktion wird nach dem letzten Lesen der Inputs ausgefuehrt, gefolgt vom letzten Schreiben der Outputs - -

-RevPiModIO.import_replaced_ios

-import_replaced_ios(filename) -

-Importiert ersetzte IOs in diese Instanz. -

- Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...) - in eine Datei exportiert worden sind. Diese IOs werden in dieser - Instanz wieder hergestellt. -

-
filename
-
-Dateiname der Exportdatei -

RevPiModIO.mainloop

@@ -632,7 +632,7 @@ Static Methods

RevPiModIODriver (Constructor)

-RevPiModIODriver(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False) +RevPiModIODriver(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None)

Instantiiert die Grundfunktionen.

@@ -692,7 +692,7 @@ Static Methods

RevPiModIOSelected (Constructor)

-RevPiModIOSelected(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False) +RevPiModIOSelected(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None)

Instantiiert nur fuer angegebene Devices die Grundfunktionen.

diff --git a/doc/revpimodio2.netio.html b/doc/revpimodio2.netio.html index eb4a16a..4c614a8 100644 --- a/doc/revpimodio2.netio.html +++ b/doc/revpimodio2.netio.html @@ -423,7 +423,7 @@ Static Methods

RevPiNetIO (Constructor)

-RevPiNetIO(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False) +RevPiNetIO(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None)

Instantiiert die Grundfunktionen.

@@ -445,6 +445,9 @@ Laedt das Modul als Simulator und vertauscht IOs
debug
Gibt bei allen Fehlern komplette Meldungen aus +
replace_io_file
+
+Replace IO Konfiguration aus Datei laden

@@ -536,7 +539,7 @@ Static Methods

RevPiNetIODriver (Constructor)

-RevPiNetIODriver(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False) +RevPiNetIODriver(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None)

Instantiiert die Grundfunktionen.

@@ -599,7 +602,7 @@ Static Methods

RevPiNetIOSelected (Constructor)

-RevPiNetIOSelected(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False) +RevPiNetIOSelected(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None)

Instantiiert nur fuer angegebene Devices die Grundfunktionen.

diff --git a/eric-revpimodio2.api b/eric-revpimodio2.api index b580270..270362a 100644 --- a/eric-revpimodio2.api +++ b/eric-revpimodio2.api @@ -141,6 +141,7 @@ revpimodio2.io.StructIO.signed?7 revpimodio2.io.StructIO.value?7 revpimodio2.io.StructIO?1(parentio, name, frm, **kwargs) revpimodio2.modio.RevPiModIO._configure?5(jconfigrsc) +revpimodio2.modio.RevPiModIO._configure_replace_io?5() revpimodio2.modio.RevPiModIO._create_myfh?5() revpimodio2.modio.RevPiModIO._get_configrsc?5() revpimodio2.modio.RevPiModIO._get_cycletime?5() @@ -162,7 +163,6 @@ revpimodio2.modio.RevPiModIO.exit?4(full=True) revpimodio2.modio.RevPiModIO.export_replaced_ios?4(filename) revpimodio2.modio.RevPiModIO.get_jconfigrsc?4() revpimodio2.modio.RevPiModIO.handlesignalend?4(cleanupfunc=None) -revpimodio2.modio.RevPiModIO.import_replaced_ios?4(filename) revpimodio2.modio.RevPiModIO.ioerrors?7 revpimodio2.modio.RevPiModIO.length?7 revpimodio2.modio.RevPiModIO.mainloop?4(blocking=True, no_warn=False) @@ -175,9 +175,9 @@ revpimodio2.modio.RevPiModIO.setdefaultvalues?4(device=None) revpimodio2.modio.RevPiModIO.simulator?7 revpimodio2.modio.RevPiModIO.syncoutputs?4(device=None) revpimodio2.modio.RevPiModIO.writeprocimg?4(device=None) -revpimodio2.modio.RevPiModIO?1(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False) -revpimodio2.modio.RevPiModIODriver?1(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False) -revpimodio2.modio.RevPiModIOSelected?1(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False) +revpimodio2.modio.RevPiModIO?1(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None) +revpimodio2.modio.RevPiModIODriver?1(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None) +revpimodio2.modio.RevPiModIOSelected?1(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None) revpimodio2.netio.NetFH._connect?5() revpimodio2.netio.NetFH._direct_send?5(send_bytes, recv_count) revpimodio2.netio.NetFH.clear_dirtybytes?4(position=None) @@ -204,9 +204,9 @@ revpimodio2.netio.RevPiNetIO.disconnect?4() revpimodio2.netio.RevPiNetIO.get_jconfigrsc?4() revpimodio2.netio.RevPiNetIO.net_cleardefaultvalues?4(device=None) revpimodio2.netio.RevPiNetIO.net_setdefaultvalues?4(device=None) -revpimodio2.netio.RevPiNetIO?1(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False) -revpimodio2.netio.RevPiNetIODriver?1(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False) -revpimodio2.netio.RevPiNetIOSelected?1(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False) +revpimodio2.netio.RevPiNetIO?1(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None) +revpimodio2.netio.RevPiNetIODriver?1(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None) +revpimodio2.netio.RevPiNetIOSelected?1(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None) revpimodio2.netio._sysdeldirty?8 revpimodio2.netio._sysexit?8 revpimodio2.netio._sysflush?8 diff --git a/revpimodio2/io.py b/revpimodio2/io.py index 3b0b9ca..ce3ba20 100644 --- a/revpimodio2/io.py +++ b/revpimodio2/io.py @@ -917,6 +917,13 @@ class IntIOReplaceable(IntIO): >Python3 struct """ + # Sperre prüfen + if self._parentdevice._modio._lck_replace_io: + raise RuntimeError( + "can not use this function while using an external " + "replace_io_file" + ) + # StructIO erzeugen io_new = StructIO( self, diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index 306f75c..589d297 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -34,11 +34,13 @@ class RevPiModIO(object): "_looprunning", "_lst_devselect", "_lst_refresh", "_maxioerrors", \ "_myfh", "_myfh_lck", "_monitoring", "_procimg", "_simulator", \ "_syncoutputs", "_th_mainloop", "_waitexit", \ - "core", "app", "device", "exitsignal", "io", "summary", "_debug" + "core", "app", "device", "exitsignal", "io", "summary", "_debug", \ + "_lck_replace_io", "_replace_io_file" def __init__( self, autorefresh=False, monitoring=False, syncoutputs=True, - procimg=None, configrsc=None, simulator=False, debug=False): + procimg=None, configrsc=None, simulator=False, debug=False, + replace_io_file=None): """Instantiiert die Grundfunktionen. @param autorefresh Wenn True, alle Devices zu autorefresh hinzufuegen @@ -48,6 +50,7 @@ class RevPiModIO(object): @param configrsc Abweichender Pfad zur piCtory Konfigurationsdatei @param simulator Laedt das Modul als Simulator und vertauscht IOs @param debug Gibt bei allen Fehlern komplette Meldungen aus + @param replace_io_file Replace IO Konfiguration aus Datei laden """ # Parameterprüfung @@ -56,7 +59,8 @@ class RevPiModIO(object): syncoutputs=syncoutputs, simulator=simulator, debug=debug ) acheck( - str, procimg_noneok=procimg, configrsc_noneok=configrsc + str, procimg_noneok=procimg, configrsc_noneok=configrsc, + replace_io_file_noneok=replace_io_file ) self._autorefresh = autorefresh @@ -76,12 +80,14 @@ class RevPiModIO(object): self._imgwriter = None self._ioerror = 0 self._length = 0 + self._lck_replace_io = False self._looprunning = False self._lst_devselect = [] self._lst_refresh = [] self._maxioerrors = 0 self._myfh = None self._myfh_lck = Lock() + self._replace_io_file = replace_io_file self._th_mainloop = None self._waitexit = Event() @@ -246,6 +252,11 @@ class RevPiModIO(object): Warning ) + # Replace IO aus Datei verarbeiten + if self._replace_io_file is not None: + self._configure_replace_io() + self._lck_replace_io = True + # ImgWriter erstellen self._imgwriter = helpermodule.ProcimgWriter(self) @@ -280,6 +291,88 @@ class RevPiModIO(object): # Summary Klasse instantiieren self.summary = summarymodule.Summary(jconfigrsc["Summary"]) + def _configure_replace_io(self): + """Importiert ersetzte IOs in diese Instanz. + + Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...) + in eine Datei exportiert worden sind. Diese IOs werden in dieser + Instanz wiederhergestellt. + + """ + cp = ConfigParser() + + try: + with open(self._replace_io_file, "r") as fh: + cp.read_file(fh) + except Exception as e: + raise RuntimeError( + "replace_io_file: could not read file '{0}' | {1}" + "".format(self._replace_io_file, e) + ) + + for io in cp: + if io == "DEFAULT": + continue + + # IO prüfen + parentio = cp[io].get("replace", "") + + # Funktionsaufruf vorbereiten + dict_replace = { + "frm": cp[io].get("frm"), + } + + # Convert defaultvalue from config file + if "defaultvalue" in cp[io]: + if dict_replace["frm"] == "?": + try: + dict_replace["defaultvalue"] = \ + cp[io].getboolean("defaultvalue") + except Exception: + raise ValueError( + "replace_io_file: could not convert '{0}' " + "defaultvalue '{1}' to boolean" + "".format(io, cp[io].get("defaultvalue")) + ) + else: + try: + dict_replace["defaultvalue"] = \ + cp[io].getint("defaultvalue") + except Exception: + raise ValueError( + "replace_io_file: could not convert '{0}' " + "defaultvalue '{1}' to integer" + "".format(io, cp[io].get("bit")) + ) + + # Get bitaddress from config file + if "bit" in cp[io]: + try: + dict_replace["bit"] = cp[io].getint("bit", 0) + except Exception: + raise ValueError( + "replace_io_file: could not convert '{0}' " + "bit '{1}' to integer" + "".format(io, cp[io].get("bit")) + ) + + # Sonstige Werte laden, wenn vorhanden + if "bmk" in cp[io]: + dict_replace["bmk"] = cp[io].get("bmk") + if "byteorder" in cp[io]: + dict_replace["byteorder"] = cp[io].get("byteorder") + + # IO ersetzen + try: + self.io[parentio].replace_io(name=io, **dict_replace) + except Exception as e: + raise RuntimeError( + "replace_io_file: can not replace '{0}' with '{1}' " + "| RevPiModIO message: {2}".format( + parentio, io, e + ) + ) + def _create_myfh(self): """Erstellt FileObject mit Pfad zum procimg. return FileObject""" @@ -622,61 +715,6 @@ class RevPiModIO(object): signal(SIGINT, self.__evt_exit) signal(SIGTERM, self.__evt_exit) - def import_replaced_ios(self, filename): - """Importiert ersetzte IOs in diese Instanz. - - Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...) - in eine Datei exportiert worden sind. Diese IOs werden in dieser - Instanz wieder hergestellt. - - @param filename Dateiname der Exportdatei""" - acheck(str, filename=filename) - - # Load config file - cp = ConfigParser() - try: - with open(filename, "r") as fh: - cp.read_file(fh) - except Exception as e: - raise RuntimeError( - "could not read export file '{0}' | {1}" - "".format(filename, e) - ) - - # Pre-check - for io in cp: - if io == "DEFAULT": - continue - - do_replace_io = cp[io].get("replace", "") - if do_replace_io not in self.io: - raise RuntimeError( - "can not find io '{0}' to replace".format(do_replace_io) - ) - - # Replace IOs - for io in cp: - if io == "DEFAULT": - continue - - replace_io = cp[io].get("replace", "") - replace_frm = cp[io].get("frm") - - # Convert defaultvalue from config file - if replace_frm == "?": - replace_defaultvalue = cp[io].getboolean("defaultvalue") - else: - replace_defaultvalue = cp[io].getint("defaultvalue") - - self.io[replace_io].replace_io( - io, - frm=replace_frm, - bmk=cp[io].get("bmk", ""), - bit=cp[io].getint("bitaddress", 0), - byteorder=cp[io].get("byteorder", "little"), - defaultvalue=replace_defaultvalue - ) - def mainloop(self, blocking=True, no_warn=False): """Startet den Mainloop mit Eventueberwachung. @@ -980,7 +1018,7 @@ class RevPiModIOSelected(RevPiModIO): def __init__( self, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, - simulator=False, debug=False): + simulator=False, debug=False, replace_io_file=None): """Instantiiert nur fuer angegebene Devices die Grundfunktionen. Der Parameter deviceselection kann eine einzelne @@ -993,7 +1031,7 @@ class RevPiModIOSelected(RevPiModIO): """ super().__init__( autorefresh, monitoring, syncoutputs, procimg, configrsc, - simulator, debug + simulator, debug, replace_io_file ) # Device liste erstellen @@ -1047,7 +1085,8 @@ class RevPiModIODriver(RevPiModIOSelected): def __init__( self, virtdev, autorefresh=False, monitoring=False, - syncoutputs=True, procimg=None, configrsc=None, debug=False): + syncoutputs=True, procimg=None, configrsc=None, debug=False, + replace_io_file=None): """Instantiiert die Grundfunktionen. Parameter 'monitoring' und 'simulator' stehen hier nicht zur @@ -1060,7 +1099,7 @@ class RevPiModIODriver(RevPiModIOSelected): # Parent mit monitoring=False und simulator=True laden super().__init__( virtdev, autorefresh, False, syncoutputs, procimg, configrsc, - True, debug + True, debug, replace_io_file ) diff --git a/revpimodio2/netio.py b/revpimodio2/netio.py index 7ac2dc2..d8c899f 100644 --- a/revpimodio2/netio.py +++ b/revpimodio2/netio.py @@ -489,7 +489,8 @@ class RevPiNetIO(_RevPiModIO): def __init__( self, address, autorefresh=False, monitoring=False, - syncoutputs=True, simulator=False, debug=False): + syncoutputs=True, simulator=False, debug=False, + replace_io_file=None): """Instantiiert die Grundfunktionen. @param address: IP-Adresse / (IP, Port) @@ -498,6 +499,7 @@ class RevPiNetIO(_RevPiModIO): @param syncoutputs Aktuell gesetzte Outputs vom Prozessabbild einlesen @param simulator Laedt das Modul als Simulator und vertauscht IOs @param debug Gibt bei allen Fehlern komplette Meldungen aus + @param replace_io_file Replace IO Konfiguration aus Datei laden """ check_ip = compile( @@ -546,7 +548,8 @@ class RevPiNetIO(_RevPiModIO): "{0}:{1}".format(*self._address), None, simulator, - debug + debug, + replace_io_file ) # Netzwerkfilehandler anlegen @@ -657,7 +660,8 @@ class RevPiNetIOSelected(RevPiNetIO): def __init__( self, address, deviceselection, autorefresh=False, - monitoring=False, syncoutputs=True, simulator=False, debug=False): + monitoring=False, syncoutputs=True, simulator=False, debug=False, + replace_io_file=None): """Instantiiert nur fuer angegebene Devices die Grundfunktionen. Der Parameter deviceselection kann eine einzelne @@ -670,7 +674,8 @@ class RevPiNetIOSelected(RevPiNetIO): """ super().__init__( - address, autorefresh, monitoring, syncoutputs, simulator, debug + address, autorefresh, monitoring, syncoutputs, simulator, debug, + replace_io_file ) # Device liste erstellen @@ -724,7 +729,7 @@ class RevPiNetIODriver(RevPiNetIOSelected): def __init__( self, address, virtdev, autorefresh=False, monitoring=False, - syncoutputs=True, debug=False): + syncoutputs=True, debug=False, replace_io_file=None): """Instantiiert die Grundfunktionen. Parameter 'monitoring' und 'simulator' stehen hier nicht zur @@ -737,5 +742,6 @@ class RevPiNetIODriver(RevPiNetIOSelected): """ # Parent mit monitoring=False und simulator=True laden super().__init__( - address, virtdev, autorefresh, False, syncoutputs, True, debug + address, virtdev, autorefresh, False, syncoutputs, True, debug, + replace_io_file )