From 9882dc197a37030ee7b87c412259e8ce3a9f8af4 Mon Sep 17 00:00:00 2001 From: NaruX Date: Fri, 27 Jul 2018 14:15:10 +0200 Subject: [PATCH] =?UTF-8?q?Timeouthandling=20f=C3=BCr=20NetFH=20verbessert?= =?UTF-8?q?=2070=20prozent=20f=C3=BCr=20Sync-Timer=20IP-Adresse=20pr=C3=BC?= =?UTF-8?q?fen=20und=20ggf.=20aufl=C3=B6sen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- revpimodio2/netio.py | 84 ++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/revpimodio2/netio.py b/revpimodio2/netio.py index b8bf4e6..ac0cebb 100644 --- a/revpimodio2/netio.py +++ b/revpimodio2/netio.py @@ -9,6 +9,7 @@ import socket import warnings from json import loads as jloads +from re import compile from threading import Thread, Event, Lock from .device import Device @@ -37,7 +38,9 @@ class NetFH(Thread): """ def __init__(self, address, timeout=500): - """Init NetFH-class.""" + """Init NetFH-class. + @param address IP Adresse des RevPis + @param timeout Verbindungstimeout in Millisekunden""" super().__init__() self.daemon = True @@ -49,11 +52,11 @@ class NetFH(Thread): self.__sockerr = Event() self.__sockend = False self.__socklock = Lock() - self.__timeout = timeout / 1000 + self.__timeout = None self.__trigger = False - self.__waitsync = self.__timeout / 2 + self.__waitsync = None - socket.setdefaulttimeout(self.__timeout) + self.__set_systimeout(timeout) # Verbindung herstellen self._address = address @@ -71,6 +74,20 @@ class NetFH(Thread): """NetworkFileHandler beenden.""" self.close() + def __set_systimeout(self, value): + """Systemfunktion fuer Timeoutberechnung. + @param value Timeout in Millisekunden 100 - 60000""" + + if isinstance(value, int) and (100 <= value <= 60000): + self.__timeout = value / 1000 + socket.setdefaulttimeout(self.__timeout) + + # 70 Prozent vom Timeout für Synctimer verwenden + self.__waitsync = self.__timeout / 10 * 7 + + else: + raise ValueError("value must between 10 and 60000 milliseconds") + def _connect(self): """Stellt die Verbindung zu einem RevPiSlave her.""" # Neuen Socket aufbauen @@ -306,29 +323,24 @@ class NetFH(Thread): if self.__sockend: raise ValueError("I/O operation on closed file") - if type(value) == int and (0 < value <= 65535): - self.__timeout = value / 1000 - self.__waitsync = self.__timeout / 2 - 0.05 + # Timeoutwert verarbeiten (könnte Exception auslösen) + self.__set_systimeout(value) - # Timeouts in Sockets übernehmen - socket.setdefaulttimeout(self.__timeout) - self._slavesock.settimeout(self.__timeout) + # Timeouts in Socket setzen + self._slavesock.settimeout(self.__timeout) - with self.__socklock: - self._slavesock.send( - b'\x01CF' + - value.to_bytes(length=2, byteorder="little") + - b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17' - ) - check = self._slavesock.recv(1) - if check != b'\x1e': - self.__sockerr.set() - raise IOError("set timeout error on network") + with self.__socklock: + self._slavesock.send( + b'\x01CF' + + value.to_bytes(length=2, byteorder="little") + + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17' + ) + check = self._slavesock.recv(1) + if check != b'\x1e': + self.__sockerr.set() + raise IOError("set timeout error on network") - self.__trigger = True - - else: - raise ValueError("value must between 1 and 65535 milliseconds") + self.__trigger = True def tell(self): """Gibt aktuelle Position zurueck. @@ -391,17 +403,19 @@ class RevPiNetIO(_RevPiModIO): @param simulator Laedt das Modul als Simulator und vertauscht IOs """ + check_ip = compile( + r"^(?P(25[0-5]|(2[0-4]|[01]?\d|)\d))(\.(?P=ipn)){3}$" + ) + # Adresse verarbeiten - if type(address) == str: - # TODO: IP-Adresse prüfen + if isinstance(address, str): self._address = (address, 55234) - elif type(address) == tuple: + elif isinstance(address, tuple): if len(address) == 2 \ - and type(address[0]) == str \ - and type(address[1]) == int: + and isinstance(address[0], str) \ + and isinstance(address[1], int): # Werte prüfen - # TODO: IP-Adresse prüfen if not 0 < address[1] <= 65535: raise ValueError("port number out of range 1 - 65535") @@ -416,6 +430,16 @@ class RevPiNetIO(_RevPiModIO): "like (, )" ) + # IP-Adresse prüfen und ggf. auflösen + if check_ip.match(self._address[0]) is None: + try: + ipv4 = socket.gethostname(self._address[0]) + self._address = (ipv4, self._address[1]) + except: + raise ValueError( + "ip '{}' is no valid ip address".format(self._address[0]) + ) + # Vererben super().__init__( autorefresh,