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>RevPiModIO Hauptklasse.</td>
</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>Bildet die Summary-Sektion von piCtory ab.</td>
</tr>

View File

@@ -66,11 +66,26 @@ Class Methods</h3>
Methods</h3>
<table>
<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>Core-Klasse vorbereiten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Core._errorlimit">_errorlimit</a></td>
<td>Verwaltet das Lesen und Schreiben der ErrorLimits.</td>
<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._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.errorlimit1">errorlimit1</a></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>Gibt CPU Taktfrequenz zurueck.</td>
</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>Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck.</td>
</tr><tr>
@@ -111,12 +117,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#Core.rightgate">rightgate</a></td>
<td>Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.</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>
<td><a style="color:#0000FF" href="#Core.temperatur">temperatur</a></td>
<td>Gibt CPU-Temperatur zurueck.</td>
</tr><tr>
@@ -129,16 +129,10 @@ Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="Core._devconfigure" ID="Core._devconfigure"></a>
<a NAME="Core.__errorlimit" ID="Core.__errorlimit"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core._devconfigure</h3>
<b>_devconfigure</b>(<i></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>)
Core.__errorlimit</h3>
<b>__errorlimit</b>(<i>io_id, errorlimit</i>)
<p>
Verwaltet das Lesen und Schreiben der ErrorLimits.
</p><dl>
@@ -151,6 +145,67 @@ Index des IOs fuer ErrorLimit
<dd>
Aktuellen ErrorLimit oder None wenn nicht verfuegbar
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.errorlimit1</h3>
@@ -184,39 +239,6 @@ Gibt CPU Taktfrequenz zurueck.
<dd>
CPU Taktfrequenz in MHz
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.iocycle</h3>
@@ -294,28 +316,6 @@ Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.
<dd>
True, wenn piGate rechts existiert
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Core.temperatur</h3>
@@ -410,6 +410,18 @@ Methods</h3>
</tr><tr>
<td><a style="color:#0000FF" href="#Device.get_outputs">get_outputs</a></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>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -420,7 +432,7 @@ Static Methods</h3>
<a NAME="Device.__init__" ID="Device.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device (Constructor)</h3>
<b>Device</b>(<i>parentmodio, dict_device, **kwargs</i>)
<b>Device</b>(<i>parentmodio, dict_device, simulator=False</i>)
<p>
Instantiierung der Device()-Klasse.
</p><dl>
@@ -430,12 +442,9 @@ RevpiModIO parent object
</dd><dt><i>dict_device</i></dt>
<dd>
dict() fuer dieses Device aus piCotry Konfiguration
</dd><dt><i>kwargs</i></dt>
</dd><dt><i>simulator:</i></dt>
<dd>
Weitere Parameter:
- 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
Laed das Modul als Simulator und vertauscht IOs
</dd>
</dl><a NAME="Device.__bytes__" ID="Device.__bytes__"></a>
<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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Device.autorefresh</h3>
<b>autorefresh</b>(<i>remove=False</i>)
<b>autorefresh</b>(<i>activate=True</i>)
<p>
Registriert dieses Device fuer die automatische Synchronisierung.
</p><dl>
<dt><i>remove</i></dt>
<dt><i>activate</i></dt>
<dd>
bool() True entfernt Device aus Synchronisierung
Default True fuegt Device zur Synchronisierung hinzu
</dd>
</dl><a NAME="Device.get_allios" ID="Device.get_allios"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -588,6 +597,50 @@ Gibt eine Liste aller Outputs zurueck.
<dd>
list() Outputs
</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>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
@@ -619,6 +672,12 @@ Methods</h3>
<td><a style="color:#0000FF" href="#DeviceList.__contains__">__contains__</a></td>
<td>Prueft ob Device existiert.</td>
</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>Gibt angegebenes Device zurueck.</td>
</tr><tr>
@@ -659,6 +718,28 @@ DeviceName str() / Positionsnummer int()
<dd>
True, wenn Device vorhanden
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
DeviceList.__getitem__</h3>
@@ -716,12 +797,16 @@ Attributobjekt
Klasse fuer die RevPi Gateway-Devices.
</p><p>
Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die
Gateways bereit. Es koennen ueber die reg_*-Funktionen eigene IOs definiert
werden, die ein RevPiStructIO-Objekt abbilden.
Gateways bereit. IOs auf diesem Device stellen die replace_io Funktion
zur verfuegung, ueber die eigene IOs definiert werden, die ein
RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
</p><p>
</p>
</p><dl>
<dt><b>See Also:</b></dt>
<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">
Derived from</h3>
Device
@@ -740,7 +825,7 @@ Methods</h3>
<table>
<tr>
<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>
<td><a style="color:#0000FF" href="#Gateway.get_rawbytes">get_rawbytes</a></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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Gateway (Constructor)</h3>
<b>Gateway</b>(<i>parent, dict_device, **kwargs</i>)
<b>Gateway</b>(<i>parent, dict_device, simulator=False</i>)
<p>
Erweitert RevPiDevice um reg_*-Funktionen.
Erweitert Device-Klasse um get_rawbytes-Funktionen.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#RevPiDevice.__init__">RevPiDevice.__init__(...)</a>
<a style="color:#0000FF" href="#Device.__init__">Device.__init__(...)</a>
</dd>
</dl><a NAME="Gateway.get_rawbytes" ID="Gateway.get_rawbytes"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -781,14 +866,14 @@ bytes() des Devices
<p>
Klasse fuer die RevPi Virtual-Devices.
</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
RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
</p><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#RevPiGateway">RevPiGateway</a>
<a style="color:#0000FF" href="#Gateway">Gateway</a>
</dd>
</dl>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -807,14 +892,34 @@ Class Methods</h3>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</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>
<hr />
</body></html>

View File

@@ -18,6 +18,9 @@ Global Attributes</h3>
Classes</h3>
<table>
<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>Basisklasse fuer alle IO-Objekte.</td>
</tr><tr>
@@ -40,6 +43,65 @@ Functions</h3>
<tr><td>None</td></tr>
</table>
<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>
<h2 style="background-color:#FFFFFF;color:#0000FF">IOBase</h2>
<p>
@@ -415,6 +477,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#IOList.__iter__">__iter__</a></td>
<td>Gibt Iterator aller IOs zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#IOList.__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>Ersetzt bestehende IOs durch den neu Registrierten.</td>
</tr><tr>
@@ -481,7 +546,7 @@ Verwaltet geloeschte IOs (Attribute, die nicht existieren).
</p><dl>
<dt><i>key</i></dt>
<dd>
Wert eines alten IOs
Name oder Byte eines alten IOs
</dd>
</dl><dl>
<dt>Returns:</dt>
@@ -494,15 +559,21 @@ IOList.__getitem__</h3>
<b>__getitem__</b>(<i>key</i>)
<p>
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>
<dt><i>key</i></dt>
<dd>
IO Name oder Byte
IO Name als <class 'str> oder Byte als <class 'int'>.
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
IO Object
IO Objekt oder Liste der IOs
</dd>
</dl><a NAME="IOList.__iter__" ID="IOList.__iter__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
@@ -515,6 +586,17 @@ Gibt Iterator aller IOs zurueck.
<dd>
Iterator aller IOs
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
IOList.__private_replace_oldio_with_newio</h3>
@@ -721,7 +803,7 @@ IOBase
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
@@ -735,6 +817,9 @@ Methods</h3>
<td><a style="color:#0000FF" href="#StructIO.__init__">StructIO</a></td>
<td>Erstellt einen IO mit struct-Formatierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#StructIO._get_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>Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.</td>
</tr><tr>
@@ -774,6 +859,17 @@ Weitere Parameter:
- byteorder: Byteorder fuer den Input, Standardwert=little
- defaultvalue: Standardwert fuer Output, Standard ist 0
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
StructIO._get_signed</h3>

View File

@@ -146,9 +146,6 @@ Methods</h3>
<td><a style="color:#0000FF" href="#RevPiModIO.syncoutputs">syncoutputs</a></td>
<td>Lesen aller aktuell gesetzten Outputs im Prozessabbild.</td>
</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>Schreiben aller Outputs aller Devices ins Prozessabbild.</td>
</tr>
@@ -470,14 +467,13 @@ None
</dl><a NAME="RevPiModIO.readprocimg" ID="RevPiModIO.readprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.readprocimg</h3>
<b>readprocimg</b>(<i>force=False, device=None</i>)
<b>readprocimg</b>(<i>device=None</i>)
<p>
Einlesen aller Inputs aller/eines Devices vom Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl>
<dt><i>force</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>
@@ -495,28 +491,24 @@ Setzt aktuellen IOError-Zaehler auf 0 zurueck.
</p><a NAME="RevPiModIO.setdefaultvalues" ID="RevPiModIO.setdefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.setdefaultvalues</h3>
<b>setdefaultvalues</b>(<i>force=False, device=None</i>)
<b>setdefaultvalues</b>(<i>device=None</i>)
<p>
Alle Outputbuffer werden auf die piCtory default Werte gesetzt.
</p><dl>
<dt><i>force</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>
</dl><a NAME="RevPiModIO.syncoutputs" ID="RevPiModIO.syncoutputs"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.syncoutputs</h3>
<b>syncoutputs</b>(<i>force=False, device=None</i>)
<b>syncoutputs</b>(<i>device=None</i>)
<p>
Lesen aller aktuell gesetzten Outputs im Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl>
<dt><i>force</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>
@@ -525,39 +517,16 @@ nur auf einzelnes Device anwenden
<dd>
True, wenn Arbeiten an allen Devices erfolgreich waren
</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>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.writeprocimg</h3>
<b>writeprocimg</b>(<i>force=False, device=None</i>)
<b>writeprocimg</b>(<i>device=None</i>)
<p>
Schreiben aller Outputs aller Devices ins Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl>
<dt><i>force</i></dt>
<dd>
auch Devices mit autoupdate=False
</dd><dt><i>device</i></dt>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>

View File

@@ -8,13 +8,14 @@ revpimodio2.app.App?1(app)
revpimodio2.device.Core.A1?7
revpimodio2.device.Core.A2?7
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.errorlimit2?4(value)
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.ioerrorcount?4()
revpimodio2.device.Core.leftgate?4()
@@ -22,22 +23,25 @@ revpimodio2.device.Core.missingdeviceorgate?4()
revpimodio2.device.Core.overunderflow?4()
revpimodio2.device.Core.picontrolrunning?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.temperatur?4()
revpimodio2.device.Core.unconfdevice?4()
revpimodio2.device.Device._buildio?5(dict_io, iotype)
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_inputs?4()
revpimodio2.device.Device.get_memmories?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.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.get_tofc?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.stop?4()
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_byteorder?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.signed?7
revpimodio2.io.IntIO.value?7
revpimodio2.io.StructIO._get_frm?5()
revpimodio2.io.StructIO._get_signed?5()
revpimodio2.io.StructIO.frm?7
revpimodio2.io.StructIO.get_structvalue?4()
revpimodio2.io.StructIO.set_structvalue?4(value)
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.monitoring?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.setdefaultvalues?4(force=False, device=None)
revpimodio2.modio.RevPiModIO.setdefaultvalues?4(device=None)
revpimodio2.modio.RevPiModIO.simulator?7
revpimodio2.modio.RevPiModIO.syncoutputs?4(force=False, device=None)
revpimodio2.modio.RevPiModIO.writedefaultinputs?4(virtual_device)
revpimodio2.modio.RevPiModIO.writeprocimg?4(force=False, device=None)
revpimodio2.modio.RevPiModIO.syncoutputs?4(device=None)
revpimodio2.modio.RevPiModIO.writeprocimg?4(device=None)
revpimodio2.modio.RevPiModIO?1(**kwargs)
revpimodio2.modio.RevPiModIODriver?1(vdev, **kwargs)
revpimodio2.modio.RevPiModIOSelected?1(deviceselection, **kwargs)

View File

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

View File

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

View File

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

View File

@@ -65,7 +65,6 @@ class RevPiModIO(object):
self._lst_devselect = []
self._lst_refresh = []
self._maxioerrors = 0
self._myfh = self._create_myfh()
self._th_mainloop = None
self._waitexit = Event()
@@ -78,6 +77,9 @@ class RevPiModIO(object):
self.io = None
self.summary = None
# Filehandler öffnen
self._myfh = self._create_myfh()
# Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiModIO:
self._configure()
@@ -85,6 +87,7 @@ class RevPiModIO(object):
def __del__(self):
"""Zerstoert alle Klassen um aufzuraeumen."""
self.exit(full=True)
if hasattr(self, "_myfh"):
self._myfh.close()
def __evt_exit(self, signum, sigframe):
@@ -139,7 +142,6 @@ class RevPiModIO(object):
# Bei VDev in alter piCtory Version, Position eindeutig machen
if device["position"] == "adap.":
device["position"] = -1
# NOTE: Testen mit alter piCtory Version
while device["position"] in self.device:
device["position"] -= 1
@@ -155,7 +157,7 @@ class RevPiModIO(object):
for io in dev_new.get_outputs():
io.set_value(io.defaultvalue)
if not self._monitoring:
self.writeprocimg(True, dev_new)
self.writeprocimg(dev_new)
elif device["type"] == "LEFT_RIGHT":
# IOs
@@ -209,7 +211,7 @@ class RevPiModIO(object):
# Aktuellen Outputstatus von procimg einlesen
if self._syncoutputs:
self.syncoutputs(force=True)
self.syncoutputs()
# Optional ins autorefresh aufnehmen
if self._autorefresh:
@@ -237,6 +239,9 @@ class RevPiModIO(object):
def _get_ioerrors(self):
"""Getter function.
@return Aktuelle Anzahl gezaehlter Fehler"""
if self._looprunning:
return self._imgwriter._ioerror
else:
return self._ioerror
def _get_length(self):
@@ -397,14 +402,14 @@ class RevPiModIO(object):
self._exit.set()
self._waitexit.set()
if full:
if self._imgwriter.is_alive():
if self._imgwriter is not None and self._imgwriter.is_alive():
self._imgwriter.stop()
self._imgwriter.join(self._imgwriter._refresh)
while len(self._lst_refresh) > 0:
dev = self._lst_refresh.pop()
dev._selfupdate = False
if not self._monitoring:
self.writeprocimg(True, dev)
self.writeprocimg(dev)
self._looprunning = False
def get_jconfigrsc(self):
@@ -541,17 +546,17 @@ class RevPiModIO(object):
for io_event in dev._dict_events:
if dev._ba_datacp[io_event.slc_address] == \
dev._ba_devdata[io_event.slc_address]:
if dev._ba_datacp[io_event._slc_address] == \
dev._ba_devdata[io_event._slc_address]:
continue
if io_event._bitaddress >= 0:
boolcp = bool(int.from_bytes(
dev._ba_datacp[io_event.slc_address],
dev._ba_datacp[io_event._slc_address],
byteorder=io_event._byteorder
) & 1 << io_event._bitaddress)
boolor = bool(int.from_bytes(
dev._ba_devdata[io_event.slc_address],
dev._ba_devdata[io_event._slc_address],
byteorder=io_event._byteorder
) & 1 << io_event._bitaddress)
@@ -603,10 +608,11 @@ class RevPiModIO(object):
# Mainloop verlassen
self._looprunning = False
def readprocimg(self, force=False, device=None):
def readprocimg(self, device=None):
"""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
@return True, wenn Arbeiten an allen Devices erfolgreich waren
@@ -633,20 +639,20 @@ class RevPiModIO(object):
return False
for dev in mylist:
if (force or dev.autoupdate) and not dev._selfupdate:
if not dev._selfupdate:
# FileHandler sperren
dev._filelock.acquire()
if self._monitoring:
# Alles vom Bus einlesen
dev._ba_devdata[:] = bytesbuff[dev.slc_devoff]
dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
else:
# 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
dev._ba_devdata[dev.slc_mem] = bytesbuff[dev.slc_memoff]
dev._ba_devdata[dev._slc_mem] = bytesbuff[dev._slc_memoff]
dev._filelock.release()
@@ -657,9 +663,8 @@ class RevPiModIO(object):
self._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.
@param force auch Devices mit autoupdate=False
@param device nur auf einzelnes Device anwenden"""
if self._monitoring:
raise RuntimeError(
@@ -675,14 +680,14 @@ class RevPiModIO(object):
mylist = [dev]
for dev in mylist:
if (force or dev.autoupdate):
for io in dev.get_outputs():
io.set_value(io.defaultvalue)
def syncoutputs(self, force=False, device=None):
def syncoutputs(self, device=None):
"""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
@return True, wenn Arbeiten an allen Devices erfolgreich waren
@@ -708,65 +713,18 @@ class RevPiModIO(object):
return False
for dev in mylist:
if (force or dev.autoupdate) and not dev._selfupdate:
if not dev._selfupdate:
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()
return True
def writedefaultinputs(self, virtual_device):
"""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):
def writeprocimg(self, device=None):
"""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
@return True, wenn Arbeiten an allen Devices erfolgreich waren
@@ -792,13 +750,13 @@ class RevPiModIO(object):
workokay = True
for dev in mylist:
if (force or dev.autoupdate) and not dev._selfupdate:
if not dev._selfupdate:
dev._filelock.acquire()
# Outpus auf Bus schreiben
try:
self._myfh.seek(dev.slc_outoff.start)
self._myfh.write(dev._ba_devdata[dev.slc_out])
self._myfh.seek(dev._slc_outoff.start)
self._myfh.write(dev._ba_devdata[dev._slc_out])
except IOError:
workokay = False