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><a style="color:#0000FF" href="#Device.__getioiter">__getioiter</a></td>
<td>Gibt <class 'iter'> mit allen IOs zurueck.</td> <td>Gibt <class 'iter'> mit allen IOs zurueck.</td>
</tr><tr> </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><a style="color:#0000FF" href="#Device.__int__">__int__</a></td>
<td>Gibt die Positon im RevPi Bus zurueck.</td> <td>Gibt die Positon im RevPi Bus zurueck.</td>
</tr><tr> </tr><tr>
@@ -580,6 +583,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Device._get_producttype">_get_producttype</a></td> <td><a style="color:#0000FF" href="#Device._get_producttype">_get_producttype</a></td>
<td>Gibt den Produkttypen des device zurueck.</td> <td>Gibt den Produkttypen des device zurueck.</td>
</tr><tr> </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><a style="color:#0000FF" href="#Device.autorefresh">autorefresh</a></td>
<td>Registriert dieses Device fuer die automatische Synchronisierung.</td> <td>Registriert dieses Device fuer die automatische Synchronisierung.</td>
</tr><tr> </tr><tr>
@@ -676,6 +682,22 @@ Filter fuer 'Export' Flag in piCtory
<dd> <dd>
IOs als Iterator IOs als Iterator
</dd> </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> </dl><a NAME="Device.__int__" ID="Device.__int__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.__int__</h3> Device.__int__</h3>
@@ -767,7 +789,13 @@ Gibt den Produkttypen des device zurueck.
<dd> <dd>
Deviceprodukttyp Deviceprodukttyp
</dd> </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"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.autorefresh</h3> Device.autorefresh</h3>
<b>autorefresh</b>(<i>activate=True</i>) <b>autorefresh</b>(<i>activate=True</i>)
@@ -1049,7 +1077,7 @@ DeviceList.__iter__</h3>
Gibt Iterator aller Devices zurueck. Gibt Iterator aller Devices zurueck.
</p><p> </p><p>
Die Reihenfolge ist nach Position im Prozessabbild sortiert und nicht 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> </p><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
<dd> <dd>

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

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

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

View File

@@ -413,6 +413,8 @@ 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
if not value:
# Nur leeren beim deaktivieren
self.__eventqth = queue.Queue() self.__eventqth = queue.Queue()
self._eventq = queue.Queue() self._eventq = queue.Queue()
self.__dict_delay = {} self.__dict_delay = {}

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