Starke Leistungsverbesserung bei device.get_*s()

auto_refresh in autorefresh überall umbenannt
ioerror Zähler auch in RevPiModIO eingebaut
_adjwait wird bei Umstellung gleich mit DIFF gesetzt
_ba_devdata wird nach IOs vollständig erstellt
StructIO Instantiierung vereinfacht / byteorder, signed automatisch
This commit is contained in:
2017-08-16 17:14:36 +02:00
parent ddc93c9b9e
commit e124da758f
10 changed files with 443 additions and 275 deletions

View File

@@ -22,7 +22,7 @@ Classes</h3>
<td>Klasse fuer den RevPi Core.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device">Device</a></td>
<td>Basisklasse fuer alle Device-Objekte der RevPiDevicelist()-Klasse.</td>
<td>Basisklasse fuer alle Device-Objekte.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#DeviceList">DeviceList</a></td>
<td>Basisklasse fuer direkten Zugriff auf Device Objekte.</td>
@@ -344,13 +344,11 @@ True, wenn IO Modul nicht konfiguriert
<a NAME="Device" ID="Device"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">Device</h2>
<p>
Basisklasse fuer alle Device-Objekte der RevPiDevicelist()-Klasse.
Basisklasse fuer alle Device-Objekte.
</p><p>
Die Basisfunktionalitaet generiert bei Instantiierung alle IOs und
erweitert den Prozessabbildpuffer um die benoetigten Bytes. Ueber diese
Klasse oder von dieser abgeleiteten Klassen, werden alle IOs angesprochen.
Sie verwaltet ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung
der IO-Werte.
erweitert den Prozessabbildpuffer um die benoetigten Bytes. Sie verwaltet
ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung der IO-Werte.
</p><p>
</p>
@@ -398,11 +396,11 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Device._devconfigure">_devconfigure</a></td>
<td>Funktion zum ueberschreiben von abgeleiteten Klassen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.auto_refresh">auto_refresh</a></td>
<td>Registriert ein Device fuer die automatische Synchronisierung.</td>
<td><a style="color:#0000FF" href="#Device.autorefresh">autorefresh</a></td>
<td>Registriert dieses Device fuer die automatische Synchronisierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.get_allios">get_allios</a></td>
<td>Gibt eine Liste aller Inputs und Outputs zurueck.</td>
<td>Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.get_inps">get_inps</a></td>
<td>Gibt eine Liste aller Inputs zurueck.</td>
@@ -436,7 +434,7 @@ dict() fuer dieses Device aus piCotry Konfiguration
<dd>
Weitere Parameter:
- autoupdate: Wenn True fuehrt dieses Device Arbeiten am
Prozessabbild bei Aufruf der RevPiDevicelist-Funktionen aus
Prozessabbild bei Aufruf der read- writeprocimg Funktionen aus
- simulator: Laed das Modul als Simulator und vertauscht IOs
</dd>
</dl><a NAME="Device.__bytes__" ID="Device.__bytes__"></a>
@@ -535,12 +533,12 @@ Device._devconfigure</h3>
<b>_devconfigure</b>(<i></i>)
<p>
Funktion zum ueberschreiben von abgeleiteten Klassen.
</p><a NAME="Device.auto_refresh" ID="Device.auto_refresh"></a>
</p><a NAME="Device.autorefresh" ID="Device.autorefresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.auto_refresh</h3>
<b>auto_refresh</b>(<i>remove=False</i>)
Device.autorefresh</h3>
<b>autorefresh</b>(<i>remove=False</i>)
<p>
Registriert ein Device fuer die automatische Synchronisierung.
Registriert dieses Device fuer die automatische Synchronisierung.
</p><dl>
<dt><i>remove</i></dt>
<dd>
@@ -551,7 +549,7 @@ bool() True entfernt Device aus Synchronisierung
Device.get_allios</h3>
<b>get_allios</b>(<i></i>)
<p>
Gibt eine Liste aller Inputs und Outputs zurueck.
Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
</p><dl>
<dt>Returns:</dt>
<dd>

View File

@@ -318,7 +318,7 @@ Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>refresh</td></tr>
<tr><td>ioerrors</td></tr><tr><td>maxioerrors</td></tr><tr><td>refresh</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
@@ -332,8 +332,14 @@ Methods</h3>
<td><a style="color:#0000FF" href="#ProcimgWriter.__init__">ProcimgWriter</a></td>
<td>Init ProcimgWriter class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter._get_ioerrors">_get_ioerrors</a></td>
<td>Ruft aktuelle Anzahl der Fehler ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter._gotioerror">_gotioerror</a></td>
<td>IOError Verwaltung fuer auto_refresh.</td>
<td>IOError Verwaltung fuer autorefresh.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.get_maxioerrors">get_maxioerrors</a></td>
<td>Gibt die Anzahl der maximal erlaubten Fehler zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.get_refresh">get_refresh</a></td>
<td>Gibt Zykluszeit zurueck.</td>
@@ -341,6 +347,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#ProcimgWriter.run">run</a></td>
<td>Startet die automatische Prozessabbildsynchronisierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.set_maxioerrors">set_maxioerrors</a></td>
<td>Setzt die Anzahl der maximal erlaubten Fehler.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.set_refresh">set_refresh</a></td>
<td>Setzt die Zykluszeit in Millisekunden.</td>
</tr><tr>
@@ -364,13 +373,35 @@ Init ProcimgWriter class.
<dd>
Parent Object
</dd>
</dl><a NAME="ProcimgWriter._get_ioerrors" ID="ProcimgWriter._get_ioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter._get_ioerrors</h3>
<b>_get_ioerrors</b>(<i></i>)
<p>
Ruft aktuelle Anzahl der Fehler ab.
</p><dl>
<dt>Returns:</dt>
<dd>
Aktuelle Fehleranzahl
</dd>
</dl><a NAME="ProcimgWriter._gotioerror" ID="ProcimgWriter._gotioerror"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter._gotioerror</h3>
<b>_gotioerror</b>(<i></i>)
<p>
IOError Verwaltung fuer auto_refresh.
</p><a NAME="ProcimgWriter.get_refresh" ID="ProcimgWriter.get_refresh"></a>
IOError Verwaltung fuer autorefresh.
</p><a NAME="ProcimgWriter.get_maxioerrors" ID="ProcimgWriter.get_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.get_maxioerrors</h3>
<b>get_maxioerrors</b>(<i></i>)
<p>
Gibt die Anzahl der maximal erlaubten Fehler zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="ProcimgWriter.get_refresh" ID="ProcimgWriter.get_refresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.get_refresh</h3>
<b>get_refresh</b>(<i></i>)
@@ -387,7 +418,18 @@ ProcimgWriter.run</h3>
<b>run</b>(<i></i>)
<p>
Startet die automatische Prozessabbildsynchronisierung.
</p><a NAME="ProcimgWriter.set_refresh" ID="ProcimgWriter.set_refresh"></a>
</p><a NAME="ProcimgWriter.set_maxioerrors" ID="ProcimgWriter.set_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.set_maxioerrors</h3>
<b>set_maxioerrors</b>(<i>value</i>)
<p>
Setzt die Anzahl der maximal erlaubten Fehler.
</p><dl>
<dt><i>value</i></dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="ProcimgWriter.set_refresh" ID="ProcimgWriter.set_refresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.set_refresh</h3>
<b>set_refresh</b>(<i>value</i>)

View File

@@ -58,7 +58,7 @@ object
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>address</td></tr><tr><td>length</td></tr><tr><td>name</td></tr><tr><td>value</td></tr>
<tr><td>address</td></tr><tr><td>byteorder</td></tr><tr><td>length</td></tr><tr><td>name</td></tr><tr><td>value</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
@@ -81,16 +81,16 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOBase.__str__">__str__</a></td>
<td>str()-wert der Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase._get_address">_get_address</a></td>
<td>Gibt die absolute Byteadresse im Prozessabbild zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase._get_byteorder">_get_byteorder</a></td>
<td>Gibt konfigurierte Byteorder zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.get_address">get_address</a></td>
<td>Gibt die absolute Byteadresse im Prozessabbild zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.get_length">get_length</a></td>
<td><a style="color:#0000FF" href="#IOBase._get_length">_get_length</a></td>
<td>Gibt die Bytelaenge des IO zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.get_name">get_name</a></td>
<td><a style="color:#0000FF" href="#IOBase._get_name">_get_name</a></td>
<td>Gibt den Namen des IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase.get_value">get_value</a></td>
@@ -120,7 +120,7 @@ Static Methods</h3>
<a NAME="IOBase.__init__" ID="IOBase.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase (Constructor)</h3>
<b>IOBase</b>(<i>parentdevice, valuelist, iotype, byteorder</i>)
<b>IOBase</b>(<i>parentdevice, valuelist, iotype, byteorder, signed</i>)
<p>
Instantiierung der IOBase()-Klasse.
</p><dl>
@@ -136,6 +136,9 @@ IOType() Wert
</dd><dt><i>byteorder</i></dt>
<dd>
Byteorder 'little' / 'big' fuer int() Berechnung
</dd><dt><i>sigend</i></dt>
<dd>
Intberechnung mit Vorzeichen durchfuehren
</dd>
</dl><a NAME="IOBase.__bool__" ID="IOBase.__bool__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -170,6 +173,17 @@ str()-wert der Klasse.
<dd>
Namen des IOs
</dd>
</dl><a NAME="IOBase._get_address" ID="IOBase._get_address"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase._get_address</h3>
<b>_get_address</b>(<i></i>)
<p>
Gibt die absolute Byteadresse im Prozessabbild zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Absolute Byteadresse
</dd>
</dl><a NAME="IOBase._get_byteorder" ID="IOBase._get_byteorder"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase._get_byteorder</h3>
@@ -181,21 +195,10 @@ Gibt konfigurierte Byteorder zurueck.
<dd>
str() Byteorder
</dd>
</dl><a NAME="IOBase.get_address" ID="IOBase.get_address"></a>
</dl><a NAME="IOBase._get_length" ID="IOBase._get_length"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.get_address</h3>
<b>get_address</b>(<i></i>)
<p>
Gibt die absolute Byteadresse im Prozessabbild zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Absolute Byteadresse
</dd>
</dl><a NAME="IOBase.get_length" ID="IOBase.get_length"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.get_length</h3>
<b>get_length</b>(<i></i>)
IOBase._get_length</h3>
<b>_get_length</b>(<i></i>)
<p>
Gibt die Bytelaenge des IO zurueck.
</p><dl>
@@ -203,10 +206,10 @@ Gibt die Bytelaenge des IO zurueck.
<dd>
Bytelaenge des IO
</dd>
</dl><a NAME="IOBase.get_name" ID="IOBase.get_name"></a>
</dl><a NAME="IOBase._get_name" ID="IOBase._get_name"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOBase.get_name</h3>
<b>get_name</b>(<i></i>)
IOBase._get_name</h3>
<b>_get_name</b>(<i></i>)
<p>
Gibt den Namen des IOs zurueck.
</p><dl>
@@ -304,7 +307,7 @@ IOBase.wait</h3>
Wartet auf Wertaenderung eines IOs.
</p><p>
Die Wertaenderung wird immer uerberprueft, wenn fuer Devices
in Devicelist.auto_refresh() neue Daten gelesen wurden.
mit aktiviertem autorefresh neue Daten gelesen wurden.
</p><p>
Bei Wertaenderung, wird das Warten mit 0 als Rueckgabewert beendet.
</p><p>
@@ -324,7 +327,7 @@ 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 auto_refresh Funktion berechnet, entspricht also nicht exact den
der autorefresh Funktion berechnet, entspricht also nicht exact den
angegeben Millisekunden! Es wird immer nach oben gerundet!)
</p><dl>
<dt><i>edge</i></dt>
@@ -387,7 +390,7 @@ Methods</h3>
<td>Entfernt angegebenen IO.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList.__getattr__">__getattr__</a></td>
<td>Verwaltet geloeschte IOs.</td>
<td>Verwaltet geloeschte IOs (Attribute, die nicht existieren).</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList.__getitem__">__getitem__</a></td>
<td>Ruft angegebenen IO ab.</td>
@@ -395,7 +398,7 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOList.__iter__">__iter__</a></td>
<td>Gibt Iterator aller IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList.__replace_oldio_with_newio">__replace_oldio_with_newio</a></td>
<td><a style="color:#0000FF" href="#IOList.__private_replace_oldio_with_newio">__private_replace_oldio_with_newio</a></td>
<td>Ersetzt bestehende IOs durch den neu Registrierten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList.__setattr__">__setattr__</a></td>
@@ -404,7 +407,10 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOList.__setitem__">__setitem__</a></td>
<td>Setzt IO Wert.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList._register_new_io_object">_register_new_io_object</a></td>
<td><a style="color:#0000FF" href="#IOList._getdict">_getdict</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList._private_register_new_io_object">_private_register_new_io_object</a></td>
<td>Registriert neues IO Objekt unabhaenging von __setattr__.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList._testme">_testme</a></td>
@@ -454,7 +460,7 @@ IO zum entfernen
IOList.__getattr__</h3>
<b>__getattr__</b>(<i>key</i>)
<p>
Verwaltet geloeschte IOs.
Verwaltet geloeschte IOs (Attribute, die nicht existieren).
</p><dl>
<dt><i>key</i></dt>
<dd>
@@ -492,10 +498,10 @@ Gibt Iterator aller IOs zurueck.
<dd>
Iterator aller IOs
</dd>
</dl><a NAME="IOList.__replace_oldio_with_newio" ID="IOList.__replace_oldio_with_newio"></a>
</dl><a NAME="IOList.__private_replace_oldio_with_newio" ID="IOList.__private_replace_oldio_with_newio"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOList.__replace_oldio_with_newio</h3>
<b>__replace_oldio_with_newio</b>(<i>io</i>)
IOList.__private_replace_oldio_with_newio</h3>
<b>__private_replace_oldio_with_newio</b>(<i>io</i>)
<p>
Ersetzt bestehende IOs durch den neu Registrierten.
</p><dl>
@@ -531,10 +537,14 @@ IO Name oder Byte
<dd>
Wert, auf den der IO gesetzt wird
</dd>
</dl><a NAME="IOList._register_new_io_object" ID="IOList._register_new_io_object"></a>
</dl><a NAME="IOList._getdict" ID="IOList._getdict"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOList._register_new_io_object</h3>
<b>_register_new_io_object</b>(<i>new_io</i>)
IOList._getdict</h3>
<b>_getdict</b>(<i></i>)
<a NAME="IOList._private_register_new_io_object" ID="IOList._private_register_new_io_object"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOList._private_register_new_io_object</h3>
<b>_private_register_new_io_object</b>(<i>new_io</i>)
<p>
Registriert neues IO Objekt unabhaenging von __setattr__.
</p><dl>
@@ -694,7 +704,7 @@ IOBase
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>byteorder</td></tr><tr><td>value</td></tr>
<tr><td>signed</td></tr><tr><td>value</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
@@ -708,6 +718,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#StructIO.__init__">StructIO</a></td>
<td>Erstellt einen IO mit struct-Formatierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#StructIO._get_signed">_get_signed</a></td>
<td>Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#StructIO.get_structvalue">get_structvalue</a></td>
<td>Gibt den Wert mit struct Formatierung zurueck.</td>
</tr><tr>
@@ -723,7 +736,7 @@ Static Methods</h3>
<a NAME="StructIO.__init__" ID="StructIO.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
StructIO (Constructor)</h3>
<b>StructIO</b>(<i>parentio, name, iotype, byteorder, frm, **kwargs</i>)
<b>StructIO</b>(<i>parentio, name, frm, **kwargs</i>)
<p>
Erstellt einen IO mit struct-Formatierung.
</p><dl>
@@ -733,12 +746,6 @@ ParentIO Objekt, welches ersetzt wird
</dd><dt><i>name</i></dt>
<dd>
Name des neuen IO
</dd><dt><i>iotype</i></dt>
<dd>
IOType() Wert
</dd><dt><i>byteorder</i></dt>
<dd>
Byteorder 'little' / 'big' fuer int() Berechnung
</dd><dt><i>frm</i></dt>
<dd>
struct() formatierung (1 Zeichen)
@@ -747,8 +754,20 @@ struct() formatierung (1 Zeichen)
Weitere Parameter:
- bmk: Bezeichnung fuer Output
- bit: Registriert Outputs als bool() am angegebenen Bit im Byte
- byteorder: Byteorder fuer den Input, Standardwert=little
- defaultvalue: Standardwert fuer Output, Standard ist 0
</dd>
</dl><a NAME="StructIO._get_signed" ID="StructIO._get_signed"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
StructIO._get_signed</h3>
<b>_get_signed</b>(<i></i>)
<p>
Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn Vorzeichenbehaftet
</dd>
</dl><a NAME="StructIO.get_structvalue" ID="StructIO.get_structvalue"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
StructIO.get_structvalue</h3>

View File

@@ -54,7 +54,7 @@ object
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>configrsc</td></tr><tr><td>cycletime</td></tr><tr><td>length</td></tr><tr><td>monitoring</td></tr><tr><td>procimg</td></tr><tr><td>simulator</td></tr>
<tr><td>configrsc</td></tr><tr><td>cycletime</td></tr><tr><td>ioerrors</td></tr><tr><td>length</td></tr><tr><td>maxioerrors</td></tr><tr><td>monitoring</td></tr><tr><td>procimg</td></tr><tr><td>simulator</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
@@ -86,9 +86,15 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO._get_cycletime">_get_cycletime</a></td>
<td>Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_ioerrors">_get_ioerrors</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_length">_get_length</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_maxioerrors">_get_maxioerrors</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_monitoring">_get_monitoring</a></td>
<td>Getter function.</td>
</tr><tr>
@@ -98,23 +104,26 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO._get_simulator">_get_simulator</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._gotioerror">_gotioerror</a></td>
<td>IOError Verwaltung fuer Prozessabbildzugriff.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._set_cycletime">_set_cycletime</a></td>
<td>Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.auto_refresh_maxioerrors">auto_refresh_maxioerrors</a></td>
<td>Maximale IO Fehler fuer auto_refresh.</td>
<td><a style="color:#0000FF" href="#RevPiModIO._set_maxioerrors">_set_maxioerrors</a></td>
<td>Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.auto_refresh_resetioerrors">auto_refresh_resetioerrors</a></td>
<td>Setzt aktuellen IOError-Zaehler auf 0 zurueck.</td>
<td><a style="color:#0000FF" href="#RevPiModIO.autorefresh_all">autorefresh_all</a></td>
<td>Setzt alle Devices in autorefresh Funktion.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.cleanup">cleanup</a></td>
<td>Beendet auto_refresh und alle Threads.</td>
<td>Beendet autorefresh und alle Threads.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.cycleloop">cycleloop</a></td>
<td>Startet den Cycleloop.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.exit">exit</a></td>
<td>Beendet mainloop() und optional auto_refresh.</td>
<td>Beendet mainloop() und optional autorefresh.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.get_jconfigrsc">get_jconfigrsc</a></td>
<td>Laed die piCotry Konfiguration und erstellt ein dict().</td>
@@ -128,6 +137,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO.readprocimg">readprocimg</a></td>
<td>Einlesen aller Inputs aller/eines Devices vom Prozessabbild.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.resetioerrors">resetioerrors</a></td>
<td>Setzt aktuellen IOError-Zaehler auf 0 zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.setdefaultvalues">setdefaultvalues</a></td>
<td>Alle Outputbuffer werden auf die piCtory default Werte gesetzt.</td>
</tr><tr>
@@ -156,7 +168,7 @@ Instantiiert die Grundfunktionen.
<dt><i>kwargs</i></dt>
<dd>
Weitere Parameter:
- auto_refresh: Wenn True, alle Devices zu auto_refresh hinzufuegen
- autorefresh: Wenn True, alle Devices zu autorefresh hinzufuegen
- configrsc: Pfad zur piCtory Konfigurationsdatei
- procimg: Pfad zum Prozessabbild
- monitoring: In- und Outputs werden gelesen, niemals geschrieben
@@ -218,6 +230,17 @@ Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.
<dd>
Millisekunden
</dd>
</dl><a NAME="RevPiModIO._get_ioerrors" ID="RevPiModIO._get_ioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_ioerrors</h3>
<b>_get_ioerrors</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Aktuelle Anzahl gezaehlter Fehler
</dd>
</dl><a NAME="RevPiModIO._get_length" ID="RevPiModIO._get_length"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_length</h3>
@@ -229,6 +252,17 @@ Getter function.
<dd>
Laenge in Bytes der Devices
</dd>
</dl><a NAME="RevPiModIO._get_maxioerrors" ID="RevPiModIO._get_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_maxioerrors</h3>
<b>_get_maxioerrors</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="RevPiModIO._get_monitoring" ID="RevPiModIO._get_monitoring"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_monitoring</h3>
@@ -262,7 +296,13 @@ Getter function.
<dd>
True, wenn als Simulator gestartet
</dd>
</dl><a NAME="RevPiModIO._set_cycletime" ID="RevPiModIO._set_cycletime"></a>
</dl><a NAME="RevPiModIO._gotioerror" ID="RevPiModIO._gotioerror"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._gotioerror</h3>
<b>_gotioerror</b>(<i>action</i>)
<p>
IOError Verwaltung fuer Prozessabbildzugriff.
</p><a NAME="RevPiModIO._set_cycletime" ID="RevPiModIO._set_cycletime"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._set_cycletime</h3>
<b>_set_cycletime</b>(<i>milliseconds</i>)
@@ -273,34 +313,29 @@ Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.
<dd>
int() in Millisekunden
</dd>
</dl><a NAME="RevPiModIO.auto_refresh_maxioerrors" ID="RevPiModIO.auto_refresh_maxioerrors"></a>
</dl><a NAME="RevPiModIO._set_maxioerrors" ID="RevPiModIO._set_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.auto_refresh_maxioerrors</h3>
<b>auto_refresh_maxioerrors</b>(<i>value=None</i>)
RevPiModIO._set_maxioerrors</h3>
<b>_set_maxioerrors</b>(<i>value</i>)
<p>
Maximale IO Fehler fuer auto_refresh.
Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.
</p><dl>
<dt><i>value</i></dt>
<dd>
Setzt maximale Anzahl bis exception ausgeloest wird
Anzahl erlaubte Fehler
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Maximale Anzahl bis exception ausgeloest wird
</dd>
</dl><a NAME="RevPiModIO.auto_refresh_resetioerrors" ID="RevPiModIO.auto_refresh_resetioerrors"></a>
</dl><a NAME="RevPiModIO.autorefresh_all" ID="RevPiModIO.autorefresh_all"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.auto_refresh_resetioerrors</h3>
<b>auto_refresh_resetioerrors</b>(<i></i>)
RevPiModIO.autorefresh_all</h3>
<b>autorefresh_all</b>(<i></i>)
<p>
Setzt aktuellen IOError-Zaehler auf 0 zurueck.
Setzt alle Devices in autorefresh Funktion.
</p><a NAME="RevPiModIO.cleanup" ID="RevPiModIO.cleanup"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.cleanup</h3>
<b>cleanup</b>(<i></i>)
<p>
Beendet auto_refresh und alle Threads.
Beendet autorefresh und alle Threads.
</p><a NAME="RevPiModIO.cycleloop" ID="RevPiModIO.cycleloop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.cycleloop</h3>
@@ -321,19 +356,18 @@ Startet den Cycleloop.
revpimodio.exit().
</p><p>
HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen
die eingestellte auto_refresh Zeit, bzw. uebergebene cycletime nicht
die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht
ueberschreiten!
</p><p>
Ueber den Parameter cycletime kann die Aktualisierungsrate fuer das
Prozessabbild gesetzt werden (selbe Funktion wie
set_refreshtime(milliseconds)).
Ueber das Attribut cycletime kann die Aktualisierungsrate fuer das
Prozessabbild gesetzt werden.
</p><dl>
<dt><i>func</i></dt>
<dd>
Funktion, die ausgefuehrt werden soll
</dd><dt><i>cycletime</i></dt>
<dd>
auto_refresh Wert in Millisekunden
autorefresh Wert in Millisekunden
</dd>
</dl><dl>
<dt>Returns:</dt>
@@ -345,18 +379,18 @@ None
RevPiModIO.exit</h3>
<b>exit</b>(<i>full=True</i>)
<p>
Beendet mainloop() und optional auto_refresh.
Beendet mainloop() und optional autorefresh.
</p><p>
Wenn sich das Programm im mainloop() befindet, wird durch Aufruf
von exit() die Kontrolle wieder an das Hauptprogramm zurueckgegeben.
</p><p>
Der Parameter full ist mit True vorbelegt und entfernt alle Devices aus
dem auto_refresh. Der Thread fuer die Prozessabbildsynchronisierung
dem autorefresh. Der Thread fuer die Prozessabbildsynchronisierung
wird dann gestoppt und das Programm kann sauber beendet werden.
</p><dl>
<dt><i>full</i></dt>
<dd>
Entfernt auch alle Devices aus auto_refresh
Entfernt auch alle Devices aus autorefresh
</dd>
</dl><a NAME="RevPiModIO.get_jconfigrsc" ID="RevPiModIO.get_jconfigrsc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -452,7 +486,13 @@ nur auf einzelnes Device anwenden
<dd>
True, wenn Arbeiten an allen Devices erfolgreich waren
</dd>
</dl><a NAME="RevPiModIO.setdefaultvalues" ID="RevPiModIO.setdefaultvalues"></a>
</dl><a NAME="RevPiModIO.resetioerrors" ID="RevPiModIO.resetioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.resetioerrors</h3>
<b>resetioerrors</b>(<i></i>)
<p>
Setzt aktuellen IOError-Zaehler auf 0 zurueck.
</p><a NAME="RevPiModIO.setdefaultvalues" ID="RevPiModIO.setdefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.setdefaultvalues</h3>
<b>setdefaultvalues</b>(<i>force=False, device=None</i>)

View File

@@ -32,7 +32,7 @@ revpimodio2.device.Core.temperatur?4()
revpimodio2.device.Core.unconfdevice?4()
revpimodio2.device.Device._buildio?5(dict_io, iotype)
revpimodio2.device.Device._devconfigure?5()
revpimodio2.device.Device.auto_refresh?4(remove=False)
revpimodio2.device.Device.autorefresh?4(remove=False)
revpimodio2.device.Device.get_allios?4()
revpimodio2.device.Device.get_inps?4()
revpimodio2.device.Device.get_mems?4()
@@ -52,18 +52,24 @@ revpimodio2.helper.Cycletools?1()
revpimodio2.helper.EventCallback.run?4()
revpimodio2.helper.EventCallback.stop?4()
revpimodio2.helper.EventCallback?1(func, name, value)
revpimodio2.helper.ProcimgWriter._get_ioerrors?5()
revpimodio2.helper.ProcimgWriter._gotioerror?5()
revpimodio2.helper.ProcimgWriter.get_maxioerrors?4()
revpimodio2.helper.ProcimgWriter.get_refresh?4()
revpimodio2.helper.ProcimgWriter.ioerrors?7
revpimodio2.helper.ProcimgWriter.maxioerrors?7
revpimodio2.helper.ProcimgWriter.refresh?7
revpimodio2.helper.ProcimgWriter.run?4()
revpimodio2.helper.ProcimgWriter.set_maxioerrors?4(value)
revpimodio2.helper.ProcimgWriter.set_refresh?4(value)
revpimodio2.helper.ProcimgWriter.stop?4()
revpimodio2.helper.ProcimgWriter?1(parentmodio)
revpimodio2.io.IOBase._get_address?5()
revpimodio2.io.IOBase._get_byteorder?5()
revpimodio2.io.IOBase._get_length?5()
revpimodio2.io.IOBase._get_name?5()
revpimodio2.io.IOBase.address?7
revpimodio2.io.IOBase.get_address?4()
revpimodio2.io.IOBase.get_length?4()
revpimodio2.io.IOBase.get_name?4()
revpimodio2.io.IOBase.byteorder?7
revpimodio2.io.IOBase.get_value?4()
revpimodio2.io.IOBase.length?7
revpimodio2.io.IOBase.name?7
@@ -73,8 +79,9 @@ revpimodio2.io.IOBase.set_value?4(value)
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)
revpimodio2.io.IOList._register_new_io_object?5(new_io)
revpimodio2.io.IOBase?1(parentdevice, valuelist, iotype, byteorder, signed)
revpimodio2.io.IOList._getdict?5()
revpimodio2.io.IOList._private_register_new_io_object?5(new_io)
revpimodio2.io.IOList._testme?5()
revpimodio2.io.IOList?1()
revpimodio2.io.IntIO._get_signed?5()
@@ -85,22 +92,26 @@ revpimodio2.io.IntIO.get_int?4()
revpimodio2.io.IntIO.set_int?4(value)
revpimodio2.io.IntIO.signed?7
revpimodio2.io.IntIO.value?7
revpimodio2.io.StructIO.byteorder?7
revpimodio2.io.StructIO._get_signed?5()
revpimodio2.io.StructIO.get_structvalue?4()
revpimodio2.io.StructIO.set_structvalue?4(value)
revpimodio2.io.StructIO.signed?7
revpimodio2.io.StructIO.value?7
revpimodio2.io.StructIO?1(parentio, name, iotype, byteorder, frm, **kwargs)
revpimodio2.io.StructIO?1(parentio, name, frm, **kwargs)
revpimodio2.modio.RevPiModIO._configure?5()
revpimodio2.modio.RevPiModIO._create_myfh?5()
revpimodio2.modio.RevPiModIO._get_configrsc?5()
revpimodio2.modio.RevPiModIO._get_cycletime?5()
revpimodio2.modio.RevPiModIO._get_ioerrors?5()
revpimodio2.modio.RevPiModIO._get_length?5()
revpimodio2.modio.RevPiModIO._get_maxioerrors?5()
revpimodio2.modio.RevPiModIO._get_monitoring?5()
revpimodio2.modio.RevPiModIO._get_procimg?5()
revpimodio2.modio.RevPiModIO._get_simulator?5()
revpimodio2.modio.RevPiModIO._gotioerror?5(action)
revpimodio2.modio.RevPiModIO._set_cycletime?5(milliseconds)
revpimodio2.modio.RevPiModIO.auto_refresh_maxioerrors?4(value=None)
revpimodio2.modio.RevPiModIO.auto_refresh_resetioerrors?4()
revpimodio2.modio.RevPiModIO._set_maxioerrors?5(value)
revpimodio2.modio.RevPiModIO.autorefresh_all?4()
revpimodio2.modio.RevPiModIO.cleanup?4()
revpimodio2.modio.RevPiModIO.configrsc?7
revpimodio2.modio.RevPiModIO.cycleloop?4(func, cycletime=50)
@@ -108,11 +119,14 @@ revpimodio2.modio.RevPiModIO.cycletime?7
revpimodio2.modio.RevPiModIO.exit?4(full=True)
revpimodio2.modio.RevPiModIO.get_jconfigrsc?4()
revpimodio2.modio.RevPiModIO.handlesignalend?4(cleanupfunc=None)
revpimodio2.modio.RevPiModIO.ioerrors?7
revpimodio2.modio.RevPiModIO.length?7
revpimodio2.modio.RevPiModIO.mainloop?4(freeze=False, blocking=True)
revpimodio2.modio.RevPiModIO.maxioerrors?7
revpimodio2.modio.RevPiModIO.monitoring?7
revpimodio2.modio.RevPiModIO.procimg?7
revpimodio2.modio.RevPiModIO.readprocimg?4(force=False, device=None)
revpimodio2.modio.RevPiModIO.resetioerrors?4()
revpimodio2.modio.RevPiModIO.setdefaultvalues?4(force=False, device=None)
revpimodio2.modio.RevPiModIO.simulator?7
revpimodio2.modio.RevPiModIO.syncoutputs?4(force=False, device=None)

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-15, 08:04:54 -->
<!-- Saved: 2017-08-16, 17:05:08 -->
<!-- Copyright (C) 2017 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
@@ -25,6 +25,7 @@
<Source>test/test_dio_while2.py</Source>
<Source>test/test_dio_mainloop.py</Source>
<Source>test/test_dio_cycleloop.py</Source>
<Source>revpimodio2/net.py</Source>
</Sources>
<Forms/>
<Translations/>
@@ -173,6 +174,7 @@
<value>
<list>
<string>setup.py</string>
<string>net.py</string>
</list>
</value>
<key>
@@ -219,6 +221,7 @@
<value>
<list>
<string>setup.py</string>
<string>net.py</string>
</list>
</value>
<key>

View File

@@ -25,8 +25,10 @@ class DeviceList(object):
@return True, wenn Device vorhanden"""
if type(key) == int:
return key in self.__dict_position
else:
elif type(key) == str:
return hasattr(self, key)
else:
return key in self.__dict_position.values()
def __getitem__(self, key):
"""Gibt angegebenes Device zurueck.
@@ -61,13 +63,11 @@ class DeviceList(object):
class Device(object):
"""Basisklasse fuer alle Device-Objekte der RevPiDevicelist()-Klasse.
"""Basisklasse fuer alle Device-Objekte.
Die Basisfunktionalitaet generiert bei Instantiierung alle IOs und
erweitert den Prozessabbildpuffer um die benoetigten Bytes. Ueber diese
Klasse oder von dieser abgeleiteten Klassen, werden alle IOs angesprochen.
Sie verwaltet ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung
der IO-Werte.
erweitert den Prozessabbildpuffer um die benoetigten Bytes. Sie verwaltet
ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung der IO-Werte.
"""
@@ -78,7 +78,7 @@ class Device(object):
@param dict_device dict() fuer dieses Device aus piCotry Konfiguration
@param kwargs Weitere Parameter:
- autoupdate: Wenn True fuehrt dieses Device Arbeiten am
Prozessabbild bei Aufruf der RevPiDevicelist-Funktionen aus
Prozessabbild bei Aufruf der read- writeprocimg Funktionen aus
- simulator: Laed das Modul als Simulator und vertauscht IOs
"""
@@ -87,7 +87,6 @@ class Device(object):
self._dict_events = {}
self._filelock = Lock()
self._length = 0
self._lst_io = []
self._selfupdate = False
self.autoupdate = kwargs.get("autoupdate", True)
@@ -98,11 +97,7 @@ class Device(object):
self.position = int(dict_device.pop("position"))
self.producttype = int(dict_device.pop("productType"))
# Neues bytearray und Kopie für mainloop anlegen
self._ba_devdata = bytearray()
self._ba_datacp = bytearray()
# Erst inp/out/mem poppen, dann in Klasse einfügen
# IOM-Objekte erstellen und Adressen in SLCs speichern
if kwargs.get("simulator", False):
self.slc_inp = self._buildio(dict_device.pop("out"), IOType.INP)
self.slc_out = self._buildio(dict_device.pop("inp"), IOType.OUT)
@@ -123,6 +118,11 @@ class Device(object):
self.slc_mem.start + self.offset, self.slc_mem.stop + self.offset
)
# Neues bytearray und Kopie für mainloop anlegen
# NOTE: Testen
self._ba_devdata = bytearray(self._length)
self._ba_datacp = bytearray()
# Alle restlichen attribute an Klasse anhängen
self.__dict__.update(dict_device)
@@ -156,8 +156,8 @@ class Device(object):
def __iter__(self):
"""Gibt Iterator aller IOs zurueck.
@return iter() aller IOs"""
for i_byte in range(self.slc_devoff.start, self.slc_devoff.stop):
for io in self._modio.io[i_byte]:
for lst_io in self._modio.io[self.slc_devoff]:
for io in lst_io:
yield io
def __len__(self):
@@ -178,7 +178,9 @@ class Device(object):
@return slice()-Objekt mit Start und Stop Position dieser IOs
"""
if len(dict_io) > 0:
if len(dict_io) <= 0:
return slice(0, 0)
int_min, int_max = 4096, 0
for key in sorted(dict_io, key=lambda x: int(x)):
@@ -186,24 +188,18 @@ class Device(object):
if bool(dict_io[key][7]) or self.producttype == 95:
# Bei Bitwerten oder Core RevPiIOBase verwenden
io_new = iomodule.IOBase(
self,
dict_io[key],
iotype,
byteorder="little"
self, dict_io[key], iotype, "little", False
)
else:
io_new = iomodule.IntIO(
self,
dict_io[key],
self, dict_io[key],
iotype,
byteorder="little"
"little",
self.producttype == 103
)
# IO registrieren
self._modio.io._register_new_io_object(io_new)
# Speicherbereich zuweisen
self._ba_devdata.extend(bytes(io_new._length))
self._modio.io._private_register_new_io_object(io_new)
self._length += io_new._length
@@ -215,15 +211,12 @@ class Device(object):
return slice(int_min, int_max)
else:
return slice(0, 0)
def _devconfigure(self):
"""Funktion zum ueberschreiben von abgeleiteten Klassen."""
pass
def auto_refresh(self, remove=False):
"""Registriert ein Device fuer die automatische Synchronisierung.
def autorefresh(self, remove=False):
"""Registriert dieses Device fuer die automatische Synchronisierung.
@param remove bool() True entfernt Device aus Synchronisierung"""
if not remove and self not in self._modio._lst_refresh:
@@ -266,36 +259,37 @@ class Device(object):
self._modio.writeprocimg(True, self)
def get_allios(self):
"""Gibt eine Liste aller Inputs und Outputs zurueck.
"""Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
@return list() Input und Output, keine MEMs"""
return [
io for io in self._modio.io
if io._parentdevice == self and io._iotype != IOType.MEM
]
lst_return = []
for lst_io in self._modio.io[
self.slc_inpoff.start:self.slc_outoff.stop]:
lst_return += lst_io
return lst_return
def get_inps(self):
"""Gibt eine Liste aller Inputs zurueck.
@return list() Inputs"""
return [
io for io in self._modio.io
if io._parentdevice == self and io._iotype == IOType.INP
]
lst_return = []
for lst_io in self._modio.io[self.slc_inpoff]:
lst_return += lst_io
return lst_return
def get_outs(self):
"""Gibt eine Liste aller Outputs zurueck.
@return list() Outputs"""
return [
io for io in self._modio.io
if io._parentdevice == self and io._iotype == IOType.OUT
]
lst_return = []
for lst_io in self._modio.io[self.slc_outoff]:
lst_return += lst_io
return lst_return
def get_mems(self):
"""Gibt eine Liste aller mems zurueck.
@return list() Mems"""
return [
io for io in self._modio.io
if io._parentdevice == self and io._iotype == IOType.MEM
]
lst_return = []
for lst_io in self._modio.io[self.slc_memoff]:
lst_return += lst_io
return lst_return
class Core(Device):

View File

@@ -228,22 +228,27 @@ class ProcimgWriter(Thread):
super().__init__()
self._adjwait = 0
self._ioerror = 0
self._maxioerrors = 0
self._modio = parentmodio
self._refresh = 0.05
self._work = Event()
self.daemon = True
self.lck_refresh = Lock()
self.maxioerrors = 0
self.newdata = Event()
def _get_ioerrors(self):
"""Ruft aktuelle Anzahl der Fehler ab.
@return Aktuelle Fehleranzahl"""
return self._ioerror
def _gotioerror(self):
"""IOError Verwaltung fuer auto_refresh."""
"""IOError Verwaltung fuer autorefresh."""
self._ioerror += 1
if self.maxioerrors != 0 and self._ioerror >= self.maxioerrors:
if self._maxioerrors != 0 and self._ioerror >= self._maxioerrors:
raise RuntimeError(
"reach max io error count {} on process image".format(
self.maxioerrors
self._maxioerrors
)
)
warnings.warn(
@@ -251,6 +256,11 @@ class ProcimgWriter(Thread):
RuntimeWarning
)
def get_maxioerrors(self):
"""Gibt die Anzahl der maximal erlaubten Fehler zurueck.
@return Anzahl erlaubte Fehler"""
return self._maxioerrors
def get_refresh(self):
"""Gibt Zykluszeit zurueck.
@return int() Zykluszeit in Millisekunden"""
@@ -342,15 +352,26 @@ class ProcimgWriter(Thread):
"""Beendet die automatische Prozessabbildsynchronisierung."""
self._work.set()
def set_maxioerrors(self, value):
"""Setzt die Anzahl der maximal erlaubten Fehler.
@param value Anzahl erlaubte Fehler"""
if type(value) == int and value >= 0:
self._maxioerrors = value
else:
raise ValueError("value must be 0 or a positive integer")
def set_refresh(self, value):
"""Setzt die Zykluszeit in Millisekunden.
@param value int() Millisekunden"""
if value >= 10 and value < 2000:
if type(value) == int and 10 <= value <= 2000:
waitdiff = self._refresh - self._adjwait
self._refresh = value / 1000
self._adjwait = self._refresh
self._adjwait = self._refresh - waitdiff
else:
raise ValueError(
"refresh time must be 10 to 2000 milliseconds"
)
ioerrors = property(_get_ioerrors)
maxioerrors = property(get_maxioerrors, set_maxioerrors)
refresh = property(get_refresh, set_refresh)

View File

@@ -46,7 +46,7 @@ class IOList(object):
object.__delattr__(self, key)
def __getattr__(self, key):
"""Verwaltet geloeschte IOs.
"""Verwaltet geloeschte IOs (Attribute, die nicht existieren).
@param key Wert eines alten IOs
@return Alten IO, wenn in Ref-Listen"""
if key in self.__dict_iorefname:
@@ -65,6 +65,11 @@ class IOList(object):
return self.__dict_iobyte[key]
else:
raise KeyError("byte '{}' does not exist".format(key))
elif type(key) == slice:
return [
self.__dict_iobyte[int_io]
for int_io in range(key.start, key.stop)
]
else:
return getattr(self, key)
@@ -105,12 +110,11 @@ class IOList(object):
"_IOList__dict_iorefbyte"
]:
object.__setattr__(self, key, value)
else:
# Setzt Wert bei Zuweisung
getattr(self, key).value = value
def __replace_oldio_with_newio(self, io):
def __private_replace_oldio_with_newio(self, io):
"""Ersetzt bestehende IOs durch den neu Registrierten.
@param io Neuer IO der eingefuegt werden soll"""
for i in range(io.slc_address.start, io.slc_address.stop):
@@ -125,7 +129,6 @@ class IOList(object):
io._bitaddress, oldio._name
)
)
else:
# Bereits überschriebene bytes() sind ungültig
raise MemoryError(
@@ -133,7 +136,6 @@ class IOList(object):
io._name, oldio._name
)
)
elif oldio is not None:
# IOs im Speicherbereich des neuen IO merken
if io._bitaddress >= 0:
@@ -144,7 +146,7 @@ class IOList(object):
# ios aus listen entfernen
delattr(self, oldio.name)
def _register_new_io_object(self, new_io):
def _private_register_new_io_object(self, new_io):
"""Registriert neues IO Objekt unabhaenging von __setattr__.
@param new_io Neues IO Objekt"""
if issubclass(type(new_io), IOBase):
@@ -156,7 +158,7 @@ class IOList(object):
)
if type(new_io) is StructIO:
self.__replace_oldio_with_newio(new_io)
self.__private_replace_oldio_with_newio(new_io)
object.__setattr__(self, new_io.name, new_io)
@@ -181,6 +183,10 @@ class IOList(object):
print(self.__dict_iorefname)
print(self.__dict_iorefbyte)
def _getdict(self):
# NOTE: Nur Debugging
return self.__dict_iobyte.copy()
class IOBase(object):
@@ -196,13 +202,14 @@ class IOBase(object):
"""
def __init__(self, parentdevice, valuelist, iotype, byteorder):
def __init__(self, parentdevice, valuelist, iotype, byteorder, signed):
"""Instantiierung der IOBase()-Klasse.
@param parentdevice Parentdevice auf dem der IO liegt
@param valuelist Datenliste fuer Instantiierung
@param iotype IOType() Wert
@param byteorder Byteorder 'little' / 'big' fuer int() Berechnung
@param sigend Intberechnung mit Vorzeichen durchfuehren
"""
self._parentdevice = parentdevice
@@ -217,7 +224,7 @@ class IOBase(object):
self._byteorder = byteorder
self._iotype = iotype
self._name = valuelist[0]
self._signed = False
self._signed = signed
self.bmk = valuelist[6]
int_startaddress = int(valuelist[3])
@@ -274,22 +281,22 @@ class IOBase(object):
@return Namen des IOs"""
return self._name
def _get_address(self):
"""Gibt die absolute Byteadresse im Prozessabbild zurueck.
@return Absolute Byteadresse"""
return self._parentdevice.offset + self.slc_address.start
def _get_byteorder(self):
"""Gibt konfigurierte Byteorder zurueck.
@return str() Byteorder"""
return self._byteorder
def get_address(self):
"""Gibt die absolute Byteadresse im Prozessabbild zurueck.
@return Absolute Byteadresse"""
return self._parentdevice.offset + self.slc_address.start
def get_length(self):
def _get_length(self):
"""Gibt die Bytelaenge des IO zurueck.
@return Bytelaenge des IO"""
return self._length
def get_name(self):
def _get_name(self):
"""Gibt den Namen des IOs zurueck.
@return IO Name"""
return self._name
@@ -384,12 +391,10 @@ class IOBase(object):
io_new = StructIO(
self,
name,
self._iotype,
kwargs.get("byteorder", "little"),
frm,
**kwargs
)
self._parentdevice._modio.io._register_new_io_object(io_new)
self._parentdevice._modio.io._private_register_new_io_object(io_new)
# Optional Event eintragen
reg_event = kwargs.get("event", None)
@@ -473,7 +478,7 @@ class IOBase(object):
"""Wartet auf Wertaenderung eines IOs.
Die Wertaenderung wird immer uerberprueft, wenn fuer Devices
in Devicelist.auto_refresh() neue Daten gelesen wurden.
mit aktiviertem autorefresh neue Daten gelesen wurden.
Bei Wertaenderung, wird das Warten mit 0 als Rueckgabewert beendet.
@@ -493,7 +498,7 @@ class IOBase(object):
Der Timeoutwert bricht beim Erreichen das Warten sofort mit
Wert 2 Rueckgabewert ab. (Das Timeout wird ueber die Zykluszeit
der auto_refresh Funktion berechnet, entspricht also nicht exact den
der autorefresh Funktion berechnet, entspricht also nicht exact den
angegeben Millisekunden! Es wird immer nach oben gerundet!)
@param edge Flanke RISING, FALLING, BOTH bei der mit True beendet wird
@@ -510,10 +515,10 @@ class IOBase(object):
Wert 100: Devicelist.exit() wurde aufgerufen
"""
# Prüfen ob Device in auto_refresh ist
# Prüfen ob Device in autorefresh ist
if not self._parentdevice._selfupdate:
raise RuntimeError(
"auto_refresh is not activated for device '{}|{}' - there "
"autorefresh is not activated for device '{}|{}' - there "
"will never be new data".format(
self._parentdevice.position, self._parentdevice.name
)
@@ -570,9 +575,10 @@ class IOBase(object):
# Timeout abgelaufen
return 2
address = property(get_address)
length = property(get_length)
name = property(get_name)
address = property(_get_address)
byteorder = property(_get_byteorder)
length = property(_get_length)
name = property(_get_name)
value = property(get_value, set_value)
@@ -651,29 +657,28 @@ class StructIO(IOBase):
"""
def __init__(self, parentio, name, iotype, byteorder, frm, **kwargs):
def __init__(self, parentio, name, frm, **kwargs):
"""Erstellt einen IO mit struct-Formatierung.
@param parentio ParentIO Objekt, welches ersetzt wird
@param name Name des neuen IO
@param iotype IOType() Wert
@param byteorder Byteorder 'little' / 'big' fuer int() Berechnung
@param frm struct() formatierung (1 Zeichen)
@param kwargs Weitere Parameter:
- bmk: Bezeichnung fuer Output
- bit: Registriert Outputs als bool() am angegebenen Bit im Byte
- byteorder: Byteorder fuer den Input, Standardwert=little
- defaultvalue: Standardwert fuer Output, Standard ist 0
"""
if len(frm) == 1:
# Byteorder prüfen und übernehmen
byteorder = kwargs.get("byteorder", "little")
if not (byteorder == "little" or byteorder == "big"):
raise ValueError("byteorder must be 'little' or 'big'")
bofrm = "<" if byteorder == "little" else ">"
bitaddress = "" if frm != "?" else str(kwargs.get("bit", 0))
if bitaddress == "" or \
(int(bitaddress) >= 0 and int(bitaddress) < 8):
if bitaddress == "" or (0 <= int(bitaddress) < 8):
bitlength = "1" if bitaddress.isnumeric() else \
struct.calcsize(bofrm + frm) * 8
@@ -698,19 +703,31 @@ class StructIO(IOBase):
raise AttributeError("parameter frm has to be a single sign")
# Basisklasse instantiieren
super().__init__(parentio._parentdevice, valuelist, iotype, byteorder)
# parentdevice, valuelist, iotype, byteorder, signed
super().__init__(
parentio._parentdevice,
valuelist,
parentio._iotype,
byteorder,
frm == frm.lower()
)
self.frm = frm
# Platz für neuen IO prüfen
if not (self.slc_address.start >=
parentio._parentdevice._dict_slc[iotype].start and
parentio._parentdevice._dict_slc[parentio._iotype].start and
self.slc_address.stop <=
parentio._parentdevice._dict_slc[iotype].stop):
parentio._parentdevice._dict_slc[parentio._iotype].stop):
raise BufferError(
"registered value does not fit process image scope"
)
def _get_signed(self):
"""Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
@return True, wenn Vorzeichenbehaftet"""
return self._signed
def get_structvalue(self):
"""Gibt den Wert mit struct Formatierung zurueck.
@return Wert vom Typ der struct-Formatierung"""
@@ -727,7 +744,7 @@ class StructIO(IOBase):
else:
self.set_value(struct.pack(self.frm, value))
byteorder = property(IOBase._get_byteorder)
signed = property(_get_signed)
value = property(get_structvalue, set_structvalue)

View File

@@ -37,7 +37,7 @@ class RevPiModIO(object):
"""Instantiiert die Grundfunktionen.
@param kwargs Weitere Parameter:
- auto_refresh: Wenn True, alle Devices zu auto_refresh hinzufuegen
- autorefresh: Wenn True, alle Devices zu autorefresh hinzufuegen
- configrsc: Pfad zur piCtory Konfigurationsdatei
- procimg: Pfad zum Prozessabbild
- monitoring: In- und Outputs werden gelesen, niemals geschrieben
@@ -45,7 +45,7 @@ class RevPiModIO(object):
- syncoutputs: Aktuell gesetzte Outputs vom Prozessabbild einlesen
"""
self._auto_refresh = kwargs.get("auto_refresh", False)
self._autorefresh = kwargs.get("autorefresh", False)
self._configrsc = kwargs.get("configrsc", None)
self._monitoring = kwargs.get("monitoring", False)
self._procimg = kwargs.get("procimg", "/dev/piControl0")
@@ -59,10 +59,12 @@ class RevPiModIO(object):
self._buffedwrite = False
self._exit = Event()
self._imgwriter = None
self._ioerror = 0
self._length = 0
self._looprunning = False
self._lst_devselect = []
self._lst_refresh = []
self._maxioerrors = 0
self._myfh = self._create_myfh()
self._th_mainloop = None
self._waitexit = Event()
@@ -209,10 +211,9 @@ class RevPiModIO(object):
if self._syncoutputs:
self.syncoutputs(force=True)
# Optional ins auto_refresh aufnehmen
if self._auto_refresh:
for dev in self.device:
dev.auto_refresh()
# Optional ins autorefresh aufnehmen
if self._autorefresh:
self.autorefresh_all()
# Summary Klasse instantiieren
self.summary = summarymodule.Summary(jconfigrsc["Summary"])
@@ -233,11 +234,21 @@ class RevPiModIO(object):
@return Millisekunden"""
return self._imgwriter.refresh
def _get_ioerrors(self):
"""Getter function.
@return Aktuelle Anzahl gezaehlter Fehler"""
return self._ioerror
def _get_length(self):
"""Getter function.
@return Laenge in Bytes der Devices"""
return self._length
def _get_maxioerrors(self):
"""Getter function.
@return Anzahl erlaubte Fehler"""
return self._maxioerrors
def _get_monitoring(self):
"""Getter function.
@return True, wenn als Monitoring gestartet"""
@@ -253,26 +264,43 @@ class RevPiModIO(object):
@return True, wenn als Simulator gestartet"""
return self._simulator
def _gotioerror(self, action):
"""IOError Verwaltung fuer Prozessabbildzugriff."""
self._ioerror += 1
if self._maxioerrors != 0 and self._ioerror >= self._maxioerrors:
raise RuntimeError(
"reach max io error count {} on process image".format(
self._maxioerrors
)
)
warnings.warn(
"got io error during {} and count {} errors now".format(
self._ioerror, self._ioerror
),
RuntimeWarning
)
def _set_cycletime(self, milliseconds):
"""Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.
@param milliseconds int() in Millisekunden"""
self._imgwriter.refresh = milliseconds
def auto_refresh_maxioerrors(self, value=None):
"""Maximale IO Fehler fuer auto_refresh.
@param value Setzt maximale Anzahl bis exception ausgeloest wird
@return Maximale Anzahl bis exception ausgeloest wird"""
if value is None:
return self._imgwriter.maxioerrors
elif type(value) == int and value >= 0:
def _set_maxioerrors(self, value):
"""Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.
@param value Anzahl erlaubte Fehler"""
if type(value) == int and value >= 0:
self._maxioerrors = value
self._imgwriter.maxioerrors = value
else:
raise ValueError("value must be 0 or a positive integer")
def auto_refresh_resetioerrors(self):
"""Setzt aktuellen IOError-Zaehler auf 0 zurueck."""
self._imgwriter.maxioerrors = 0
def autorefresh_all(self):
"""Setzt alle Devices in autorefresh Funktion."""
for dev in self.device:
dev.autorefresh()
def cleanup(self):
"""Beendet auto_refresh und alle Threads."""
"""Beendet autorefresh und alle Threads."""
self.exit(full=True)
self._myfh.close()
self.app = None
@@ -297,15 +325,14 @@ class RevPiModIO(object):
revpimodio.exit().
HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen
die eingestellte auto_refresh Zeit, bzw. uebergebene cycletime nicht
die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht
ueberschreiten!
Ueber den Parameter cycletime kann die Aktualisierungsrate fuer das
Prozessabbild gesetzt werden (selbe Funktion wie
set_refreshtime(milliseconds)).
Ueber das Attribut cycletime kann die Aktualisierungsrate fuer das
Prozessabbild gesetzt werden.
@param func Funktion, die ausgefuehrt werden soll
@param cycletime auto_refresh Wert in Millisekunden
@param cycletime autorefresh Wert in Millisekunden
@return None
"""
@@ -315,9 +342,9 @@ class RevPiModIO(object):
"can not start multiple loops mainloop/cycleloop"
)
# Prüfen ob Devices in auto_refresh sind
# Prüfen ob Devices in autorefresh sind
if len(self._lst_refresh) == 0:
raise RuntimeError("no device with auto_refresh activated")
raise RuntimeError("no device with autorefresh activated")
# Prüfen ob Funktion callable ist
if not callable(func):
@@ -337,18 +364,18 @@ class RevPiModIO(object):
# 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():
raise RuntimeError("auto_refresh thread not running")
raise RuntimeError("autorefresh thread not running")
continue
self._imgwriter.newdata.clear()
# Vor Aufruf der Funktion auto_refresh sperren
# Vor Aufruf der Funktion autorefresh sperren
self._imgwriter.lck_refresh.acquire()
# Funktion aufrufen und auswerten
ec = func(cycleinfo)
cycleinfo._docycle()
# auto_refresh freigeben
# autorefresh freigeben
self._imgwriter.lck_refresh.release()
# Cycleloop beenden
@@ -357,16 +384,16 @@ class RevPiModIO(object):
return ec
def exit(self, full=True):
"""Beendet mainloop() und optional auto_refresh.
"""Beendet mainloop() und optional autorefresh.
Wenn sich das Programm im mainloop() befindet, wird durch Aufruf
von exit() die Kontrolle wieder an das Hauptprogramm zurueckgegeben.
Der Parameter full ist mit True vorbelegt und entfernt alle Devices aus
dem auto_refresh. Der Thread fuer die Prozessabbildsynchronisierung
dem autorefresh. Der Thread fuer die Prozessabbildsynchronisierung
wird dann gestoppt und das Programm kann sauber beendet werden.
@param full Entfernt auch alle Devices aus auto_refresh"""
@param full Entfernt auch alle Devices aus autorefresh"""
self._exit.set()
self._waitexit.set()
if full:
@@ -469,9 +496,9 @@ class RevPiModIO(object):
"can not start multiple loops mainloop/cycleloop"
)
# Prüfen ob Devices in auto_refresh sind
# Prüfen ob Devices in autorefresh sind
if len(self._lst_refresh) == 0:
raise RuntimeError("no device with auto_refresh activated")
raise RuntimeError("no device with autorefresh activated")
# Thread erstellen, wenn nicht blockieren soll
if not blocking:
@@ -498,7 +525,7 @@ class RevPiModIO(object):
# 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():
raise RuntimeError("auto_refresh thread not running")
raise RuntimeError("autorefresh thread not running")
continue
self._imgwriter.newdata.clear()
@@ -593,7 +620,7 @@ class RevPiModIO(object):
if dev._selfupdate:
raise RuntimeError(
"can not read process image, while device '{}|{}'"
"is in auto_refresh mode".format(dev.position, dev.name)
"is in autorefresh mode".format(dev.position, dev.name)
)
mylist = [dev]
@@ -602,10 +629,7 @@ class RevPiModIO(object):
self._myfh.seek(0)
bytesbuff = self._myfh.read(self._length)
except IOError:
warnings.warn(
"read error on process image '{}'".format(self.myfh.name),
RuntimeWarning
)
self._gotioerror("read")
return False
for dev in mylist:
@@ -628,6 +652,11 @@ class RevPiModIO(object):
return True
def resetioerrors(self):
"""Setzt aktuellen IOError-Zaehler auf 0 zurueck."""
self._ioerror = 0
self._imgwriter._ioerror = 0
def setdefaultvalues(self, force=False, device=None):
"""Alle Outputbuffer werden auf die piCtory default Werte gesetzt.
@param force auch Devices mit autoupdate=False
@@ -667,7 +696,7 @@ class RevPiModIO(object):
if dev._selfupdate:
raise RuntimeError(
"can not sync process image, while device '{}|{}'"
"is in auto_refresh mode".format(dev.position, dev.name)
"is in autorefresh mode".format(dev.position, dev.name)
)
mylist = [dev]
@@ -675,10 +704,7 @@ class RevPiModIO(object):
self._myfh.seek(0)
bytesbuff = self._myfh.read(self._length)
except IOError:
warnings.warn(
"read error on process image '{}'".format(self._myfh.name),
RuntimeWarning
)
self._gotioerror("read")
return False
for dev in mylist:
@@ -731,11 +757,7 @@ class RevPiModIO(object):
if self._buffedwrite:
self._myfh.flush()
except IOError:
warnings.warn(
"write error on process image '{}'"
"".format(self._myfh.name),
RuntimeWarning
)
self._gotioerror("write")
workokay = False
dev._filelock.release()
@@ -764,7 +786,7 @@ class RevPiModIO(object):
if dev._selfupdate:
raise RuntimeError(
"can not write process image, while device '{}|{}'"
"is in auto_refresh mode".format(dev.position, dev.name)
"is in autorefresh mode".format(dev.position, dev.name)
)
mylist = [dev]
@@ -789,17 +811,15 @@ class RevPiModIO(object):
workokay = False
if not workokay:
warnings.warn(
"write error on process image '{}'"
"".format(self._myfh.name),
RuntimeWarning
)
self._gotioerror("write")
return workokay
configrsc = property(_get_configrsc)
cycletime = property(_get_cycletime, _set_cycletime)
ioerrors = property(_get_ioerrors)
length = property(_get_length)
maxioerrors = property(_get_maxioerrors, _set_maxioerrors)
monitoring = property(_get_monitoring)
procimg = property(_get_procimg)
simulator = property(_get_simulator)