mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
Watchdog for all RevPis, cycletools with .core/.io/.runtime, bugfix on MemIO for str()
All RevPis got .core.wd for Software-Watchdog with RevPiPyLoad All RevPis has .core.wd_toggle() function to toggle watchdog bit Cycletools has .core and .io attribute to be independent of rpi object Cycletools has .runtime to get the actual runtime of function
This commit is contained in:
6
.idea/codeStyles/Project.xml
generated
Normal file
6
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<option name="LINE_SEPARATOR" value=" " />
|
||||||
|
<option name="RIGHT_MARGIN" value="80" />
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
@@ -542,12 +542,13 @@ class Core(Base):
|
|||||||
|
|
||||||
__slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \
|
__slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \
|
||||||
"_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \
|
"_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \
|
||||||
"_slc_frequency", "_slc_led", "a1green", "a1red", "a2green", "a2red"
|
"_slc_frequency", "_slc_led", "a1green", "a1red", \
|
||||||
|
"a2green", "a2red", "wd"
|
||||||
|
|
||||||
def __setattr__(self, key, value):
|
def __setattr__(self, key, value):
|
||||||
"""Verhindert Ueberschreibung der LEDs."""
|
"""Verhindert Ueberschreibung der LEDs."""
|
||||||
if hasattr(self, key) and key in (
|
if hasattr(self, key) and key in (
|
||||||
"a1green", "a1red", "a2green", "a2red"):
|
"a1green", "a1red", "a2green", "a2red", "wd"):
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
"direct assignment is not supported - use .value Attribute"
|
"direct assignment is not supported - use .value Attribute"
|
||||||
)
|
)
|
||||||
@@ -616,6 +617,12 @@ class Core(Base):
|
|||||||
exp_a2red, None, "LED_A2_RED", "3"
|
exp_a2red, None, "LED_A2_RED", "3"
|
||||||
], OUT, "little", False)
|
], OUT, "little", False)
|
||||||
|
|
||||||
|
# Watchdog einrichten (Core=soft / Connect=soft/hard)
|
||||||
|
self.wd = IOBase(self, [
|
||||||
|
"core.wd", 0, 1, self._slc_led.start,
|
||||||
|
False, None, "WatchDog", "7"
|
||||||
|
], OUT, "little", False)
|
||||||
|
|
||||||
def __errorlimit(self, slc_io: slice, errorlimit: int) -> None:
|
def __errorlimit(self, slc_io: slice, errorlimit: int) -> None:
|
||||||
"""
|
"""
|
||||||
Verwaltet das Schreiben der ErrorLimits.
|
Verwaltet das Schreiben der ErrorLimits.
|
||||||
@@ -694,6 +701,10 @@ class Core(Base):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
raise ValueError("led status must be between 0 and 3")
|
||||||
|
|
||||||
|
def wd_toggle(self):
|
||||||
|
"""Toggle watchdog bit to prevent a timeout."""
|
||||||
|
self.wd.value = not self.wd.value
|
||||||
|
|
||||||
A1 = property(_get_leda1, _set_leda1)
|
A1 = property(_get_leda1, _set_leda1)
|
||||||
A2 = property(_get_leda2, _set_leda2)
|
A2 = property(_get_leda2, _set_leda2)
|
||||||
status = property(_get_status)
|
status = property(_get_status)
|
||||||
@@ -865,19 +876,17 @@ class Connect(Core):
|
|||||||
Stellt Funktionen fuer die LEDs, Watchdog und den Status zur Verfuegung.
|
Stellt Funktionen fuer die LEDs, Watchdog und den Status zur Verfuegung.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", "wd", \
|
__slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", \
|
||||||
"x2in", "x2out"
|
"x2in", "x2out"
|
||||||
|
|
||||||
def __setattr__(self, key, value):
|
def __setattr__(self, key, value):
|
||||||
"""Verhindert Ueberschreibung der LEDs."""
|
"""Verhindert Ueberschreibung der speziellen IOs."""
|
||||||
if hasattr(self, key) and key in (
|
if hasattr(self, key) and key in (
|
||||||
"a1green", "a1red", "a2green", "a2red", "a3green", "a3red",
|
"a3green", "a3red", "x2in", "x2out"):
|
||||||
"wd", "x2in", "x2out"):
|
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
"direct assignment is not supported - use .value Attribute"
|
"direct assignment is not supported - use .value Attribute"
|
||||||
)
|
)
|
||||||
else:
|
super(Connect, self).__setattr__(key, value)
|
||||||
object.__setattr__(self, key, value)
|
|
||||||
|
|
||||||
def __wdtoggle(self) -> None:
|
def __wdtoggle(self) -> None:
|
||||||
"""WD Ausgang alle 10 Sekunden automatisch toggeln."""
|
"""WD Ausgang alle 10 Sekunden automatisch toggeln."""
|
||||||
@@ -921,10 +930,6 @@ class Connect(Core):
|
|||||||
], OUT, "little", False)
|
], OUT, "little", False)
|
||||||
|
|
||||||
# IO Objekte für WD und X2 in/out erzeugen
|
# IO Objekte für WD und X2 in/out erzeugen
|
||||||
self.wd = IOBase(self, [
|
|
||||||
"core.wd", 0, 1, self._slc_led.start,
|
|
||||||
exp_wd, None, "Connect_WatchDog", "7"
|
|
||||||
], OUT, "little", False)
|
|
||||||
self.x2in = IOBase(self, [
|
self.x2in = IOBase(self, [
|
||||||
"core.x2in", 0, 1, self._slc_statusbyte.start,
|
"core.x2in", 0, 1, self._slc_statusbyte.start,
|
||||||
exp_x2in, None, "Connect_X2_IN", "6"
|
exp_x2in, None, "Connect_X2_IN", "6"
|
||||||
@@ -1015,7 +1020,7 @@ class Compact(Base):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \
|
__slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \
|
||||||
"a1green", "a1red", "a2green", "a2red"
|
"a1green", "a1red", "a2green", "a2red", "wd"
|
||||||
|
|
||||||
def __setattr__(self, key, value):
|
def __setattr__(self, key, value):
|
||||||
"""Verhindert Ueberschreibung der LEDs."""
|
"""Verhindert Ueberschreibung der LEDs."""
|
||||||
@@ -1066,6 +1071,12 @@ class Compact(Base):
|
|||||||
exp_a2red, None, "LED_A2_RED", "3"
|
exp_a2red, None, "LED_A2_RED", "3"
|
||||||
], OUT, "little", False)
|
], OUT, "little", False)
|
||||||
|
|
||||||
|
# Software watchdog einrichten
|
||||||
|
self.wd = IOBase(self, [
|
||||||
|
"core.wd", 0, 1, self._slc_led.start,
|
||||||
|
False, None, "WatchDog", "7"
|
||||||
|
], OUT, "little", False)
|
||||||
|
|
||||||
def _get_leda1(self) -> int:
|
def _get_leda1(self) -> int:
|
||||||
"""
|
"""
|
||||||
Gibt den Zustand der LED A1 vom Compact zurueck.
|
Gibt den Zustand der LED A1 vom Compact zurueck.
|
||||||
@@ -1119,6 +1130,10 @@ class Compact(Base):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
raise ValueError("led status must be between 0 and 3")
|
||||||
|
|
||||||
|
def wd_toggle(self):
|
||||||
|
"""Toggle watchdog bit to prevent a timeout."""
|
||||||
|
self.wd.value = not self.wd.value
|
||||||
|
|
||||||
A1 = property(_get_leda1, _set_leda1)
|
A1 = property(_get_leda1, _set_leda1)
|
||||||
A2 = property(_get_leda2, _set_leda2)
|
A2 = property(_get_leda2, _set_leda2)
|
||||||
|
|
||||||
|
|||||||
@@ -85,12 +85,12 @@ class Cycletools:
|
|||||||
Lampen synchron blinken zu lassen.
|
Lampen synchron blinken zu lassen.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__cycle", "__cycletime", "__ucycle", \
|
__slots__ = "__cycle", "__cycletime", "__ucycle", "__dict_ton", \
|
||||||
"__dict_ton", "__dict_tof", "__dict_tp", "first", "last", \
|
"__dict_tof", "__dict_tp", "_start_timer", "core", "first", \
|
||||||
"flag1c", "flag5c", "flag10c", "flag15c", "flag20c", \
|
"io", "last", "flag1c", "flag5c", "flag10c", "flag15c", \
|
||||||
"flank5c", "flank10c", "flank15c", "flank20c", "var"
|
"flag20c", "flank5c", "flank10c", "flank15c", "flank20c", "var"
|
||||||
|
|
||||||
def __init__(self, cycletime):
|
def __init__(self, cycletime, revpi_object):
|
||||||
"""Init Cycletools class."""
|
"""Init Cycletools class."""
|
||||||
self.__cycle = 0
|
self.__cycle = 0
|
||||||
self.__cycletime = cycletime
|
self.__cycletime = cycletime
|
||||||
@@ -98,6 +98,11 @@ class Cycletools:
|
|||||||
self.__dict_ton = {}
|
self.__dict_ton = {}
|
||||||
self.__dict_tof = {}
|
self.__dict_tof = {}
|
||||||
self.__dict_tp = {}
|
self.__dict_tp = {}
|
||||||
|
self._start_timer = 0.0
|
||||||
|
|
||||||
|
# Access to core and io
|
||||||
|
self.core = revpi_object.core
|
||||||
|
self.io = revpi_object.io
|
||||||
|
|
||||||
# Taktmerker
|
# Taktmerker
|
||||||
self.first = True
|
self.first = True
|
||||||
@@ -298,6 +303,17 @@ class Cycletools:
|
|||||||
else:
|
else:
|
||||||
self.__dict_tp[name][1] = True
|
self.__dict_tp[name][1] = True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def runtime(self) -> float:
|
||||||
|
"""
|
||||||
|
Runtime im milliseconds of cycle function till now.
|
||||||
|
|
||||||
|
This property will return the actual runtime of the function. So on the
|
||||||
|
beginning of your function it will be about 0 and will rise during
|
||||||
|
the runtime to the max in the last line of your function.
|
||||||
|
"""
|
||||||
|
return (default_timer() - self._start_timer) * 1000
|
||||||
|
|
||||||
|
|
||||||
class ProcimgWriter(Thread):
|
class ProcimgWriter(Thread):
|
||||||
"""
|
"""
|
||||||
@@ -458,9 +474,10 @@ class ProcimgWriter(Thread):
|
|||||||
self._adjwait = self._refresh
|
self._adjwait = self._refresh
|
||||||
|
|
||||||
mrk_warn = True
|
mrk_warn = True
|
||||||
|
mrk_dt = default_timer()
|
||||||
|
|
||||||
while not self._work.is_set():
|
while not self._work.is_set():
|
||||||
ot = default_timer()
|
ot = mrk_dt
|
||||||
|
|
||||||
# Lockobjekt holen und Fehler werfen, wenn nicht schnell genug
|
# Lockobjekt holen und Fehler werfen, wenn nicht schnell genug
|
||||||
if not self.lck_refresh.acquire(timeout=self._adjwait):
|
if not self.lck_refresh.acquire(timeout=self._adjwait):
|
||||||
@@ -550,7 +567,8 @@ class ProcimgWriter(Thread):
|
|||||||
self._work.wait(self._adjwait)
|
self._work.wait(self._adjwait)
|
||||||
|
|
||||||
# Wartezeit anpassen um echte self._refresh zu erreichen
|
# Wartezeit anpassen um echte self._refresh zu erreichen
|
||||||
if default_timer() - ot >= self._refresh:
|
mrk_dt = default_timer()
|
||||||
|
if mrk_dt - ot >= self._refresh:
|
||||||
self._adjwait -= 0.001
|
self._adjwait -= 0.001
|
||||||
if self._adjwait < 0:
|
if self._adjwait < 0:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
|
|||||||
@@ -1253,10 +1253,10 @@ class MemIO(IOBase):
|
|||||||
def get_variantvalue(self):
|
def get_variantvalue(self):
|
||||||
val = bytes(self._defaultvalue)
|
val = bytes(self._defaultvalue)
|
||||||
|
|
||||||
if self._bitlength == 256:
|
if self._bitlength > 64:
|
||||||
# STRING
|
# STRING
|
||||||
try:
|
try:
|
||||||
val = val.strip(b'\x00').decode("ASCII")
|
val = val.strip(b'\x00').decode()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return val
|
return val
|
||||||
|
|||||||
@@ -734,9 +734,9 @@ class RevPiModIO(object):
|
|||||||
# Cycleloop starten
|
# Cycleloop starten
|
||||||
self._exit.clear()
|
self._exit.clear()
|
||||||
self._looprunning = True
|
self._looprunning = True
|
||||||
cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh)
|
cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh, self)
|
||||||
e = None
|
e = None # Exception
|
||||||
ec = None
|
ec = None # Return value of cycle_function
|
||||||
try:
|
try:
|
||||||
while ec is None and not cycleinfo.last:
|
while ec is None and not cycleinfo.last:
|
||||||
# Auf neue Daten warten und nur ausführen wenn set()
|
# Auf neue Daten warten und nur ausführen wenn set()
|
||||||
@@ -752,8 +752,11 @@ class RevPiModIO(object):
|
|||||||
# Vor Aufruf der Funktion autorefresh sperren
|
# Vor Aufruf der Funktion autorefresh sperren
|
||||||
self._imgwriter.lck_refresh.acquire()
|
self._imgwriter.lck_refresh.acquire()
|
||||||
|
|
||||||
# Funktion aufrufen und auswerten
|
# Vorbereitung für cycleinfo
|
||||||
|
cycleinfo._start_timer = default_timer()
|
||||||
cycleinfo.last = self._exit.is_set()
|
cycleinfo.last = self._exit.is_set()
|
||||||
|
|
||||||
|
# Funktion aufrufen und auswerten
|
||||||
ec = func(cycleinfo)
|
ec = func(cycleinfo)
|
||||||
cycleinfo._docycle()
|
cycleinfo._docycle()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user