Mit prefire zusammenführen

This commit is contained in:
2019-07-25 17:01:39 +02:00
5 changed files with 52 additions and 18 deletions

View File

@@ -241,7 +241,7 @@ Bytelaenge des IO - 0 bei BITs
</dl><a NAME="IOBase.__reg_xevent" ID="IOBase.__reg_xevent"></a> </dl><a NAME="IOBase.__reg_xevent" ID="IOBase.__reg_xevent"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.__reg_xevent</h3> IOBase.__reg_xevent</h3>
<b>__reg_xevent</b>(<i>func, delay, edge, as_thread, overwrite</i>) <b>__reg_xevent</b>(<i>func, delay, edge, as_thread, overwrite, prefire</i>)
<p> <p>
Verwaltet reg_event und reg_timerevent. Verwaltet reg_event und reg_timerevent.
</p><dl> </p><dl>
@@ -260,6 +260,9 @@ Bei True, Funktion als EventCallback-Thread ausfuehren
</dd><dt><i>overwrite</i></dt> </dd><dt><i>overwrite</i></dt>
<dd> <dd>
Wenn True, wird Event bei ueberschrieben Wenn True, wird Event bei ueberschrieben
</dd><dt><i>prefire</i></dt>
<dd>
Ausloesen mit aktuellem Wert, wenn mainloop startet
</dd> </dd>
</dl><a NAME="IOBase.__str__" ID="IOBase.__str__"></a> </dl><a NAME="IOBase.__str__" ID="IOBase.__str__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -330,7 +333,7 @@ IO-Wert als <class 'bytes'> oder <class 'bool'>
</dl><a NAME="IOBase.reg_event" ID="IOBase.reg_event"></a> </dl><a NAME="IOBase.reg_event" ID="IOBase.reg_event"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.reg_event</h3> IOBase.reg_event</h3>
<b>reg_event</b>(<i>func, delay=0, edge=BOTH, as_thread=False</i>) <b>reg_event</b>(<i>func, delay=0, edge=BOTH, as_thread=False, prefire=False</i>)
<p> <p>
Registriert fuer IO ein Event bei der Eventueberwachung. Registriert fuer IO ein Event bei der Eventueberwachung.
</p><p> </p><p>
@@ -353,6 +356,9 @@ Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
</dd><dt><i>as_thread</i></dt> </dd><dt><i>as_thread</i></dt>
<dd> <dd>
Bei True, Funktion als EventCallback-Thread ausfuehren Bei True, Funktion als EventCallback-Thread ausfuehren
</dd><dt><i>prefire</i></dt>
<dd>
Ausloesen mit aktuellem Wert, wenn mainloop startet
</dd> </dd>
</dl><a NAME="IOBase.reg_timerevent" ID="IOBase.reg_timerevent"></a> </dl><a NAME="IOBase.reg_timerevent" ID="IOBase.reg_timerevent"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -502,7 +508,7 @@ Static Methods</h3>
<a NAME="IOEvent.__init__" ID="IOEvent.__init__"></a> <a NAME="IOEvent.__init__" ID="IOEvent.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
IOEvent (Constructor)</h3> IOEvent (Constructor)</h3>
<b>IOEvent</b>(<i>func, edge, as_thread, delay, overwrite</i>) <b>IOEvent</b>(<i>func, edge, as_thread, delay, overwrite, prefire</i>)
<p> <p>
Init IOEvent class. Init IOEvent class.
</p> </p>

View File

@@ -106,7 +106,7 @@ revpimodio2.io.IOBase.get_defaultvalue?4()
revpimodio2.io.IOBase.get_value?4() revpimodio2.io.IOBase.get_value?4()
revpimodio2.io.IOBase.length?7 revpimodio2.io.IOBase.length?7
revpimodio2.io.IOBase.name?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.reg_timerevent?4(func, delay, edge=BOTH, as_thread=False)
revpimodio2.io.IOBase.set_value?4(value) revpimodio2.io.IOBase.set_value?4(value)
revpimodio2.io.IOBase.type?7 revpimodio2.io.IOBase.type?7
@@ -114,7 +114,7 @@ revpimodio2.io.IOBase.unreg_event?4(func=None, edge=None)
revpimodio2.io.IOBase.value?7 revpimodio2.io.IOBase.value?7
revpimodio2.io.IOBase.wait?4(edge=BOTH, exitevent=None, okvalue=None, timeout=0) revpimodio2.io.IOBase.wait?4(edge=BOTH, exitevent=None, okvalue=None, timeout=0)
revpimodio2.io.IOBase?1(parentdevice, valuelist, iotype, byteorder, signed) 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._private_register_new_io_object?5(new_io)
revpimodio2.io.IOList?1() revpimodio2.io.IOList?1()
revpimodio2.io.IntIO._get_signed?5() revpimodio2.io.IntIO._get_signed?5()

View File

@@ -413,9 +413,11 @@ class ProcimgWriter(Thread):
if self.__eventwork != value: if self.__eventwork != value:
with self.lck_refresh: with self.lck_refresh:
self.__eventwork = value self.__eventwork = value
self.__eventqth = queue.Queue() if not value:
self._eventq = queue.Queue() # Nur leeren beim deaktivieren
self.__dict_delay = {} self.__eventqth = queue.Queue()
self._eventq = queue.Queue()
self.__dict_delay = {}
# Threadmanagement # Threadmanagement
if value and not self.__eventth.is_alive(): if value and not self.__eventth.is_alive():

View File

@@ -21,15 +21,16 @@ class IOEvent(object):
"""Basisklasse fuer IO-Events.""" """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.""" """Init IOEvent class."""
self.as_thread = as_thread self.as_thread = as_thread
self.delay = delay self.delay = delay
self.edge = edge self.edge = edge
self.func = func self.func = func
self.overwrite = overwrite self.overwrite = overwrite
self.prefire = prefire
class IOList(object): class IOList(object):
@@ -368,7 +369,7 @@ class IOBase(object):
@return Namen des IOs""" @return Namen des IOs"""
return self._name 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. """Verwaltet reg_event und reg_timerevent.
@param func Funktion die bei Aenderung aufgerufen werden soll @param func Funktion die bei Aenderung aufgerufen werden soll
@@ -376,6 +377,7 @@ class IOBase(object):
@param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung @param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
@param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren @param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren
@param overwrite Wenn True, wird Event bei ueberschrieben @param overwrite Wenn True, wird Event bei ueberschrieben
@param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet
""" """
# Prüfen ob Funktion callable ist # Prüfen ob Funktion callable ist
@@ -391,11 +393,15 @@ class IOBase(object):
raise ValueError( raise ValueError(
"parameter 'edge' can be used with bit io objects only" "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: if self not in self._parentdevice._dict_events:
with self._parentdevice._filelock: with self._parentdevice._filelock:
self._parentdevice._dict_events[self] = \ self._parentdevice._dict_events[self] = \
[IOEvent(func, edge, as_thread, delay, overwrite)] [IOEvent(func, edge, as_thread, delay, overwrite, prefire)]
else: else:
# Prüfen ob Funktion schon registriert ist # Prüfen ob Funktion schon registriert ist
for regfunc in self._parentdevice._dict_events[self]: for regfunc in self._parentdevice._dict_events[self]:
@@ -429,7 +435,7 @@ class IOBase(object):
# Eventfunktion einfügen # Eventfunktion einfügen
with self._parentdevice._filelock: with self._parentdevice._filelock:
self._parentdevice._dict_events[self].append( 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): def _get_address(self):
@@ -464,7 +470,8 @@ class IOBase(object):
else: else:
return bytes(self._parentdevice._ba_devdata[self._slc_address]) 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. """Registriert fuer IO ein Event bei der Eventueberwachung.
Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert
@@ -478,9 +485,10 @@ class IOBase(object):
@param delay Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt @param delay Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
@param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung @param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
@param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren @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): def reg_timerevent(self, func, delay, edge=BOTH, as_thread=False):
"""Registriert fuer IO einen Timer, welcher nach delay func ausfuehrt. """Registriert fuer IO einen Timer, welcher nach delay func ausfuehrt.
@@ -501,7 +509,7 @@ class IOBase(object):
@param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren @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): def set_value(self, value):
"""Setzt den Wert des IOs. """Setzt den Wert des IOs.

View File

@@ -10,7 +10,7 @@ from json import load as jload
from multiprocessing import cpu_count from multiprocessing import cpu_count
from os import access, F_OK, R_OK from os import access, F_OK, R_OK
from queue import Empty 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 signal import signal, SIG_DFL, SIGINT, SIGTERM
from threading import Thread, Event, Lock from threading import Thread, Event, Lock
from timeit import default_timer from timeit import default_timer
@@ -771,11 +771,29 @@ class RevPiModIO(object):
self._exit.clear() self._exit.clear()
self._looprunning = True 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: for dev in self._lst_refresh:
with dev._filelock: with dev._filelock:
dev._ba_datacp = dev._ba_devdata[:] 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 # ImgWriter mit Eventüberwachung aktivieren
self._imgwriter._collect_events(True) self._imgwriter._collect_events(True)
e = None e = None