diff --git a/doc/revpimodio2.io.html b/doc/revpimodio2.io.html index 0637b6f..673584e 100644 --- a/doc/revpimodio2.io.html +++ b/doc/revpimodio2.io.html @@ -241,7 +241,7 @@ Bytelaenge des IO - 0 bei BITs

IOBase.__reg_xevent

-__reg_xevent(func, delay, edge, as_thread, overwrite) +__reg_xevent(func, delay, edge, as_thread, overwrite, prefire)

Verwaltet reg_event und reg_timerevent.

@@ -260,6 +260,9 @@ Bei True, Funktion als EventCallback-Thread ausfuehren
overwrite
Wenn True, wird Event bei ueberschrieben +
prefire
+
+Ausloesen mit aktuellem Wert, wenn mainloop startet

@@ -330,7 +333,7 @@ IO-Wert als oder

IOBase.reg_event

-reg_event(func, delay=0, edge=BOTH, as_thread=False) +reg_event(func, delay=0, edge=BOTH, as_thread=False, prefire=False)

Registriert fuer IO ein Event bei der Eventueberwachung.

@@ -353,6 +356,9 @@ Ausfuehren bei RISING, FALLING or BOTH Wertaenderung

as_thread
Bei True, Funktion als EventCallback-Thread ausfuehren +
prefire
+
+Ausloesen mit aktuellem Wert, wenn mainloop startet

@@ -502,7 +508,7 @@ Static Methods

IOEvent (Constructor)

-IOEvent(func, edge, as_thread, delay, overwrite) +IOEvent(func, edge, as_thread, delay, overwrite, prefire)

Init IOEvent class.

@@ -961,6 +967,7 @@ Weitere Parameter: - delay: Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt - edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung - as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus + - prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet
See Also:
diff --git a/eric-revpimodio2.api b/eric-revpimodio2.api index a6a10cb..f677fe9 100644 --- a/eric-revpimodio2.api +++ b/eric-revpimodio2.api @@ -107,7 +107,7 @@ revpimodio2.io.IOBase.get_defaultvalue?4() revpimodio2.io.IOBase.get_value?4() revpimodio2.io.IOBase.length?7 revpimodio2.io.IOBase.name?7 -revpimodio2.io.IOBase.reg_event?4(func, delay=0, edge=BOTH, as_thread=False) +revpimodio2.io.IOBase.reg_event?4(func, delay=0, edge=BOTH, as_thread=False, prefire=False) revpimodio2.io.IOBase.reg_timerevent?4(func, delay, edge=BOTH, as_thread=False) revpimodio2.io.IOBase.set_value?4(value) revpimodio2.io.IOBase.type?7 @@ -115,7 +115,7 @@ revpimodio2.io.IOBase.unreg_event?4(func=None, edge=None) revpimodio2.io.IOBase.value?7 revpimodio2.io.IOBase.wait?4(edge=BOTH, exitevent=None, okvalue=None, timeout=0) revpimodio2.io.IOBase?1(parentdevice, valuelist, iotype, byteorder, signed) -revpimodio2.io.IOEvent?1(func, edge, as_thread, delay, overwrite) +revpimodio2.io.IOEvent?1(func, edge, as_thread, delay, overwrite, prefire) revpimodio2.io.IOList._private_register_new_io_object?5(new_io) revpimodio2.io.IOList?1() revpimodio2.io.IntIO._get_signed?5() diff --git a/revpimodio2/helper.py b/revpimodio2/helper.py index 37af3cb..fb5e2ce 100644 --- a/revpimodio2/helper.py +++ b/revpimodio2/helper.py @@ -413,9 +413,11 @@ class ProcimgWriter(Thread): if self.__eventwork != value: with self.lck_refresh: self.__eventwork = value - self.__eventqth = queue.Queue() - self._eventq = queue.Queue() - self.__dict_delay = {} + if not value: + # Nur leeren beim deaktivieren + self.__eventqth = queue.Queue() + self._eventq = queue.Queue() + self.__dict_delay = {} # Threadmanagement if value and not self.__eventth.is_alive(): diff --git a/revpimodio2/io.py b/revpimodio2/io.py index e274894..6cc2bad 100644 --- a/revpimodio2/io.py +++ b/revpimodio2/io.py @@ -21,15 +21,16 @@ class IOEvent(object): """Basisklasse fuer IO-Events.""" - __slots__ = "as_thread", "delay", "edge", "func", "overwrite" + __slots__ = "as_thread", "delay", "edge", "func", "overwrite", "prefire" - def __init__(self, func, edge, as_thread, delay, overwrite): + def __init__(self, func, edge, as_thread, delay, overwrite, prefire): """Init IOEvent class.""" self.as_thread = as_thread self.delay = delay self.edge = edge self.func = func self.overwrite = overwrite + self.prefire = prefire class IOList(object): @@ -372,7 +373,7 @@ class IOBase(object): @return Namen des IOs""" return self._name - def __reg_xevent(self, func, delay, edge, as_thread, overwrite): + def __reg_xevent(self, func, delay, edge, as_thread, overwrite, prefire): """Verwaltet reg_event und reg_timerevent. @param func Funktion die bei Aenderung aufgerufen werden soll @@ -380,6 +381,7 @@ class IOBase(object): @param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren @param overwrite Wenn True, wird Event bei ueberschrieben + @param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet """ # Prüfen ob Funktion callable ist @@ -395,11 +397,15 @@ class IOBase(object): raise ValueError( "parameter 'edge' can be used with bit io objects only" ) + if prefire and self._parentdevice._modio._looprunning: + raise RuntimeError( + "prefire can not be used if mainloop is running" + ) if self not in self._parentdevice._dict_events: with self._parentdevice._filelock: self._parentdevice._dict_events[self] = \ - [IOEvent(func, edge, as_thread, delay, overwrite)] + [IOEvent(func, edge, as_thread, delay, overwrite, prefire)] else: # Prüfen ob Funktion schon registriert ist for regfunc in self._parentdevice._dict_events[self]: @@ -433,7 +439,7 @@ class IOBase(object): # Eventfunktion einfügen with self._parentdevice._filelock: self._parentdevice._dict_events[self].append( - IOEvent(func, edge, as_thread, delay, overwrite) + IOEvent(func, edge, as_thread, delay, overwrite, prefire) ) def _get_address(self): @@ -468,7 +474,8 @@ class IOBase(object): else: return bytes(self._parentdevice._ba_devdata[self._slc_address]) - def reg_event(self, func, delay=0, edge=BOTH, as_thread=False): + def reg_event( + self, func, delay=0, edge=BOTH, as_thread=False, prefire=False): """Registriert fuer IO ein Event bei der Eventueberwachung. Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert @@ -482,9 +489,10 @@ class IOBase(object): @param delay Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt @param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren + @param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet """ - self.__reg_xevent(func, delay, edge, as_thread, True) + self.__reg_xevent(func, delay, edge, as_thread, True, prefire) def reg_timerevent(self, func, delay, edge=BOTH, as_thread=False): """Registriert fuer IO einen Timer, welcher nach delay func ausfuehrt. @@ -505,7 +513,7 @@ class IOBase(object): @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren """ - self.__reg_xevent(func, delay, edge, as_thread, False) + self.__reg_xevent(func, delay, edge, as_thread, False, False) def set_value(self, value): """Setzt den Wert des IOs. @@ -916,6 +924,7 @@ class IntIOReplaceable(IntIO): - delay: Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt - edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung - as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus + - prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet @see Python3 struct diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index d08544c..ee5677d 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -10,7 +10,7 @@ from json import load as jload from multiprocessing import cpu_count from os import access, F_OK, R_OK from queue import Empty -from revpimodio2 import acheck, DeviceNotFoundError +from revpimodio2 import acheck, DeviceNotFoundError, BOTH, RISING, FALLING from signal import signal, SIG_DFL, SIGINT, SIGTERM from threading import Thread, Event, Lock from timeit import default_timer @@ -643,7 +643,7 @@ class RevPiModIO(object): # Optional values if io._bitaddress >= 0: - cp[io.name]["bitaddress"] = str(io._bitaddress) + cp[io.name]["bit"] = str(io._bitaddress) cp[io.name]["byteorder"] = io._byteorder cp[io.name]["defaultvalue"] = str(io.defaultvalue) if io.bmk != "": @@ -771,11 +771,29 @@ class RevPiModIO(object): self._exit.clear() self._looprunning = True - # Beim Eintritt in mainloop Bytecopy erstellen + # Beim Eintritt in mainloop Bytecopy erstellen und prefire anhängen for dev in self._lst_refresh: with dev._filelock: dev._ba_datacp = dev._ba_devdata[:] + # Prefire Events vorbereiten + for io in dev._dict_events: + for regfunc in dev._dict_events[io]: + if not regfunc.prefire: + continue + + if regfunc.edge == BOTH \ + or regfunc.edge == RISING and io.value \ + or regfunc.edge == FALLING and not io.value: + if regfunc.as_thread: + self._imgwriter.__eventqth.put( + (regfunc, io._name, io.value), False + ) + else: + self._imgwriter._eventq.put( + (regfunc, io._name, io.value), False + ) + # ImgWriter mit Eventüberwachung aktivieren self._imgwriter._collect_events(True) e = None