Parameter replace_io_file hinzugefügt für IO replacement

Wenn replace_io_file verwendet wird, ist .replace_io gesperrt
Verarbeitung der Datei direkt beim Instanziieren
This commit is contained in:
2019-06-16 13:44:59 +02:00
parent 2e802544c9
commit 2dbd37f2e7
6 changed files with 154 additions and 99 deletions

View File

@@ -77,6 +77,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO._configure">_configure</a></td>
<td>Verarbeitet die piCtory Konfigurationsdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._configure_replace_io">_configure_replace_io</a></td>
<td>Importiert ersetzte IOs in diese Instanz.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._create_myfh">_create_myfh</a></td>
<td>Erstellt FileObject mit Pfad zum procimg.</td>
</tr><tr>
@@ -134,9 +137,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO.handlesignalend">handlesignalend</a></td>
<td>Signalhandler fuer Programmende verwalten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.import_replaced_ios">import_replaced_ios</a></td>
<td>Importiert ersetzte IOs in diese Instanz.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.mainloop">mainloop</a></td>
<td>Startet den Mainloop mit Eventueberwachung.</td>
</tr><tr>
@@ -164,7 +164,7 @@ Static Methods</h3>
<a NAME="RevPiModIO.__init__" ID="RevPiModIO.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO (Constructor)</h3>
<b>RevPiModIO</b>(<i>autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False</i>)
<b>RevPiModIO</b>(<i>autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None</i>)
<p>
Instantiiert die Grundfunktionen.
</p><dl>
@@ -189,6 +189,9 @@ Laedt das Modul als Simulator und vertauscht IOs
</dd><dt><i>debug</i></dt>
<dd>
Gibt bei allen Fehlern komplette Meldungen aus
</dd><dt><i>replace_io_file</i></dt>
<dd>
Replace IO Konfiguration aus Datei laden
</dd>
</dl><a NAME="RevPiModIO.__del__" ID="RevPiModIO.__del__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -216,6 +219,18 @@ RevPiModIO._configure</h3>
<b>_configure</b>(<i>jconfigrsc</i>)
<p>
Verarbeitet die piCtory Konfigurationsdatei.
</p><a NAME="RevPiModIO._configure_replace_io" ID="RevPiModIO._configure_replace_io"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._configure_replace_io</h3>
<b>_configure_replace_io</b>(<i></i>)
<p>
Importiert ersetzte IOs in diese Instanz.
</p><p>
Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...)
in eine Datei exportiert worden sind. Diese IOs werden in dieser
Instanz wiederhergestellt.
</p><p>
</p><a NAME="RevPiModIO._create_myfh" ID="RevPiModIO._create_myfh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._create_myfh</h3>
@@ -471,21 +486,6 @@ Signalhandler fuer Programmende verwalten.
Funktion wird nach dem letzten Lesen der Inputs
ausgefuehrt, gefolgt vom letzten Schreiben der Outputs
</dd>
</dl><a NAME="RevPiModIO.import_replaced_ios" ID="RevPiModIO.import_replaced_ios"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.import_replaced_ios</h3>
<b>import_replaced_ios</b>(<i>filename</i>)
<p>
Importiert ersetzte IOs in diese Instanz.
</p><p>
Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...)
in eine Datei exportiert worden sind. Diese IOs werden in dieser
Instanz wieder hergestellt.
</p><dl>
<dt><i>filename</i></dt>
<dd>
Dateiname der Exportdatei
</dd>
</dl><a NAME="RevPiModIO.mainloop" ID="RevPiModIO.mainloop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.mainloop</h3>
@@ -632,7 +632,7 @@ Static Methods</h3>
<a NAME="RevPiModIODriver.__init__" ID="RevPiModIODriver.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIODriver (Constructor)</h3>
<b>RevPiModIODriver</b>(<i>virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False</i>)
<b>RevPiModIODriver</b>(<i>virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None</i>)
<p>
Instantiiert die Grundfunktionen.
</p><p>
@@ -692,7 +692,7 @@ Static Methods</h3>
<a NAME="RevPiModIOSelected.__init__" ID="RevPiModIOSelected.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIOSelected (Constructor)</h3>
<b>RevPiModIOSelected</b>(<i>deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False</i>)
<b>RevPiModIOSelected</b>(<i>deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None</i>)
<p>
Instantiiert nur fuer angegebene Devices die Grundfunktionen.
</p><p>

View File

@@ -423,7 +423,7 @@ Static Methods</h3>
<a NAME="RevPiNetIO.__init__" ID="RevPiNetIO.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO (Constructor)</h3>
<b>RevPiNetIO</b>(<i>address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False</i>)
<b>RevPiNetIO</b>(<i>address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None</i>)
<p>
Instantiiert die Grundfunktionen.
</p><dl>
@@ -445,6 +445,9 @@ Laedt das Modul als Simulator und vertauscht IOs
</dd><dt><i>debug</i></dt>
<dd>
Gibt bei allen Fehlern komplette Meldungen aus
</dd><dt><i>replace_io_file</i></dt>
<dd>
Replace IO Konfiguration aus Datei laden
</dd>
</dl><a NAME="RevPiNetIO._create_myfh" ID="RevPiNetIO._create_myfh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -536,7 +539,7 @@ Static Methods</h3>
<a NAME="RevPiNetIODriver.__init__" ID="RevPiNetIODriver.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIODriver (Constructor)</h3>
<b>RevPiNetIODriver</b>(<i>address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False</i>)
<b>RevPiNetIODriver</b>(<i>address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None</i>)
<p>
Instantiiert die Grundfunktionen.
</p><p>
@@ -599,7 +602,7 @@ Static Methods</h3>
<a NAME="RevPiNetIOSelected.__init__" ID="RevPiNetIOSelected.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIOSelected (Constructor)</h3>
<b>RevPiNetIOSelected</b>(<i>address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False</i>)
<b>RevPiNetIOSelected</b>(<i>address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None</i>)
<p>
Instantiiert nur fuer angegebene Devices die Grundfunktionen.
</p><p>

View File

@@ -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

View File

@@ -917,6 +917,13 @@ class IntIOReplaceable(IntIO):
>Python3 struct</a>
"""
# 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,

View File

@@ -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
)

View File

@@ -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 <class 'str'> / (IP, Port) <class 'tuple'>
@@ -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
)