mirror of
https://github.com/naruxde/revpipyload.git
synced 2025-11-08 15:13:52 +01:00
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:
2
.idea/inspectionProfiles/profiles_settings.xml
generated
2
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<settings>
|
<settings>
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
<option name="PROJECT_PROFILE" value="wheezy" />
|
||||||
<version value="1.0" />
|
<version value="1.0" />
|
||||||
</settings>
|
</settings>
|
||||||
</component>
|
</component>
|
||||||
23
.idea/inspectionProfiles/wheezy.xml
generated
Normal file
23
.idea/inspectionProfiles/wheezy.xml
generated
Normal 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>
|
||||||
@@ -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.
|
Find byte address of revpiled output.
|
||||||
|
|
||||||
|
|||||||
@@ -798,7 +798,9 @@ class RevPiPyLoad():
|
|||||||
reset_driver_detected = pictory_reset_driver.triggered
|
reset_driver_detected = pictory_reset_driver.triggered
|
||||||
|
|
||||||
# Dateiveränderungen prüfen mit beiden Funktionen!
|
# 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
|
file_changed = True
|
||||||
|
|
||||||
# Alle Verbindungen von ProcImgServer trennen
|
# Alle Verbindungen von ProcImgServer trennen
|
||||||
@@ -830,9 +832,10 @@ class RevPiPyLoad():
|
|||||||
# Kein psstart um Reload im Client zu erzeugen
|
# Kein psstart um Reload im Client zu erzeugen
|
||||||
|
|
||||||
# Restart plc program after piCtory change
|
# Restart plc program after piCtory change
|
||||||
if self.plc is not None and self.plc.is_alive() and (
|
if not pictory_reset_driver.not_implemented and \
|
||||||
self.reset_driver_action == 1 and file_changed or
|
self.plc is not None and self.plc.is_alive() and (
|
||||||
self.reset_driver_action == 2 and reset_driver_detected):
|
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
|
# Plc program is running and we have to restart it
|
||||||
proginit.logger.warning(
|
proginit.logger.warning(
|
||||||
"restart plc program after 'reset driver' was requested"
|
"restart plc program after 'reset driver' was requested"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import proginit as pi
|
|||||||
|
|
||||||
class SoftwareWatchdog:
|
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.
|
Software watchdog thread, which must be recreate if triggered.
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ class SoftwareWatchdog:
|
|||||||
self._exit = Event()
|
self._exit = Event()
|
||||||
self._ioctl_bytes = b''
|
self._ioctl_bytes = b''
|
||||||
self._process = None
|
self._process = None
|
||||||
|
self._stopped = False
|
||||||
self._timeout = 0.0
|
self._timeout = 0.0
|
||||||
self.triggered = False
|
self.triggered = False
|
||||||
|
|
||||||
@@ -85,6 +86,7 @@ class SoftwareWatchdog:
|
|||||||
def reset(self):
|
def reset(self):
|
||||||
"""Reset watchdog functions after triggered or stopped."""
|
"""Reset watchdog functions after triggered or stopped."""
|
||||||
pi.logger.debug("enter SoftwareWatchdog.reset()")
|
pi.logger.debug("enter SoftwareWatchdog.reset()")
|
||||||
|
self._stopped = False
|
||||||
self._exit.clear()
|
self._exit.clear()
|
||||||
self.triggered = False
|
self.triggered = False
|
||||||
|
|
||||||
@@ -96,18 +98,19 @@ class SoftwareWatchdog:
|
|||||||
def stop(self):
|
def stop(self):
|
||||||
"""Shut down watchdog task and wait for exit."""
|
"""Shut down watchdog task and wait for exit."""
|
||||||
pi.logger.debug("enter SoftwareWatchdog.stop()")
|
pi.logger.debug("enter SoftwareWatchdog.stop()")
|
||||||
|
self._stopped = True
|
||||||
self._exit.set()
|
self._exit.set()
|
||||||
if self.__th.is_alive():
|
if self.__th.is_alive():
|
||||||
self.__th.join()
|
self.__th.join()
|
||||||
pi.logger.debug("leave SoftwareWatchdog.stop()")
|
pi.logger.debug("leave SoftwareWatchdog.stop()")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def address(self) -> int:
|
def address(self):
|
||||||
"""Byte address of RevPiLED byte."""
|
"""Byte address of RevPiLED byte."""
|
||||||
return unpack("<Hxx", self._ioctl_bytes)[0]
|
return unpack("<Hxx", self._ioctl_bytes)[0]
|
||||||
|
|
||||||
@address.setter
|
@address.setter
|
||||||
def address(self, value: int) -> None:
|
def address(self, value):
|
||||||
"""Byte address of RevPiLED byte."""
|
"""Byte address of RevPiLED byte."""
|
||||||
if not isinstance(value, int):
|
if not isinstance(value, int):
|
||||||
raise TypeError("address must be <class '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))
|
pi.logger.debug("set software watchdog address to {0}".format(value))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kill_process(self) -> Popen:
|
def kill_process(self):
|
||||||
return self._process
|
return self._process
|
||||||
|
|
||||||
@kill_process.setter
|
@kill_process.setter
|
||||||
def kill_process(self, value: Popen) -> None:
|
def kill_process(self, value):
|
||||||
if not (value is None or isinstance(value, Popen)):
|
if not (value is None or isinstance(value, Popen)):
|
||||||
raise TypeError("kill_process must be <class 'subprocess.Popen'>")
|
raise TypeError("kill_process must be <class 'subprocess.Popen'>")
|
||||||
self._process = value
|
self._process = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def timeout(self) -> int:
|
def timeout(self):
|
||||||
"""Timeout to trigger watchdog on no change of bit."""
|
"""Timeout to trigger watchdog on no change of bit."""
|
||||||
return int(self._timeout)
|
return int(self._timeout)
|
||||||
|
|
||||||
@timeout.setter
|
@timeout.setter
|
||||||
def timeout(self, value: int):
|
def timeout(self, value):
|
||||||
"""
|
"""
|
||||||
Timeout to trigger watchdog on no change of bit.
|
Timeout to trigger watchdog on no change of bit.
|
||||||
|
|
||||||
@@ -150,12 +153,17 @@ class SoftwareWatchdog:
|
|||||||
|
|
||||||
if value == 0:
|
if value == 0:
|
||||||
# A value of 0 will stop the watchdog thread
|
# 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
|
self._timeout = 0.0
|
||||||
else:
|
else:
|
||||||
self._timeout = float(value)
|
self._timeout = float(value)
|
||||||
if not (self.triggered or
|
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 = Thread(target=self.__th_run)
|
||||||
self.__th.start()
|
self.__th.start()
|
||||||
pi.logger.debug(
|
pi.logger.debug(
|
||||||
@@ -172,10 +180,12 @@ class ResetDriverWatchdog(Thread):
|
|||||||
self.daemon = True
|
self.daemon = True
|
||||||
self._exit = False
|
self._exit = False
|
||||||
self._fh = None
|
self._fh = None
|
||||||
|
self.not_implemented = False
|
||||||
|
"""True, if KB_WAIT_FOR_EVENT is not implemented in piControl."""
|
||||||
self._triggered = False
|
self._triggered = False
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self):
|
||||||
"""
|
"""
|
||||||
Mainloop of watchdog for reset_driver.
|
Mainloop of watchdog for reset_driver.
|
||||||
|
|
||||||
@@ -188,6 +198,7 @@ class ResetDriverWatchdog(Thread):
|
|||||||
try:
|
try:
|
||||||
self._fh = os.open(pi.pargs.procimg, os.O_RDONLY)
|
self._fh = os.open(pi.pargs.procimg, os.O_RDONLY)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
self.not_implemented = True
|
||||||
pi.logger.error(
|
pi.logger.error(
|
||||||
"can not open process image at '{0}' for piCtory "
|
"can not open process image at '{0}' for piCtory "
|
||||||
"reset_driver watchdog".format(pi.pargs.procimg)
|
"reset_driver watchdog".format(pi.pargs.procimg)
|
||||||
@@ -203,6 +214,7 @@ class ResetDriverWatchdog(Thread):
|
|||||||
self._triggered = True
|
self._triggered = True
|
||||||
pi.logger.debug("piCtory reset_driver detected")
|
pi.logger.debug("piCtory reset_driver detected")
|
||||||
except Exception:
|
except Exception:
|
||||||
|
self.not_implemented = True
|
||||||
os.close(self._fh)
|
os.close(self._fh)
|
||||||
self._fh = None
|
self._fh = None
|
||||||
pi.logger.warning("IOCTL KB_WAIT_FOR_EVENT is not implemented")
|
pi.logger.warning("IOCTL KB_WAIT_FOR_EVENT is not implemented")
|
||||||
@@ -210,7 +222,7 @@ class ResetDriverWatchdog(Thread):
|
|||||||
|
|
||||||
pi.logger.debug("leave ResetDriverWatchdog.run()")
|
pi.logger.debug("leave ResetDriverWatchdog.run()")
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self):
|
||||||
"""Stop watchdog for piCtory reset_driver."""
|
"""Stop watchdog for piCtory reset_driver."""
|
||||||
pi.logger.debug("enter ResetDriverWatchdog.stop()")
|
pi.logger.debug("enter ResetDriverWatchdog.stop()")
|
||||||
|
|
||||||
@@ -222,7 +234,8 @@ class ResetDriverWatchdog(Thread):
|
|||||||
pi.logger.debug("leave ResetDriverWatchdog.stop()")
|
pi.logger.debug("leave ResetDriverWatchdog.stop()")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def triggered(self) -> bool:
|
def triggered(self):
|
||||||
rc = self._triggered or not self.is_alive()
|
"""Will return True one time after watchdog was triggered."""
|
||||||
|
rc = self._triggered
|
||||||
self._triggered = False
|
self._triggered = False
|
||||||
return rc
|
return rc
|
||||||
|
|||||||
Reference in New Issue
Block a user