Fehlerabfang bei procimg verbessert

Device.autoupdate entfernt (nie verwendet)
RevPiModIO.ioerrors liefert Anzahl von _imgwriter, wenn Loop aktiv ist
RevPiModIO.*procimg force Parameter entfernt, da autoupdate weg ist
RevPiModIO.writeinputdefaults auf device.Virtual verschoben
Docstrings angepasst
alle Slices von Device und IOBase privatisiert _
DeviceList.__delattr__ eingefügt
Bugfix: Byteorder wurde bei StructIO nicht übernommen
Diverse Verbesserungen an DeviceList und IOList
class DeadIO eingefügt
This commit is contained in:
2017-08-21 12:17:49 +02:00
parent 37eb012e16
commit d6dd63a53f
9 changed files with 681 additions and 422 deletions

View File

@@ -38,9 +38,6 @@ Modules</h3>
<td><a style="color:#0000FF" href="revpimodio2.modio.html">modio</a></td> <td><a style="color:#0000FF" href="revpimodio2.modio.html">modio</a></td>
<td>RevPiModIO Hauptklasse.</td> <td>RevPiModIO Hauptklasse.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.netio.html">netio</a></td>
<td></td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.summary.html">summary</a></td> <td><a style="color:#0000FF" href="revpimodio2.summary.html">summary</a></td>
<td>Bildet die Summary-Sektion von piCtory ab.</td> <td>Bildet die Summary-Sektion von piCtory ab.</td>
</tr> </tr>

View File

@@ -66,11 +66,26 @@ Class Methods</h3>
Methods</h3> Methods</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#Core.__errorlimit">__errorlimit</a></td>
<td>Verwaltet das Lesen und Schreiben der ErrorLimits.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core._devconfigure">_devconfigure</a></td> <td><a style="color:#0000FF" href="#Core._devconfigure">_devconfigure</a></td>
<td>Core-Klasse vorbereiten.</td> <td>Core-Klasse vorbereiten.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Core._errorlimit">_errorlimit</a></td> <td><a style="color:#0000FF" href="#Core._get_leda1">_get_leda1</a></td>
<td>Verwaltet das Lesen und Schreiben der ErrorLimits.</td> <td>Gibt den Zustand der LED A1 vom core zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core._get_leda2">_get_leda2</a></td>
<td>Gibt den Zustand der LED A2 vom core zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core._get_status">_get_status</a></td>
<td>Gibt den RevPi Core Status zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core._set_leda1">_set_leda1</a></td>
<td>Setzt den Zustand der LED A1 vom core.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core._set_leda2">_set_leda2</a></td>
<td>Setzt den Zustand der LED A2 vom core.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Core.errorlimit1">errorlimit1</a></td> <td><a style="color:#0000FF" href="#Core.errorlimit1">errorlimit1</a></td>
<td>Setzt RS485 ErrorLimit1 auf neuen Wert.</td> <td>Setzt RS485 ErrorLimit1 auf neuen Wert.</td>
@@ -81,15 +96,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Core.frequency">frequency</a></td> <td><a style="color:#0000FF" href="#Core.frequency">frequency</a></td>
<td>Gibt CPU Taktfrequenz zurueck.</td> <td>Gibt CPU Taktfrequenz zurueck.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Core.get_leda1">get_leda1</a></td>
<td>Gibt den Zustand der LED A1 vom core zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core.get_leda2">get_leda2</a></td>
<td>Gibt den Zustand der LED A2 vom core zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core.get_status">get_status</a></td>
<td>Gibt den RevPi Core Status zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core.iocycle">iocycle</a></td> <td><a style="color:#0000FF" href="#Core.iocycle">iocycle</a></td>
<td>Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck.</td> <td>Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck.</td>
</tr><tr> </tr><tr>
@@ -111,12 +117,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Core.rightgate">rightgate</a></td> <td><a style="color:#0000FF" href="#Core.rightgate">rightgate</a></td>
<td>Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.</td> <td>Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Core.set_leda1">set_leda1</a></td>
<td>Setzt den Zustand der LED A1 vom core.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core.set_leda2">set_leda2</a></td>
<td>Setzt den Zustand der LED A2 vom core.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core.temperatur">temperatur</a></td> <td><a style="color:#0000FF" href="#Core.temperatur">temperatur</a></td>
<td>Gibt CPU-Temperatur zurueck.</td> <td>Gibt CPU-Temperatur zurueck.</td>
</tr><tr> </tr><tr>
@@ -129,16 +129,10 @@ Static Methods</h3>
<table> <table>
<tr><td>None</td></tr> <tr><td>None</td></tr>
</table> </table>
<a NAME="Core._devconfigure" ID="Core._devconfigure"></a> <a NAME="Core.__errorlimit" ID="Core.__errorlimit"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Core._devconfigure</h3> Core.__errorlimit</h3>
<b>_devconfigure</b>(<i></i>) <b>__errorlimit</b>(<i>io_id, errorlimit</i>)
<p>
Core-Klasse vorbereiten.
</p><a NAME="Core._errorlimit" ID="Core._errorlimit"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._errorlimit</h3>
<b>_errorlimit</b>(<i>io_id, errorlimit</i>)
<p> <p>
Verwaltet das Lesen und Schreiben der ErrorLimits. Verwaltet das Lesen und Schreiben der ErrorLimits.
</p><dl> </p><dl>
@@ -151,6 +145,67 @@ Index des IOs fuer ErrorLimit
<dd> <dd>
Aktuellen ErrorLimit oder None wenn nicht verfuegbar Aktuellen ErrorLimit oder None wenn nicht verfuegbar
</dd> </dd>
</dl><a NAME="Core._devconfigure" ID="Core._devconfigure"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._devconfigure</h3>
<b>_devconfigure</b>(<i></i>)
<p>
Core-Klasse vorbereiten.
</p><a NAME="Core._get_leda1" ID="Core._get_leda1"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._get_leda1</h3>
<b>_get_leda1</b>(<i></i>)
<p>
Gibt den Zustand der LED A1 vom core zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core._get_leda2" ID="Core._get_leda2"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._get_leda2</h3>
<b>_get_leda2</b>(<i></i>)
<p>
Gibt den Zustand der LED A2 vom core zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core._get_status" ID="Core._get_status"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._get_status</h3>
<b>_get_status</b>(<i></i>)
<p>
Gibt den RevPi Core Status zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Status als int()
</dd>
</dl><a NAME="Core._set_leda1" ID="Core._set_leda1"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._set_leda1</h3>
<b>_set_leda1</b>(<i>value</i>)
<p>
Setzt den Zustand der LED A1 vom core.
</p><dl>
<dt><i>value</i></dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core._set_leda2" ID="Core._set_leda2"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._set_leda2</h3>
<b>_set_leda2</b>(<i>value</i>)
<p>
Setzt den Zustand der LED A2 vom core.
</p><dl>
<dt><i>value</i></dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core.errorlimit1" ID="Core.errorlimit1"></a> </dl><a NAME="Core.errorlimit1" ID="Core.errorlimit1"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Core.errorlimit1</h3> Core.errorlimit1</h3>
@@ -184,39 +239,6 @@ Gibt CPU Taktfrequenz zurueck.
<dd> <dd>
CPU Taktfrequenz in MHz CPU Taktfrequenz in MHz
</dd> </dd>
</dl><a NAME="Core.get_leda1" ID="Core.get_leda1"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.get_leda1</h3>
<b>get_leda1</b>(<i></i>)
<p>
Gibt den Zustand der LED A1 vom core zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core.get_leda2" ID="Core.get_leda2"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.get_leda2</h3>
<b>get_leda2</b>(<i></i>)
<p>
Gibt den Zustand der LED A2 vom core zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core.get_status" ID="Core.get_status"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.get_status</h3>
<b>get_status</b>(<i></i>)
<p>
Gibt den RevPi Core Status zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Status als int()
</dd>
</dl><a NAME="Core.iocycle" ID="Core.iocycle"></a> </dl><a NAME="Core.iocycle" ID="Core.iocycle"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Core.iocycle</h3> Core.iocycle</h3>
@@ -294,28 +316,6 @@ Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.
<dd> <dd>
True, wenn piGate rechts existiert True, wenn piGate rechts existiert
</dd> </dd>
</dl><a NAME="Core.set_leda1" ID="Core.set_leda1"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.set_leda1</h3>
<b>set_leda1</b>(<i>value</i>)
<p>
Setzt den Zustand der LED A1 vom core.
</p><dl>
<dt><i>value</i></dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core.set_leda2" ID="Core.set_leda2"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.set_leda2</h3>
<b>set_leda2</b>(<i>value</i>)
<p>
Setzt den Zustand der LED A2 vom core.
</p><dl>
<dt><i>value</i></dt>
<dd>
0=aus, 1=gruen, 2=rot
</dd>
</dl><a NAME="Core.temperatur" ID="Core.temperatur"></a> </dl><a NAME="Core.temperatur" ID="Core.temperatur"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Core.temperatur</h3> Core.temperatur</h3>
@@ -410,6 +410,18 @@ Methods</h3>
</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>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.readprocimg">readprocimg</a></td>
<td>Alle Inputs fuer dieses Device vom Prozessabbild einlesen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.setdefaultvalues">setdefaultvalues</a></td>
<td>Alle Outputbuffer fuer dieses Device auf default Werte setzen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.syncoutputs">syncoutputs</a></td>
<td>Lesen aller Outputs im Prozessabbild fuer dieses Device.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.writeprocimg">writeprocimg</a></td>
<td>Schreiben aller Outputs dieses Devices ins Prozessabbild.</td>
</tr> </tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -420,7 +432,7 @@ Static Methods</h3>
<a NAME="Device.__init__" ID="Device.__init__"></a> <a NAME="Device.__init__" ID="Device.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device (Constructor)</h3> Device (Constructor)</h3>
<b>Device</b>(<i>parentmodio, dict_device, **kwargs</i>) <b>Device</b>(<i>parentmodio, dict_device, simulator=False</i>)
<p> <p>
Instantiierung der Device()-Klasse. Instantiierung der Device()-Klasse.
</p><dl> </p><dl>
@@ -430,12 +442,9 @@ RevpiModIO parent object
</dd><dt><i>dict_device</i></dt> </dd><dt><i>dict_device</i></dt>
<dd> <dd>
dict() fuer dieses Device aus piCotry Konfiguration dict() fuer dieses Device aus piCotry Konfiguration
</dd><dt><i>kwargs</i></dt> </dd><dt><i>simulator:</i></dt>
<dd> <dd>
Weitere Parameter: Laed das Modul als Simulator und vertauscht IOs
- autoupdate: Wenn True fuehrt dieses Device Arbeiten am
Prozessabbild bei Aufruf der read- writeprocimg Funktionen aus
- simulator: Laed das Modul als Simulator und vertauscht IOs
</dd> </dd>
</dl><a NAME="Device.__bytes__" ID="Device.__bytes__"></a> </dl><a NAME="Device.__bytes__" ID="Device.__bytes__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -536,13 +545,13 @@ Funktion zum ueberschreiben von abgeleiteten Klassen.
</p><a NAME="Device.autorefresh" ID="Device.autorefresh"></a> </p><a NAME="Device.autorefresh" ID="Device.autorefresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Device.autorefresh</h3> Device.autorefresh</h3>
<b>autorefresh</b>(<i>remove=False</i>) <b>autorefresh</b>(<i>activate=True</i>)
<p> <p>
Registriert dieses Device fuer die automatische Synchronisierung. Registriert dieses Device fuer die automatische Synchronisierung.
</p><dl> </p><dl>
<dt><i>remove</i></dt> <dt><i>activate</i></dt>
<dd> <dd>
bool() True entfernt Device aus Synchronisierung Default True fuegt Device zur Synchronisierung hinzu
</dd> </dd>
</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">
@@ -588,6 +597,50 @@ Gibt eine Liste aller Outputs zurueck.
<dd> <dd>
list() Outputs list() Outputs
</dd> </dd>
</dl><a NAME="Device.readprocimg" ID="Device.readprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.readprocimg</h3>
<b>readprocimg</b>(<i></i>)
<p>
Alle Inputs fuer dieses Device vom Prozessabbild einlesen.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="revpimodio2.modio.html#RevPiModIO.readprocimg">RevPiModIO.readprocimg()</a>
</dd>
</dl><a NAME="Device.setdefaultvalues" ID="Device.setdefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.setdefaultvalues</h3>
<b>setdefaultvalues</b>(<i></i>)
<p>
Alle Outputbuffer fuer dieses Device auf default Werte setzen.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="revpimodio2.modio.html#RevPiModIO.setdefaultvalues">RevPiModIO.setdefaultvalues()</a>
</dd>
</dl><a NAME="Device.syncoutputs" ID="Device.syncoutputs"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.syncoutputs</h3>
<b>syncoutputs</b>(<i></i>)
<p>
Lesen aller Outputs im Prozessabbild fuer dieses Device.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="revpimodio2.modio.html#RevPiModIO.syncoutputs">RevPiModIO.syncoutputs()</a>
</dd>
</dl><a NAME="Device.writeprocimg" ID="Device.writeprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.writeprocimg</h3>
<b>writeprocimg</b>(<i></i>)
<p>
Schreiben aller Outputs dieses Devices ins Prozessabbild.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="revpimodio2.modio.html#RevPiModIO.writeprocimg">RevPiModIO.writeprocimg()</a>
</dd>
</dl> </dl>
<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 /> <hr /><hr />
@@ -619,6 +672,12 @@ Methods</h3>
<td><a style="color:#0000FF" href="#DeviceList.__contains__">__contains__</a></td> <td><a style="color:#0000FF" href="#DeviceList.__contains__">__contains__</a></td>
<td>Prueft ob Device existiert.</td> <td>Prueft ob Device existiert.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#DeviceList.__delattr__">__delattr__</a></td>
<td>Entfernt angegebenes Device.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#DeviceList.__delitem__">__delitem__</a></td>
<td>Entfernt Device an angegebener Position.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#DeviceList.__getitem__">__getitem__</a></td> <td><a style="color:#0000FF" href="#DeviceList.__getitem__">__getitem__</a></td>
<td>Gibt angegebenes Device zurueck.</td> <td>Gibt angegebenes Device zurueck.</td>
</tr><tr> </tr><tr>
@@ -659,6 +718,28 @@ DeviceName str() / Positionsnummer int()
<dd> <dd>
True, wenn Device vorhanden True, wenn Device vorhanden
</dd> </dd>
</dl><a NAME="DeviceList.__delattr__" ID="DeviceList.__delattr__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
DeviceList.__delattr__</h3>
<b>__delattr__</b>(<i>key</i>)
<p>
Entfernt angegebenes Device.
</p><dl>
<dt><i>key</i></dt>
<dd>
Device zum entfernen
</dd>
</dl><a NAME="DeviceList.__delitem__" ID="DeviceList.__delitem__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
DeviceList.__delitem__</h3>
<b>__delitem__</b>(<i>key</i>)
<p>
Entfernt Device an angegebener Position.
</p><dl>
<dt><i>key</i></dt>
<dd>
Deviceposition zum entfernen
</dd>
</dl><a NAME="DeviceList.__getitem__" ID="DeviceList.__getitem__"></a> </dl><a NAME="DeviceList.__getitem__" ID="DeviceList.__getitem__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
DeviceList.__getitem__</h3> DeviceList.__getitem__</h3>
@@ -716,12 +797,16 @@ Attributobjekt
Klasse fuer die RevPi Gateway-Devices. Klasse fuer die RevPi Gateway-Devices.
</p><p> </p><p>
Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die
Gateways bereit. Es koennen ueber die reg_*-Funktionen eigene IOs definiert Gateways bereit. IOs auf diesem Device stellen die replace_io Funktion
werden, die ein RevPiStructIO-Objekt abbilden. zur verfuegung, ueber die eigene IOs definiert werden, die ein
RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben. Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
</p><p> </p><dl>
<dt><b>See Also:</b></dt>
</p> <dd>
<a style="color:#0000FF" href="revpimodio2.io.html#IOBase.replace_io">replace_io(name, frm, **kwargs)</a>
</dd>
</dl>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3> Derived from</h3>
Device Device
@@ -740,7 +825,7 @@ Methods</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#Gateway.__init__">Gateway</a></td> <td><a style="color:#0000FF" href="#Gateway.__init__">Gateway</a></td>
<td>Erweitert RevPiDevice um reg_*-Funktionen.</td> <td>Erweitert Device-Klasse um get_rawbytes-Funktionen.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#Gateway.get_rawbytes">get_rawbytes</a></td> <td><a style="color:#0000FF" href="#Gateway.get_rawbytes">get_rawbytes</a></td>
<td>Gibt die Bytes aus, die dieses Device verwendet.</td> <td>Gibt die Bytes aus, die dieses Device verwendet.</td>
@@ -754,13 +839,13 @@ Static Methods</h3>
<a NAME="Gateway.__init__" ID="Gateway.__init__"></a> <a NAME="Gateway.__init__" ID="Gateway.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Gateway (Constructor)</h3> Gateway (Constructor)</h3>
<b>Gateway</b>(<i>parent, dict_device, **kwargs</i>) <b>Gateway</b>(<i>parent, dict_device, simulator=False</i>)
<p> <p>
Erweitert RevPiDevice um reg_*-Funktionen. Erweitert Device-Klasse um get_rawbytes-Funktionen.
</p><dl> </p><dl>
<dt><b>See Also:</b></dt> <dt><b>See Also:</b></dt>
<dd> <dd>
<a style="color:#0000FF" href="#RevPiDevice.__init__">RevPiDevice.__init__(...)</a> <a style="color:#0000FF" href="#Device.__init__">Device.__init__(...)</a>
</dd> </dd>
</dl><a NAME="Gateway.get_rawbytes" ID="Gateway.get_rawbytes"></a> </dl><a NAME="Gateway.get_rawbytes" ID="Gateway.get_rawbytes"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -781,14 +866,14 @@ bytes() des Devices
<p> <p>
Klasse fuer die RevPi Virtual-Devices. Klasse fuer die RevPi Virtual-Devices.
</p><p> </p><p>
Stellt die selben Funktionen wie RevPiGateway zur Verfuegung. Es koennen Stellt die selben Funktionen wie Gateway zur Verfuegung. Es koennen
ueber die reg_*-Funktionen eigene IOs definiert werden, die ein ueber die reg_*-Funktionen eigene IOs definiert werden, die ein
RevPiStructIO-Objekt abbilden. RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben. Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
</p><dl> </p><dl>
<dt><b>See Also:</b></dt> <dt><b>See Also:</b></dt>
<dd> <dd>
<a style="color:#0000FF" href="#RevPiGateway">RevPiGateway</a> <a style="color:#0000FF" href="#Gateway">Gateway</a>
</dd> </dd>
</dl> </dl>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -807,14 +892,34 @@ Class Methods</h3>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3> Methods</h3>
<table> <table>
<tr><td>None</td></tr> <tr>
<td><a style="color:#0000FF" href="#Virtual.writeinputdefaults">writeinputdefaults</a></td>
<td>Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.</td>
</tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3> Static Methods</h3>
<table> <table>
<tr><td>None</td></tr> <tr><td>None</td></tr>
</table> </table>
<a NAME="Virtual.writeinputdefaults" ID="Virtual.writeinputdefaults"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Virtual.writeinputdefaults</h3>
<b>writeinputdefaults</b>(<i></i>)
<p>
Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.
</p><p>
Sollten in piCtory Defaultwerte fuer Inputs eines virtuellen Devices
angegeben sein, werden diese nur beim Systemstart oder einem piControl
Reset gesetzt. Sollte danach das Prozessabbild mit NULL ueberschrieben,
gehen diese Werte verloren.
Diese Funktion kann nur auf virtuelle Devices angewendet werden!
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn Arbeiten am virtuellen Device erfolgreich waren
</dd>
</dl>
<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

@@ -18,6 +18,9 @@ Global Attributes</h3>
Classes</h3> Classes</h3>
<table> <table>
<tr> <tr>
<td><a style="color:#0000FF" href="#DeadIO">DeadIO</a></td>
<td>Klasse, mit der ersetzte IOs verwaltet werden.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOBase">IOBase</a></td> <td><a style="color:#0000FF" href="#IOBase">IOBase</a></td>
<td>Basisklasse fuer alle IO-Objekte.</td> <td>Basisklasse fuer alle IO-Objekte.</td>
</tr><tr> </tr><tr>
@@ -40,6 +43,65 @@ Functions</h3>
<tr><td>None</td></tr> <tr><td>None</td></tr>
</table> </table>
<hr /><hr /> <hr /><hr />
<a NAME="DeadIO" ID="DeadIO"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">DeadIO</h2>
<p>
Klasse, mit der ersetzte IOs verwaltet werden.
</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>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><a style="color:#0000FF" href="#DeadIO.__init__">DeadIO</a></td>
<td>Instantiierung der DeadIO()-Klasse.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#DeadIO.replace_io">replace_io</a></td>
<td>Stellt Funktion fuer weiter Bit-Ersetzungen bereit.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="DeadIO.__init__" ID="DeadIO.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
DeadIO (Constructor)</h3>
<b>DeadIO</b>(<i>deadio</i>)
<p>
Instantiierung der DeadIO()-Klasse.
</p><dl>
<dt><i>deadio</i></dt>
<dd>
IO, der ersetzt wurde
</dd>
</dl><a NAME="DeadIO.replace_io" ID="DeadIO.replace_io"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
DeadIO.replace_io</h3>
<b>replace_io</b>(<i>name, frm, **kwargs</i>)
<p>
Stellt Funktion fuer weiter Bit-Ersetzungen bereit.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#IOBase.replace_io">replace_io(...)</a>
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="IOBase" ID="IOBase"></a> <a NAME="IOBase" ID="IOBase"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">IOBase</h2> <h2 style="background-color:#FFFFFF;color:#0000FF">IOBase</h2>
<p> <p>
@@ -415,6 +477,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOList.__iter__">__iter__</a></td> <td><a style="color:#0000FF" href="#IOList.__iter__">__iter__</a></td>
<td>Gibt Iterator aller IOs zurueck.</td> <td>Gibt Iterator aller IOs zurueck.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#IOList.__len__">__len__</a></td>
<td>Gibt die Anzahl aller IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList.__private_replace_oldio_with_newio">__private_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> <td>Ersetzt bestehende IOs durch den neu Registrierten.</td>
</tr><tr> </tr><tr>
@@ -481,7 +546,7 @@ Verwaltet geloeschte IOs (Attribute, die nicht existieren).
</p><dl> </p><dl>
<dt><i>key</i></dt> <dt><i>key</i></dt>
<dd> <dd>
Wert eines alten IOs Name oder Byte eines alten IOs
</dd> </dd>
</dl><dl> </dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
@@ -494,15 +559,21 @@ IOList.__getitem__</h3>
<b>__getitem__</b>(<i>key</i>) <b>__getitem__</b>(<i>key</i>)
<p> <p>
Ruft angegebenen IO ab. Ruft angegebenen IO ab.
</p><p>
Wenn der Key <class 'str'> ist, wird ein einzelner IO geliefert. Wird
der Key als <class 'int'> uebergeben, wird eine <class 'list'>
geliefert mit 0, 1 oder 8 Eintraegen.
Wird als Key <class 'slice'> gegeben, werden die Listen in einer Liste
zurueckgegeben.
</p><dl> </p><dl>
<dt><i>key</i></dt> <dt><i>key</i></dt>
<dd> <dd>
IO Name oder Byte IO Name als <class 'str> oder Byte als <class 'int'>.
</dd> </dd>
</dl><dl> </dl><dl>
<dt>Returns:</dt> <dt>Returns:</dt>
<dd> <dd>
IO Object IO Objekt oder Liste der IOs
</dd> </dd>
</dl><a NAME="IOList.__iter__" ID="IOList.__iter__"></a> </dl><a NAME="IOList.__iter__" ID="IOList.__iter__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -515,6 +586,17 @@ Gibt Iterator aller IOs zurueck.
<dd> <dd>
Iterator aller IOs Iterator aller IOs
</dd> </dd>
</dl><a NAME="IOList.__len__" ID="IOList.__len__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOList.__len__</h3>
<b>__len__</b>(<i></i>)
<p>
Gibt die Anzahl aller IOs zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Anzahl aller IOs
</dd>
</dl><a NAME="IOList.__private_replace_oldio_with_newio" ID="IOList.__private_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"> <h3 style="background-color:#FFFFFF;color:#FF0000">
IOList.__private_replace_oldio_with_newio</h3> IOList.__private_replace_oldio_with_newio</h3>
@@ -721,7 +803,7 @@ IOBase
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3> Class Attributes</h3>
<table> <table>
<tr><td>signed</td></tr><tr><td>value</td></tr> <tr><td>frm</td></tr><tr><td>signed</td></tr><tr><td>value</td></tr>
</table> </table>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3> Class Methods</h3>
@@ -735,6 +817,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#StructIO.__init__">StructIO</a></td> <td><a style="color:#0000FF" href="#StructIO.__init__">StructIO</a></td>
<td>Erstellt einen IO mit struct-Formatierung.</td> <td>Erstellt einen IO mit struct-Formatierung.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#StructIO._get_frm">_get_frm</a></td>
<td>Ruft die struct() Formatierung ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#StructIO._get_signed">_get_signed</a></td> <td><a style="color:#0000FF" href="#StructIO._get_signed">_get_signed</a></td>
<td>Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.</td> <td>Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.</td>
</tr><tr> </tr><tr>
@@ -774,6 +859,17 @@ Weitere Parameter:
- byteorder: Byteorder fuer den Input, Standardwert=little - byteorder: Byteorder fuer den Input, Standardwert=little
- defaultvalue: Standardwert fuer Output, Standard ist 0 - defaultvalue: Standardwert fuer Output, Standard ist 0
</dd> </dd>
</dl><a NAME="StructIO._get_frm" ID="StructIO._get_frm"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
StructIO._get_frm</h3>
<b>_get_frm</b>(<i></i>)
<p>
Ruft die struct() Formatierung ab.
</p><dl>
<dt>Returns:</dt>
<dd>
struct() Formatierung
</dd>
</dl><a NAME="StructIO._get_signed" ID="StructIO._get_signed"></a> </dl><a NAME="StructIO._get_signed" ID="StructIO._get_signed"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
StructIO._get_signed</h3> StructIO._get_signed</h3>

View File

@@ -146,9 +146,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO.syncoutputs">syncoutputs</a></td> <td><a style="color:#0000FF" href="#RevPiModIO.syncoutputs">syncoutputs</a></td>
<td>Lesen aller aktuell gesetzten Outputs im Prozessabbild.</td> <td>Lesen aller aktuell gesetzten Outputs im Prozessabbild.</td>
</tr><tr> </tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.writedefaultinputs">writedefaultinputs</a></td>
<td>Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.writeprocimg">writeprocimg</a></td> <td><a style="color:#0000FF" href="#RevPiModIO.writeprocimg">writeprocimg</a></td>
<td>Schreiben aller Outputs aller Devices ins Prozessabbild.</td> <td>Schreiben aller Outputs aller Devices ins Prozessabbild.</td>
</tr> </tr>
@@ -470,14 +467,13 @@ None
</dl><a NAME="RevPiModIO.readprocimg" ID="RevPiModIO.readprocimg"></a> </dl><a NAME="RevPiModIO.readprocimg" ID="RevPiModIO.readprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.readprocimg</h3> RevPiModIO.readprocimg</h3>
<b>readprocimg</b>(<i>force=False, device=None</i>) <b>readprocimg</b>(<i>device=None</i>)
<p> <p>
Einlesen aller Inputs aller/eines Devices vom Prozessabbild. Einlesen aller Inputs aller/eines Devices vom Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl> </p><dl>
<dt><i>force</i></dt> <dt><i>device</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dd> <dd>
nur auf einzelnes Device anwenden nur auf einzelnes Device anwenden
</dd> </dd>
@@ -495,28 +491,24 @@ Setzt aktuellen IOError-Zaehler auf 0 zurueck.
</p><a NAME="RevPiModIO.setdefaultvalues" ID="RevPiModIO.setdefaultvalues"></a> </p><a NAME="RevPiModIO.setdefaultvalues" ID="RevPiModIO.setdefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.setdefaultvalues</h3> RevPiModIO.setdefaultvalues</h3>
<b>setdefaultvalues</b>(<i>force=False, device=None</i>) <b>setdefaultvalues</b>(<i>device=None</i>)
<p> <p>
Alle Outputbuffer werden auf die piCtory default Werte gesetzt. Alle Outputbuffer werden auf die piCtory default Werte gesetzt.
</p><dl> </p><dl>
<dt><i>force</i></dt> <dt><i>device</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dd> <dd>
nur auf einzelnes Device anwenden nur auf einzelnes Device anwenden
</dd> </dd>
</dl><a NAME="RevPiModIO.syncoutputs" ID="RevPiModIO.syncoutputs"></a> </dl><a NAME="RevPiModIO.syncoutputs" ID="RevPiModIO.syncoutputs"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.syncoutputs</h3> RevPiModIO.syncoutputs</h3>
<b>syncoutputs</b>(<i>force=False, device=None</i>) <b>syncoutputs</b>(<i>device=None</i>)
<p> <p>
Lesen aller aktuell gesetzten Outputs im Prozessabbild. Lesen aller aktuell gesetzten Outputs im Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl> </p><dl>
<dt><i>force</i></dt> <dt><i>device</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dd> <dd>
nur auf einzelnes Device anwenden nur auf einzelnes Device anwenden
</dd> </dd>
@@ -525,39 +517,16 @@ nur auf einzelnes Device anwenden
<dd> <dd>
True, wenn Arbeiten an allen Devices erfolgreich waren True, wenn Arbeiten an allen Devices erfolgreich waren
</dd> </dd>
</dl><a NAME="RevPiModIO.writedefaultinputs" ID="RevPiModIO.writedefaultinputs"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.writedefaultinputs</h3>
<b>writedefaultinputs</b>(<i>virtual_device</i>)
<p>
Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.
</p><p>
Sollten in piCtory Defaultwerte fuer Inputs eines virtuellen Devices
angegeben sein, werden diese nur beim Systemstart oder einem piControl
Reset gesetzt. Sollte danach das Prozessabbild mit NULL ueberschrieben,
gehen diese Werte verloren.
Diese Funktion kann nur auf virtuelle Devices angewendet werden!
</p><dl>
<dt><i>virtual_device</i></dt>
<dd>
Virtuelles Device fuer Wiederherstellung
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Arbeiten am virtuellen Device erfolgreich waren
</dd>
</dl><a NAME="RevPiModIO.writeprocimg" ID="RevPiModIO.writeprocimg"></a> </dl><a NAME="RevPiModIO.writeprocimg" ID="RevPiModIO.writeprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000"> <h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.writeprocimg</h3> RevPiModIO.writeprocimg</h3>
<b>writeprocimg</b>(<i>force=False, device=None</i>) <b>writeprocimg</b>(<i>device=None</i>)
<p> <p>
Schreiben aller Outputs aller Devices ins Prozessabbild. Schreiben aller Outputs aller Devices ins Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl> </p><dl>
<dt><i>force</i></dt> <dt><i>device</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dd> <dd>
nur auf einzelnes Device anwenden nur auf einzelnes Device anwenden
</dd> </dd>

View File

@@ -8,13 +8,14 @@ revpimodio2.app.App?1(app)
revpimodio2.device.Core.A1?7 revpimodio2.device.Core.A1?7
revpimodio2.device.Core.A2?7 revpimodio2.device.Core.A2?7
revpimodio2.device.Core._devconfigure?5() revpimodio2.device.Core._devconfigure?5()
revpimodio2.device.Core._errorlimit?5(io_id, errorlimit) revpimodio2.device.Core._get_leda1?5()
revpimodio2.device.Core._get_leda2?5()
revpimodio2.device.Core._get_status?5()
revpimodio2.device.Core._set_leda1?5(value)
revpimodio2.device.Core._set_leda2?5(value)
revpimodio2.device.Core.errorlimit1?4(value) revpimodio2.device.Core.errorlimit1?4(value)
revpimodio2.device.Core.errorlimit2?4(value) revpimodio2.device.Core.errorlimit2?4(value)
revpimodio2.device.Core.frequency?4() revpimodio2.device.Core.frequency?4()
revpimodio2.device.Core.get_leda1?4()
revpimodio2.device.Core.get_leda2?4()
revpimodio2.device.Core.get_status?4()
revpimodio2.device.Core.iocycle?4() revpimodio2.device.Core.iocycle?4()
revpimodio2.device.Core.ioerrorcount?4() revpimodio2.device.Core.ioerrorcount?4()
revpimodio2.device.Core.leftgate?4() revpimodio2.device.Core.leftgate?4()
@@ -22,22 +23,25 @@ revpimodio2.device.Core.missingdeviceorgate?4()
revpimodio2.device.Core.overunderflow?4() revpimodio2.device.Core.overunderflow?4()
revpimodio2.device.Core.picontrolrunning?4() revpimodio2.device.Core.picontrolrunning?4()
revpimodio2.device.Core.rightgate?4() revpimodio2.device.Core.rightgate?4()
revpimodio2.device.Core.set_leda1?4(value)
revpimodio2.device.Core.set_leda2?4(value)
revpimodio2.device.Core.status?7 revpimodio2.device.Core.status?7
revpimodio2.device.Core.temperatur?4() revpimodio2.device.Core.temperatur?4()
revpimodio2.device.Core.unconfdevice?4() revpimodio2.device.Core.unconfdevice?4()
revpimodio2.device.Device._buildio?5(dict_io, iotype) revpimodio2.device.Device._buildio?5(dict_io, iotype)
revpimodio2.device.Device._devconfigure?5() revpimodio2.device.Device._devconfigure?5()
revpimodio2.device.Device.autorefresh?4(remove=False) revpimodio2.device.Device.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4() revpimodio2.device.Device.get_allios?4()
revpimodio2.device.Device.get_inputs?4() revpimodio2.device.Device.get_inputs?4()
revpimodio2.device.Device.get_memmories?4() revpimodio2.device.Device.get_memmories?4()
revpimodio2.device.Device.get_outputs?4() revpimodio2.device.Device.get_outputs?4()
revpimodio2.device.Device?1(parentmodio, dict_device, **kwargs) revpimodio2.device.Device.readprocimg?4()
revpimodio2.device.Device.setdefaultvalues?4()
revpimodio2.device.Device.syncoutputs?4()
revpimodio2.device.Device.writeprocimg?4()
revpimodio2.device.Device?1(parentmodio, dict_device, simulator=False)
revpimodio2.device.DeviceList?1() revpimodio2.device.DeviceList?1()
revpimodio2.device.Gateway.get_rawbytes?4() revpimodio2.device.Gateway.get_rawbytes?4()
revpimodio2.device.Gateway?1(parent, dict_device, **kwargs) revpimodio2.device.Gateway?1(parent, dict_device, simulator=False)
revpimodio2.device.Virtual.writeinputdefaults?4()
revpimodio2.helper.Cycletools._docycle?5() revpimodio2.helper.Cycletools._docycle?5()
revpimodio2.helper.Cycletools.get_tofc?4(name) revpimodio2.helper.Cycletools.get_tofc?4(name)
revpimodio2.helper.Cycletools.get_tonc?4(name) revpimodio2.helper.Cycletools.get_tonc?4(name)
@@ -61,6 +65,8 @@ revpimodio2.helper.ProcimgWriter.set_maxioerrors?4(value)
revpimodio2.helper.ProcimgWriter.set_refresh?4(value) revpimodio2.helper.ProcimgWriter.set_refresh?4(value)
revpimodio2.helper.ProcimgWriter.stop?4() revpimodio2.helper.ProcimgWriter.stop?4()
revpimodio2.helper.ProcimgWriter?1(parentmodio) revpimodio2.helper.ProcimgWriter?1(parentmodio)
revpimodio2.io.DeadIO.replace_io?4(name, frm, **kwargs)
revpimodio2.io.DeadIO?1(deadio)
revpimodio2.io.IOBase._get_address?5() revpimodio2.io.IOBase._get_address?5()
revpimodio2.io.IOBase._get_byteorder?5() revpimodio2.io.IOBase._get_byteorder?5()
revpimodio2.io.IOBase._get_iotype?5() revpimodio2.io.IOBase._get_iotype?5()
@@ -91,7 +97,9 @@ revpimodio2.io.IntIO.get_int?4()
revpimodio2.io.IntIO.set_int?4(value) revpimodio2.io.IntIO.set_int?4(value)
revpimodio2.io.IntIO.signed?7 revpimodio2.io.IntIO.signed?7
revpimodio2.io.IntIO.value?7 revpimodio2.io.IntIO.value?7
revpimodio2.io.StructIO._get_frm?5()
revpimodio2.io.StructIO._get_signed?5() revpimodio2.io.StructIO._get_signed?5()
revpimodio2.io.StructIO.frm?7
revpimodio2.io.StructIO.get_structvalue?4() revpimodio2.io.StructIO.get_structvalue?4()
revpimodio2.io.StructIO.set_structvalue?4(value) revpimodio2.io.StructIO.set_structvalue?4(value)
revpimodio2.io.StructIO.signed?7 revpimodio2.io.StructIO.signed?7
@@ -127,13 +135,12 @@ revpimodio2.modio.RevPiModIO.mainloop?4(freeze=False, blocking=True)
revpimodio2.modio.RevPiModIO.maxioerrors?7 revpimodio2.modio.RevPiModIO.maxioerrors?7
revpimodio2.modio.RevPiModIO.monitoring?7 revpimodio2.modio.RevPiModIO.monitoring?7
revpimodio2.modio.RevPiModIO.procimg?7 revpimodio2.modio.RevPiModIO.procimg?7
revpimodio2.modio.RevPiModIO.readprocimg?4(force=False, device=None) revpimodio2.modio.RevPiModIO.readprocimg?4(device=None)
revpimodio2.modio.RevPiModIO.resetioerrors?4() revpimodio2.modio.RevPiModIO.resetioerrors?4()
revpimodio2.modio.RevPiModIO.setdefaultvalues?4(force=False, device=None) revpimodio2.modio.RevPiModIO.setdefaultvalues?4(device=None)
revpimodio2.modio.RevPiModIO.simulator?7 revpimodio2.modio.RevPiModIO.simulator?7
revpimodio2.modio.RevPiModIO.syncoutputs?4(force=False, device=None) revpimodio2.modio.RevPiModIO.syncoutputs?4(device=None)
revpimodio2.modio.RevPiModIO.writedefaultinputs?4(virtual_device) revpimodio2.modio.RevPiModIO.writeprocimg?4(device=None)
revpimodio2.modio.RevPiModIO.writeprocimg?4(force=False, device=None)
revpimodio2.modio.RevPiModIO?1(**kwargs) revpimodio2.modio.RevPiModIO?1(**kwargs)
revpimodio2.modio.RevPiModIODriver?1(vdev, **kwargs) revpimodio2.modio.RevPiModIODriver?1(vdev, **kwargs)
revpimodio2.modio.RevPiModIOSelected?1(deviceselection, **kwargs) revpimodio2.modio.RevPiModIOSelected?1(deviceselection, **kwargs)

View File

@@ -29,11 +29,31 @@ class DeviceList(object):
else: else:
return key in self.__dict_position.values() return key in self.__dict_position.values()
def __delattr__(self, key):
"""Entfernt angegebenes Device.
@param key Device zum entfernen"""
dev_del = getattr(self, key)
# Reinigungsjobs
dev_del.autorefresh(False)
for io in dev_del:
delattr(dev_del._modio.io, io.name)
del self.__dict_position[dev_del.position]
object.__delattr__(self, key)
def __delitem__(self, key):
"""Entfernt Device an angegebener Position.
@param key Deviceposition zum entfernen"""
self.__delattr__(self[key].name)
def __getitem__(self, key): def __getitem__(self, key):
"""Gibt angegebenes Device zurueck. """Gibt angegebenes Device zurueck.
@param key DeviceName str() / Positionsnummer int() @param key DeviceName str() / Positionsnummer int()
@return Gefundenes Device()-Objekt""" @return Gefundenes Device()-Objekt"""
if type(key) == int: if type(key) == int:
if key not in self.__dict_position:
raise KeyError("no device on position {}".format(key))
return self.__dict_position[key] return self.__dict_position[key]
else: else:
return getattr(self, key) return getattr(self, key)
@@ -70,15 +90,12 @@ class Device(object):
""" """
def __init__(self, parentmodio, dict_device, **kwargs): def __init__(self, parentmodio, dict_device, simulator=False):
"""Instantiierung der Device()-Klasse. """Instantiierung der Device()-Klasse.
@param parent RevpiModIO parent object @param parent RevpiModIO parent object
@param dict_device dict() fuer dieses Device aus piCotry Konfiguration @param dict_device dict() fuer dieses Device aus piCotry Konfiguration
@param kwargs Weitere Parameter: @param simulator: Laed das Modul als Simulator und vertauscht IOs
- autoupdate: Wenn True fuehrt dieses Device Arbeiten am
Prozessabbild bei Aufruf der read- writeprocimg Funktionen aus
- simulator: Laed das Modul als Simulator und vertauscht IOs
""" """
self._modio = parentmodio self._modio = parentmodio
@@ -88,8 +105,6 @@ class Device(object):
self._length = 0 self._length = 0
self._selfupdate = False self._selfupdate = False
self.autoupdate = kwargs.get("autoupdate", True)
# Wertzuweisung aus dict_device # Wertzuweisung aus dict_device
self.name = dict_device.pop("name") self.name = dict_device.pop("name")
self.offset = int(dict_device.pop("offset")) self.offset = int(dict_device.pop("offset"))
@@ -97,32 +112,33 @@ class Device(object):
self.producttype = int(dict_device.pop("productType")) self.producttype = int(dict_device.pop("productType"))
# IOM-Objekte erstellen und Adressen in SLCs speichern # IOM-Objekte erstellen und Adressen in SLCs speichern
if kwargs.get("simulator", False): if simulator:
self.slc_inp = self._buildio( self._slc_inp = self._buildio(
dict_device.pop("out"), iomodule.Type.INP) dict_device.pop("out"), iomodule.Type.INP)
self.slc_out = self._buildio( self._slc_out = self._buildio(
dict_device.pop("inp"), iomodule.Type.OUT) dict_device.pop("inp"), iomodule.Type.OUT)
else: else:
self.slc_inp = self._buildio( self._slc_inp = self._buildio(
dict_device.pop("inp"), iomodule.Type.INP) dict_device.pop("inp"), iomodule.Type.INP)
self.slc_out = self._buildio( self._slc_out = self._buildio(
dict_device.pop("out"), iomodule.Type.OUT) dict_device.pop("out"), iomodule.Type.OUT)
self.slc_mem = self._buildio(dict_device.pop("mem"), iomodule.Type.MEM) self._slc_mem = self._buildio(
dict_device.pop("mem"), iomodule.Type.MEM
)
# SLCs mit offset berechnen # SLCs mit offset berechnen
self.slc_devoff = slice(self.offset, self.offset + self._length) self._slc_devoff = slice(self.offset, self.offset + self._length)
self.slc_inpoff = slice( self._slc_inpoff = slice(
self.slc_inp.start + self.offset, self.slc_inp.stop + self.offset self._slc_inp.start + self.offset, self._slc_inp.stop + self.offset
) )
self.slc_outoff = slice( self._slc_outoff = slice(
self.slc_out.start + self.offset, self.slc_out.stop + self.offset self._slc_out.start + self.offset, self._slc_out.stop + self.offset
) )
self.slc_memoff = slice( self._slc_memoff = slice(
self.slc_mem.start + self.offset, self.slc_mem.stop + self.offset self._slc_mem.start + self.offset, self._slc_mem.stop + self.offset
) )
# Neues bytearray und Kopie für mainloop anlegen # Neues bytearray und Kopie für mainloop anlegen
# NOTE: Testen
self._ba_devdata = bytearray(self._length) self._ba_devdata = bytearray(self._length)
self._ba_datacp = bytearray() self._ba_datacp = bytearray()
@@ -142,12 +158,14 @@ class Device(object):
@param key IO-Name str() / IO-Bytenummer int() @param key IO-Name str() / IO-Bytenummer int()
@return True, wenn device vorhanden""" @return True, wenn device vorhanden"""
if type(key) == str: if type(key) == str:
return hasattr(self._modio.io, key) \ return key in self._modio.io \
and getattr(self._modio.io, key)._parentdevice == self and getattr(self._modio.io, key)._parentdevice == self
elif type(key) == int: elif type(key) == int:
return key in self._modio.io \ if key in self._modio.io:
and len(self._modio.io[key]) > 0 \ for io in self._modio.io[key]:
and self._modio.io[key][0]._parentdevice == self if io is not None and io._parentdevice == self:
return True
return False
else: else:
return key._parentdevice == self return key._parentdevice == self
@@ -159,7 +177,7 @@ class Device(object):
def __iter__(self): def __iter__(self):
"""Gibt Iterator aller IOs zurueck. """Gibt Iterator aller IOs zurueck.
@return iter() aller IOs""" @return iter() aller IOs"""
for lst_io in self._modio.io[self.slc_devoff]: for lst_io in self._modio.io[self._slc_devoff]:
for io in lst_io: for io in lst_io:
yield io yield io
@@ -207,10 +225,10 @@ class Device(object):
self._length += io_new._length self._length += io_new._length
# Kleinste und größte Speicheradresse ermitteln # Kleinste und größte Speicheradresse ermitteln
if io_new.slc_address.start < int_min: if io_new._slc_address.start < int_min:
int_min = io_new.slc_address.start int_min = io_new._slc_address.start
if io_new.slc_address.stop > int_max: if io_new._slc_address.stop > int_max:
int_max = io_new.slc_address.stop int_max = io_new._slc_address.stop
return slice(int_min, int_max) return slice(int_min, int_max)
@@ -218,13 +236,13 @@ class Device(object):
"""Funktion zum ueberschreiben von abgeleiteten Klassen.""" """Funktion zum ueberschreiben von abgeleiteten Klassen."""
pass pass
def autorefresh(self, remove=False): def autorefresh(self, activate=True):
"""Registriert dieses Device fuer die automatische Synchronisierung. """Registriert dieses Device fuer die automatische Synchronisierung.
@param remove bool() True entfernt Device aus Synchronisierung""" @param activate Default True fuegt Device zur Synchronisierung hinzu"""
if not remove and self not in self._modio._lst_refresh: if activate and self not in self._modio._lst_refresh:
# Daten bei Aufnahme direkt einlesen! # Daten bei Aufnahme direkt einlesen!
self._modio.readprocimg(True, self) self._modio.readprocimg(self)
# Datenkopie anlegen # Datenkopie anlegen
self._filelock.acquire() self._filelock.acquire()
@@ -247,7 +265,7 @@ class Device(object):
self._modio._imgwriter.refresh = imgrefresh self._modio._imgwriter.refresh = imgrefresh
self._modio._imgwriter.start() self._modio._imgwriter.start()
elif remove and self in self._modio._lst_refresh: elif not activate and self in self._modio._lst_refresh:
# Sicher aus Liste entfernen # Sicher aus Liste entfernen
with self._modio._imgwriter.lck_refresh: with self._modio._imgwriter.lck_refresh:
self._modio._lst_refresh.remove(self) self._modio._lst_refresh.remove(self)
@@ -259,14 +277,14 @@ class Device(object):
# Daten beim Entfernen noch einmal schreiben # Daten beim Entfernen noch einmal schreiben
if not self._modio._monitoring: if not self._modio._monitoring:
self._modio.writeprocimg(True, self) self._modio.writeprocimg(self)
def get_allios(self): def get_allios(self):
"""Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs. """Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
@return list() Input und Output, keine MEMs""" @return list() Input und Output, keine MEMs"""
lst_return = [] lst_return = []
for lst_io in self._modio.io[ for lst_io in self._modio.io[
self.slc_inpoff.start:self.slc_outoff.stop]: self._slc_inpoff.start:self._slc_outoff.stop]:
lst_return += lst_io lst_return += lst_io
return lst_return return lst_return
@@ -274,7 +292,7 @@ class Device(object):
"""Gibt eine Liste aller Inputs zurueck. """Gibt eine Liste aller Inputs zurueck.
@return list() Inputs""" @return list() Inputs"""
lst_return = [] lst_return = []
for lst_io in self._modio.io[self.slc_inpoff]: for lst_io in self._modio.io[self._slc_inpoff]:
lst_return += lst_io lst_return += lst_io
return lst_return return lst_return
@@ -282,7 +300,7 @@ class Device(object):
"""Gibt eine Liste aller Outputs zurueck. """Gibt eine Liste aller Outputs zurueck.
@return list() Outputs""" @return list() Outputs"""
lst_return = [] lst_return = []
for lst_io in self._modio.io[self.slc_outoff]: for lst_io in self._modio.io[self._slc_outoff]:
lst_return += lst_io lst_return += lst_io
return lst_return return lst_return
@@ -290,10 +308,34 @@ class Device(object):
"""Gibt eine Liste aller mems zurueck. """Gibt eine Liste aller mems zurueck.
@return list() Mems""" @return list() Mems"""
lst_return = [] lst_return = []
for lst_io in self._modio.io[self.slc_memoff]: for lst_io in self._modio.io[self._slc_memoff]:
lst_return += lst_io lst_return += lst_io
return lst_return return lst_return
def readprocimg(self):
"""Alle Inputs fuer dieses Device vom Prozessabbild einlesen.
@see revpimodio2.modio#RevPiModIO.readprocimg
RevPiModIO.readprocimg()"""
self._modio.readprocimg(self)
def setdefaultvalues(self):
"""Alle Outputbuffer fuer dieses Device auf default Werte setzen.
@see revpimodio2.modio#RevPiModIO.setdefaultvalues
RevPiModIO.setdefaultvalues()"""
self._modio.setdefaultvalues(self)
def syncoutputs(self):
"""Lesen aller Outputs im Prozessabbild fuer dieses Device.
@see revpimodio2.modio#RevPiModIO.syncoutputs
RevPiModIO.syncoutputs()"""
self._modio.syncoutputs(self)
def writeprocimg(self):
"""Schreiben aller Outputs dieses Devices ins Prozessabbild.
@see revpimodio2.modio#RevPiModIO.writeprocimg
RevPiModIO.writeprocimg()"""
self._modio.writeprocimg(self)
class Core(Device): class Core(Device):
@@ -314,9 +356,9 @@ class Core(Device):
self._ioerrorlimit2 = None self._ioerrorlimit2 = None
# Eigene IO-Liste aufbauen # Eigene IO-Liste aufbauen
self._lst_io = [x for x in self.__iter__()] self.__lst_io = [x for x in self.__iter__()]
int_lenio = len(self._lst_io) int_lenio = len(self.__lst_io)
if int_lenio == 6: if int_lenio == 6:
# Core 1.1 # Core 1.1
self._iocycle = 1 self._iocycle = 1
@@ -334,87 +376,87 @@ class Core(Device):
self._ioerrorlimit1 = 6 self._ioerrorlimit1 = 6
self._ioerrorlimit2 = 7 self._ioerrorlimit2 = 7
def _errorlimit(self, io_id, errorlimit): def __errorlimit(self, io_id, errorlimit):
"""Verwaltet das Lesen und Schreiben der ErrorLimits. """Verwaltet das Lesen und Schreiben der ErrorLimits.
@param io_id Index des IOs fuer ErrorLimit @param io_id Index des IOs fuer ErrorLimit
@return Aktuellen ErrorLimit oder None wenn nicht verfuegbar""" @return Aktuellen ErrorLimit oder None wenn nicht verfuegbar"""
if errorlimit is None: if errorlimit is None:
return None if io_id is None else int.from_bytes( return None if io_id is None else int.from_bytes(
self._lst_io[io_id].get_value(), self.__lst_io[io_id].get_value(),
byteorder=self._lst_io[io_id]._byteorder byteorder=self.__lst_io[io_id]._byteorder
) )
else: else:
if 0 <= errorlimit <= 65535: if 0 <= errorlimit <= 65535:
self._lst_io[io_id].set_value(errorlimit.to_bytes( self.__lst_io[io_id].set_value(errorlimit.to_bytes(
2, byteorder=self._lst_io[io_id]._byteorder 2, byteorder=self.__lst_io[io_id]._byteorder
)) ))
else: else:
raise ValueError( raise ValueError(
"errorlimit value int() must be between 0 and 65535" "errorlimit value int() must be between 0 and 65535"
) )
def get_status(self): def _get_status(self):
"""Gibt den RevPi Core Status zurueck. """Gibt den RevPi Core Status zurueck.
@return Status als int()""" @return Status als int()"""
return int.from_bytes( return int.from_bytes(
self._lst_io[0].get_value(), byteorder=self._lst_io[0]._byteorder self.__lst_io[0].get_value(), byteorder=self.__lst_io[0]._byteorder
) )
def get_leda1(self): def _get_leda1(self):
"""Gibt den Zustand der LED A1 vom core zurueck. """Gibt den Zustand der LED A1 vom core zurueck.
@return 0=aus, 1=gruen, 2=rot""" @return 0=aus, 1=gruen, 2=rot"""
int_led = int.from_bytes( int_led = int.from_bytes(
self._lst_io[self._ioled].get_value(), self.__lst_io[self._ioled].get_value(),
byteorder=self._lst_io[self._ioled]._byteorder byteorder=self.__lst_io[self._ioled]._byteorder
) )
led = int_led & 1 led = int_led & 1
led += int_led & 2 led += int_led & 2
return led return led
def get_leda2(self): def _get_leda2(self):
"""Gibt den Zustand der LED A2 vom core zurueck. """Gibt den Zustand der LED A2 vom core zurueck.
@return 0=aus, 1=gruen, 2=rot""" @return 0=aus, 1=gruen, 2=rot"""
int_led = int.from_bytes( int_led = int.from_bytes(
self._lst_io[self._ioled].get_value(), self.__lst_io[self._ioled].get_value(),
byteorder=self._lst_io[self._ioled]._byteorder byteorder=self.__lst_io[self._ioled]._byteorder
) )
led = 1 if bool(int_led & 4) else 0 led = 1 if bool(int_led & 4) else 0
led = led + 2 if bool(int_led & 8) else led led = led + 2 if bool(int_led & 8) else led
return led return led
def set_leda1(self, value): def _set_leda1(self, value):
"""Setzt den Zustand der LED A1 vom core. """Setzt den Zustand der LED A1 vom core.
@param value 0=aus, 1=gruen, 2=rot""" @param value 0=aus, 1=gruen, 2=rot"""
if 0 <= value <= 3: if 0 <= value <= 3:
int_led = (self.get_leda2() << 2) + value int_led = (self._get_leda2() << 2) + value
self._lst_io[self._ioled].set_value(int_led.to_bytes( self.__lst_io[self._ioled].set_value(int_led.to_bytes(
length=1, byteorder=self._lst_io[self._ioled]._byteorder length=1, byteorder=self.__lst_io[self._ioled]._byteorder
)) ))
else: else:
raise ValueError("led status int() must be between 0 and 3") raise ValueError("led status int() must be between 0 and 3")
def set_leda2(self, value): def _set_leda2(self, value):
"""Setzt den Zustand der LED A2 vom core. """Setzt den Zustand der LED A2 vom core.
@param value 0=aus, 1=gruen, 2=rot""" @param value 0=aus, 1=gruen, 2=rot"""
if 0 <= value <= 3: if 0 <= value <= 3:
int_led = (value << 2) + self.get_leda1() int_led = (value << 2) + self._get_leda1()
self._lst_io[self._ioled].set_value(int_led.to_bytes( self.__lst_io[self._ioled].set_value(int_led.to_bytes(
length=1, byteorder=self._lst_io[self._ioled]._byteorder length=1, byteorder=self.__lst_io[self._ioled]._byteorder
)) ))
else: else:
raise ValueError("led status int() must be between 0 and 3") raise ValueError("led status int() must be between 0 and 3")
A1 = property(get_leda1, set_leda1) A1 = property(_get_leda1, _set_leda1)
A2 = property(get_leda2, set_leda2) A2 = property(_get_leda2, _set_leda2)
status = property(get_status) status = property(_get_status)
@property @property
def picontrolrunning(self): def picontrolrunning(self):
"""Statusbit fuer piControl-Treiber laeuft. """Statusbit fuer piControl-Treiber laeuft.
@return True, wenn Treiber laeuft""" @return True, wenn Treiber laeuft"""
return bool(int.from_bytes( return bool(int.from_bytes(
self._lst_io[0].get_value(), self.__lst_io[0].get_value(),
byteorder=self._lst_io[0]._byteorder byteorder=self.__lst_io[0]._byteorder
) & 1) ) & 1)
@property @property
@@ -422,8 +464,8 @@ class Core(Device):
"""Statusbit fuer ein IO-Modul nicht mit PiCtory konfiguriert. """Statusbit fuer ein IO-Modul nicht mit PiCtory konfiguriert.
@return True, wenn IO Modul nicht konfiguriert""" @return True, wenn IO Modul nicht konfiguriert"""
return bool(int.from_bytes( return bool(int.from_bytes(
self._lst_io[0].get_value(), self.__lst_io[0].get_value(),
byteorder=self._lst_io[0]._byteorder byteorder=self.__lst_io[0]._byteorder
) & 2) ) & 2)
@property @property
@@ -431,8 +473,8 @@ class Core(Device):
"""Statusbit fuer ein IO-Modul fehlt oder piGate konfiguriert. """Statusbit fuer ein IO-Modul fehlt oder piGate konfiguriert.
@return True, wenn IO-Modul fehlt oder piGate konfiguriert""" @return True, wenn IO-Modul fehlt oder piGate konfiguriert"""
return bool(int.from_bytes( return bool(int.from_bytes(
self._lst_io[0].get_value(), self.__lst_io[0].get_value(),
byteorder=self._lst_io[0]._byteorder byteorder=self.__lst_io[0]._byteorder
) & 4) ) & 4)
@property @property
@@ -440,8 +482,8 @@ class Core(Device):
"""Statusbit Modul belegt mehr oder weniger Speicher als konfiguriert. """Statusbit Modul belegt mehr oder weniger Speicher als konfiguriert.
@return True, wenn falscher Speicher belegt ist""" @return True, wenn falscher Speicher belegt ist"""
return bool(int.from_bytes( return bool(int.from_bytes(
self._lst_io[0].get_value(), self.__lst_io[0].get_value(),
byteorder=self._lst_io[0]._byteorder byteorder=self.__lst_io[0]._byteorder
) & 8) ) & 8)
@property @property
@@ -449,8 +491,8 @@ class Core(Device):
"""Statusbit links vom RevPi ist ein piGate Modul angeschlossen. """Statusbit links vom RevPi ist ein piGate Modul angeschlossen.
@return True, wenn piGate links existiert""" @return True, wenn piGate links existiert"""
return bool(int.from_bytes( return bool(int.from_bytes(
self._lst_io[0].get_value(), self.__lst_io[0].get_value(),
byteorder=self._lst_io[0]._byteorder byteorder=self.__lst_io[0]._byteorder
) & 16) ) & 16)
@property @property
@@ -458,8 +500,8 @@ class Core(Device):
"""Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen. """Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.
@return True, wenn piGate rechts existiert""" @return True, wenn piGate rechts existiert"""
return bool(int.from_bytes( return bool(int.from_bytes(
self._lst_io[0].get_value(), self.__lst_io[0].get_value(),
byteorder=self._lst_io[0]._byteorder byteorder=self.__lst_io[0]._byteorder
) & 32) ) & 32)
@property @property
@@ -467,8 +509,8 @@ class Core(Device):
"""Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck. """Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck.
@return Zykluszeit in ms""" @return Zykluszeit in ms"""
return None if self._iocycle is None else int.from_bytes( return None if self._iocycle is None else int.from_bytes(
self._lst_io[self._iocycle].get_value(), self.__lst_io[self._iocycle].get_value(),
byteorder=self._lst_io[self._iocycle]._byteorder byteorder=self.__lst_io[self._iocycle]._byteorder
) )
@property @property
@@ -476,8 +518,8 @@ class Core(Device):
"""Gibt CPU-Temperatur zurueck. """Gibt CPU-Temperatur zurueck.
@return CPU-Temperatur in Celsius""" @return CPU-Temperatur in Celsius"""
return None if self._iotemperatur is None else int.from_bytes( return None if self._iotemperatur is None else int.from_bytes(
self._lst_io[self._iotemperatur].get_value(), self.__lst_io[self._iotemperatur].get_value(),
byteorder=self._lst_io[self._iotemperatur]._byteorder byteorder=self.__lst_io[self._iotemperatur]._byteorder
) )
@property @property
@@ -485,8 +527,8 @@ class Core(Device):
"""Gibt CPU Taktfrequenz zurueck. """Gibt CPU Taktfrequenz zurueck.
@return CPU Taktfrequenz in MHz""" @return CPU Taktfrequenz in MHz"""
return None if self._iofrequency is None else int.from_bytes( return None if self._iofrequency is None else int.from_bytes(
self._lst_io[self._iofrequency].get_value(), self.__lst_io[self._iofrequency].get_value(),
byteorder=self._lst_io[self._iofrequency]._byteorder byteorder=self.__lst_io[self._iofrequency]._byteorder
) * 10 ) * 10
@property @property
@@ -494,33 +536,33 @@ class Core(Device):
"""Gibt Fehleranzahl auf RS485 piBridge Bus zurueck. """Gibt Fehleranzahl auf RS485 piBridge Bus zurueck.
@return Fehleranzahl der piBridge""" @return Fehleranzahl der piBridge"""
return None if self._ioerrorcnt is None else int.from_bytes( return None if self._ioerrorcnt is None else int.from_bytes(
self._lst_io[self._ioerrorcnt].get_value(), self.__lst_io[self._ioerrorcnt].get_value(),
byteorder=self._lst_io[self._ioerrorcnt]._byteorder byteorder=self.__lst_io[self._ioerrorcnt]._byteorder
) )
@property @property
def errorlimit1(self): def errorlimit1(self):
"""Gibt RS485 ErrorLimit1 Wert zurueck. """Gibt RS485 ErrorLimit1 Wert zurueck.
@return Aktueller Wert fuer ErrorLimit1""" @return Aktueller Wert fuer ErrorLimit1"""
return self._errorlimit(self._ioerrorlimit1, None) return self.__errorlimit(self._ioerrorlimit1, None)
@errorlimit1.setter @errorlimit1.setter
def errorlimit1(self, value): def errorlimit1(self, value):
"""Setzt RS485 ErrorLimit1 auf neuen Wert. """Setzt RS485 ErrorLimit1 auf neuen Wert.
@param value Neuer ErrorLimit1 Wert""" @param value Neuer ErrorLimit1 Wert"""
self._errorlimit(self._ioerrorlimit1, value) self.__errorlimit(self._ioerrorlimit1, value)
@property @property
def errorlimit2(self): def errorlimit2(self):
"""Gibt RS485 ErrorLimit2 Wert zurueck. """Gibt RS485 ErrorLimit2 Wert zurueck.
@return Aktueller Wert fuer ErrorLimit2""" @return Aktueller Wert fuer ErrorLimit2"""
return self._errorlimit(self._ioerrorlimit2, None) return self.__errorlimit(self._ioerrorlimit2, None)
@errorlimit2.setter @errorlimit2.setter
def errorlimit2(self, value): def errorlimit2(self, value):
"""Setzt RS485 ErrorLimit2 auf neuen Wert. """Setzt RS485 ErrorLimit2 auf neuen Wert.
@param value Neuer ErrorLimit2 Wert""" @param value Neuer ErrorLimit2 Wert"""
self._errorlimit(self._ioerrorlimit2, value) self.__errorlimit(self._ioerrorlimit2, value)
class Gateway(Device): class Gateway(Device):
@@ -528,21 +570,23 @@ class Gateway(Device):
"""Klasse fuer die RevPi Gateway-Devices. """Klasse fuer die RevPi Gateway-Devices.
Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die
Gateways bereit. Es koennen ueber die reg_*-Funktionen eigene IOs definiert Gateways bereit. IOs auf diesem Device stellen die replace_io Funktion
werden, die ein RevPiStructIO-Objekt abbilden. zur verfuegung, ueber die eigene IOs definiert werden, die ein
RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben. Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
@see revpimodio2.io#IOBase.replace_io replace_io(name, frm, **kwargs)
""" """
def __init__(self, parent, dict_device, **kwargs): def __init__(self, parent, dict_device, simulator=False):
"""Erweitert RevPiDevice um reg_*-Funktionen. """Erweitert Device-Klasse um get_rawbytes-Funktionen.
@see #RevPiDevice.__init__ RevPiDevice.__init__(...)""" @see #Device.__init__ Device.__init__(...)"""
super().__init__(parent, dict_device, **kwargs) super().__init__(parent, dict_device, simulator)
self._dict_slc = { self._dict_slc = {
iomodule.Type.INP: self.slc_inp, iomodule.Type.INP: self._slc_inp,
iomodule.Type.OUT: self.slc_out, iomodule.Type.OUT: self._slc_out,
iomodule.Type.MEM: self.slc_mem iomodule.Type.MEM: self._slc_mem
} }
def get_rawbytes(self): def get_rawbytes(self):
@@ -555,15 +599,50 @@ class Virtual(Gateway):
"""Klasse fuer die RevPi Virtual-Devices. """Klasse fuer die RevPi Virtual-Devices.
Stellt die selben Funktionen wie RevPiGateway zur Verfuegung. Es koennen Stellt die selben Funktionen wie Gateway zur Verfuegung. Es koennen
ueber die reg_*-Funktionen eigene IOs definiert werden, die ein ueber die reg_*-Funktionen eigene IOs definiert werden, die ein
RevPiStructIO-Objekt abbilden. RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben. Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
@see #RevPiGateway RevPiGateway @see #Gateway Gateway
""" """
pass def writeinputdefaults(self):
"""Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.
Sollten in piCtory Defaultwerte fuer Inputs eines virtuellen Devices
angegeben sein, werden diese nur beim Systemstart oder einem piControl
Reset gesetzt. Sollte danach das Prozessabbild mit NULL ueberschrieben,
gehen diese Werte verloren.
Diese Funktion kann nur auf virtuelle Devices angewendet werden!
@return True, wenn Arbeiten am virtuellen Device erfolgreich waren
"""
if self._modio._monitoring:
raise RuntimeError(
"can not write process image, while system is in monitoring "
"mode"
)
workokay = True
self._filelock.acquire()
for io in self.get_inputs():
self._ba_devdata[io._slc_address] = io.defaultvalue
# Outpus auf Bus schreiben
try:
self._modio._myfh.seek(self._slc_inpoff.start)
self._modio._myfh.write(self._ba_devdata[self._slc_inp])
if self._modio._buffedwrite:
self._modio._myfh.flush()
except IOError:
self._modio._gotioerror("write")
workokay = False
self._filelock.release()
return workokay
# Nachträglicher Import # Nachträglicher Import

View File

@@ -296,17 +296,17 @@ class ProcimgWriter(Thread):
# Inputs und Outputs in Puffer # Inputs und Outputs in Puffer
for dev in self._modio._lst_refresh: for dev in self._modio._lst_refresh:
dev._filelock.acquire() dev._filelock.acquire()
dev._ba_devdata[:] = bytesbuff[dev.slc_devoff] dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
dev._filelock.release() dev._filelock.release()
else: else:
# Inputs in Puffer, Outputs in Prozessabbild # Inputs in Puffer, Outputs in Prozessabbild
ioerr = False ioerr = False
for dev in self._modio._lst_refresh: for dev in self._modio._lst_refresh:
dev._filelock.acquire() dev._filelock.acquire()
dev._ba_devdata[dev.slc_inp] = bytesbuff[dev.slc_inpoff] dev._ba_devdata[dev._slc_inp] = bytesbuff[dev._slc_inpoff]
try: try:
fh.seek(dev.slc_outoff.start) fh.seek(dev._slc_outoff.start)
fh.write(dev._ba_devdata[dev.slc_out]) fh.write(dev._ba_devdata[dev._slc_out])
except IOError: except IOError:
ioerr = True ioerr = True
finally: finally:

View File

@@ -27,7 +27,6 @@ class IOList(object):
def __init__(self): def __init__(self):
"""Init IOList class.""" """Init IOList class."""
self.__dict_iobyte = {k: [] for k in range(4096)} self.__dict_iobyte = {k: [] for k in range(4096)}
self.__dict_iorefbyte = {}
self.__dict_iorefname = {} self.__dict_iorefname = {}
def __contains__(self, key): def __contains__(self, key):
@@ -38,42 +37,53 @@ class IOList(object):
return key in self.__dict_iobyte \ return key in self.__dict_iobyte \
and len(self.__dict_iobyte[key]) > 0 and len(self.__dict_iobyte[key]) > 0
else: else:
return hasattr(self, key) return hasattr(self, key) and type(getattr(self, key)) != DeadIO
def __delattr__(self, key): def __delattr__(self, key):
"""Entfernt angegebenen IO. """Entfernt angegebenen IO.
@param key IO zum entfernen""" @param key IO zum entfernen"""
# TODO: Prüfen ob auch Bit sein kann io_del = object.__getattribute__(self, key)
io_del = getattr(self, key)
# Alte Events vom Device löschen # Alte Events vom Device löschen
io_del.unreg_event() io_del.unreg_event()
# IO aus Byteliste und Attributen entfernen # IO aus Byteliste und Attributen entfernen
self.__dict_iobyte[io_del.address].remove(io_del) if io_del._bitaddress < 0:
self.__dict_iobyte[io_del.address].remove(io_del)
else:
self.__dict_iobyte[io_del.address][io_del._bitaddress] = None
if self.__dict_iobyte[io_del.address] == \
[None, None, None, None, None, None, None, None]:
self.__dict_iobyte[io_del.address] = []
object.__delattr__(self, key) object.__delattr__(self, key)
def __getattr__(self, key): def __getattr__(self, key):
"""Verwaltet geloeschte IOs (Attribute, die nicht existieren). """Verwaltet geloeschte IOs (Attribute, die nicht existieren).
@param key Wert eines alten IOs @param key Name oder Byte eines alten IOs
@return Alten IO, wenn in Ref-Listen""" @return Alten IO, wenn in Ref-Listen"""
if key in self.__dict_iorefname: if key in self.__dict_iorefname:
return self.__dict_iorefname[key] return self.__dict_iorefname[key]
elif key in self.__dict_iorefbyte:
return self.__dict_iorefbyte[key]
else: else:
raise AttributeError("can not find io '{}'".format(key)) raise AttributeError("can not find io '{}'".format(key))
def __getitem__(self, key): def __getitem__(self, key):
"""Ruft angegebenen IO ab. """Ruft angegebenen IO ab.
@param key IO Name oder Byte
@return IO Object""" Wenn der Key <class 'str'> ist, wird ein einzelner IO geliefert. Wird
der Key als <class 'int'> uebergeben, wird eine <class 'list'>
geliefert mit 0, 1 oder 8 Eintraegen.
Wird als Key <class 'slice'> gegeben, werden die Listen in einer Liste
zurueckgegeben.
@param key IO Name als <class 'str> oder Byte als <class 'int'>.
@return IO Objekt oder Liste der IOs
"""
if type(key) == int: if type(key) == int:
if key in self.__dict_iobyte: if key not in self.__dict_iobyte:
return self.__dict_iobyte[key]
else:
raise KeyError("byte '{}' does not exist".format(key)) raise KeyError("byte '{}' does not exist".format(key))
return self.__dict_iobyte[key]
elif type(key) == slice: elif type(key) == slice:
return [ return [
self.__dict_iobyte[int_io] self.__dict_iobyte[int_io]
@@ -87,25 +97,37 @@ class IOList(object):
@return Iterator aller IOs""" @return Iterator aller IOs"""
for int_io in sorted(self.__dict_iobyte): for int_io in sorted(self.__dict_iobyte):
for io in self.__dict_iobyte[int_io]: for io in self.__dict_iobyte[int_io]:
yield io if io is not None:
yield io
def __len__(self):
"""Gibt die Anzahl aller IOs zurueck.
@return Anzahl aller IOs"""
int_ios = 0
for int_io in self.__dict_iobyte:
for io in self.__dict_iobyte[int_io]:
if io is not None:
int_ios += 1
return int_ios
def __setitem__(self, key, value): def __setitem__(self, key, value):
"""Setzt IO Wert. """Setzt IO Wert.
@param key IO Name oder Byte @param key IO Name oder Byte
@param value Wert, auf den der IO gesetzt wird""" @param value Wert, auf den der IO gesetzt wird"""
if type(key) == int: if type(key) == int:
if key in self.__dict_iobyte: if key not in self.__dict_iobyte:
if len(self.__dict_iobyte[key]) == 1: raise KeyError(
self.__dict_iobyte[key][0].value = value "byte '{}' does not contain io object".format(key)
elif len(self.__dict_iobyte[key]) == 0: )
raise KeyError("byte '{}' contains no input".format(key))
else: if len(self.__dict_iobyte[key]) == 1:
raise KeyError( self.__dict_iobyte[key][0].value = value
"byte '{}' contains more than one bit-input" elif len(self.__dict_iobyte[key]) == 0:
"".format(key) raise KeyError("byte '{}' contains no input".format(key))
)
else: else:
raise KeyError("byte '{}' does not exist".format(key)) raise KeyError(
"byte '{}' contains more than one bit-input".format(key)
)
else: else:
getattr(self, key).value = value getattr(self, key).value = value
@@ -115,8 +137,7 @@ class IOList(object):
@param value Wert, auf den der IO gesetzt wird""" @param value Wert, auf den der IO gesetzt wird"""
if key in [ if key in [
"_IOList__dict_iobyte", "_IOList__dict_iobyte",
"_IOList__dict_iorefname", "_IOList__dict_iorefname"
"_IOList__dict_iorefbyte"
]: ]:
object.__setattr__(self, key, value) object.__setattr__(self, key, value)
else: else:
@@ -126,8 +147,9 @@ class IOList(object):
def __private_replace_oldio_with_newio(self, io): def __private_replace_oldio_with_newio(self, io):
"""Ersetzt bestehende IOs durch den neu Registrierten. """Ersetzt bestehende IOs durch den neu Registrierten.
@param io Neuer IO der eingefuegt werden soll""" @param io Neuer IO der eingefuegt werden soll"""
for i in range(io.slc_address.start, io.slc_address.stop): int_length = 1 if io._length == 0 else io._length
for oldio in self.__dict_iobyte[i + io._parentdevice.offset]: for i in range(io.address, io.address + int_length):
for oldio in self.__dict_iobyte[i]:
if type(oldio) == StructIO: if type(oldio) == StructIO:
# Hier gibt es schon einen neuen IO # Hier gibt es schon einen neuen IO
@@ -149,8 +171,7 @@ class IOList(object):
# IOs im Speicherbereich des neuen IO merken # IOs im Speicherbereich des neuen IO merken
if io._bitaddress >= 0: if io._bitaddress >= 0:
# ios für ref bei bitaddress speichern # ios für ref bei bitaddress speichern
self.__dict_iorefbyte[oldio.slc_address.start] = oldio self.__dict_iorefname[oldio.name] = DeadIO(oldio)
self.__dict_iorefname[oldio.name] = oldio
# ios aus listen entfernen # ios aus listen entfernen
delattr(self, oldio.name) delattr(self, oldio.name)
@@ -171,7 +192,7 @@ class IOList(object):
object.__setattr__(self, new_io.name, new_io) object.__setattr__(self, new_io.name, new_io)
# Bytedict erstellen für Adresszugriff # Bytedict für Adresszugriff anpassen
if new_io._bitaddress < 0: if new_io._bitaddress < 0:
self.__dict_iobyte[new_io.address].append(new_io) self.__dict_iobyte[new_io.address].append(new_io)
else: else:
@@ -182,7 +203,7 @@ class IOList(object):
] ]
self.__dict_iobyte[new_io.address][new_io._bitaddress] = new_io self.__dict_iobyte[new_io.address][new_io._bitaddress] = new_io
else: else:
raise AttributeError("io must be IOBase or sub class") raise AttributeError("io must be <class 'IOBase'> or sub class")
def _testme(self): def _testme(self):
# NOTE: Nur Debugging # NOTE: Nur Debugging
@@ -190,13 +211,27 @@ class IOList(object):
if len(self.__dict_iobyte[x]) > 0: if len(self.__dict_iobyte[x]) > 0:
print(x, self.__dict_iobyte[x]) print(x, self.__dict_iobyte[x])
print(self.__dict_iorefname) print(self.__dict_iorefname)
print(self.__dict_iorefbyte)
def _getdict(self): def _getdict(self):
# NOTE: Nur Debugging # NOTE: Nur Debugging
return self.__dict_iobyte.copy() return self.__dict_iobyte.copy()
class DeadIO(object):
"""Klasse, mit der ersetzte IOs verwaltet werden."""
def __init__(self, deadio):
"""Instantiierung der DeadIO()-Klasse.
@param deadio IO, der ersetzt wurde"""
self.__deadio = deadio
def replace_io(self, name, frm, **kwargs):
"""Stellt Funktion fuer weiter Bit-Ersetzungen bereit.
@see #IOBase.replace_io replace_io(...)"""
self.__deadio.replace_io(name, frm, **kwargs)
class IOBase(object): class IOBase(object):
"""Basisklasse fuer alle IO-Objekte. """Basisklasse fuer alle IO-Objekte.
@@ -238,7 +273,7 @@ class IOBase(object):
int_startaddress = int(valuelist[3]) int_startaddress = int(valuelist[3])
if self._bitaddress == -1: if self._bitaddress == -1:
self.slc_address = slice( self._slc_address = slice(
int_startaddress, int_startaddress + self._length int_startaddress, int_startaddress + self._length
) )
# Defaultvalue aus Zahl in Bytes umrechnen # Defaultvalue aus Zahl in Bytes umrechnen
@@ -262,7 +297,7 @@ class IOBase(object):
else: else:
# Höhere Bits als 7 auf nächste Bytes umbrechen # Höhere Bits als 7 auf nächste Bytes umbrechen
int_startaddress += int((int(valuelist[7]) % 16) / 8) int_startaddress += int((int(valuelist[7]) % 16) / 8)
self.slc_address = slice( self._slc_address = slice(
int_startaddress, int_startaddress + 1 int_startaddress, int_startaddress + 1
) )
self.defaultvalue = bool(int(valuelist[1])) self.defaultvalue = bool(int(valuelist[1]))
@@ -277,13 +312,13 @@ class IOBase(object):
@return IO-Wert als bytes()""" @return IO-Wert als bytes()"""
if self._bitaddress >= 0: if self._bitaddress >= 0:
int_byte = int.from_bytes( int_byte = int.from_bytes(
self._parentdevice._ba_devdata[self.slc_address], self._parentdevice._ba_devdata[self._slc_address],
byteorder=self._byteorder byteorder=self._byteorder
) )
return b'\x01' if bool(int_byte & 1 << self._bitaddress) \ return b'\x01' if bool(int_byte & 1 << self._bitaddress) \
else b'\x00' else b'\x00'
else: else:
return bytes(self._parentdevice._ba_devdata[self.slc_address]) return bytes(self._parentdevice._ba_devdata[self._slc_address])
def __str__(self): def __str__(self):
"""str()-wert der Klasse. """str()-wert der Klasse.
@@ -293,7 +328,7 @@ class IOBase(object):
def _get_address(self): def _get_address(self):
"""Gibt die absolute Byteadresse im Prozessabbild zurueck. """Gibt die absolute Byteadresse im Prozessabbild zurueck.
@return Absolute Byteadresse""" @return Absolute Byteadresse"""
return self._parentdevice.offset + self.slc_address.start return self._parentdevice.offset + self._slc_address.start
def _get_byteorder(self): def _get_byteorder(self):
"""Gibt konfigurierte Byteorder zurueck. """Gibt konfigurierte Byteorder zurueck.
@@ -320,13 +355,13 @@ class IOBase(object):
@return IO-Wert""" @return IO-Wert"""
if self._bitaddress >= 0: if self._bitaddress >= 0:
int_byte = int.from_bytes( int_byte = int.from_bytes(
self._parentdevice._ba_devdata[self.slc_address], self._parentdevice._ba_devdata[self._slc_address],
byteorder=self._byteorder byteorder=self._byteorder
) )
return bool(int_byte & 1 << self._bitaddress) return bool(int_byte & 1 << self._bitaddress)
else: else:
return bytes(self._parentdevice._ba_devdata[self.slc_address]) return bytes(self._parentdevice._ba_devdata[self._slc_address])
def reg_event(self, func, edge=BOTH, as_thread=False): def reg_event(self, func, edge=BOTH, as_thread=False):
"""Registriert ein Event bei der Eventueberwachung. """Registriert ein Event bei der Eventueberwachung.
@@ -413,9 +448,11 @@ class IOBase(object):
# Optional Event eintragen # Optional Event eintragen
reg_event = kwargs.get("event", None) reg_event = kwargs.get("event", None)
if reg_event is not None: if reg_event is not None:
as_thread = kwargs.get("as_thread", False) io_new.reg_event(
edge = kwargs.get("edge", BOTH) reg_event,
io_new.reg_event(reg_event, as_thread=as_thread, edge=edge) as_thread=kwargs.get("as_thread", False),
edge=kwargs.get("edge", BOTH)
)
def set_value(self, value): def set_value(self, value):
"""Setzt den Wert des IOs mit bytes() oder bool(). """Setzt den Wert des IOs mit bytes() oder bool().
@@ -426,7 +463,7 @@ class IOBase(object):
value = bool(value) value = bool(value)
# ganzes Byte laden # ganzes Byte laden
byte_buff = self._parentdevice._ba_devdata[self.slc_address] byte_buff = self._parentdevice._ba_devdata[self._slc_address]
# Bytes in integer umwandeln # Bytes in integer umwandeln
int_len = len(byte_buff) int_len = len(byte_buff)
@@ -441,31 +478,37 @@ class IOBase(object):
int_byte -= int_bit int_byte -= int_bit
# Zurückschreiben wenn verändert # Zurückschreiben wenn verändert
self._parentdevice._ba_devdata[self.slc_address] = \ self._parentdevice._ba_devdata[self._slc_address] = \
int_byte.to_bytes(int_len, byteorder=self._byteorder) int_byte.to_bytes(int_len, byteorder=self._byteorder)
else: else:
if type(value) == bytes: if type(value) == bytes:
if self._length == len(value): if self._length == len(value):
self._parentdevice._ba_devdata[self.slc_address] = \ self._parentdevice._ba_devdata[self._slc_address] = \
value value
else: else:
raise ValueError( raise ValueError(
"'{}' requires a bytes() object of length {}, but " "'{}' requires a <class 'bytes'> object of length "
"{} was given".format( "{}, but {} was given".format(
self._name, self._length, len(value) self._name, self._length, len(value)
) )
) )
else: else:
raise ValueError( raise ValueError(
"'{}' requires a bytes() object, not {}" "'{}' requires a <class 'bytes'> object, not {}"
"".format(self._name, type(value)) "".format(self._name, type(value))
) )
elif self._iotype == Type.INP: elif self._iotype == Type.INP:
raise AttributeError( if self._parentdevice._modio._simulator:
"can not write to input '{}'".format(self._name) raise AttributeError(
) "can not write to output '{}' in simulator mode"
"".format(self._name)
)
else:
raise AttributeError(
"can not write to input '{}'".format(self._name)
)
elif self._iotype == Type.MEM: elif self._iotype == Type.MEM:
raise AttributeError( raise AttributeError(
"can not write to memory '{}'".format(self._name) "can not write to memory '{}'".format(self._name)
@@ -582,8 +625,7 @@ class IOBase(object):
flt_timecount += \ flt_timecount += \
self._parentdevice._modio._imgwriter._refresh self._parentdevice._modio._imgwriter._refresh
elif bool_timecount: elif bool_timecount:
# TODO: Prüfen flt_timecount += 2.5
flt_timecount += 1
# Abbruchevent wurde gesetzt # Abbruchevent wurde gesetzt
if exitevent.is_set(): if exitevent.is_set():
@@ -637,14 +679,14 @@ class IntIO(IOBase):
"""Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll. """Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.
@param value True, wenn mit Vorzeichen behandel""" @param value True, wenn mit Vorzeichen behandel"""
if type(value) != bool: if type(value) != bool:
raise ValueError("signed must be bool() True or False") raise ValueError("signed must be <class 'bool'> True or False")
self._signed = value self._signed = value
def get_int(self): def get_int(self):
"""Gibt IO als int() Wert zurueck mit Beachtung byteorder/signed. """Gibt IO als int() Wert zurueck mit Beachtung byteorder/signed.
@return int() Wert""" @return int() Wert"""
return int.from_bytes( return int.from_bytes(
self._parentdevice._ba_devdata[self.slc_address], self._parentdevice._ba_devdata[self._slc_address],
byteorder=self._byteorder, byteorder=self._byteorder,
signed=self._signed signed=self._signed
) )
@@ -660,7 +702,7 @@ class IntIO(IOBase):
)) ))
else: else:
raise ValueError( raise ValueError(
"'{}' need an int() value, but {} was given" "'{}' need a <class 'int'> value, but {} was given"
"".format(self._name, type(value)) "".format(self._name, type(value))
) )
@@ -711,9 +753,9 @@ class StructIO(IOBase):
name, name,
kwargs.get("defaultvalue", 0), kwargs.get("defaultvalue", 0),
bitlength, bitlength,
parentio.slc_address.start, parentio._slc_address.start,
False, False,
str(parentio.slc_address.start).rjust(4, "0"), str(parentio._slc_address.start).rjust(4, "0"),
kwargs.get("bmk", ""), kwargs.get("bmk", ""),
bitaddress bitaddress
] ]
@@ -734,18 +776,23 @@ class StructIO(IOBase):
byteorder, byteorder,
frm == frm.lower() frm == frm.lower()
) )
self.frm = frm self.__frm = bofrm + frm
# Platz für neuen IO prüfen # Platz für neuen IO prüfen
if not (self.slc_address.start >= if not (self._slc_address.start >=
parentio._parentdevice._dict_slc[parentio._iotype].start and parentio._parentdevice._dict_slc[parentio._iotype].start and
self.slc_address.stop <= self._slc_address.stop <=
parentio._parentdevice._dict_slc[parentio._iotype].stop): parentio._parentdevice._dict_slc[parentio._iotype].stop):
raise BufferError( raise BufferError(
"registered value does not fit process image scope" "registered value does not fit process image scope"
) )
def _get_frm(self):
"""Ruft die struct() Formatierung ab.
@return struct() Formatierung"""
return self.__frm
def _get_signed(self): def _get_signed(self):
"""Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll. """Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
@return True, wenn Vorzeichenbehaftet""" @return True, wenn Vorzeichenbehaftet"""
@@ -757,7 +804,7 @@ class StructIO(IOBase):
if self._bitaddress >= 0: if self._bitaddress >= 0:
return self.get_value() return self.get_value()
else: else:
return struct.unpack(self.frm, self.get_value())[0] return struct.unpack(self.__frm, self.get_value())[0]
def set_structvalue(self, value): def set_structvalue(self, value):
"""Setzt den Wert mit struct Formatierung. """Setzt den Wert mit struct Formatierung.
@@ -765,8 +812,9 @@ class StructIO(IOBase):
if self._bitaddress >= 0: if self._bitaddress >= 0:
self.set_value(value) self.set_value(value)
else: else:
self.set_value(struct.pack(self.frm, value)) self.set_value(struct.pack(self.__frm, value))
frm = property(_get_frm)
signed = property(_get_signed) signed = property(_get_signed)
value = property(get_structvalue, set_structvalue) value = property(get_structvalue, set_structvalue)

View File

@@ -65,7 +65,6 @@ class RevPiModIO(object):
self._lst_devselect = [] self._lst_devselect = []
self._lst_refresh = [] self._lst_refresh = []
self._maxioerrors = 0 self._maxioerrors = 0
self._myfh = self._create_myfh()
self._th_mainloop = None self._th_mainloop = None
self._waitexit = Event() self._waitexit = Event()
@@ -78,6 +77,9 @@ class RevPiModIO(object):
self.io = None self.io = None
self.summary = None self.summary = None
# Filehandler öffnen
self._myfh = self._create_myfh()
# Nur Konfigurieren, wenn nicht vererbt # Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiModIO: if type(self) == RevPiModIO:
self._configure() self._configure()
@@ -85,7 +87,8 @@ class RevPiModIO(object):
def __del__(self): def __del__(self):
"""Zerstoert alle Klassen um aufzuraeumen.""" """Zerstoert alle Klassen um aufzuraeumen."""
self.exit(full=True) self.exit(full=True)
self._myfh.close() if hasattr(self, "_myfh"):
self._myfh.close()
def __evt_exit(self, signum, sigframe): def __evt_exit(self, signum, sigframe):
"""Eventhandler fuer Programmende. """Eventhandler fuer Programmende.
@@ -139,7 +142,6 @@ class RevPiModIO(object):
# Bei VDev in alter piCtory Version, Position eindeutig machen # Bei VDev in alter piCtory Version, Position eindeutig machen
if device["position"] == "adap.": if device["position"] == "adap.":
device["position"] = -1 device["position"] = -1
# NOTE: Testen mit alter piCtory Version
while device["position"] in self.device: while device["position"] in self.device:
device["position"] -= 1 device["position"] -= 1
@@ -155,7 +157,7 @@ class RevPiModIO(object):
for io in dev_new.get_outputs(): for io in dev_new.get_outputs():
io.set_value(io.defaultvalue) io.set_value(io.defaultvalue)
if not self._monitoring: if not self._monitoring:
self.writeprocimg(True, dev_new) self.writeprocimg(dev_new)
elif device["type"] == "LEFT_RIGHT": elif device["type"] == "LEFT_RIGHT":
# IOs # IOs
@@ -209,7 +211,7 @@ class RevPiModIO(object):
# Aktuellen Outputstatus von procimg einlesen # Aktuellen Outputstatus von procimg einlesen
if self._syncoutputs: if self._syncoutputs:
self.syncoutputs(force=True) self.syncoutputs()
# Optional ins autorefresh aufnehmen # Optional ins autorefresh aufnehmen
if self._autorefresh: if self._autorefresh:
@@ -237,7 +239,10 @@ class RevPiModIO(object):
def _get_ioerrors(self): def _get_ioerrors(self):
"""Getter function. """Getter function.
@return Aktuelle Anzahl gezaehlter Fehler""" @return Aktuelle Anzahl gezaehlter Fehler"""
return self._ioerror if self._looprunning:
return self._imgwriter._ioerror
else:
return self._ioerror
def _get_length(self): def _get_length(self):
"""Getter function. """Getter function.
@@ -397,14 +402,14 @@ class RevPiModIO(object):
self._exit.set() self._exit.set()
self._waitexit.set() self._waitexit.set()
if full: if full:
if self._imgwriter.is_alive(): if self._imgwriter is not None and self._imgwriter.is_alive():
self._imgwriter.stop() self._imgwriter.stop()
self._imgwriter.join(self._imgwriter._refresh) self._imgwriter.join(self._imgwriter._refresh)
while len(self._lst_refresh) > 0: while len(self._lst_refresh) > 0:
dev = self._lst_refresh.pop() dev = self._lst_refresh.pop()
dev._selfupdate = False dev._selfupdate = False
if not self._monitoring: if not self._monitoring:
self.writeprocimg(True, dev) self.writeprocimg(dev)
self._looprunning = False self._looprunning = False
def get_jconfigrsc(self): def get_jconfigrsc(self):
@@ -541,17 +546,17 @@ class RevPiModIO(object):
for io_event in dev._dict_events: for io_event in dev._dict_events:
if dev._ba_datacp[io_event.slc_address] == \ if dev._ba_datacp[io_event._slc_address] == \
dev._ba_devdata[io_event.slc_address]: dev._ba_devdata[io_event._slc_address]:
continue continue
if io_event._bitaddress >= 0: if io_event._bitaddress >= 0:
boolcp = bool(int.from_bytes( boolcp = bool(int.from_bytes(
dev._ba_datacp[io_event.slc_address], dev._ba_datacp[io_event._slc_address],
byteorder=io_event._byteorder byteorder=io_event._byteorder
) & 1 << io_event._bitaddress) ) & 1 << io_event._bitaddress)
boolor = bool(int.from_bytes( boolor = bool(int.from_bytes(
dev._ba_devdata[io_event.slc_address], dev._ba_devdata[io_event._slc_address],
byteorder=io_event._byteorder byteorder=io_event._byteorder
) & 1 << io_event._bitaddress) ) & 1 << io_event._bitaddress)
@@ -603,10 +608,11 @@ class RevPiModIO(object):
# Mainloop verlassen # Mainloop verlassen
self._looprunning = False self._looprunning = False
def readprocimg(self, force=False, device=None): def readprocimg(self, device=None):
"""Einlesen aller Inputs aller/eines Devices vom Prozessabbild. """Einlesen aller Inputs aller/eines Devices vom Prozessabbild.
@param force auch Devices mit autoupdate=False Devices mit aktiverem autorefresh werden ausgenommen!
@param device nur auf einzelnes Device anwenden @param device nur auf einzelnes Device anwenden
@return True, wenn Arbeiten an allen Devices erfolgreich waren @return True, wenn Arbeiten an allen Devices erfolgreich waren
@@ -633,20 +639,20 @@ class RevPiModIO(object):
return False return False
for dev in mylist: for dev in mylist:
if (force or dev.autoupdate) and not dev._selfupdate: if not dev._selfupdate:
# FileHandler sperren # FileHandler sperren
dev._filelock.acquire() dev._filelock.acquire()
if self._monitoring: if self._monitoring:
# Alles vom Bus einlesen # Alles vom Bus einlesen
dev._ba_devdata[:] = bytesbuff[dev.slc_devoff] dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
else: else:
# Inputs vom Bus einlesen # Inputs vom Bus einlesen
dev._ba_devdata[dev.slc_inp] = bytesbuff[dev.slc_inpoff] dev._ba_devdata[dev._slc_inp] = bytesbuff[dev._slc_inpoff]
# Mems vom Bus lesen # Mems vom Bus lesen
dev._ba_devdata[dev.slc_mem] = bytesbuff[dev.slc_memoff] dev._ba_devdata[dev._slc_mem] = bytesbuff[dev._slc_memoff]
dev._filelock.release() dev._filelock.release()
@@ -657,9 +663,8 @@ class RevPiModIO(object):
self._ioerror = 0 self._ioerror = 0
self._imgwriter._ioerror = 0 self._imgwriter._ioerror = 0
def setdefaultvalues(self, force=False, device=None): def setdefaultvalues(self, device=None):
"""Alle Outputbuffer werden auf die piCtory default Werte gesetzt. """Alle Outputbuffer werden auf die piCtory default Werte gesetzt.
@param force auch Devices mit autoupdate=False
@param device nur auf einzelnes Device anwenden""" @param device nur auf einzelnes Device anwenden"""
if self._monitoring: if self._monitoring:
raise RuntimeError( raise RuntimeError(
@@ -675,14 +680,14 @@ class RevPiModIO(object):
mylist = [dev] mylist = [dev]
for dev in mylist: for dev in mylist:
if (force or dev.autoupdate): for io in dev.get_outputs():
for io in dev.get_outputs(): io.set_value(io.defaultvalue)
io.set_value(io.defaultvalue)
def syncoutputs(self, force=False, device=None): def syncoutputs(self, device=None):
"""Lesen aller aktuell gesetzten Outputs im Prozessabbild. """Lesen aller aktuell gesetzten Outputs im Prozessabbild.
@param force auch Devices mit autoupdate=False Devices mit aktiverem autorefresh werden ausgenommen!
@param device nur auf einzelnes Device anwenden @param device nur auf einzelnes Device anwenden
@return True, wenn Arbeiten an allen Devices erfolgreich waren @return True, wenn Arbeiten an allen Devices erfolgreich waren
@@ -708,65 +713,18 @@ class RevPiModIO(object):
return False return False
for dev in mylist: for dev in mylist:
if (force or dev.autoupdate) and not dev._selfupdate: if not dev._selfupdate:
dev._filelock.acquire() dev._filelock.acquire()
# Outputs vom Bus einlesen dev._ba_devdata[dev._slc_out] = bytesbuff[dev._slc_outoff]
dev._ba_devdata[dev.slc_out] = bytesbuff[dev.slc_outoff]
dev._filelock.release() dev._filelock.release()
return True return True
def writedefaultinputs(self, virtual_device): def writeprocimg(self, device=None):
"""Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.
Sollten in piCtory Defaultwerte fuer Inputs eines virtuellen Devices
angegeben sein, werden diese nur beim Systemstart oder einem piControl
Reset gesetzt. Sollte danach das Prozessabbild mit NULL ueberschrieben,
gehen diese Werte verloren.
Diese Funktion kann nur auf virtuelle Devices angewendet werden!
@param virtual_device Virtuelles Device fuer Wiederherstellung
@return True, wenn Arbeiten am virtuellen Device erfolgreich waren
"""
if self._monitoring:
raise RuntimeError(
"can not write process image, while system is in monitoring "
"mode"
)
# Device suchen
dev = virtual_device if issubclass(type(virtual_device), devicemodule.Device) \
else self.__getitem__(virtual_device)
# Prüfen ob es ein virtuelles Device ist
if not issubclass(type(dev), devicemodule.Virtual):
raise RuntimeError(
"this function can be used for virtual devices only"
)
workokay = True
dev._filelock.acquire()
for io in dev.get_inputs():
dev._ba_devdata[io.slc_address] = io.defaultvalue
# Outpus auf Bus schreiben
try:
self._myfh.seek(dev.slc_inpoff.start)
self._myfh.write(dev._ba_devdata[dev.slc_inp])
if self._buffedwrite:
self._myfh.flush()
except IOError:
self._gotioerror("write")
workokay = False
dev._filelock.release()
return workokay
def writeprocimg(self, force=False, device=None):
"""Schreiben aller Outputs aller Devices ins Prozessabbild. """Schreiben aller Outputs aller Devices ins Prozessabbild.
@param force auch Devices mit autoupdate=False Devices mit aktiverem autorefresh werden ausgenommen!
@param device nur auf einzelnes Device anwenden @param device nur auf einzelnes Device anwenden
@return True, wenn Arbeiten an allen Devices erfolgreich waren @return True, wenn Arbeiten an allen Devices erfolgreich waren
@@ -792,13 +750,13 @@ class RevPiModIO(object):
workokay = True workokay = True
for dev in mylist: for dev in mylist:
if (force or dev.autoupdate) and not dev._selfupdate: if not dev._selfupdate:
dev._filelock.acquire() dev._filelock.acquire()
# Outpus auf Bus schreiben # Outpus auf Bus schreiben
try: try:
self._myfh.seek(dev.slc_outoff.start) self._myfh.seek(dev._slc_outoff.start)
self._myfh.write(dev._ba_devdata[dev.slc_out]) self._myfh.write(dev._ba_devdata[dev._slc_out])
except IOError: except IOError:
workokay = False workokay = False