mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
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:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user