delay Parameter für reg_event eingebaut

reg_event schneller und Prüfung auf doppelte Events verbessert
cycletime kann nicht mehr verändert werden, wenn ein Loop läuft
io.IntIO.get_int und .set_int in get_intvalue und set_intvalue geändert
docstring
This commit is contained in:
2017-08-29 18:22:14 +02:00
parent dcc8c22428
commit 5c7a540d29
11 changed files with 220 additions and 124 deletions

View File

@@ -23,6 +23,9 @@ fuehrt das Modul bei Datenaenderung aus.
Modules</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="revpimodio2.__init__.html">revpimodio2</a></td>
<td>Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.app.html">app</a></td>
<td>Bildet die App Sektion von piCtory ab.</td>
</tr><tr>

View File

@@ -25,46 +25,35 @@ Global Attributes</h3>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#IOType">IOType</a></td>
<td>IO Typen.</td>
</tr>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
<tr>
<td><a style="color:#0000FF" href="#consttostr">consttostr</a></td>
<td>Gibt <class 'str'> fuer Konstanten zurueck.</td>
</tr>
</table>
<hr /><hr />
<a NAME="IOType" ID="IOType"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">IOType</h2>
<a NAME="consttostr" ID="consttostr"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">consttostr</h2>
<b>consttostr</b>(<i>value</i>)
<p>
IO Typen.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
object
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>INP</td></tr><tr><td>MEM</td></tr><tr><td>OUT</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
Gibt <class 'str'> fuer Konstanten zurueck.
</p><p>
Diese Funktion ist erforderlich, da enum in Python 3.2 nicht existiert.
</p><dl>
<dt><i>value</i></dt>
<dd>
Konstantenwert
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
<class 'str'> Name der Konstanten
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -411,7 +411,7 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Device.get_inputs">get_inputs</a></td>
<td>Gibt eine Liste aller Inputs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.get_memmories">get_memmories</a></td>
<td><a style="color:#0000FF" href="#Device.get_memories">get_memories</a></td>
<td>Gibt eine Liste aller mems zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.get_outputs">get_outputs</a></td>
@@ -603,10 +603,10 @@ Gibt eine Liste aller Inputs zurueck.
<dd>
<class 'list'> Inputs
</dd>
</dl><a NAME="Device.get_memmories" ID="Device.get_memmories"></a>
</dl><a NAME="Device.get_memories" ID="Device.get_memories"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.get_memmories</h3>
<b>get_memmories</b>(<i></i>)
Device.get_memories</h3>
<b>get_memories</b>(<i></i>)
<p>
Gibt eine Liste aller mems zurueck.
</p><dl>

View File

@@ -163,7 +163,7 @@ Methods</h3>
<td>Gibt den Wert des IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.reg_event">reg_event</a></td>
<td>Registriert ein Event bei der Eventueberwachung.</td>
<td>Registriert fuer IO ein Event bei der Eventueberwachung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.replace_io">replace_io</a></td>
<td>Ersetzt bestehenden IO mit Neuem.</td>
@@ -297,13 +297,20 @@ 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, edge=BOTH, as_thread=False</i>)
<b>reg_event</b>(<i>func, delay=0, edge=BOTH, as_thread=False</i>)
<p>
Registriert ein Event bei der Eventueberwachung.
Registriert fuer IO ein Event bei der Eventueberwachung.
</p><p>
Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert
aendert. Mit Angabe von optionalen Parametern kann das
Ausloeseverhalten gesteuert werden.
</p><dl>
<dt><i>func</i></dt>
<dd>
Funktion die bei Aenderung aufgerufen werden soll
</dd><dt><i>delay</i></dt>
<dd>
Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
</dd><dt><i>edge</i></dt>
<dd>
Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
@@ -317,23 +324,27 @@ IOBase.replace_io</h3>
<b>replace_io</b>(<i>name, frm, **kwargs</i>)
<p>
Ersetzt bestehenden IO mit Neuem.
</p><p>
Wenn die kwargs fuer byteorder und defaultvalue nicht angegeben werden,
uebernimmt das System die Daten aus dem ersetzten IO.
</p><dl>
<dt><i>name</i></dt>
<dd>
Name des neuen Inputs
</dd><dt><i>frm</i></dt>
<dd>
struct formatierung (1 Zeichen)
struct Formatierung (1 Zeichen)
</dd><dt><i>kwargs</i></dt>
<dd>
Weitere Parameter:
- bmk: Bezeichnung fuer Input
- bmk: interne Bezeichnung fuer IO
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
- byteorder: Byteorder fuer den Input, Standardwert=little
- defaultvalue: Standardwert fuer Input, Standard ist 0
- byteorder: Byteorder fuer den IO, Standardwert=little
- defaultvalue: Standardwert fuer IO
- event: Funktion fuer Eventhandling registrieren
- 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
- edge: event-Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
</dd>
</dl><dl>
<dt><b>See Also:</b></dt>
@@ -380,7 +391,7 @@ Wartet auf Wertaenderung eines IOs.
HINWEIS: Wenn <class 'ProcimgWriter'> keine neuen Daten liefert, wird
bis in die Ewigkeit gewartet (nicht bei Angabe von "timeout").
</p><p>
Wenn edge mit RISING oder FALLING angegeben wird muss diese Flanke
Wenn edge mit RISING oder FALLING angegeben wird, muss diese Flanke
ausgeloest werden. Sollte der Wert 1 sein beim Eintritt mit Flanke
RISING, wird das Warten erst bei Aenderung von 0 auf 1 beendet.
</p><p>
@@ -393,21 +404,21 @@ Wartet auf Wertaenderung eines IOs.
</p><p>
Der Timeoutwert bricht beim Erreichen das Warten sofort mit
Wert 2 Rueckgabewert ab. (Das Timeout wird ueber die Zykluszeit
der autorefresh Funktion berechnet, entspricht also nicht exact den
der autorefresh Funktion berechnet, entspricht also nicht exakt den
angegeben Millisekunden! Es wird immer nach oben gerundet!)
</p><dl>
<dt><i>edge</i></dt>
<dd>
Flanke RISING, FALLING, BOTH bei der mit True beendet wird
Flanke RISING, FALLING, BOTH die eintreten muss
</dd><dt><i>exitevent</i></dt>
<dd>
<class 'thrading.Event'> fuer vorzeitiges Beenden
</dd><dt><i>okvalue</i></dt>
<dd>
IO-Wert, bei dem das Warten sofort mit True beendet wird
IO-Wert, bei dem das Warten sofort beendet wird
</dd><dt><i>timeout</i></dt>
<dd>
Zeit in ms nach der mit False abgebrochen wird
Zeit in ms nach der abgebrochen wird
</dd>
</dl><dl>
<dt>Returns:</dt>
@@ -650,13 +661,13 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IntIO._set_signed">_set_signed</a></td>
<td>Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IntIO.get_int">get_int</a></td>
<td>Gibt IO-Wert zurueck mit Beachtung byteorder/signed.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IntIO.get_intdefaultvalue">get_intdefaultvalue</a></td>
<td>Gibt die Defaultvalue als <class 'int'> zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IntIO.set_int">set_int</a></td>
<td><a style="color:#0000FF" href="#IntIO.get_intvalue">get_intvalue</a></td>
<td>Gibt IO-Wert zurueck mit Beachtung byteorder/signed.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IntIO.set_intvalue">set_intvalue</a></td>
<td>Setzt IO mit Beachtung byteorder/signed.</td>
</tr>
</table>
@@ -709,17 +720,6 @@ Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.
<dd>
True, wenn mit Vorzeichen behandel
</dd>
</dl><a NAME="IntIO.get_int" ID="IntIO.get_int"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IntIO.get_int</h3>
<b>get_int</b>(<i></i>)
<p>
Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
</p><dl>
<dt>Returns:</dt>
<dd>
IO-Wert als <class 'int'>
</dd>
</dl><a NAME="IntIO.get_intdefaultvalue" ID="IntIO.get_intdefaultvalue"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IntIO.get_intdefaultvalue</h3>
@@ -731,10 +731,21 @@ Gibt die Defaultvalue als <class 'int'> zurueck.
<dd>
<class 'int'> Defaultvalue
</dd>
</dl><a NAME="IntIO.set_int" ID="IntIO.set_int"></a>
</dl><a NAME="IntIO.get_intvalue" ID="IntIO.get_intvalue"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IntIO.set_int</h3>
<b>set_int</b>(<i>value</i>)
IntIO.get_intvalue</h3>
<b>get_intvalue</b>(<i></i>)
<p>
Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
</p><dl>
<dt>Returns:</dt>
<dd>
IO-Wert als <class 'int'>
</dd>
</dl><a NAME="IntIO.set_intvalue" ID="IntIO.set_intvalue"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IntIO.set_intvalue</h3>
<b>set_intvalue</b>(<i>value</i>)
<p>
Setzt IO mit Beachtung byteorder/signed.
</p><dl>

View File

@@ -350,7 +350,7 @@ RevPiModIO.cycleloop</h3>
Startet den Cycleloop.
</p><p>
Der aktuelle Programmthread wird hier bis Aufruf von
RevPiDevicelist.exit() "gefangen". Er fuehrt nach jeder Aktualisierung
.exit() "gefangen". Er fuehrt nach jeder Aktualisierung
des Prozessabbilds die uebergebene Funktion "func" aus und arbeitet sie
ab. Waehrend der Ausfuehrung der Funktion wird das Prozessabbild nicht
weiter aktualisiert. Die Inputs behalten bis zum Ende den aktuellen

View File

@@ -5,6 +5,7 @@ revpimodio2.OFF?7
revpimodio2.RED?7
revpimodio2.RISING?7
revpimodio2.app.App?1(app)
revpimodio2.consttostr?4(value)
revpimodio2.device.Core.A1?7
revpimodio2.device.Core.A2?7
revpimodio2.device.Core._devconfigure?5()
@@ -33,7 +34,7 @@ revpimodio2.device.Device._get_producttype?5()
revpimodio2.device.Device.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4()
revpimodio2.device.Device.get_inputs?4()
revpimodio2.device.Device.get_memmories?4()
revpimodio2.device.Device.get_memories?4()
revpimodio2.device.Device.get_outputs?4()
revpimodio2.device.Device.length?7
revpimodio2.device.Device.name?7
@@ -84,7 +85,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, edge=BOTH, as_thread=False)
revpimodio2.io.IOBase.reg_event?4(func, delay=0, edge=BOTH, as_thread=False)
revpimodio2.io.IOBase.replace_io?4(name, frm, **kwargs)
revpimodio2.io.IOBase.set_value?4(value)
revpimodio2.io.IOBase.type?7
@@ -99,9 +100,9 @@ revpimodio2.io.IntIO._set_byteorder?5(value)
revpimodio2.io.IntIO._set_signed?5(value)
revpimodio2.io.IntIO.byteorder?7
revpimodio2.io.IntIO.defaultvalue?7
revpimodio2.io.IntIO.get_int?4()
revpimodio2.io.IntIO.get_intdefaultvalue?4()
revpimodio2.io.IntIO.set_int?4(value)
revpimodio2.io.IntIO.get_intvalue?4()
revpimodio2.io.IntIO.set_intvalue?4(value)
revpimodio2.io.IntIO.signed?7
revpimodio2.io.IntIO.value?7
revpimodio2.io.StructIO._get_frm?5()

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpimodio2 -->
<!-- Saved: 2017-08-26, 09:26:35 -->
<!-- Saved: 2017-08-29, 18:21:17 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
@@ -26,7 +26,6 @@
<Source>test/test_dio_mainloop.py</Source>
<Source>test/test_dio_cycleloop.py</Source>
<Source>test/test_net_leistung.py</Source>
<Source>revpimodio2/net.py</Source>
<Source>test/web_cycleloop.py</Source>
<Source>test/web_mainloop.py</Source>
</Sources>
@@ -338,4 +337,23 @@
</dict>
</CheckersParams>
</Checkers>
<OtherTools>
<OtherToolsParams>
<dict>
<key>
<string>CodeMetrics</string>
</key>
<value>
<dict>
<key>
<string>ExcludeFiles</string>
</key>
<value>
<string>*/test/*</string>
</value>
</dict>
</value>
</dict>
</OtherToolsParams>
</OtherTools>
</Project>

View File

@@ -35,3 +35,28 @@ FALLING = 32
BOTH = 33
warnings.simplefilter(action="always")
def consttostr(value):
"""Gibt <class 'str'> fuer Konstanten zurueck.
Diese Funktion ist erforderlich, da enum in Python 3.2 nicht existiert.
@param value Konstantenwert
@return <class 'str'> Name der Konstanten
"""
if value == 0:
return "OFF"
elif value == 1:
return "GREEN"
elif value == 2:
return "RED"
elif value == 31:
return "RISING"
elif value == 32:
return "FALLING"
elif value == 33:
return "BOTH"
else:
return ""

View File

@@ -317,7 +317,7 @@ class Device(object):
lst_return += lst_io
return lst_return
def get_memmories(self):
def get_memories(self):
"""Gibt eine Liste aller mems zurueck.
@return <class 'list'> Mems"""
lst_return = []

View File

@@ -8,7 +8,7 @@
"""RevPiModIO Modul fuer die Verwaltung der IOs."""
import struct
from threading import Event
from .__init__ import RISING, FALLING, BOTH
from .__init__ import RISING, FALLING, BOTH, consttostr
class Type(object):
@@ -356,32 +356,44 @@ class IOBase(object):
else:
return bytes(self._parentdevice._ba_devdata[self._slc_address])
def reg_event(self, func, edge=BOTH, as_thread=False):
"""Registriert ein Event bei der Eventueberwachung.
def reg_event(self, func, delay=0, edge=BOTH, as_thread=False):
"""Registriert fuer IO ein Event bei der Eventueberwachung.
Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert
aendert. Mit Angabe von optionalen Parametern kann das
Ausloeseverhalten gesteuert werden.
@param func Funktion die bei Aenderung aufgerufen werden soll
@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
"""
# Prüfen ob Funktion callable ist
if not callable(func):
raise RuntimeError(
"registered function '{}' ist not callable".format(func)
raise AttributeError(
"registered function '{}' is not callable".format(func)
)
if type(delay) != int or delay < 0:
raise AttributeError(
"parameter 'delay' must be greater or equal 0"
)
if edge != BOTH and self._bitaddress < 0:
raise AttributeError(
"parameter 'edge' can be used with bit io objects only"
)
if self not in self._parentdevice._dict_events:
self._parentdevice._dict_events[self] = [(func, edge, as_thread)]
self._parentdevice._dict_events[self] = \
[(func, edge, as_thread, delay)]
else:
# Prüfen ob Funktion schon registriert ist
for regfunc in self._parentdevice._dict_events[self]:
if regfunc[0] != func:
# Nächsten Eintrag testen
continue
if regfunc[0] == func and edge == BOTH:
if edge == BOTH or regfunc[1] == BOTH:
if self._bitaddress < 0:
raise AttributeError(
"io '{}' with function '{}' already in list."
@@ -389,35 +401,42 @@ class IOBase(object):
)
else:
raise AttributeError(
"io '{}' with function '{}' already in list. "
"edge 'BOTH' not allowed anymore".format(
self._name, func
"io '{}' with function '{}' already in list with "
"edge '{}' - edge '{}' not allowed anymore".format(
self._name, func,
consttostr(regfunc[1]), consttostr(edge)
)
)
elif regfunc[0] == func and regfunc[1] == edge:
elif regfunc[1] == edge:
raise AttributeError(
"io '{}' with function '{}' for given edge "
"already in list".format(self._name, func)
"io '{}' with function '{}' for given edge '{}' "
"already in list".format(
self._name, func, consttostr(edge)
)
)
else:
self._parentdevice._dict_events[self].append(
(func, edge, as_thread)
)
break
# Eventfunktion einfügen
self._parentdevice._dict_events[self].append(
(func, edge, as_thread, delay)
)
def replace_io(self, name, frm, **kwargs):
"""Ersetzt bestehenden IO mit Neuem.
Wenn die kwargs fuer byteorder und defaultvalue nicht angegeben werden,
uebernimmt das System die Daten aus dem ersetzten IO.
@param name Name des neuen Inputs
@param frm struct formatierung (1 Zeichen)
@param frm struct Formatierung (1 Zeichen)
@param kwargs Weitere Parameter:
- bmk: Bezeichnung fuer Input
- bmk: interne Bezeichnung fuer IO
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
- byteorder: Byteorder fuer den Input, Standardwert=little
- defaultvalue: Standardwert fuer Input, Standard ist 0
- byteorder: Byteorder fuer den IO, Standardwert=little
- defaultvalue: Standardwert fuer IO
- event: Funktion fuer Eventhandling registrieren
- 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
- edge: event-Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
@see <a target="_blank"
href="https://docs.python.org/3/library/struct.html#format-characters"
>Python3 struct</a>
@@ -449,8 +468,9 @@ class IOBase(object):
if reg_event is not None:
io_new.reg_event(
reg_event,
as_thread=kwargs.get("as_thread", False),
edge=kwargs.get("edge", BOTH)
kwargs.get("delay", 0),
kwargs.get("edge", BOTH),
kwargs.get("as_thread", False)
)
def set_value(self, value):
@@ -548,7 +568,7 @@ class IOBase(object):
HINWEIS: Wenn <class 'ProcimgWriter'> keine neuen Daten liefert, wird
bis in die Ewigkeit gewartet (nicht bei Angabe von "timeout").
Wenn edge mit RISING oder FALLING angegeben wird muss diese Flanke
Wenn edge mit RISING oder FALLING angegeben wird, muss diese Flanke
ausgeloest werden. Sollte der Wert 1 sein beim Eintritt mit Flanke
RISING, wird das Warten erst bei Aenderung von 0 auf 1 beendet.
@@ -561,13 +581,13 @@ class IOBase(object):
Der Timeoutwert bricht beim Erreichen das Warten sofort mit
Wert 2 Rueckgabewert ab. (Das Timeout wird ueber die Zykluszeit
der autorefresh Funktion berechnet, entspricht also nicht exact den
der autorefresh Funktion berechnet, entspricht also nicht exakt den
angegeben Millisekunden! Es wird immer nach oben gerundet!)
@param edge Flanke RISING, FALLING, BOTH bei der mit True beendet wird
@param edge Flanke RISING, FALLING, BOTH die eintreten muss
@param exitevent <class 'thrading.Event'> fuer vorzeitiges Beenden
@param okvalue IO-Wert, bei dem das Warten sofort mit True beendet wird
@param timeout Zeit in ms nach der mit False abgebrochen wird
@param okvalue IO-Wert, bei dem das Warten sofort beendet wird
@param timeout Zeit in ms nach der abgebrochen wird
@return <class 'int'> erfolgreich Werte <= 0
- Erfolgreich gewartet
Wert 0: IO hat den Wert gewechselt
@@ -695,7 +715,7 @@ class IntIO(IOBase):
self._defaultvalue, byteorder=self._byteorder, signed=self._signed
)
def get_int(self):
def get_intvalue(self):
"""Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
@return IO-Wert als <class 'int'>"""
return int.from_bytes(
@@ -704,7 +724,7 @@ class IntIO(IOBase):
signed=self._signed
)
def set_int(self, value):
def set_intvalue(self, value):
"""Setzt IO mit Beachtung byteorder/signed.
@param value <class 'int'> Wert"""
if type(value) == int:
@@ -722,7 +742,7 @@ class IntIO(IOBase):
byteorder = property(IOBase._get_byteorder, _set_byteorder)
defaultvalue = property(get_intdefaultvalue)
signed = property(_get_signed, _set_signed)
value = property(get_int, set_int)
value = property(get_intvalue, set_intvalue)
class StructIO(IOBase):

View File

@@ -281,7 +281,13 @@ class RevPiModIO(object):
def _set_cycletime(self, milliseconds):
"""Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.
@param milliseconds <class 'int'> in Millisekunden"""
self._imgwriter.refresh = milliseconds
if self._looprunning:
raise RuntimeError(
"can not change cycletime when cycleloop or mainloop are "
"running"
)
else:
self._imgwriter.refresh = milliseconds
def _set_maxioerrors(self, value):
"""Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.
@@ -311,7 +317,7 @@ class RevPiModIO(object):
"""Startet den Cycleloop.
Der aktuelle Programmthread wird hier bis Aufruf von
RevPiDevicelist.exit() "gefangen". Er fuehrt nach jeder Aktualisierung
.exit() "gefangen". Er fuehrt nach jeder Aktualisierung
des Prozessabbilds die uebergebene Funktion "func" aus und arbeitet sie
ab. Waehrend der Ausfuehrung der Funktion wird das Prozessabbild nicht
weiter aktualisiert. Die Inputs behalten bis zum Ende den aktuellen
@@ -518,6 +524,7 @@ class RevPiModIO(object):
dev._filelock.release()
lst_fire = []
dict_delay = {}
while not self._exit.is_set():
# Auf neue Daten warten und nur ausführen wenn set()
@@ -560,15 +567,28 @@ class RevPiModIO(object):
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
dict_delay[(
regfunc, io_event._name, io_event.value
)] = int(
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:
for regfunc in dev._dict_events[io_event]:
lst_fire.append(
(regfunc, io_event._name, io_event.value)
)
else:
# Verzögertes Event in dict einfügen
dict_delay[(
regfunc, io_event._name, io_event.value
)] = int(regfunc[3] / self._imgwriter.refresh)
# Nach Verarbeitung aller IOs die Bytes kopieren
dev._filelock.acquire()
@@ -579,20 +599,29 @@ class RevPiModIO(object):
if not freeze:
self._imgwriter.lck_refresh.release()
# Verzögerte Events prüfen
for tup_fire in list(dict_delay.keys()):
if 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
while len(lst_fire) > 0:
# EventTuple ((func, edge, as_thread, delay), ioname, iovalue)
tup_fire = lst_fire.pop()
event_func = tup_fire[0][0]
passname = tup_fire[1]
passvalue = tup_fire[2]
if tup_fire[0][2]:
th = helpermodule.EventCallback(
event_func, passname, passvalue
tup_fire[0][0], tup_fire[1], tup_fire[2]
)
th.start()
else:
# Direct callen da Prüfung in RevPiDevice.reg_event ist
event_func(passname, passvalue)
# Direct callen da Prüfung in io.IOBase.reg_event ist
tup_fire[0][0](tup_fire[1], tup_fire[2])
# Refreshsperre aufheben wenn freeze
if freeze: