Bugfix on watchdogs.py, remove type hints because of wheezy and jessie

SoftwareWatchdog did not restart after daemon reload and switching from 0 to >=1 value
ResetDriver trigger will not always return True if not_implemented is True
This commit is contained in:
2020-05-02 19:45:05 +02:00
parent beb073893b
commit a40b39eb22
6 changed files with 59 additions and 20 deletions

View File

@@ -1,6 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<option name="PROJECT_PROFILE" value="wheezy" />
<version value="1.0" />
</settings>
</component>

23
.idea/inspectionProfiles/wheezy.xml generated Normal file
View File

@@ -0,0 +1,23 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="wheezy" />
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ourVersions">
<value>
<list size="5">
<item index="0" class="java.lang.String" itemvalue="3.4" />
<item index="1" class="java.lang.String" itemvalue="3.5" />
<item index="2" class="java.lang.String" itemvalue="3.6" />
<item index="3" class="java.lang.String" itemvalue="3.7" />
<item index="4" class="java.lang.String" itemvalue="3.8" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyMandatoryEncodingInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myAllPythons" value="true" />
</inspection_tool>
<inspection_tool class="PyMissingOrEmptyDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyMissingTypeHintsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
</profile>
</component>

View File

@@ -120,7 +120,7 @@ def _zeroprocimg():
)
def get_revpiled_address(configrsc_bytes: bytes) -> int:
def get_revpiled_address(configrsc_bytes):
"""
Find byte address of revpiled output.

View File

@@ -798,7 +798,9 @@ class RevPiPyLoad():
reset_driver_detected = pictory_reset_driver.triggered
# Dateiveränderungen prüfen mit beiden Funktionen!
if reset_driver_detected and self.check_pictory_changed():
if (reset_driver_detected or
pictory_reset_driver.not_implemented) and \
self.check_pictory_changed():
file_changed = True
# Alle Verbindungen von ProcImgServer trennen
@@ -830,9 +832,10 @@ class RevPiPyLoad():
# Kein psstart um Reload im Client zu erzeugen
# Restart plc program after piCtory change
if self.plc is not None and self.plc.is_alive() and (
self.reset_driver_action == 1 and file_changed or
self.reset_driver_action == 2 and reset_driver_detected):
if not pictory_reset_driver.not_implemented and \
self.plc is not None and self.plc.is_alive() and (
self.reset_driver_action == 2 and reset_driver_detected or
self.reset_driver_action == 1 and file_changed):
# Plc program is running and we have to restart it
proginit.logger.warning(
"restart plc program after 'reset driver' was requested"

View File

@@ -17,7 +17,7 @@ import proginit as pi
class SoftwareWatchdog:
def __init__(self, address: int, timeout: int, kill_process=None):
def __init__(self, address, timeout, kill_process=None):
"""
Software watchdog thread, which must be recreate if triggered.
@@ -29,6 +29,7 @@ class SoftwareWatchdog:
self._exit = Event()
self._ioctl_bytes = b''
self._process = None
self._stopped = False
self._timeout = 0.0
self.triggered = False
@@ -85,6 +86,7 @@ class SoftwareWatchdog:
def reset(self):
"""Reset watchdog functions after triggered or stopped."""
pi.logger.debug("enter SoftwareWatchdog.reset()")
self._stopped = False
self._exit.clear()
self.triggered = False
@@ -96,18 +98,19 @@ class SoftwareWatchdog:
def stop(self):
"""Shut down watchdog task and wait for exit."""
pi.logger.debug("enter SoftwareWatchdog.stop()")
self._stopped = True
self._exit.set()
if self.__th.is_alive():
self.__th.join()
pi.logger.debug("leave SoftwareWatchdog.stop()")
@property
def address(self) -> int:
def address(self):
"""Byte address of RevPiLED byte."""
return unpack("<Hxx", self._ioctl_bytes)[0]
@address.setter
def address(self, value: int) -> None:
def address(self, value):
"""Byte address of RevPiLED byte."""
if not isinstance(value, int):
raise TypeError("address must be <class 'int'>")
@@ -120,22 +123,22 @@ class SoftwareWatchdog:
pi.logger.debug("set software watchdog address to {0}".format(value))
@property
def kill_process(self) -> Popen:
def kill_process(self):
return self._process
@kill_process.setter
def kill_process(self, value: Popen) -> None:
def kill_process(self, value):
if not (value is None or isinstance(value, Popen)):
raise TypeError("kill_process must be <class 'subprocess.Popen'>")
self._process = value
@property
def timeout(self) -> int:
def timeout(self):
"""Timeout to trigger watchdog on no change of bit."""
return int(self._timeout)
@timeout.setter
def timeout(self, value: int):
def timeout(self, value):
"""
Timeout to trigger watchdog on no change of bit.
@@ -150,12 +153,17 @@ class SoftwareWatchdog:
if value == 0:
# A value of 0 will stop the watchdog thread
self.stop()
self._exit.set()
if self.__th.is_alive():
self.__th.join()
# Set after exit thread to not trigger watchdog
self._timeout = 0.0
else:
self._timeout = float(value)
if not (self.triggered or
self._exit.is_set() or self.__th.is_alive()):
self._stopped or self.__th.is_alive()):
self._exit.clear()
self.__th = Thread(target=self.__th_run)
self.__th.start()
pi.logger.debug(
@@ -172,10 +180,12 @@ class ResetDriverWatchdog(Thread):
self.daemon = True
self._exit = False
self._fh = None
self.not_implemented = False
"""True, if KB_WAIT_FOR_EVENT is not implemented in piControl."""
self._triggered = False
self.start()
def run(self) -> None:
def run(self):
"""
Mainloop of watchdog for reset_driver.
@@ -188,6 +198,7 @@ class ResetDriverWatchdog(Thread):
try:
self._fh = os.open(pi.pargs.procimg, os.O_RDONLY)
except Exception:
self.not_implemented = True
pi.logger.error(
"can not open process image at '{0}' for piCtory "
"reset_driver watchdog".format(pi.pargs.procimg)
@@ -203,6 +214,7 @@ class ResetDriverWatchdog(Thread):
self._triggered = True
pi.logger.debug("piCtory reset_driver detected")
except Exception:
self.not_implemented = True
os.close(self._fh)
self._fh = None
pi.logger.warning("IOCTL KB_WAIT_FOR_EVENT is not implemented")
@@ -210,7 +222,7 @@ class ResetDriverWatchdog(Thread):
pi.logger.debug("leave ResetDriverWatchdog.run()")
def stop(self) -> None:
def stop(self):
"""Stop watchdog for piCtory reset_driver."""
pi.logger.debug("enter ResetDriverWatchdog.stop()")
@@ -222,7 +234,8 @@ class ResetDriverWatchdog(Thread):
pi.logger.debug("leave ResetDriverWatchdog.stop()")
@property
def triggered(self) -> bool:
rc = self._triggered or not self.is_alive()
def triggered(self):
"""Will return True one time after watchdog was triggered."""
rc = self._triggered
self._triggered = False
return rc

View File

@@ -27,7 +27,7 @@ setup(
license="LGPLv3",
name="revpipyload",
version="0.8.5",
version="0.8.5d",
scripts=["data/revpipyload"],