diff --git a/doc/revpimodio2.modio.html b/doc/revpimodio2.modio.html
index 2841f45..30e412e 100644
--- a/doc/revpimodio2.modio.html
+++ b/doc/revpimodio2.modio.html
@@ -86,6 +86,9 @@ Methods
_get_configrsc |
Getter function. |
+| _get_cpreplaceio |
+Laed die replace_io_file Konfiguration und verarbeitet sie. |
+
| _get_cycletime |
Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus. |
@@ -219,19 +222,27 @@ RevPiModIO._configure
_configure(jconfigrsc)
Verarbeitet die piCtory Konfigurationsdatei.
-
+
+- jconfigrsc:
+-
+Data to build IOs as of JSON
+
+
RevPiModIO._configure_replace_io
-_configure_replace_io()
+_configure_replace_io(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.
-
-
-
+
+- ireplaceio:
+-
+Data to replace ios as
+
+
RevPiModIO._create_myfh
_create_myfh()
@@ -249,6 +260,17 @@ Getter function.
Pfad der verwendeten piCtory Konfiguration
+
+
+RevPiModIO._get_cpreplaceio
+_get_cpreplaceio()
+
+Laed die replace_io_file Konfiguration und verarbeitet sie.
+
+- Returns:
+-
+ der replace io daten
+
RevPiModIO._get_cycletime
diff --git a/doc/revpimodio2.netio.html b/doc/revpimodio2.netio.html
index 4c614a8..bc0c938 100644
--- a/doc/revpimodio2.netio.html
+++ b/doc/revpimodio2.netio.html
@@ -12,7 +12,7 @@ RevPiModIO Hauptklasse fuer Netzwerkzugriff.
Global Attributes
-| __author__ |
| __copyright__ |
| __license__ |
| _sysdeldirty |
| _sysexit |
| _sysflush |
| _syspictory |
| _syssync |
+| __author__ |
| __copyright__ |
| __license__ |
| _sysdeldirty |
| _sysexit |
| _sysflush |
| _syspictory |
| _sysreplaceio |
| _syssync |
Classes
@@ -110,6 +110,9 @@ Methods
readpictory |
Ruft die piCtory Konfiguration ab. |
+| readreplaceio |
+Ruft die replace_io Konfiguration ab. |
+
| run |
Handler fuer Synchronisierung. |
@@ -293,6 +296,17 @@ Ruft die piCtory Konfiguration ab.
piCtory Datei
+
+
+NetFH.readreplaceio
+readreplaceio()
+
+Ruft die replace_io Konfiguration ab.
+
+- Returns:
+-
+ replace_io_file
+
NetFH.run
@@ -402,6 +416,9 @@ Methods
_create_myfh |
Erstellt NetworkFileObject. |
+| _get_cpreplaceio |
+Laed die replace_io Konfiguration ueber das Netzwerk. |
+
| disconnect |
Trennt Verbindungen und beendet autorefresh inkl. |
@@ -456,7 +473,18 @@ RevPiNetIO._create_myfh
Erstellt NetworkFileObject.
return FileObject
-
+
+
+RevPiNetIO._get_cpreplaceio
+_get_cpreplaceio()
+
+Laed die replace_io Konfiguration ueber das Netzwerk.
+
+- Returns:
+-
+ der replace io daten
+
+
RevPiNetIO.disconnect
disconnect()
diff --git a/eric-revpimodio2.api b/eric-revpimodio2.api
index 270362a..692878b 100644
--- a/eric-revpimodio2.api
+++ b/eric-revpimodio2.api
@@ -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)
diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py
index 589d297..81551bd 100644
--- a/revpimodio2/modio.py
+++ b/revpimodio2/modio.py
@@ -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 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
+
"""
- 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 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:
diff --git a/revpimodio2/netio.py b/revpimodio2/netio.py
index d8c899f..78bfcaf 100644
--- a/revpimodio2/netio.py
+++ b/revpimodio2/netio.py
@@ -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 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 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: