Mit default zusammenführen

This commit is contained in:
2019-07-31 21:13:07 +02:00
7 changed files with 105 additions and 24 deletions

View File

@@ -556,6 +556,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Device.__getioiter">__getioiter</a></td>
<td>Gibt <class 'iter'> mit allen IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.__getitem__">__getitem__</a></td>
<td>Gibt IO an angegebener Stelle zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.__int__">__int__</a></td>
<td>Gibt die Positon im RevPi Bus zurueck.</td>
</tr><tr>
@@ -580,6 +583,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Device._get_producttype">_get_producttype</a></td>
<td>Gibt den Produkttypen des device zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device._update_my_io_list">_update_my_io_list</a></td>
<td>Erzeugt eine neue IO Liste fuer schnellen Zugriff.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.autorefresh">autorefresh</a></td>
<td>Registriert dieses Device fuer die automatische Synchronisierung.</td>
</tr><tr>
@@ -676,6 +682,22 @@ Filter fuer 'Export' Flag in piCtory
<dd>
IOs als Iterator
</dd>
</dl><a NAME="Device.__getitem__" ID="Device.__getitem__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.__getitem__</h3>
<b>__getitem__</b>(<i>key</i>)
<p>
Gibt IO an angegebener Stelle zurueck.
</p><dl>
<dt><i>key</i></dt>
<dd>
Index des IOs auf dem device als <class 'int'>
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Gefundenes IO-Objekt
</dd>
</dl><a NAME="Device.__int__" ID="Device.__int__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.__int__</h3>
@@ -767,7 +789,13 @@ Gibt den Produkttypen des device zurueck.
<dd>
Deviceprodukttyp
</dd>
</dl><a NAME="Device.autorefresh" ID="Device.autorefresh"></a>
</dl><a NAME="Device._update_my_io_list" ID="Device._update_my_io_list"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device._update_my_io_list</h3>
<b>_update_my_io_list</b>(<i></i>)
<p>
Erzeugt eine neue IO Liste fuer schnellen Zugriff.
</p><a NAME="Device.autorefresh" ID="Device.autorefresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.autorefresh</h3>
<b>autorefresh</b>(<i>activate=True</i>)
@@ -1049,7 +1077,7 @@ DeviceList.__iter__</h3>
Gibt Iterator aller Devices zurueck.
</p><p>
Die Reihenfolge ist nach Position im Prozessabbild sortiert und nicht
nach Position (Dies entspricht der Positionierung aus piCtory)!
nach Positionsnummer (Dies entspricht der Positionierung aus piCtory)!
</p><dl>
<dt>Returns:</dt>
<dd>

View File

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

View File

@@ -43,6 +43,7 @@ revpimodio2.device.Device._buildio?5(dict_io, iotype)
revpimodio2.device.Device._devconfigure?5()
revpimodio2.device.Device._get_offset?5()
revpimodio2.device.Device._get_producttype?5()
revpimodio2.device.Device._update_my_io_list?5()
revpimodio2.device.Device.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4(export=None)
revpimodio2.device.Device.get_inputs?4(export=None)
@@ -106,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
@@ -114,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()

View File

@@ -72,7 +72,7 @@ class DeviceList(object):
"""Gibt Iterator aller Devices zurueck.
Die Reihenfolge ist nach Position im Prozessabbild sortiert und nicht
nach Position (Dies entspricht der Positionierung aus piCtory)!
nach Positionsnummer (Dies entspricht der Positionierung aus piCtory)!
@return <class 'iter'> aller Devices"""
for dev in sorted(
@@ -106,7 +106,7 @@ class Device(object):
"""
__slots__ = "_ba_devdata", "_ba_datacp", \
__slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \
"_dict_events", "_filelock", "_length", "_modio", "_name", "_offset", \
"_position", "_producttype", "_selfupdate", "_slc_devoff", \
"_slc_inp", "_slc_inpoff", "_slc_mem", "_slc_memoff", \
@@ -126,6 +126,7 @@ class Device(object):
self._dict_events = {}
self._filelock = Lock()
self._length = 0
self.__my_io_list = []
self._selfupdate = False
# Wertzuweisung aus dict_device
@@ -182,6 +183,9 @@ class Device(object):
# Spezielle Konfiguration von abgeleiteten Klassen durchführen
self._devconfigure()
# IO Liste aktualisieren für schnellen Indexzugriff
self._update_my_io_list()
def __bytes__(self):
"""Gibt alle Daten des Devices als <class 'bytes'> zurueck.
@return Devicedaten als <class 'bytes'>"""
@@ -205,6 +209,12 @@ class Device(object):
return key in self._modio.io \
and getattr(self._modio.io, key)._parentdevice == self
def __getitem__(self, key):
"""Gibt IO an angegebener Stelle zurueck.
@param key Index des IOs auf dem device als <class 'int'>
@return Gefundenes IO-Objekt"""
return self.__my_io_list[key]
def __int__(self):
"""Gibt die Positon im RevPi Bus zurueck.
@return Positionsnummer"""
@@ -312,6 +322,10 @@ class Device(object):
@return Deviceprodukttyp"""
return self._producttype
def _update_my_io_list(self):
"""Erzeugt eine neue IO Liste fuer schnellen Zugriff."""
self.__my_io_list = list(self.__iter__())
def autorefresh(self, activate=True):
"""Registriert dieses Device fuer die automatische Synchronisierung.
@param activate Default True fuegt Device zur Synchronisierung hinzu"""

View File

@@ -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():

View File

@@ -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):
@@ -68,6 +69,7 @@ class IOList(object):
self.__dict_iobyte[io_del.address] = []
object.__delattr__(self, key)
io_del._parentdevice._update_my_io_list()
def __getattr__(self, key):
"""Verwaltet geloeschte IOs (Attribute, die nicht existieren).
@@ -125,10 +127,10 @@ class IOList(object):
def __setattr__(self, key, value):
"""Verbietet aus Leistungsguenden das direkte Setzen von Attributen."""
if key in [
if key in (
"_IOList__dict_iobyte",
"_IOList__dict_iorefname"
]:
):
object.__setattr__(self, key, value)
else:
raise AttributeError(
@@ -221,6 +223,9 @@ class IOList(object):
None, None, None, None, None, None, None, None
]
self.__dict_iobyte[new_io.address][new_io._bitaddress] = new_io
if type(new_io) is StructIO:
new_io._parentdevice._update_my_io_list()
else:
raise TypeError("io must be <class 'IOBase'> or sub class")
@@ -368,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
@@ -376,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
@@ -391,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]:
@@ -429,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):
@@ -464,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
@@ -478,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.
@@ -501,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.

View File

@@ -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
@@ -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