diff --git a/frappy_psi/logo.py b/frappy_psi/logo.py index 1e614b3..6824714 100644 --- a/frappy_psi/logo.py +++ b/frappy_psi/logo.py @@ -19,6 +19,8 @@ # Markus Zolliker # # ***************************************************************************** +import sys +import time from ast import literal_eval from threading import RLock import snap7 @@ -31,22 +33,45 @@ class IO(Communicator): tsap_server = Property('tcap_server', IntRange()) ip_address = Property('numeric ip address', StringType()) _plc = None + _last_try = 0 + + def initModule(self): + self._lock = RLock() + super().initModule() def _init(self): if not self._plc: - self._lock = RLock() + if time.time() < self._last_try + 10: + raise CommunicationFailedError('logo PLC not reachable') self._plc = snap7.logo.Logo() - self._plc.connect(self.ip_address, self.tcap_client, self.tsap_server) - if not self._plc.get_connected(): - raise CommunicationFailedError + prev_stderr = sys.stdout + sys.stderr = open('/dev/null', 'w') # suppress output of snap7 + try: + self._plc.connect(self.ip_address, self.tcap_client, self.tsap_server) + if self._plc.get_connected(): + return + except Exception: + pass + finally: + sys.stderr = prev_stderr + self._plc = None + self._last_try = time.time() + raise CommunicationFailedError('logo PLC not reachable') def communicate(self, cmd): - self._init() with self._lock: + self._init() cmd = cmd.split(maxsplit=1) if len(cmd) == 2: self._plc.write(cmd[0], literal_eval(cmd[1])) - return self._plc.read(cmd[0]) + try: + return self._plc.read(cmd[0]) + except Exception as e: + if self._plc: + self.log.exception('error in plc read') + self._plc = None + raise + class Snap7Mixin(HasIO): ioclass = IO