mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-12-29 02:08:03 +01:00
Eventüberwachung über Queues realisiert
This commit is contained in:
@@ -440,6 +440,12 @@ Methods</h3>
|
|||||||
<td><a style="color:#0000FF" href="#ProcimgWriter.__init__">ProcimgWriter</a></td>
|
<td><a style="color:#0000FF" href="#ProcimgWriter.__init__">ProcimgWriter</a></td>
|
||||||
<td>Init ProcimgWriter class.</td>
|
<td>Init ProcimgWriter class.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
|
<td><a style="color:#0000FF" href="#ProcimgWriter.__check_change">__check_change</a></td>
|
||||||
|
<td>Findet Aenderungen fuer die Eventueberwachung.</td>
|
||||||
|
</tr><tr>
|
||||||
|
<td><a style="color:#0000FF" href="#ProcimgWriter._collect_events">_collect_events</a></td>
|
||||||
|
<td>Aktiviert oder Deaktiviert die Eventueberwachung.</td>
|
||||||
|
</tr><tr>
|
||||||
<td><a style="color:#0000FF" href="#ProcimgWriter._get_ioerrors">_get_ioerrors</a></td>
|
<td><a style="color:#0000FF" href="#ProcimgWriter._get_ioerrors">_get_ioerrors</a></td>
|
||||||
<td>Ruft aktuelle Anzahl der Fehler ab.</td>
|
<td>Ruft aktuelle Anzahl der Fehler ab.</td>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
@@ -481,6 +487,23 @@ Init ProcimgWriter class.
|
|||||||
<dd>
|
<dd>
|
||||||
Parent Object
|
Parent Object
|
||||||
</dd>
|
</dd>
|
||||||
|
</dl><a NAME="ProcimgWriter.__check_change" ID="ProcimgWriter.__check_change"></a>
|
||||||
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
|
ProcimgWriter.__check_change</h3>
|
||||||
|
<b>__check_change</b>(<i>dev</i>)
|
||||||
|
<p>
|
||||||
|
Findet Aenderungen fuer die Eventueberwachung.
|
||||||
|
</p><a NAME="ProcimgWriter._collect_events" ID="ProcimgWriter._collect_events"></a>
|
||||||
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
|
ProcimgWriter._collect_events</h3>
|
||||||
|
<b>_collect_events</b>(<i>value</i>)
|
||||||
|
<p>
|
||||||
|
Aktiviert oder Deaktiviert die Eventueberwachung.
|
||||||
|
</p><dl>
|
||||||
|
<dt><i>value</i></dt>
|
||||||
|
<dd>
|
||||||
|
True aktiviert / False deaktiviert
|
||||||
|
</dd>
|
||||||
</dl><a NAME="ProcimgWriter._get_ioerrors" ID="ProcimgWriter._get_ioerrors"></a>
|
</dl><a NAME="ProcimgWriter._get_ioerrors" ID="ProcimgWriter._get_ioerrors"></a>
|
||||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
ProcimgWriter._get_ioerrors</h3>
|
ProcimgWriter._get_ioerrors</h3>
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ Funktion wird nach dem letzten Lesen der Inputs
|
|||||||
</dl><a NAME="RevPiModIO.mainloop" ID="RevPiModIO.mainloop"></a>
|
</dl><a NAME="RevPiModIO.mainloop" ID="RevPiModIO.mainloop"></a>
|
||||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||||
RevPiModIO.mainloop</h3>
|
RevPiModIO.mainloop</h3>
|
||||||
<b>mainloop</b>(<i>freeze=False, blocking=True</i>)
|
<b>mainloop</b>(<i>blocking=True</i>)
|
||||||
<p>
|
<p>
|
||||||
Startet den Mainloop mit Eventueberwachung.
|
Startet den Mainloop mit Eventueberwachung.
|
||||||
</p><p>
|
</p><p>
|
||||||
@@ -449,12 +449,6 @@ Startet den Mainloop mit Eventueberwachung.
|
|||||||
durchlaeuft die Eventueberwachung und prueft Aenderungen der, mit
|
durchlaeuft die Eventueberwachung und prueft Aenderungen der, mit
|
||||||
einem Event registrierten, IOs. Wird eine Veraenderung erkannt,
|
einem Event registrierten, IOs. Wird eine Veraenderung erkannt,
|
||||||
fuert das Programm die dazugehoerigen Funktionen der Reihe nach aus.
|
fuert das Programm die dazugehoerigen Funktionen der Reihe nach aus.
|
||||||
</p><p>
|
|
||||||
Wenn der Parameter "freeze" mit True angegeben ist, wird die
|
|
||||||
Prozessabbildsynchronisierung angehalten bis alle Eventfunktionen
|
|
||||||
ausgefuehrt wurden. Inputs behalten fuer die gesamte Dauer ihren
|
|
||||||
aktuellen Wert und Outputs werden erst nach Durchlauf aller Funktionen
|
|
||||||
in das Prozessabbild geschrieben.
|
|
||||||
</p><p>
|
</p><p>
|
||||||
Wenn der Parameter "blocking" mit False angegeben wird, aktiviert
|
Wenn der Parameter "blocking" mit False angegeben wird, aktiviert
|
||||||
dies die Eventueberwachung und blockiert das Programm NICHT an der
|
dies die Eventueberwachung und blockiert das Programm NICHT an der
|
||||||
@@ -462,10 +456,7 @@ Startet den Mainloop mit Eventueberwachung.
|
|||||||
Events vom RevPi benoetigt werden, aber das Programm weiter ausgefuehrt
|
Events vom RevPi benoetigt werden, aber das Programm weiter ausgefuehrt
|
||||||
werden soll.
|
werden soll.
|
||||||
</p><dl>
|
</p><dl>
|
||||||
<dt><i>freeze</i></dt>
|
<dt><i>blocking</i></dt>
|
||||||
<dd>
|
|
||||||
Wenn True, Prozessabbildsynchronisierung anhalten
|
|
||||||
</dd><dt><i>blocking</i></dt>
|
|
||||||
<dd>
|
<dd>
|
||||||
Wenn False, blockiert das Programm NICHT
|
Wenn False, blockiert das Programm NICHT
|
||||||
</dd>
|
</dd>
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ revpimodio2.helper.Cycletools?1(cycletime)
|
|||||||
revpimodio2.helper.EventCallback.run?4()
|
revpimodio2.helper.EventCallback.run?4()
|
||||||
revpimodio2.helper.EventCallback.stop?4()
|
revpimodio2.helper.EventCallback.stop?4()
|
||||||
revpimodio2.helper.EventCallback?1(func, name, value)
|
revpimodio2.helper.EventCallback?1(func, name, value)
|
||||||
|
revpimodio2.helper.ProcimgWriter._collect_events?5(value)
|
||||||
revpimodio2.helper.ProcimgWriter._get_ioerrors?5()
|
revpimodio2.helper.ProcimgWriter._get_ioerrors?5()
|
||||||
revpimodio2.helper.ProcimgWriter._gotioerror?5()
|
revpimodio2.helper.ProcimgWriter._gotioerror?5()
|
||||||
revpimodio2.helper.ProcimgWriter.get_maxioerrors?4()
|
revpimodio2.helper.ProcimgWriter.get_maxioerrors?4()
|
||||||
@@ -149,7 +150,7 @@ revpimodio2.modio.RevPiModIO.get_jconfigrsc?4()
|
|||||||
revpimodio2.modio.RevPiModIO.handlesignalend?4(cleanupfunc=None)
|
revpimodio2.modio.RevPiModIO.handlesignalend?4(cleanupfunc=None)
|
||||||
revpimodio2.modio.RevPiModIO.ioerrors?7
|
revpimodio2.modio.RevPiModIO.ioerrors?7
|
||||||
revpimodio2.modio.RevPiModIO.length?7
|
revpimodio2.modio.RevPiModIO.length?7
|
||||||
revpimodio2.modio.RevPiModIO.mainloop?4(freeze=False, blocking=True)
|
revpimodio2.modio.RevPiModIO.mainloop?4(blocking=True)
|
||||||
revpimodio2.modio.RevPiModIO.maxioerrors?7
|
revpimodio2.modio.RevPiModIO.maxioerrors?7
|
||||||
revpimodio2.modio.RevPiModIO.monitoring?7
|
revpimodio2.modio.RevPiModIO.monitoring?7
|
||||||
revpimodio2.modio.RevPiModIO.procimg?7
|
revpimodio2.modio.RevPiModIO.procimg?7
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
# (c) Sven Sager, License: LGPLv3
|
# (c) Sven Sager, License: LGPLv3
|
||||||
#
|
#
|
||||||
"""RevPiModIO Helperklassen und Tools."""
|
"""RevPiModIO Helperklassen und Tools."""
|
||||||
|
import queue
|
||||||
import warnings
|
import warnings
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from threading import Event, Lock, Thread
|
from threading import Event, Lock, Thread
|
||||||
from timeit import default_timer
|
from timeit import default_timer
|
||||||
|
from revpimodio2 import RISING, FALLING, BOTH
|
||||||
|
|
||||||
|
|
||||||
class EventCallback(Thread):
|
class EventCallback(Thread):
|
||||||
@@ -281,7 +283,10 @@ class ProcimgWriter(Thread):
|
|||||||
"""Init ProcimgWriter class.
|
"""Init ProcimgWriter class.
|
||||||
@param parentmodio Parent Object"""
|
@param parentmodio Parent Object"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.__dict_delay = {}
|
||||||
|
self.__eventwork = False
|
||||||
self._adjwait = 0
|
self._adjwait = 0
|
||||||
|
self._eventq = queue.Queue()
|
||||||
self._ioerror = 0
|
self._ioerror = 0
|
||||||
self._maxioerrors = 0
|
self._maxioerrors = 0
|
||||||
self._modio = parentmodio
|
self._modio = parentmodio
|
||||||
@@ -292,6 +297,77 @@ class ProcimgWriter(Thread):
|
|||||||
self.lck_refresh = Lock()
|
self.lck_refresh = Lock()
|
||||||
self.newdata = Event()
|
self.newdata = Event()
|
||||||
|
|
||||||
|
def __check_change(self, dev):
|
||||||
|
"""Findet Aenderungen fuer die Eventueberwachung."""
|
||||||
|
for io_event in dev._dict_events:
|
||||||
|
|
||||||
|
if dev._ba_datacp[io_event._slc_address] == \
|
||||||
|
dev._ba_devdata[io_event._slc_address]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if io_event._bitaddress >= 0:
|
||||||
|
boolcp = bool(int.from_bytes(
|
||||||
|
dev._ba_datacp[io_event._slc_address],
|
||||||
|
byteorder=io_event._byteorder
|
||||||
|
) & 1 << io_event._bitaddress)
|
||||||
|
boolor = bool(int.from_bytes(
|
||||||
|
dev._ba_devdata[io_event._slc_address],
|
||||||
|
byteorder=io_event._byteorder
|
||||||
|
) & 1 << io_event._bitaddress)
|
||||||
|
|
||||||
|
if boolor == boolcp:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for regfunc in dev._dict_events[io_event]:
|
||||||
|
if regfunc[1] == BOTH \
|
||||||
|
or regfunc[1] == RISING and boolor \
|
||||||
|
or regfunc[1] == FALLING and not boolor:
|
||||||
|
if regfunc[3] == 0:
|
||||||
|
self._eventq.put(
|
||||||
|
(regfunc, io_event._name, io_event.value),
|
||||||
|
False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Verzögertes Event in dict einfügen
|
||||||
|
tupfire = (
|
||||||
|
regfunc, io_event._name, io_event.value
|
||||||
|
)
|
||||||
|
if regfunc[4] or tupfire not in self.__dict_delay:
|
||||||
|
self.__dict_delay[tupfire] = ceil(
|
||||||
|
regfunc[3] / 1000 / self._refresh
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for regfunc in dev._dict_events[io_event]:
|
||||||
|
if regfunc[3] == 0:
|
||||||
|
self._eventq.put(
|
||||||
|
(regfunc, io_event._name, io_event.value),
|
||||||
|
False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Verzögertes Event in dict einfügen
|
||||||
|
tupfire = (
|
||||||
|
regfunc, io_event._name, io_event.value
|
||||||
|
)
|
||||||
|
if regfunc[4] or tupfire not in self.__dict_delay:
|
||||||
|
self.__dict_delay[tupfire] = ceil(
|
||||||
|
regfunc[3] / 1000 / self._refresh
|
||||||
|
)
|
||||||
|
|
||||||
|
# Nach Verarbeitung aller IOs die Bytes kopieren (Lock ist noch drauf)
|
||||||
|
dev._ba_datacp = dev._ba_devdata[:]
|
||||||
|
|
||||||
|
def _collect_events(self, value):
|
||||||
|
"""Aktiviert oder Deaktiviert die Eventueberwachung.
|
||||||
|
@param value True aktiviert / False deaktiviert"""
|
||||||
|
if type(value) != bool:
|
||||||
|
raise ValueError("value must be <class 'bool'>")
|
||||||
|
|
||||||
|
if self.__eventwork != value:
|
||||||
|
with self.lck_refresh:
|
||||||
|
self.__eventwork = value
|
||||||
|
self._eventq = queue.Queue()
|
||||||
|
self.__dict_delay = {}
|
||||||
|
|
||||||
def _get_ioerrors(self):
|
def _get_ioerrors(self):
|
||||||
"""Ruft aktuelle Anzahl der Fehler ab.
|
"""Ruft aktuelle Anzahl der Fehler ab.
|
||||||
@return Aktuelle Fehleranzahl"""
|
@return Aktuelle Fehleranzahl"""
|
||||||
@@ -328,6 +404,21 @@ class ProcimgWriter(Thread):
|
|||||||
while not self._work.is_set():
|
while not self._work.is_set():
|
||||||
ot = default_timer()
|
ot = default_timer()
|
||||||
|
|
||||||
|
# Verzögerte Events prüfen
|
||||||
|
# NOTE: Darf dies VOR der Aktualisierung der Daten gemacht werden?
|
||||||
|
if self.__eventwork:
|
||||||
|
for tup_fire in list(self.__dict_delay.keys()):
|
||||||
|
if tup_fire[0][4] \
|
||||||
|
and getattr(self._modio.io, tup_fire[1]).value != \
|
||||||
|
tup_fire[2]:
|
||||||
|
del self.__dict_delay[tup_fire]
|
||||||
|
else:
|
||||||
|
self.__dict_delay[tup_fire] -= 1
|
||||||
|
if self.__dict_delay[tup_fire] <= 1:
|
||||||
|
# Verzögertes Event übernehmen und löschen
|
||||||
|
self._eventq.put(tup_fire, False)
|
||||||
|
del self.__dict_delay[tup_fire]
|
||||||
|
|
||||||
# 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):
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
@@ -352,6 +443,10 @@ class ProcimgWriter(Thread):
|
|||||||
for dev in self._modio._lst_refresh:
|
for dev in self._modio._lst_refresh:
|
||||||
dev._filelock.acquire()
|
dev._filelock.acquire()
|
||||||
dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
|
dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
|
||||||
|
if self.__eventwork \
|
||||||
|
and len(dev._dict_events) > 0 \
|
||||||
|
and dev._ba_datacp != dev._ba_devdata:
|
||||||
|
self.__check_change(dev)
|
||||||
dev._filelock.release()
|
dev._filelock.release()
|
||||||
else:
|
else:
|
||||||
# Inputs in Puffer, Outputs in Prozessabbild
|
# Inputs in Puffer, Outputs in Prozessabbild
|
||||||
@@ -359,6 +454,11 @@ class ProcimgWriter(Thread):
|
|||||||
for dev in self._modio._lst_refresh:
|
for dev in self._modio._lst_refresh:
|
||||||
dev._filelock.acquire()
|
dev._filelock.acquire()
|
||||||
dev._ba_devdata[dev._slc_inp] = bytesbuff[dev._slc_inpoff]
|
dev._ba_devdata[dev._slc_inp] = bytesbuff[dev._slc_inpoff]
|
||||||
|
if self.__eventwork\
|
||||||
|
and len(dev._dict_events) > 0 \
|
||||||
|
and dev._ba_datacp != dev._ba_devdata:
|
||||||
|
self.__check_change(dev)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fh.seek(dev._slc_outoff.start)
|
fh.seek(dev._slc_outoff.start)
|
||||||
fh.write(dev._ba_devdata[dev._slc_out])
|
fh.write(dev._ba_devdata[dev._slc_out])
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
"""RevPiModIO Hauptklasse fuer piControl0 Zugriff."""
|
"""RevPiModIO Hauptklasse fuer piControl0 Zugriff."""
|
||||||
import warnings
|
import warnings
|
||||||
from json import load as jload
|
from json import load as jload
|
||||||
from math import ceil
|
|
||||||
from os import access, F_OK, R_OK
|
from os import access, F_OK, R_OK
|
||||||
|
from queue import Empty
|
||||||
from signal import signal, SIG_DFL, SIGINT, SIGTERM
|
from signal import signal, SIG_DFL, SIGINT, SIGTERM
|
||||||
from threading import Thread, Event
|
from threading import Thread, Event
|
||||||
|
|
||||||
@@ -18,7 +18,6 @@ from . import device as devicemodule
|
|||||||
from . import helper as helpermodule
|
from . import helper as helpermodule
|
||||||
from . import summary as summarymodule
|
from . import summary as summarymodule
|
||||||
from .io import IOList
|
from .io import IOList
|
||||||
from revpimodio2 import RISING, FALLING, BOTH
|
|
||||||
|
|
||||||
|
|
||||||
class RevPiModIO(object):
|
class RevPiModIO(object):
|
||||||
@@ -419,12 +418,15 @@ class RevPiModIO(object):
|
|||||||
if self._imgwriter is not None and self._imgwriter.is_alive():
|
if self._imgwriter is not None and self._imgwriter.is_alive():
|
||||||
self._imgwriter.stop()
|
self._imgwriter.stop()
|
||||||
self._imgwriter.join(self._imgwriter._refresh)
|
self._imgwriter.join(self._imgwriter._refresh)
|
||||||
|
# NOTE: Prüfen, ob es sauber läuft!
|
||||||
|
if self._th_mainloop is not None and self._th_mainloop.is_alive():
|
||||||
|
self._th_mainloop.join(1)
|
||||||
while len(self._lst_refresh) > 0:
|
while len(self._lst_refresh) > 0:
|
||||||
dev = self._lst_refresh.pop()
|
dev = self._lst_refresh.pop()
|
||||||
dev._selfupdate = False
|
dev._selfupdate = False
|
||||||
if not self._monitoring:
|
if not self._monitoring:
|
||||||
self.writeprocimg(dev)
|
self.writeprocimg(dev)
|
||||||
self._looprunning = False
|
# NOTE: Loops müssen sich selber IMMER sauber beenden
|
||||||
|
|
||||||
def get_jconfigrsc(self):
|
def get_jconfigrsc(self):
|
||||||
"""Laed die piCotry Konfiguration und erstellt ein <class 'dict'>.
|
"""Laed die piCotry Konfiguration und erstellt ein <class 'dict'>.
|
||||||
@@ -483,7 +485,7 @@ class RevPiModIO(object):
|
|||||||
signal(SIGINT, self.__evt_exit)
|
signal(SIGINT, self.__evt_exit)
|
||||||
signal(SIGTERM, self.__evt_exit)
|
signal(SIGTERM, self.__evt_exit)
|
||||||
|
|
||||||
def mainloop(self, freeze=False, blocking=True):
|
def mainloop(self, blocking=True):
|
||||||
"""Startet den Mainloop mit Eventueberwachung.
|
"""Startet den Mainloop mit Eventueberwachung.
|
||||||
|
|
||||||
Der aktuelle Programmthread wird hier bis Aufruf von
|
Der aktuelle Programmthread wird hier bis Aufruf von
|
||||||
@@ -492,19 +494,12 @@ class RevPiModIO(object):
|
|||||||
einem Event registrierten, IOs. Wird eine Veraenderung erkannt,
|
einem Event registrierten, IOs. Wird eine Veraenderung erkannt,
|
||||||
fuert das Programm die dazugehoerigen Funktionen der Reihe nach aus.
|
fuert das Programm die dazugehoerigen Funktionen der Reihe nach aus.
|
||||||
|
|
||||||
Wenn der Parameter "freeze" mit True angegeben ist, wird die
|
|
||||||
Prozessabbildsynchronisierung angehalten bis alle Eventfunktionen
|
|
||||||
ausgefuehrt wurden. Inputs behalten fuer die gesamte Dauer ihren
|
|
||||||
aktuellen Wert und Outputs werden erst nach Durchlauf aller Funktionen
|
|
||||||
in das Prozessabbild geschrieben.
|
|
||||||
|
|
||||||
Wenn der Parameter "blocking" mit False angegeben wird, aktiviert
|
Wenn der Parameter "blocking" mit False angegeben wird, aktiviert
|
||||||
dies die Eventueberwachung und blockiert das Programm NICHT an der
|
dies die Eventueberwachung und blockiert das Programm NICHT an der
|
||||||
Stelle des Aufrufs. Eignet sich gut fuer die GUI Programmierung, wenn
|
Stelle des Aufrufs. Eignet sich gut fuer die GUI Programmierung, wenn
|
||||||
Events vom RevPi benoetigt werden, aber das Programm weiter ausgefuehrt
|
Events vom RevPi benoetigt werden, aber das Programm weiter ausgefuehrt
|
||||||
werden soll.
|
werden soll.
|
||||||
|
|
||||||
@param freeze Wenn True, Prozessabbildsynchronisierung anhalten
|
|
||||||
@param blocking Wenn False, blockiert das Programm NICHT
|
@param blocking Wenn False, blockiert das Programm NICHT
|
||||||
@return None
|
@return None
|
||||||
|
|
||||||
@@ -522,8 +517,7 @@ class RevPiModIO(object):
|
|||||||
# Thread erstellen, wenn nicht blockieren soll
|
# Thread erstellen, wenn nicht blockieren soll
|
||||||
if not blocking:
|
if not blocking:
|
||||||
self._th_mainloop = Thread(
|
self._th_mainloop = Thread(
|
||||||
target=self.mainloop,
|
target=self.mainloop, kwargs={"blocking": True}
|
||||||
kwargs={"freeze": freeze, "blocking": True}
|
|
||||||
)
|
)
|
||||||
self._th_mainloop.start()
|
self._th_mainloop.start()
|
||||||
return
|
return
|
||||||
@@ -538,108 +532,13 @@ class RevPiModIO(object):
|
|||||||
dev._ba_datacp = dev._ba_devdata[:]
|
dev._ba_datacp = dev._ba_devdata[:]
|
||||||
dev._filelock.release()
|
dev._filelock.release()
|
||||||
|
|
||||||
lst_fire = []
|
# ImgWriter mit Eventüberwachung aktivieren
|
||||||
dict_delay = {}
|
self._imgwriter._collect_events(True)
|
||||||
|
e = None
|
||||||
|
|
||||||
while not self._exit.is_set():
|
while not self._exit.is_set():
|
||||||
# Auf neue Daten warten und nur ausführen wenn set()
|
|
||||||
if not self._imgwriter.newdata.wait(2.5):
|
|
||||||
if not self._exit.is_set() and not self._imgwriter.is_alive():
|
|
||||||
self.exit(full=False)
|
|
||||||
self._looprunning = False
|
|
||||||
raise RuntimeError("autorefresh thread not running")
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._imgwriter.newdata.clear()
|
|
||||||
|
|
||||||
# Während Auswertung refresh sperren
|
|
||||||
self._imgwriter.lck_refresh.acquire()
|
|
||||||
|
|
||||||
for dev in self._lst_refresh:
|
|
||||||
|
|
||||||
if len(dev._dict_events) == 0 \
|
|
||||||
or dev._ba_datacp == dev._ba_devdata:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for io_event in dev._dict_events:
|
|
||||||
|
|
||||||
if dev._ba_datacp[io_event._slc_address] == \
|
|
||||||
dev._ba_devdata[io_event._slc_address]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if io_event._bitaddress >= 0:
|
|
||||||
boolcp = bool(int.from_bytes(
|
|
||||||
dev._ba_datacp[io_event._slc_address],
|
|
||||||
byteorder=io_event._byteorder
|
|
||||||
) & 1 << io_event._bitaddress)
|
|
||||||
boolor = bool(int.from_bytes(
|
|
||||||
dev._ba_devdata[io_event._slc_address],
|
|
||||||
byteorder=io_event._byteorder
|
|
||||||
) & 1 << io_event._bitaddress)
|
|
||||||
|
|
||||||
if boolor == boolcp:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for regfunc in dev._dict_events[io_event]:
|
|
||||||
if regfunc[1] == BOTH \
|
|
||||||
or regfunc[1] == RISING and boolor \
|
|
||||||
or regfunc[1] == FALLING and not boolor:
|
|
||||||
if regfunc[3] == 0:
|
|
||||||
lst_fire.append((
|
|
||||||
regfunc, io_event._name, io_event.value
|
|
||||||
))
|
|
||||||
else:
|
|
||||||
# Verzögertes Event in dict einfügen
|
|
||||||
tupfire = (
|
|
||||||
regfunc, io_event._name, io_event.value
|
|
||||||
)
|
|
||||||
if regfunc[4] or tupfire not in dict_delay:
|
|
||||||
dict_delay[tupfire] = ceil(
|
|
||||||
regfunc[3] /
|
|
||||||
self._imgwriter.refresh
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
for regfunc in dev._dict_events[io_event]:
|
|
||||||
if regfunc[3] == 0:
|
|
||||||
lst_fire.append(
|
|
||||||
(regfunc, io_event._name, io_event.value)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Verzögertes Event in dict einfügen
|
|
||||||
if regfunc[4] or regfunc not in dict_delay:
|
|
||||||
dict_delay[(
|
|
||||||
regfunc, io_event._name, io_event.value
|
|
||||||
)] = ceil(
|
|
||||||
regfunc[3] / self._imgwriter.refresh
|
|
||||||
)
|
|
||||||
|
|
||||||
# Nach Verarbeitung aller IOs die Bytes kopieren
|
|
||||||
dev._filelock.acquire()
|
|
||||||
dev._ba_datacp = dev._ba_devdata[:]
|
|
||||||
dev._filelock.release()
|
|
||||||
|
|
||||||
# Refreshsperre aufheben wenn nicht freeze
|
|
||||||
if not freeze:
|
|
||||||
self._imgwriter.lck_refresh.release()
|
|
||||||
|
|
||||||
# EventTuple:
|
|
||||||
# ((func, edge, as_thread, delay, löschen), ioname, iovalue)
|
|
||||||
|
|
||||||
# Verzögerte Events prüfen
|
|
||||||
for tup_fire in list(dict_delay.keys()):
|
|
||||||
if tup_fire[0][4] \
|
|
||||||
and getattr(self.io, tup_fire[1]).value != tup_fire[2]:
|
|
||||||
del dict_delay[tup_fire]
|
|
||||||
else:
|
|
||||||
dict_delay[tup_fire] -= 1
|
|
||||||
if dict_delay[tup_fire] <= 0:
|
|
||||||
# Verzögertes Event übernehmen und löschen
|
|
||||||
lst_fire.append(tup_fire)
|
|
||||||
del dict_delay[tup_fire]
|
|
||||||
|
|
||||||
# Erst nach Datenübernahme alle Events feuern
|
|
||||||
try:
|
try:
|
||||||
while len(lst_fire) > 0:
|
tup_fire = self._imgwriter._eventq.get(timeout=1)
|
||||||
tup_fire = lst_fire.pop()
|
|
||||||
if tup_fire[0][2]:
|
if tup_fire[0][2]:
|
||||||
th = helpermodule.EventCallback(
|
th = helpermodule.EventCallback(
|
||||||
tup_fire[0][0], tup_fire[1], tup_fire[2]
|
tup_fire[0][0], tup_fire[1], tup_fire[2]
|
||||||
@@ -648,19 +547,22 @@ class RevPiModIO(object):
|
|||||||
else:
|
else:
|
||||||
# Direct callen da Prüfung in io.IOBase.reg_event ist
|
# Direct callen da Prüfung in io.IOBase.reg_event ist
|
||||||
tup_fire[0][0](tup_fire[1], tup_fire[2])
|
tup_fire[0][0](tup_fire[1], tup_fire[2])
|
||||||
except Exception as e:
|
except Empty:
|
||||||
if self._imgwriter.lck_refresh.locked():
|
if not self._exit.is_set() and not self._imgwriter.is_alive():
|
||||||
self._imgwriter.lck_refresh.release()
|
|
||||||
self.exit(full=False)
|
self.exit(full=False)
|
||||||
self._looprunning = False
|
e = RuntimeError("autorefresh thread not running")
|
||||||
raise e
|
except Exception as ex:
|
||||||
|
self.exit(full=False)
|
||||||
# Refreshsperre aufheben wenn freeze
|
e = ex
|
||||||
if freeze:
|
|
||||||
self._imgwriter.lck_refresh.release()
|
|
||||||
|
|
||||||
# Mainloop verlassen
|
# Mainloop verlassen
|
||||||
|
self._imgwriter._collect_events(False)
|
||||||
self._looprunning = False
|
self._looprunning = False
|
||||||
|
self._th_mainloop = None
|
||||||
|
|
||||||
|
# Fehler prüfen
|
||||||
|
if e is not None:
|
||||||
|
raise e
|
||||||
|
|
||||||
def readprocimg(self, device=None):
|
def readprocimg(self, device=None):
|
||||||
"""Einlesen aller Inputs aller/eines Devices vom Prozessabbild.
|
"""Einlesen aller Inputs aller/eines Devices vom Prozessabbild.
|
||||||
|
|||||||
Reference in New Issue
Block a user