replace_io_file nimmt nun Wert :network: und läd Konfiguration über RevPiPyLoad

._configure_replace_io ist eigenständige Funktion
._get_cpreplaceio für Überschreibungen bei Vererbung hinzugefügt
This commit is contained in:
2019-06-23 15:32:26 +02:00
parent 2dbd37f2e7
commit ea99f3f3fe
5 changed files with 175 additions and 54 deletions

View File

@@ -86,6 +86,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO._get_configrsc">_get_configrsc</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_cpreplaceio">_get_cpreplaceio</a></td>
<td>Laed die replace_io_file Konfiguration und verarbeitet sie.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_cycletime">_get_cycletime</a></td>
<td>Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.</td>
</tr><tr>
@@ -219,19 +222,27 @@ 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>
</p><dl>
<dt><i>jconfigrsc:</i></dt>
<dd>
Data to build IOs as <class 'dict'> of JSON
</dd>
</dl><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>)
<b>_configure_replace_io</b>(<i>creplaceio</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>
</p><dl>
<dt><i>ireplaceio:</i></dt>
<dd>
Data to replace ios as <class 'ConfigParser'>
</dd>
</dl><a NAME="RevPiModIO._create_myfh" ID="RevPiModIO._create_myfh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._create_myfh</h3>
<b>_create_myfh</b>(<i></i>)
@@ -249,6 +260,17 @@ Getter function.
<dd>
Pfad der verwendeten piCtory Konfiguration
</dd>
</dl><a NAME="RevPiModIO._get_cpreplaceio" ID="RevPiModIO._get_cpreplaceio"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_cpreplaceio</h3>
<b>_get_cpreplaceio</b>(<i></i>)
<p>
Laed die replace_io_file Konfiguration und verarbeitet sie.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'ConfigParser'> der replace io daten
</dd>
</dl><a NAME="RevPiModIO._get_cycletime" ID="RevPiModIO._get_cycletime"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_cycletime</h3>

View File

@@ -12,7 +12,7 @@ RevPiModIO Hauptklasse fuer Netzwerkzugriff.
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr><tr><td>_sysdeldirty</td></tr><tr><td>_sysexit</td></tr><tr><td>_sysflush</td></tr><tr><td>_syspictory</td></tr><tr><td>_syssync</td></tr>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr><tr><td>_sysdeldirty</td></tr><tr><td>_sysexit</td></tr><tr><td>_sysflush</td></tr><tr><td>_syspictory</td></tr><tr><td>_sysreplaceio</td></tr><tr><td>_syssync</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
@@ -110,6 +110,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#NetFH.readpictory">readpictory</a></td>
<td>Ruft die piCtory Konfiguration ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.readreplaceio">readreplaceio</a></td>
<td>Ruft die replace_io Konfiguration ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.run">run</a></td>
<td>Handler fuer Synchronisierung.</td>
</tr><tr>
@@ -293,6 +296,17 @@ Ruft die piCtory Konfiguration ab.
<dd>
<class 'bytes'> piCtory Datei
</dd>
</dl><a NAME="NetFH.readreplaceio" ID="NetFH.readreplaceio"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.readreplaceio</h3>
<b>readreplaceio</b>(<i></i>)
<p>
Ruft die replace_io Konfiguration ab.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'bytes'> replace_io_file
</dd>
</dl><a NAME="NetFH.run" ID="NetFH.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.run</h3>
@@ -402,6 +416,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiNetIO._create_myfh">_create_myfh</a></td>
<td>Erstellt NetworkFileObject.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO._get_cpreplaceio">_get_cpreplaceio</a></td>
<td>Laed die replace_io Konfiguration ueber das Netzwerk.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO.disconnect">disconnect</a></td>
<td>Trennt Verbindungen und beendet autorefresh inkl.</td>
</tr><tr>
@@ -456,7 +473,18 @@ RevPiNetIO._create_myfh</h3>
<p>
Erstellt NetworkFileObject.
return FileObject
</p><a NAME="RevPiNetIO.disconnect" ID="RevPiNetIO.disconnect"></a>
</p><a NAME="RevPiNetIO._get_cpreplaceio" ID="RevPiNetIO._get_cpreplaceio"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO._get_cpreplaceio</h3>
<b>_get_cpreplaceio</b>(<i></i>)
<p>
Laed die replace_io Konfiguration ueber das Netzwerk.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'ConfigParser'> der replace io daten
</dd>
</dl><a NAME="RevPiNetIO.disconnect" ID="RevPiNetIO.disconnect"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO.disconnect</h3>
<b>disconnect</b>(<i></i>)

View File

@@ -141,9 +141,10 @@ 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._configure_replace_io?5(creplaceio)
revpimodio2.modio.RevPiModIO._create_myfh?5()
revpimodio2.modio.RevPiModIO._get_configrsc?5()
revpimodio2.modio.RevPiModIO._get_cpreplaceio?5()
revpimodio2.modio.RevPiModIO._get_cycletime?5()
revpimodio2.modio.RevPiModIO._get_ioerrors?5()
revpimodio2.modio.RevPiModIO._get_length?5()
@@ -191,6 +192,7 @@ revpimodio2.netio.NetFH.ioctl?4(request, arg=b'')
revpimodio2.netio.NetFH.name?7
revpimodio2.netio.NetFH.read?4(length)
revpimodio2.netio.NetFH.readpictory?4()
revpimodio2.netio.NetFH.readreplaceio?4()
revpimodio2.netio.NetFH.run?4()
revpimodio2.netio.NetFH.seek?4(position)
revpimodio2.netio.NetFH.set_dirtybytes?4(position, dirtybytes)
@@ -200,6 +202,7 @@ revpimodio2.netio.NetFH.timeout?7
revpimodio2.netio.NetFH.write?4(bytebuff)
revpimodio2.netio.NetFH?1(address, timeout=500)
revpimodio2.netio.RevPiNetIO._create_myfh?5()
revpimodio2.netio.RevPiNetIO._get_cpreplaceio?5()
revpimodio2.netio.RevPiNetIO.disconnect?4()
revpimodio2.netio.RevPiNetIO.get_jconfigrsc?4()
revpimodio2.netio.RevPiNetIO.net_cleardefaultvalues?4(device=None)
@@ -211,5 +214,6 @@ revpimodio2.netio._sysdeldirty?8
revpimodio2.netio._sysexit?8
revpimodio2.netio._sysflush?8
revpimodio2.netio._syspictory?8
revpimodio2.netio._sysreplaceio?8
revpimodio2.netio._syssync?8
revpimodio2.summary.Summary?1(summary)

View File

@@ -106,6 +106,7 @@ class RevPiModIO(object):
# Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiModIO:
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
def __del__(self):
"""Zerstoert alle Klassen um aufzuraeumen."""
@@ -128,7 +129,8 @@ class RevPiModIO(object):
self.writeprocimg()
def _configure(self, jconfigrsc):
"""Verarbeitet die piCtory Konfigurationsdatei."""
"""Verarbeitet die piCtory Konfigurationsdatei.
@param jconfigrsc: Data to build IOs as <class 'dict'> of JSON"""
# Filehandler konfigurieren, wenn er noch nicht existiert
if self._myfh is None:
@@ -252,11 +254,6 @@ 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)
@@ -291,88 +288,83 @@ class RevPiModIO(object):
# Summary Klasse instantiieren
self.summary = summarymodule.Summary(jconfigrsc["Summary"])
def _configure_replace_io(self):
def _configure_replace_io(self, creplaceio):
"""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.
@param ireplaceio: Data to replace ios as <class 'ConfigParser'>
"""
cp = ConfigParser()
need_replace_lock = False
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:
for io in creplaceio:
if io == "DEFAULT":
continue
# IO prüfen
parentio = cp[io].get("replace", "")
parentio = creplaceio[io].get("replace", "")
# Funktionsaufruf vorbereiten
dict_replace = {
"frm": cp[io].get("frm"),
"frm": creplaceio[io].get("frm"),
}
# Convert defaultvalue from config file
if "defaultvalue" in cp[io]:
if "defaultvalue" in creplaceio[io]:
if dict_replace["frm"] == "?":
try:
dict_replace["defaultvalue"] = \
cp[io].getboolean("defaultvalue")
creplaceio[io].getboolean("defaultvalue")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"defaultvalue '{1}' to boolean"
"".format(io, cp[io].get("defaultvalue"))
"".format(io, creplaceio[io].get("defaultvalue"))
)
else:
try:
dict_replace["defaultvalue"] = \
cp[io].getint("defaultvalue")
creplaceio[io].getint("defaultvalue")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"defaultvalue '{1}' to integer"
"".format(io, cp[io].get("bit"))
"".format(io, creplaceio[io].get("bit"))
)
# Get bitaddress from config file
if "bit" in cp[io]:
if "bit" in creplaceio[io]:
try:
dict_replace["bit"] = cp[io].getint("bit", 0)
dict_replace["bit"] = creplaceio[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"))
"".format(io, creplaceio[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")
if "bmk" in creplaceio[io]:
dict_replace["bmk"] = creplaceio[io].get("bmk")
if "byteorder" in creplaceio[io]:
dict_replace["byteorder"] = creplaceio[io].get("byteorder")
# IO ersetzen
try:
self.io[parentio].replace_io(name=io, **dict_replace)
need_replace_lock = True
except Exception as e:
raise RuntimeError(
"replace_io_file: can not replace '{0}' with '{1}' "
"| RevPiModIO message: {2}".format(
parentio, io, e
)
"| RevPiModIO message: {2}".format(parentio, io, e)
)
# Sperre für weiter .replace_io Aufrufe setzen
self._lck_replace_io = need_replace_lock
def _create_myfh(self):
"""Erstellt FileObject mit Pfad zum procimg.
return FileObject"""
@@ -384,6 +376,25 @@ class RevPiModIO(object):
@return Pfad der verwendeten piCtory Konfiguration"""
return self._configrsc
def _get_cpreplaceio(self):
"""Laed die replace_io_file Konfiguration und verarbeitet sie.
@return <class 'ConfigParser'> der replace io daten"""
cp = ConfigParser()
# TODO: verfeinern!
if self._replace_io_file:
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/parse file '{0}' | {1}"
"".format(self._replace_io_file, e)
)
return cp
def _get_cycletime(self):
"""Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.
@return Millisekunden"""
@@ -1049,6 +1060,7 @@ class RevPiModIOSelected(RevPiModIO):
)
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
if len(self.device) == 0:
if type(self) == RevPiModIODriver:

View File

@@ -6,6 +6,7 @@ __license__ = "LGPLv3"
import socket
import warnings
from configparser import ConfigParser
from json import loads as jloads
from re import compile
from threading import Thread, Event, Lock
@@ -21,6 +22,8 @@ _sysexit = b'\x01EX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
_sysdeldirty = b'\x01EY\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x17'
# piCtory Konfiguration laden
_syspictory = b'\x01PI\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
# ReplaceIO Konfiguration laden
_sysreplaceio = b'\x01RP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
# Übertragene Bytes schreiben
_sysflush = b'\x01SD\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x17'
@@ -330,19 +333,48 @@ class NetFH(Thread):
self._slavesock.send(_syspictory)
byte_buff = bytearray()
while not self.__sockend:
data = self._slavesock.recv(1024)
zero_byte = 0
while not self.__sockend and zero_byte < 100:
data = self._slavesock.recv(128)
if data == b'':
zero_byte += 1
byte_buff += data
if data.find(b'\x04') >= 0:
# NOTE: Nur suchen oder Ende prüfen?
return byte_buff[:-1]
return bytes(byte_buff[:-1])
self.__sockerr.set()
raise IOError("readpictory error on network")
self.__trigger = True
def readreplaceio(self):
"""Ruft die replace_io Konfiguration ab.
@return <class 'bytes'> replace_io_file"""
if self.__sockend:
raise ValueError("read of closed file")
with self.__socklock:
self._slavesock.send(_sysreplaceio)
byte_buff = bytearray()
zero_byte = 0
while not self.__sockend and zero_byte < 100:
data = self._slavesock.recv(128)
if data == b'':
zero_byte += 1
byte_buff += data
if data.find(b'\x04') >= 0:
# NOTE: Nur suchen oder Ende prüfen?
return bytes(byte_buff[:-1])
self.__sockerr.set()
raise IOError("readreplaceio error on network")
self.__trigger = True
def run(self):
"""Handler fuer Synchronisierung."""
while not self.__sockend:
@@ -542,14 +574,14 @@ class RevPiNetIO(_RevPiModIO):
# Vererben
super().__init__(
autorefresh,
monitoring,
syncoutputs,
"{0}:{1}".format(*self._address),
None,
simulator,
debug,
replace_io_file
autorefresh=autorefresh,
monitoring=monitoring,
syncoutputs=syncoutputs,
procimg="{0}:{1}".format(*self._address),
configrsc=None,
simulator=simulator,
debug=debug,
replace_io_file=replace_io_file
)
# Netzwerkfilehandler anlegen
@@ -558,6 +590,7 @@ class RevPiNetIO(_RevPiModIO):
# Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiNetIO:
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
def _create_myfh(self):
"""Erstellt NetworkFileObject.
@@ -565,6 +598,27 @@ class RevPiNetIO(_RevPiModIO):
self._buffedwrite = True
return NetFH(self._address)
def _get_cpreplaceio(self):
"""Laed die replace_io Konfiguration ueber das Netzwerk.
@return <class 'ConfigParser'> der replace io daten"""
# Normale Verwendung über Elternklasse erledigen
if self._replace_io_file != ":network:":
return super()._get_cpreplaceio()
# Replace IO Daten über das Netzwerk beziehen
byte_buff = self._myfh.readreplaceio()
cp = ConfigParser()
try:
cp.read_string(byte_buff.decode("utf-8"))
except Exception as e:
raise RuntimeError(
"replace_io_file: could not read/parse network data | {0}"
"".format(e)
)
return cp
def disconnect(self):
"""Trennt Verbindungen und beendet autorefresh inkl. alle Threads."""
self.cleanup()
@@ -693,6 +747,7 @@ class RevPiNetIOSelected(RevPiNetIO):
)
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
if len(self.device) == 0:
if type(self) == RevPiNetIODriver: