diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..48d4e66
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/revpimodio2/device.py b/revpimodio2/device.py
index f70b266..08092e8 100644
--- a/revpimodio2/device.py
+++ b/revpimodio2/device.py
@@ -542,12 +542,13 @@ class Core(Base):
__slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \
"_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):
"""Verhindert Ueberschreibung der LEDs."""
if hasattr(self, key) and key in (
- "a1green", "a1red", "a2green", "a2red"):
+ "a1green", "a1red", "a2green", "a2red", "wd"):
raise AttributeError(
"direct assignment is not supported - use .value Attribute"
)
@@ -616,6 +617,12 @@ class Core(Base):
exp_a2red, None, "LED_A2_RED", "3"
], 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:
"""
Verwaltet das Schreiben der ErrorLimits.
@@ -694,6 +701,10 @@ class Core(Base):
else:
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)
A2 = property(_get_leda2, _set_leda2)
status = property(_get_status)
@@ -865,19 +876,17 @@ class Connect(Core):
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"
def __setattr__(self, key, value):
- """Verhindert Ueberschreibung der LEDs."""
+ """Verhindert Ueberschreibung der speziellen IOs."""
if hasattr(self, key) and key in (
- "a1green", "a1red", "a2green", "a2red", "a3green", "a3red",
- "wd", "x2in", "x2out"):
+ "a3green", "a3red", "x2in", "x2out"):
raise AttributeError(
"direct assignment is not supported - use .value Attribute"
)
- else:
- object.__setattr__(self, key, value)
+ super(Connect, self).__setattr__(key, value)
def __wdtoggle(self) -> None:
"""WD Ausgang alle 10 Sekunden automatisch toggeln."""
@@ -921,10 +930,6 @@ class Connect(Core):
], OUT, "little", False)
# 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, [
"core.x2in", 0, 1, self._slc_statusbyte.start,
exp_x2in, None, "Connect_X2_IN", "6"
@@ -1015,7 +1020,7 @@ class Compact(Base):
"""
__slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \
- "a1green", "a1red", "a2green", "a2red"
+ "a1green", "a1red", "a2green", "a2red", "wd"
def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der LEDs."""
@@ -1066,6 +1071,12 @@ class Compact(Base):
exp_a2red, None, "LED_A2_RED", "3"
], 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:
"""
Gibt den Zustand der LED A1 vom Compact zurueck.
@@ -1119,6 +1130,10 @@ class Compact(Base):
else:
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)
A2 = property(_get_leda2, _set_leda2)
diff --git a/revpimodio2/helper.py b/revpimodio2/helper.py
index 44439b6..1b93ece 100644
--- a/revpimodio2/helper.py
+++ b/revpimodio2/helper.py
@@ -85,12 +85,12 @@ class Cycletools:
Lampen synchron blinken zu lassen.
"""
- __slots__ = "__cycle", "__cycletime", "__ucycle", \
- "__dict_ton", "__dict_tof", "__dict_tp", "first", "last", \
- "flag1c", "flag5c", "flag10c", "flag15c", "flag20c", \
- "flank5c", "flank10c", "flank15c", "flank20c", "var"
+ __slots__ = "__cycle", "__cycletime", "__ucycle", "__dict_ton", \
+ "__dict_tof", "__dict_tp", "_start_timer", "core", "first", \
+ "io", "last", "flag1c", "flag5c", "flag10c", "flag15c", \
+ "flag20c", "flank5c", "flank10c", "flank15c", "flank20c", "var"
- def __init__(self, cycletime):
+ def __init__(self, cycletime, revpi_object):
"""Init Cycletools class."""
self.__cycle = 0
self.__cycletime = cycletime
@@ -98,6 +98,11 @@ class Cycletools:
self.__dict_ton = {}
self.__dict_tof = {}
self.__dict_tp = {}
+ self._start_timer = 0.0
+
+ # Access to core and io
+ self.core = revpi_object.core
+ self.io = revpi_object.io
# Taktmerker
self.first = True
@@ -298,6 +303,17 @@ class Cycletools:
else:
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):
"""
@@ -458,9 +474,10 @@ class ProcimgWriter(Thread):
self._adjwait = self._refresh
mrk_warn = True
+ mrk_dt = default_timer()
while not self._work.is_set():
- ot = default_timer()
+ ot = mrk_dt
# Lockobjekt holen und Fehler werfen, wenn nicht schnell genug
if not self.lck_refresh.acquire(timeout=self._adjwait):
@@ -550,7 +567,8 @@ class ProcimgWriter(Thread):
self._work.wait(self._adjwait)
# 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
if self._adjwait < 0:
warnings.warn(
diff --git a/revpimodio2/io.py b/revpimodio2/io.py
index 5e75e21..8ac2f45 100644
--- a/revpimodio2/io.py
+++ b/revpimodio2/io.py
@@ -1253,10 +1253,10 @@ class MemIO(IOBase):
def get_variantvalue(self):
val = bytes(self._defaultvalue)
- if self._bitlength == 256:
+ if self._bitlength > 64:
# STRING
try:
- val = val.strip(b'\x00').decode("ASCII")
+ val = val.strip(b'\x00').decode()
except Exception:
pass
return val
diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py
index 79a67a8..75ef4b7 100644
--- a/revpimodio2/modio.py
+++ b/revpimodio2/modio.py
@@ -734,9 +734,9 @@ class RevPiModIO(object):
# Cycleloop starten
self._exit.clear()
self._looprunning = True
- cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh)
- e = None
- ec = None
+ cycleinfo = helpermodule.Cycletools(self._imgwriter.refresh, self)
+ e = None # Exception
+ ec = None # Return value of cycle_function
try:
while ec is None and not cycleinfo.last:
# Auf neue Daten warten und nur ausführen wenn set()
@@ -752,8 +752,11 @@ class RevPiModIO(object):
# Vor Aufruf der Funktion autorefresh sperren
self._imgwriter.lck_refresh.acquire()
- # Funktion aufrufen und auswerten
+ # Vorbereitung für cycleinfo
+ cycleinfo._start_timer = default_timer()
cycleinfo.last = self._exit.is_set()
+
+ # Funktion aufrufen und auswerten
ec = func(cycleinfo)
cycleinfo._docycle()
diff --git a/setup.py b/setup.py
index 8c44350..10c68e1 100644
--- a/setup.py
+++ b/setup.py
@@ -17,7 +17,7 @@ setup(
license="LGPLv3",
name="revpimodio2",
- version="2.4.5c",
+ version="2.4.5d",
packages=["revpimodio2"],
python_requires="~=3.2",