mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 13:53:53 +01:00
IP Adresse aus Hostnamen ermitteln .gethostbyname
NetFH Schreibpuffer wird bei flush immer geleert, auch bei Fehlern __flusherr wird nach Fehler bei _connect auf False gesetzt Start des Sync nun sofort mit Sync und dann Wait Bei ACL Fehlern Exception auslösen Synctimer wird auf 45% des Timeouts angepasst (Senden nur bei Leerlauf) __set_systimout setzt auch für bestehenden Socket das Timeout
This commit is contained in:
@@ -68,9 +68,15 @@ Methods</h3>
|
|||||||
<td><a style="color:#0000FF" href="#NetFH.__init__">NetFH</a></td>
|
<td><a style="color:#0000FF" href="#NetFH.__init__">NetFH</a></td>
|
||||||
<td>Init NetFH-class.</td>
|
<td>Init NetFH-class.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
|
<td><a style="color:#0000FF" href="#NetFH.__check_acl">__check_acl</a></td>
|
||||||
|
<td>Pueft ob ACL auf RevPi den Vorgang erlaubt oder wirft exception.</td>
|
||||||
|
</tr><tr>
|
||||||
<td><a style="color:#0000FF" href="#NetFH.__del__">__del__</a></td>
|
<td><a style="color:#0000FF" href="#NetFH.__del__">__del__</a></td>
|
||||||
<td>NetworkFileHandler beenden.</td>
|
<td>NetworkFileHandler beenden.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
|
<td><a style="color:#0000FF" href="#NetFH.__set_systimeout">__set_systimeout</a></td>
|
||||||
|
<td>Systemfunktion fuer Timeoutberechnung.</td>
|
||||||
|
</tr><tr>
|
||||||
<td><a style="color:#0000FF" href="#NetFH._connect">_connect</a></td>
|
<td><a style="color:#0000FF" href="#NetFH._connect">_connect</a></td>
|
||||||
<td>Stellt die Verbindung zu einem RevPiSlave her.</td>
|
<td>Stellt die Verbindung zu einem RevPiSlave her.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
@@ -131,18 +137,35 @@ Init NetFH-class.
|
|||||||
</p><dl>
|
</p><dl>
|
||||||
<dt><i>address</i></dt>
|
<dt><i>address</i></dt>
|
||||||
<dd>
|
<dd>
|
||||||
IP Adresse des RevPi
|
IP Adresse, Port des RevPi als <class 'tuple'>
|
||||||
</dd><dt><i>timeout</i></dt>
|
</dd><dt><i>timeout</i></dt>
|
||||||
<dd>
|
<dd>
|
||||||
Timeout in Millisekunden der Verbindung
|
Timeout in Millisekunden der Verbindung
|
||||||
</dd>
|
</dd>
|
||||||
</dl><a NAME="NetFH.__del__" ID="NetFH.__del__"></a>
|
</dl><a NAME="NetFH.__check_acl" ID="NetFH.__check_acl"></a>
|
||||||
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
|
NetFH.__check_acl</h3>
|
||||||
|
<b>__check_acl</b>(<i>bytecode</i>)
|
||||||
|
<p>
|
||||||
|
Pueft ob ACL auf RevPi den Vorgang erlaubt oder wirft exception.
|
||||||
|
</p><a NAME="NetFH.__del__" ID="NetFH.__del__"></a>
|
||||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
NetFH.__del__</h3>
|
NetFH.__del__</h3>
|
||||||
<b>__del__</b>(<i></i>)
|
<b>__del__</b>(<i></i>)
|
||||||
<p>
|
<p>
|
||||||
NetworkFileHandler beenden.
|
NetworkFileHandler beenden.
|
||||||
</p><a NAME="NetFH._connect" ID="NetFH._connect"></a>
|
</p><a NAME="NetFH.__set_systimeout" ID="NetFH.__set_systimeout"></a>
|
||||||
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
|
NetFH.__set_systimeout</h3>
|
||||||
|
<b>__set_systimeout</b>(<i>value</i>)
|
||||||
|
<p>
|
||||||
|
Systemfunktion fuer Timeoutberechnung.
|
||||||
|
</p><dl>
|
||||||
|
<dt><i>value</i></dt>
|
||||||
|
<dd>
|
||||||
|
Timeout in Millisekunden 100 - 60000
|
||||||
|
</dd>
|
||||||
|
</dl><a NAME="NetFH._connect" ID="NetFH._connect"></a>
|
||||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
NetFH._connect</h3>
|
NetFH._connect</h3>
|
||||||
<b>_connect</b>(<i></i>)
|
<b>_connect</b>(<i></i>)
|
||||||
|
|||||||
@@ -43,8 +43,15 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
def __init__(self, address, timeout=500):
|
def __init__(self, address, timeout=500):
|
||||||
"""Init NetFH-class.
|
"""Init NetFH-class.
|
||||||
@param address IP Adresse des RevPi
|
@param address IP Adresse, Port des RevPi als <class 'tuple'>
|
||||||
@param timeout Timeout in Millisekunden der Verbindung"""
|
@param timeout Timeout in Millisekunden der Verbindung"""
|
||||||
|
if not isinstance(address, tuple):
|
||||||
|
raise ValueError(
|
||||||
|
"parameter address must be <class 'tuple'> ('IP', PORT)"
|
||||||
|
)
|
||||||
|
if not isinstance(timeout, int):
|
||||||
|
raise ValueError("parameter timeout must be <class 'int'>")
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
|
|
||||||
@@ -60,11 +67,11 @@ class NetFH(Thread):
|
|||||||
self.__trigger = False
|
self.__trigger = False
|
||||||
self.__waitsync = None
|
self.__waitsync = None
|
||||||
|
|
||||||
self.__set_systimeout(timeout)
|
|
||||||
|
|
||||||
# Verbindung herstellen
|
# Verbindung herstellen
|
||||||
self._address = address
|
self._address = address
|
||||||
self._slavesock = None
|
self._slavesock = None
|
||||||
|
|
||||||
|
self.__set_systimeout(timeout)
|
||||||
self._connect()
|
self._connect()
|
||||||
|
|
||||||
if self._slavesock is None:
|
if self._slavesock is None:
|
||||||
@@ -78,16 +85,35 @@ class NetFH(Thread):
|
|||||||
"""NetworkFileHandler beenden."""
|
"""NetworkFileHandler beenden."""
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
def __check_acl(self, bytecode):
|
||||||
|
"""Pueft ob ACL auf RevPi den Vorgang erlaubt oder wirft exception."""
|
||||||
|
if bytecode == b'\x18':
|
||||||
|
|
||||||
|
# Alles beenden, wenn nicht erlaubt
|
||||||
|
self.__sockend = True
|
||||||
|
self.__sockerr.set()
|
||||||
|
self._slavesock.close()
|
||||||
|
raise RuntimeError(
|
||||||
|
"write access to the process image is not permitted - use "
|
||||||
|
"monitoring=True or check aclplcslave.conf on RevPi and "
|
||||||
|
"reload revpipyload!"
|
||||||
|
)
|
||||||
|
|
||||||
def __set_systimeout(self, value):
|
def __set_systimeout(self, value):
|
||||||
"""Systemfunktion fuer Timeoutberechnung.
|
"""Systemfunktion fuer Timeoutberechnung.
|
||||||
@param value Timeout in Millisekunden 100 - 60000"""
|
@param value Timeout in Millisekunden 100 - 60000"""
|
||||||
|
|
||||||
if isinstance(value, int) and (100 <= value <= 60000):
|
if isinstance(value, int) and (100 <= value <= 60000):
|
||||||
self.__timeout = value / 1000
|
self.__timeout = value / 1000
|
||||||
|
|
||||||
socket.setdefaulttimeout(self.__timeout)
|
socket.setdefaulttimeout(self.__timeout)
|
||||||
|
|
||||||
# 70 Prozent vom Timeout für Synctimer verwenden
|
# Timeouts in Socket setzen
|
||||||
self.__waitsync = self.__timeout / 10 * 7
|
if self._slavesock is not None:
|
||||||
|
self._slavesock.settimeout(self.__timeout)
|
||||||
|
|
||||||
|
# 45 Prozent vom Timeout für Synctimer verwenden
|
||||||
|
self.__waitsync = self.__timeout / 10 * 4.5
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("value must between 10 and 60000 milliseconds")
|
raise ValueError("value must between 10 and 60000 milliseconds")
|
||||||
@@ -108,6 +134,7 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
self._slavesock = so
|
self._slavesock = so
|
||||||
self.__sockerr.clear()
|
self.__sockerr.clear()
|
||||||
|
self.__flusherr = False
|
||||||
|
|
||||||
# Timeout setzen
|
# Timeout setzen
|
||||||
self.set_timeout(int(self.__timeout * 1000))
|
self.set_timeout(int(self.__timeout * 1000))
|
||||||
@@ -136,6 +163,10 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
check = self._slavesock.recv(1)
|
check = self._slavesock.recv(1)
|
||||||
if check != b'\x1e':
|
if check != b'\x1e':
|
||||||
|
|
||||||
|
# ACL prüfen und ggf Fehler werfen
|
||||||
|
self.__check_acl(check)
|
||||||
|
|
||||||
self.__sockerr.set()
|
self.__sockerr.set()
|
||||||
raise IOError("clear dirtybytes error on network")
|
raise IOError("clear dirtybytes error on network")
|
||||||
|
|
||||||
@@ -149,6 +180,9 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Verbindung trennen."""
|
"""Verbindung trennen."""
|
||||||
|
if self.__sockend:
|
||||||
|
return
|
||||||
|
|
||||||
self.__sockend = True
|
self.__sockend = True
|
||||||
self.__sockerr.set()
|
self.__sockerr.set()
|
||||||
|
|
||||||
@@ -176,17 +210,22 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
# Rückmeldebyte auswerten
|
# Rückmeldebyte auswerten
|
||||||
blockok = self._slavesock.recv(1)
|
blockok = self._slavesock.recv(1)
|
||||||
|
|
||||||
|
# Puffer immer leeren
|
||||||
|
self.__int_buff = 0
|
||||||
|
self.__by_buff = b''
|
||||||
|
|
||||||
if blockok != b'\x1e':
|
if blockok != b'\x1e':
|
||||||
self.__sockerr.set()
|
|
||||||
|
# ACL prüfen und ggf Fehler werfen
|
||||||
|
self.__check_acl(blockok)
|
||||||
|
|
||||||
self.__flusherr = True
|
self.__flusherr = True
|
||||||
|
self.__sockerr.set()
|
||||||
raise IOError("flush error on network")
|
raise IOError("flush error on network")
|
||||||
else:
|
else:
|
||||||
self.__flusherr = False
|
self.__flusherr = False
|
||||||
|
|
||||||
# Puffer leeren
|
|
||||||
self.__int_buff = 0
|
|
||||||
self.__by_buff = b''
|
|
||||||
|
|
||||||
self.__trigger = True
|
self.__trigger = True
|
||||||
|
|
||||||
def get_closed(self):
|
def get_closed(self):
|
||||||
@@ -260,20 +299,18 @@ class NetFH(Thread):
|
|||||||
"""Handler fuer Synchronisierung."""
|
"""Handler fuer Synchronisierung."""
|
||||||
while not self.__sockend:
|
while not self.__sockend:
|
||||||
|
|
||||||
# Auf Fehlermeldung warten
|
# Bei Fehlermeldung neu verbinden
|
||||||
if self.__sockerr.wait(self.__waitsync):
|
if self.__sockerr.is_set():
|
||||||
if not self.__sockend:
|
self._connect()
|
||||||
# Im Fehlerfall neu verbinden
|
|
||||||
self._connect()
|
|
||||||
|
|
||||||
elif not self.__sockend:
|
else:
|
||||||
# Kein Fehler aufgetreten, sync durchführen wenn socket frei
|
# Kein Fehler aufgetreten, sync durchführen wenn socket frei
|
||||||
if not self.__trigger and \
|
if not self.__trigger and \
|
||||||
self.__socklock.acquire(blocking=False):
|
self.__socklock.acquire(blocking=False):
|
||||||
try:
|
try:
|
||||||
self._slavesock.send(_syssync)
|
self._slavesock.send(_syssync)
|
||||||
data = self._slavesock.recv(2)
|
data = self._slavesock.recv(2)
|
||||||
except IOError:
|
except IOError as e:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
"network error in sync of NetFH", RuntimeWarning
|
"network error in sync of NetFH", RuntimeWarning
|
||||||
)
|
)
|
||||||
@@ -286,8 +323,12 @@ class NetFH(Thread):
|
|||||||
self.__sockerr.set()
|
self.__sockerr.set()
|
||||||
|
|
||||||
self.__socklock.release()
|
self.__socklock.release()
|
||||||
|
|
||||||
self.__trigger = False
|
self.__trigger = False
|
||||||
|
|
||||||
|
# Warten nach Sync damit Instantiierung funktioniert
|
||||||
|
self.__sockerr.wait(self.__waitsync)
|
||||||
|
|
||||||
def seek(self, position):
|
def seek(self, position):
|
||||||
"""Springt an angegebene Position.
|
"""Springt an angegebene Position.
|
||||||
@param position An diese Position springen"""
|
@param position An diese Position springen"""
|
||||||
@@ -313,6 +354,10 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
check = self._slavesock.recv(1)
|
check = self._slavesock.recv(1)
|
||||||
if check != b'\x1e':
|
if check != b'\x1e':
|
||||||
|
|
||||||
|
# ACL prüfen und ggf Fehler werfen
|
||||||
|
self.__check_acl(check)
|
||||||
|
|
||||||
self.__sockerr.set()
|
self.__sockerr.set()
|
||||||
raise IOError("set dirtybytes error on network")
|
raise IOError("set dirtybytes error on network")
|
||||||
|
|
||||||
@@ -330,9 +375,6 @@ class NetFH(Thread):
|
|||||||
# Timeoutwert verarbeiten (könnte Exception auslösen)
|
# Timeoutwert verarbeiten (könnte Exception auslösen)
|
||||||
self.__set_systimeout(value)
|
self.__set_systimeout(value)
|
||||||
|
|
||||||
# Timeouts in Socket setzen
|
|
||||||
self._slavesock.settimeout(self.__timeout)
|
|
||||||
|
|
||||||
with self.__socklock:
|
with self.__socklock:
|
||||||
self._slavesock.send(
|
self._slavesock.send(
|
||||||
b'\x01CF' +
|
b'\x01CF' +
|
||||||
@@ -439,11 +481,12 @@ class RevPiNetIO(_RevPiModIO):
|
|||||||
# IP-Adresse prüfen und ggf. auflösen
|
# IP-Adresse prüfen und ggf. auflösen
|
||||||
if check_ip.match(self._address[0]) is None:
|
if check_ip.match(self._address[0]) is None:
|
||||||
try:
|
try:
|
||||||
ipv4 = socket.gethostname(self._address[0])
|
ipv4 = socket.gethostbyname(self._address[0])
|
||||||
self._address = (ipv4, self._address[1])
|
self._address = (ipv4, self._address[1])
|
||||||
except:
|
except Exception:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"ip '{}' is no valid ip address".format(self._address[0])
|
"ip '{0}' is no valid IPv4 address"
|
||||||
|
"".format(self._address[0])
|
||||||
)
|
)
|
||||||
|
|
||||||
# Vererben
|
# Vererben
|
||||||
|
|||||||
Reference in New Issue
Block a user