Kleinste refresh-Zeit auf 5 ms gesetzt

Zykluszeit vom .cycleloop wird bei Aufruf auf 50 ms gesetzt
Standardrefreshzeit wird nach CPU-Anzahl bestimmt
Laufzeitüberwachung für Eventsystem eingebaut
IOBase.export gibt Wert von 'Export' in piCtory zurück
Device.get_* Parameter 'export' Filtert auf piCtory 'Export' Wert
This commit is contained in:
2018-08-18 19:01:13 +02:00
parent 6ef9a55f93
commit ebbdbcaceb
8 changed files with 205 additions and 57 deletions

View File

@@ -553,7 +553,7 @@ Methods</h3>
<td>Gibt eine Liste aller Inputs zurueck.</td> <td>Gibt eine Liste aller Inputs zurueck.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Device.get_memories">get_memories</a></td> <td><a style="color:#0000FF" href="#Device.get_memories">get_memories</a></td>
<td>Gibt eine Liste aller mems zurueck.</td> <td>Gibt eine Liste aller Memoryobjekte zurueck.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Device.get_outputs">get_outputs</a></td> <td><a style="color:#0000FF" href="#Device.get_outputs">get_outputs</a></td>
<td>Gibt eine Liste aller Outputs zurueck.</td> <td>Gibt eine Liste aller Outputs zurueck.</td>
@@ -623,13 +623,16 @@ True, wenn IO auf Device vorhanden
</dl><a NAME="Device.__getioiter" ID="Device.__getioiter"></a> </dl><a NAME="Device.__getioiter" ID="Device.__getioiter"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.__getioiter</h3> Device.__getioiter</h3>
<b>__getioiter</b>(<i>ioslc</i>) <b>__getioiter</b>(<i>ioslc, export</i>)
<p> <p>
Gibt <class 'iter'> mit allen IOs zurueck. Gibt <class 'iter'> mit allen IOs zurueck.
</p><dl> </p><dl>
<dt><i>ioslc</i></dt> <dt><i>ioslc</i></dt>
<dd> <dd>
IO Abschnitt <class 'slice'> IO Abschnitt <class 'slice'>
</dd><dt><i>export</i></dt>
<dd>
Filter fuer 'Export' Flag in piCtory
</dd> </dd>
</dl><dl> </dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
@@ -741,10 +744,20 @@ Default True fuegt Device zur Synchronisierung hinzu
</dl><a NAME="Device.get_allios" ID="Device.get_allios"></a> </dl><a NAME="Device.get_allios" ID="Device.get_allios"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.get_allios</h3> Device.get_allios</h3>
<b>get_allios</b>(<i></i>) <b>get_allios</b>(<i>export=None</i>)
<p> <p>
Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs. Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
</p><p>
Bleibt Parameter 'export' auf None werden alle Inputs und Outputs
zurueckgegeben. Wird 'export' auf True/False gesetzt, werden nur Inputs
und Outputs zurueckgegeben, bei denen der Wert 'Export' in piCtory
uebereinstimmt.
</p><dl> </p><dl>
<dt><i>export</i></dt>
<dd>
Nur In-/Outputs mit angegebenen 'Export' Wert in piCtory
</dd>
</dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
<dd> <dd>
<class 'list'> Input und Output, keine MEMs <class 'list'> Input und Output, keine MEMs
@@ -752,10 +765,19 @@ Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
</dl><a NAME="Device.get_inputs" ID="Device.get_inputs"></a> </dl><a NAME="Device.get_inputs" ID="Device.get_inputs"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.get_inputs</h3> Device.get_inputs</h3>
<b>get_inputs</b>(<i></i>) <b>get_inputs</b>(<i>export=None</i>)
<p> <p>
Gibt eine Liste aller Inputs zurueck. Gibt eine Liste aller Inputs zurueck.
</p><p>
Bleibt Parameter 'export' auf None werden alle Inputs zurueckgegeben.
Wird 'export' auf True/False gesetzt, werden nur Inputs zurueckgegeben,
bei denen der Wert 'Export' in piCtory uebereinstimmt.
</p><dl> </p><dl>
<dt><i>export</i></dt>
<dd>
Nur Inputs mit angegebenen 'Export' Wert in piCtory
</dd>
</dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
<dd> <dd>
<class 'list'> Inputs <class 'list'> Inputs
@@ -763,10 +785,19 @@ Gibt eine Liste aller Inputs zurueck.
</dl><a NAME="Device.get_memories" ID="Device.get_memories"></a> </dl><a NAME="Device.get_memories" ID="Device.get_memories"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.get_memories</h3> Device.get_memories</h3>
<b>get_memories</b>(<i></i>) <b>get_memories</b>(<i>export=None</i>)
<p> <p>
Gibt eine Liste aller mems zurueck. Gibt eine Liste aller Memoryobjekte zurueck.
</p><p>
Bleibt Parameter 'export' auf None werden alle Mems zurueckgegeben.
Wird 'export' auf True/False gesetzt, werden nur Mems zurueckgegeben,
bei denen der Wert 'Export' in piCtory uebereinstimmt.
</p><dl> </p><dl>
<dt><i>export</i></dt>
<dd>
Nur Mems mit angegebenen 'Export' Wert in piCtory
</dd>
</dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
<dd> <dd>
<class 'list'> Mems <class 'list'> Mems
@@ -774,10 +805,19 @@ Gibt eine Liste aller mems zurueck.
</dl><a NAME="Device.get_outputs" ID="Device.get_outputs"></a> </dl><a NAME="Device.get_outputs" ID="Device.get_outputs"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.get_outputs</h3> Device.get_outputs</h3>
<b>get_outputs</b>(<i></i>) <b>get_outputs</b>(<i>export=None</i>)
<p> <p>
Gibt eine Liste aller Outputs zurueck. Gibt eine Liste aller Outputs zurueck.
</p><p>
Bleibt Parameter 'export' auf None werden alle Outputs zurueckgegeben.
Wird 'export' auf True/False gesetzt, werden nur Outputs
zurueckgegeben, bei denen der Wert 'Export' in piCtory uebereinstimmt.
</p><dl> </p><dl>
<dt><i>export</i></dt>
<dd>
Nur Outputs mit angegebenen 'Export' Wert in piCtory
</dd>
</dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
<dd> <dd>
<class 'list'> Outputs <class 'list'> Outputs

View File

@@ -26,6 +26,9 @@ Classes</h3>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter">ProcimgWriter</a></td> <td><a style="color:#0000FF" href="#ProcimgWriter">ProcimgWriter</a></td>
<td>Klasse fuer Synchroniseriungs-Thread.</td> <td>Klasse fuer Synchroniseriungs-Thread.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Var">Var</a></td>
<td></td>
</tr> </tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -65,7 +68,7 @@ None
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3> Class Attributes</h3>
<table> <table>
<tr><td>None</td></tr> <tr><td>__slots__</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3> Class Methods</h3>
@@ -351,7 +354,7 @@ Thread
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3> Class Attributes</h3>
<table> <table>
<tr><td>None</td></tr> <tr><td>__slots__</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3> Class Methods</h3>
@@ -426,7 +429,7 @@ Thread
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3> Class Attributes</h3>
<table> <table>
<tr><td>ioerrors</td></tr><tr><td>maxioerrors</td></tr><tr><td>refresh</td></tr> <tr><td>__slots__</td></tr><tr><td>ioerrors</td></tr><tr><td>maxioerrors</td></tr><tr><td>refresh</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3> Class Methods</h3>
@@ -592,6 +595,35 @@ ProcimgWriter.stop</h3>
<p> <p>
Beendet die automatische Prozessabbildsynchronisierung. Beendet die automatische Prozessabbildsynchronisierung.
</p> </p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="Var" ID="Var"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">Var</h2>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</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>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div> <div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /> <hr />
</body></html> </body></html>

View File

@@ -345,7 +345,7 @@ Beendet autorefresh und alle Threads.
</p><a NAME="RevPiModIO.cycleloop" ID="RevPiModIO.cycleloop"></a> </p><a NAME="RevPiModIO.cycleloop" ID="RevPiModIO.cycleloop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.cycleloop</h3> RevPiModIO.cycleloop</h3>
<b>cycleloop</b>(<i>func, cycletime=None</i>) <b>cycleloop</b>(<i>func, cycletime=50</i>)
<p> <p>
Startet den Cycleloop. Startet den Cycleloop.
</p><p> </p><p>
@@ -358,23 +358,24 @@ Startet den Cycleloop.
Prozessabbild geschrieben. Prozessabbild geschrieben.
</p><p> </p><p>
Verlassen wird der Cycleloop, wenn die aufgerufene Funktion einen Verlassen wird der Cycleloop, wenn die aufgerufene Funktion einen
Rueckgabewert nicht gleich None liefert, oder durch Aufruf von Rueckgabewert nicht gleich None liefert (z.B. return True), oder durch
revpimodio.exit(). Aufruf von .exit().
</p><p> </p><p>
HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen
die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht
ueberschreiten! ueberschreiten!
</p><p> </p><p>
Ueber das Attribut cycletime kann die Aktualisierungsrate fuer das Ueber den Parameter cycletime wird die gewuenschte Zukluszeit der
Prozessabbild gesetzt werden. uebergebenen Funktion gesetzt. Der Standardwert betraegt
50 Millisekunden, in denen das Prozessabild eingelesen, die uebergebene
Funktion ausgefuert und das Prozessabbild geschrieben wird.
</p><dl> </p><dl>
<dt><i>func</i></dt> <dt><i>func</i></dt>
<dd> <dd>
Funktion, die ausgefuehrt werden soll Funktion, die ausgefuehrt werden soll
</dd><dt><i>cycletime</i></dt> </dd><dt><i>cycletime</i></dt>
<dd> <dd>
Zykluszeit in Millisekunden, bei Nichtangabe wird Zykluszeit in Millisekunden - Standardwert 50 ms
aktuelle .cycletime Zeit verwendet - Standardwert 50 ms
</dd> </dd>
</dl><dl> </dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>

View File

@@ -43,10 +43,10 @@ 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.autorefresh?4(activate=True) revpimodio2.device.Device.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4() revpimodio2.device.Device.get_allios?4(export=None)
revpimodio2.device.Device.get_inputs?4() revpimodio2.device.Device.get_inputs?4(export=None)
revpimodio2.device.Device.get_memories?4() revpimodio2.device.Device.get_memories?4(export=None)
revpimodio2.device.Device.get_outputs?4() revpimodio2.device.Device.get_outputs?4(export=None)
revpimodio2.device.Device.length?7 revpimodio2.device.Device.length?7
revpimodio2.device.Device.name?7 revpimodio2.device.Device.name?7
revpimodio2.device.Device.offset?7 revpimodio2.device.Device.offset?7
@@ -152,7 +152,7 @@ revpimodio2.modio.RevPiModIO._set_maxioerrors?5(value)
revpimodio2.modio.RevPiModIO.autorefresh_all?4() revpimodio2.modio.RevPiModIO.autorefresh_all?4()
revpimodio2.modio.RevPiModIO.cleanup?4() revpimodio2.modio.RevPiModIO.cleanup?4()
revpimodio2.modio.RevPiModIO.configrsc?7 revpimodio2.modio.RevPiModIO.configrsc?7
revpimodio2.modio.RevPiModIO.cycleloop?4(func, cycletime=None) revpimodio2.modio.RevPiModIO.cycleloop?4(func, cycletime=50)
revpimodio2.modio.RevPiModIO.cycletime?7 revpimodio2.modio.RevPiModIO.cycletime?7
revpimodio2.modio.RevPiModIO.exit?4(full=True) revpimodio2.modio.RevPiModIO.exit?4(full=True)
revpimodio2.modio.RevPiModIO.get_jconfigrsc?4() revpimodio2.modio.RevPiModIO.get_jconfigrsc?4()

View File

@@ -213,7 +213,7 @@ class Device(object):
def __iter__(self): def __iter__(self):
"""Gibt Iterator aller IOs zurueck. """Gibt Iterator aller IOs zurueck.
@return <class 'iter'> aller IOs""" @return <class 'iter'> aller IOs"""
return self.__getioiter(self._slc_devoff) return self.__getioiter(self._slc_devoff, None)
def __len__(self): def __len__(self):
"""Gibt Anzahl der Bytes zurueck, die dieses Device belegt. """Gibt Anzahl der Bytes zurueck, die dieses Device belegt.
@@ -225,13 +225,17 @@ class Device(object):
@return Devicename""" @return Devicename"""
return self._name return self._name
def __getioiter(self, ioslc): def __getioiter(self, ioslc, export):
"""Gibt <class 'iter'> mit allen IOs zurueck. """Gibt <class 'iter'> mit allen IOs zurueck.
@param ioslc IO Abschnitt <class 'slice'> @param ioslc IO Abschnitt <class 'slice'>
@return IOs als Iterator""" @param export Filter fuer 'Export' Flag in piCtory
@return IOs als Iterator
"""
for lst_io in self._modio.io[ioslc]: for lst_io in self._modio.io[ioslc]:
for io in lst_io: for io in lst_io:
if io is not None: if io is not None and (export is None or io.export == export):
yield io yield io
def _buildio(self, dict_io, iotype): def _buildio(self, dict_io, iotype):
@@ -335,27 +339,60 @@ class Device(object):
if not self._modio._monitoring: if not self._modio._monitoring:
self._modio.writeprocimg(self) self._modio.writeprocimg(self)
def get_allios(self): def get_allios(self, export=None):
"""Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs. """Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
@return <class 'list'> Input und Output, keine MEMs"""
Bleibt Parameter 'export' auf None werden alle Inputs und Outputs
zurueckgegeben. Wird 'export' auf True/False gesetzt, werden nur Inputs
und Outputs zurueckgegeben, bei denen der Wert 'Export' in piCtory
uebereinstimmt.
@param export Nur In-/Outputs mit angegebenen 'Export' Wert in piCtory
@return <class 'list'> Input und Output, keine MEMs
"""
return list(self.__getioiter( return list(self.__getioiter(
slice(self._slc_inpoff.start, self._slc_outoff.stop) slice(self._slc_inpoff.start, self._slc_outoff.stop), export
)) ))
def get_inputs(self): def get_inputs(self, export=None):
"""Gibt eine Liste aller Inputs zurueck. """Gibt eine Liste aller Inputs zurueck.
@return <class 'list'> Inputs"""
return list(self.__getioiter(self._slc_inpoff))
def get_outputs(self): Bleibt Parameter 'export' auf None werden alle Inputs zurueckgegeben.
Wird 'export' auf True/False gesetzt, werden nur Inputs zurueckgegeben,
bei denen der Wert 'Export' in piCtory uebereinstimmt.
@param export Nur Inputs mit angegebenen 'Export' Wert in piCtory
@return <class 'list'> Inputs
"""
return list(self.__getioiter(self._slc_inpoff, export))
def get_outputs(self, export=None):
"""Gibt eine Liste aller Outputs zurueck. """Gibt eine Liste aller Outputs zurueck.
@return <class 'list'> Outputs"""
return list(self.__getioiter(self._slc_outoff))
def get_memories(self): Bleibt Parameter 'export' auf None werden alle Outputs zurueckgegeben.
"""Gibt eine Liste aller mems zurueck. Wird 'export' auf True/False gesetzt, werden nur Outputs
@return <class 'list'> Mems""" zurueckgegeben, bei denen der Wert 'Export' in piCtory uebereinstimmt.
return list(self.__getioiter(self._slc_memoff))
@param export Nur Outputs mit angegebenen 'Export' Wert in piCtory
@return <class 'list'> Outputs
"""
return list(self.__getioiter(self._slc_outoff, export))
def get_memories(self, export=None):
"""Gibt eine Liste aller Memoryobjekte zurueck.
Bleibt Parameter 'export' auf None werden alle Mems zurueckgegeben.
Wird 'export' auf True/False gesetzt, werden nur Mems zurueckgegeben,
bei denen der Wert 'Export' in piCtory uebereinstimmt.
@param export Nur Mems mit angegebenen 'Export' Wert in piCtory
@return <class 'list'> Mems
"""
return list(self.__getioiter(self._slc_memoff, export))
def readprocimg(self): def readprocimg(self):
"""Alle Inputs fuer dieses Device vom Prozessabbild einlesen. """Alle Inputs fuer dieses Device vom Prozessabbild einlesen.
@@ -832,7 +869,7 @@ class Virtual(Gateway):
for io in self.get_inputs(): for io in self.get_inputs():
self._ba_devdata[io._slc_address] = io._defaultvalue self._ba_devdata[io._slc_address] = io._defaultvalue
# Outpus auf Bus schreiben # Outputs auf Bus schreiben
try: try:
self._modio._myfh.seek(self._slc_inpoff.start) self._modio._myfh.seek(self._slc_inpoff.start)
self._modio._myfh.write(self._ba_devdata[self._slc_inp]) self._modio._myfh.write(self._ba_devdata[self._slc_inp])

View File

@@ -556,7 +556,6 @@ class ProcimgWriter(Thread):
def stop(self): def stop(self):
"""Beendet die automatische Prozessabbildsynchronisierung.""" """Beendet die automatische Prozessabbildsynchronisierung."""
self._collect_events(False)
self._work.set() self._work.set()
def set_maxioerrors(self, value): def set_maxioerrors(self, value):
@@ -570,13 +569,13 @@ class ProcimgWriter(Thread):
def set_refresh(self, value): def set_refresh(self, value):
"""Setzt die Zykluszeit in Millisekunden. """Setzt die Zykluszeit in Millisekunden.
@param value <class 'int'> Millisekunden""" @param value <class 'int'> Millisekunden"""
if type(value) == int and 10 <= value <= 2000: if type(value) == int and 5 <= value <= 2000:
waitdiff = self._refresh - self._adjwait waitdiff = self._refresh - self._adjwait
self._refresh = value / 1000 self._refresh = value / 1000
self._adjwait = self._refresh - waitdiff self._adjwait = 0 if waitdiff < 0 else self._refresh - waitdiff
else: else:
raise ValueError( raise ValueError(
"refresh time must be 10 to 2000 milliseconds" "refresh time must be 5 to 2000 milliseconds"
) )
ioerrors = property(_get_ioerrors) ioerrors = property(_get_ioerrors)

View File

@@ -254,7 +254,7 @@ class IOBase(object):
__slots__ = "_bitaddress", "_bitlength", "_byteorder", "_defaultvalue", \ __slots__ = "_bitaddress", "_bitlength", "_byteorder", "_defaultvalue", \
"_iotype", "_length", "_name", "_parentdevice", \ "_iotype", "_length", "_name", "_parentdevice", \
"_signed", "_slc_address", "bmk" "_signed", "_slc_address", "bmk", "export"
def __init__(self, parentdevice, valuelist, iotype, byteorder, signed): def __init__(self, parentdevice, valuelist, iotype, byteorder, signed):
"""Instantiierung der IOBase-Klasse. """Instantiierung der IOBase-Klasse.
@@ -283,6 +283,7 @@ class IOBase(object):
self._name = valuelist[0] self._name = valuelist[0]
self._signed = signed self._signed = signed
self.bmk = valuelist[6] self.bmk = valuelist[6]
self.export = bool(valuelist[4])
int_startaddress = int(valuelist[3]) int_startaddress = int(valuelist[3])
if self._bitaddress == -1: if self._bitaddress == -1:

View File

@@ -6,10 +6,12 @@ __license__ = "LGPLv3"
import warnings import warnings
from json import load as jload from json import load as jload
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 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
from timeit import default_timer
from . import app as appmodule from . import app as appmodule
from . import device as devicemodule from . import device as devicemodule
@@ -224,6 +226,10 @@ class RevPiModIO(object):
# ImgWriter erstellen # ImgWriter erstellen
self._imgwriter = helpermodule.ProcimgWriter(self) self._imgwriter = helpermodule.ProcimgWriter(self)
# Refreshzeit CM1 25 Hz / CM3 50 Hz
if not isinstance(self, RevPiNetIO):
self._imgwriter.refresh = 20 if cpu_count() > 1 else 40
# Aktuellen Outputstatus von procimg einlesen # Aktuellen Outputstatus von procimg einlesen
if self._syncoutputs: if self._syncoutputs:
self.syncoutputs() self.syncoutputs()
@@ -349,7 +355,7 @@ class RevPiModIO(object):
self.io = None self.io = None
self.summary = None self.summary = None
def cycleloop(self, func, cycletime=None): def cycleloop(self, func, cycletime=50):
"""Startet den Cycleloop. """Startet den Cycleloop.
Der aktuelle Programmthread wird hier bis Aufruf von Der aktuelle Programmthread wird hier bis Aufruf von
@@ -361,19 +367,20 @@ class RevPiModIO(object):
Prozessabbild geschrieben. Prozessabbild geschrieben.
Verlassen wird der Cycleloop, wenn die aufgerufene Funktion einen Verlassen wird der Cycleloop, wenn die aufgerufene Funktion einen
Rueckgabewert nicht gleich None liefert, oder durch Aufruf von Rueckgabewert nicht gleich None liefert (z.B. return True), oder durch
revpimodio.exit(). Aufruf von .exit().
HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen
die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht
ueberschreiten! ueberschreiten!
Ueber das Attribut cycletime kann die Aktualisierungsrate fuer das Ueber den Parameter cycletime wird die gewuenschte Zukluszeit der
Prozessabbild gesetzt werden. uebergebenen Funktion gesetzt. Der Standardwert betraegt
50 Millisekunden, in denen das Prozessabild eingelesen, die uebergebene
Funktion ausgefuert und das Prozessabbild geschrieben wird.
@param func Funktion, die ausgefuehrt werden soll @param func Funktion, die ausgefuehrt werden soll
@param cycletime Zykluszeit in Millisekunden, bei Nichtangabe wird @param cycletime Zykluszeit in Millisekunden - Standardwert 50 ms
aktuelle .cycletime Zeit verwendet - Standardwert 50 ms
@return None @return None
""" """
@@ -385,7 +392,10 @@ class RevPiModIO(object):
# Prüfen ob Devices in autorefresh sind # Prüfen ob Devices in autorefresh sind
if len(self._lst_refresh) == 0: if len(self._lst_refresh) == 0:
raise RuntimeError("no device with autorefresh activated") raise RuntimeError(
"no device with autorefresh activated - use autorefresh=True "
"or call .autorefresh_all() before entering cycleloop"
)
# Prüfen ob Funktion callable ist # Prüfen ob Funktion callable ist
if not callable(func): if not callable(func):
@@ -394,7 +404,8 @@ class RevPiModIO(object):
) )
# Zykluszeit übernehmen # Zykluszeit übernehmen
if not (cycletime is None or cycletime == self._imgwriter.refresh): old_cycletime = self._imgwriter.refresh
if not cycletime == self._imgwriter.refresh:
self._imgwriter.refresh = cycletime self._imgwriter.refresh = cycletime
# Zeitänderung in _imgwriter neuladen # Zeitänderung in _imgwriter neuladen
@@ -439,6 +450,9 @@ class RevPiModIO(object):
# Cycleloop beenden # Cycleloop beenden
self._looprunning = False self._looprunning = False
# Alte autorefresh Zeit setzen
self._imgwriter.refresh = old_cycletime
return ec return ec
def exit(self, full=True): def exit(self, full=True):
@@ -568,7 +582,10 @@ class RevPiModIO(object):
# Prüfen ob Devices in autorefresh sind # Prüfen ob Devices in autorefresh sind
if len(self._lst_refresh) == 0: if len(self._lst_refresh) == 0:
raise RuntimeError("no device with autorefresh activated") raise RuntimeError(
"no device with autorefresh activated - use autorefresh=True "
"or call .autorefresh_all() before entering mainloop"
)
# Thread erstellen, wenn nicht blockieren soll # Thread erstellen, wenn nicht blockieren soll
if not blocking: if not blocking:
@@ -593,12 +610,33 @@ class RevPiModIO(object):
# ImgWriter mit Eventüberwachung aktivieren # ImgWriter mit Eventüberwachung aktivieren
self._imgwriter._collect_events(True) self._imgwriter._collect_events(True)
e = None e = None
runtime = 0
while not self._exit.is_set(): while not self._exit.is_set():
# Laufzeit der Eventqueue auf 0 setzen
if self._imgwriter._eventq.qsize() == 0:
runtime = 0
try: try:
tup_fire = self._imgwriter._eventq.get(timeout=1) tup_fire = self._imgwriter._eventq.get(timeout=1)
# Messung Laufzeit der Queue starten
if runtime == 0:
runtime = default_timer()
# 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].func(tup_fire[1], tup_fire[2]) tup_fire[0].func(tup_fire[1], tup_fire[2])
# Laufzeitprüfung
if runtime != -1 and \
default_timer() - runtime > self._imgwriter._refresh:
runtime = -1
warnings.warn(
"can not execute all event functions in one cycle - "
"rise .cycletime or optimize your event functions",
RuntimeWarning
)
except Empty: except Empty:
if not self._exit.is_set() and not self._imgwriter.is_alive(): if not self._exit.is_set() and not self._imgwriter.is_alive():
self.exit(full=False) self.exit(full=False)
@@ -889,4 +927,4 @@ class RevPiModIODriver(RevPiModIOSelected):
# Nachträglicher Import # Nachträglicher Import
from .netio import RevPiNetIODriver from .netio import RevPiNetIODriver, RevPiNetIO