From e124da758f0d9a72b34acb11c2d99337af3418e0 Mon Sep 17 00:00:00 2001 From: NaruX Date: Wed, 16 Aug 2017 17:14:36 +0200 Subject: [PATCH] =?UTF-8?q?Starke=20Leistungsverbesserung=20bei=20device.g?= =?UTF-8?q?et=5F*s()=20auto=5Frefresh=20in=20autorefresh=20=C3=BCberall=20?= =?UTF-8?q?umbenannt=20ioerror=20Z=C3=A4hler=20auch=20in=20RevPiModIO=20ei?= =?UTF-8?q?ngebaut=20=5Fadjwait=20wird=20bei=20Umstellung=20gleich=20mit?= =?UTF-8?q?=20DIFF=20gesetzt=20=5Fba=5Fdevdata=20wird=20nach=20IOs=20volls?= =?UTF-8?q?t=C3=A4ndig=20erstellt=20StructIO=20Instantiierung=20vereinfach?= =?UTF-8?q?t=20/=20byteorder,=20signed=20automatisch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/revpimodio2.device.html | 28 ++++---- doc/revpimodio2.helper.html | 52 ++++++++++++-- doc/revpimodio2.io.html | 107 ++++++++++++++++------------ doc/revpimodio2.modio.html | 106 ++++++++++++++++++--------- eric-revpimodio.api | 34 ++++++--- revpimodio2.e4p | 5 +- revpimodio2/device.py | 138 +++++++++++++++++------------------- revpimodio2/helper.py | 33 +++++++-- revpimodio2/io.py | 87 ++++++++++++++--------- revpimodio2/modio.py | 128 +++++++++++++++++++-------------- 10 files changed, 443 insertions(+), 275 deletions(-) diff --git a/doc/revpimodio2.device.html b/doc/revpimodio2.device.html index 10d480c..841c06a 100644 --- a/doc/revpimodio2.device.html +++ b/doc/revpimodio2.device.html @@ -22,7 +22,7 @@ Classes Klasse fuer den RevPi Core. Device -Basisklasse fuer alle Device-Objekte der RevPiDevicelist()-Klasse. +Basisklasse fuer alle Device-Objekte. DeviceList Basisklasse fuer direkten Zugriff auf Device Objekte. @@ -344,13 +344,11 @@ True, wenn IO Modul nicht konfiguriert

Device

-Basisklasse fuer alle Device-Objekte der RevPiDevicelist()-Klasse. +Basisklasse fuer alle Device-Objekte.

Die Basisfunktionalitaet generiert bei Instantiierung alle IOs und - erweitert den Prozessabbildpuffer um die benoetigten Bytes. Ueber diese - Klasse oder von dieser abgeleiteten Klassen, werden alle IOs angesprochen. - Sie verwaltet ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung - der IO-Werte. + erweitert den Prozessabbildpuffer um die benoetigten Bytes. Sie verwaltet + ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung der IO-Werte.

@@ -398,11 +396,11 @@ Methods _devconfigure Funktion zum ueberschreiben von abgeleiteten Klassen. -auto_refresh -Registriert ein Device fuer die automatische Synchronisierung. +autorefresh +Registriert dieses Device fuer die automatische Synchronisierung. get_allios -Gibt eine Liste aller Inputs und Outputs zurueck. +Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs. get_inps Gibt eine Liste aller Inputs zurueck. @@ -436,7 +434,7 @@ dict() fuer dieses Device aus piCotry Konfiguration
Weitere Parameter: - autoupdate: Wenn True fuehrt dieses Device Arbeiten am - Prozessabbild bei Aufruf der RevPiDevicelist-Funktionen aus + Prozessabbild bei Aufruf der read- writeprocimg Funktionen aus - simulator: Laed das Modul als Simulator und vertauscht IOs
@@ -535,12 +533,12 @@ Device._devconfigure _devconfigure()

Funktion zum ueberschreiben von abgeleiteten Klassen. -

+

-Device.auto_refresh

-auto_refresh(remove=False) +Device.autorefresh +autorefresh(remove=False)

-Registriert ein Device fuer die automatische Synchronisierung. +Registriert dieses Device fuer die automatische Synchronisierung.

remove
@@ -551,7 +549,7 @@ bool() True entfernt Device aus Synchronisierung Device.get_allios get_allios()

-Gibt eine Liste aller Inputs und Outputs zurueck. +Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.

Returns:
diff --git a/doc/revpimodio2.helper.html b/doc/revpimodio2.helper.html index c74c985..ac2ef59 100644 --- a/doc/revpimodio2.helper.html +++ b/doc/revpimodio2.helper.html @@ -318,7 +318,7 @@ Thread

Class Attributes

- +
refresh
ioerrors
maxioerrors
refresh

Class Methods

@@ -332,8 +332,14 @@ Methods ProcimgWriter Init ProcimgWriter class. +_get_ioerrors +Ruft aktuelle Anzahl der Fehler ab. + _gotioerror -IOError Verwaltung fuer auto_refresh. +IOError Verwaltung fuer autorefresh. + +get_maxioerrors +Gibt die Anzahl der maximal erlaubten Fehler zurueck. get_refresh Gibt Zykluszeit zurueck. @@ -341,6 +347,9 @@ Methods run Startet die automatische Prozessabbildsynchronisierung. +set_maxioerrors +Setzt die Anzahl der maximal erlaubten Fehler. + set_refresh Setzt die Zykluszeit in Millisekunden. @@ -364,13 +373,35 @@ Init ProcimgWriter class.
Parent Object
+
+

+ProcimgWriter._get_ioerrors

+_get_ioerrors() +

+Ruft aktuelle Anzahl der Fehler ab. +

+
Returns:
+
+Aktuelle Fehleranzahl +

ProcimgWriter._gotioerror

_gotioerror()

-IOError Verwaltung fuer auto_refresh. -

+IOError Verwaltung fuer autorefresh. +

+

+ProcimgWriter.get_maxioerrors

+get_maxioerrors() +

+Gibt die Anzahl der maximal erlaubten Fehler zurueck. +

+
Returns:
+
+Anzahl erlaubte Fehler +
+

ProcimgWriter.get_refresh

get_refresh() @@ -387,7 +418,18 @@ ProcimgWriter.run run()

Startet die automatische Prozessabbildsynchronisierung. -

+

+

+ProcimgWriter.set_maxioerrors

+set_maxioerrors(value) +

+Setzt die Anzahl der maximal erlaubten Fehler. +

+
value
+
+Anzahl erlaubte Fehler +
+

ProcimgWriter.set_refresh

set_refresh(value) diff --git a/doc/revpimodio2.io.html b/doc/revpimodio2.io.html index dd1dad9..b6f4bf9 100644 --- a/doc/revpimodio2.io.html +++ b/doc/revpimodio2.io.html @@ -58,7 +58,7 @@ object

Class Attributes

- +
address
length
name
value
address
byteorder
length
name
value

Class Methods

@@ -81,16 +81,16 @@ Methods __str__ str()-wert der Klasse. +_get_address +Gibt die absolute Byteadresse im Prozessabbild zurueck. + _get_byteorder Gibt konfigurierte Byteorder zurueck. -get_address -Gibt die absolute Byteadresse im Prozessabbild zurueck. - -get_length +_get_length Gibt die Bytelaenge des IO zurueck. -get_name +_get_name Gibt den Namen des IOs zurueck. get_value @@ -120,7 +120,7 @@ Static Methods

IOBase (Constructor)

-IOBase(parentdevice, valuelist, iotype, byteorder) +IOBase(parentdevice, valuelist, iotype, byteorder, signed)

Instantiierung der IOBase()-Klasse.

@@ -136,6 +136,9 @@ IOType() Wert
byteorder
Byteorder 'little' / 'big' fuer int() Berechnung +
sigend
+
+Intberechnung mit Vorzeichen durchfuehren

@@ -170,6 +173,17 @@ str()-wert der Klasse.
Namen des IOs
+ +

+IOBase._get_address

+_get_address() +

+Gibt die absolute Byteadresse im Prozessabbild zurueck. +

+
Returns:
+
+Absolute Byteadresse +

IOBase._get_byteorder

@@ -181,21 +195,10 @@ Gibt konfigurierte Byteorder zurueck.
str() Byteorder
- +

-IOBase.get_address

-get_address() -

-Gibt die absolute Byteadresse im Prozessabbild zurueck. -

-
Returns:
-
-Absolute Byteadresse -
-
-

-IOBase.get_length

-get_length() +IOBase._get_length +_get_length()

Gibt die Bytelaenge des IO zurueck.

@@ -203,10 +206,10 @@ Gibt die Bytelaenge des IO zurueck.
Bytelaenge des IO
-
+

-IOBase.get_name

-get_name() +IOBase._get_name +_get_name()

Gibt den Namen des IOs zurueck.

@@ -304,7 +307,7 @@ IOBase.wait Wartet auf Wertaenderung eines IOs.

Die Wertaenderung wird immer uerberprueft, wenn fuer Devices - in Devicelist.auto_refresh() neue Daten gelesen wurden. + mit aktiviertem autorefresh neue Daten gelesen wurden.

Bei Wertaenderung, wird das Warten mit 0 als Rueckgabewert beendet.

@@ -324,7 +327,7 @@ Wartet auf Wertaenderung eines IOs.

Der Timeoutwert bricht beim Erreichen das Warten sofort mit Wert 2 Rueckgabewert ab. (Das Timeout wird ueber die Zykluszeit - der auto_refresh Funktion berechnet, entspricht also nicht exact den + der autorefresh Funktion berechnet, entspricht also nicht exact den angegeben Millisekunden! Es wird immer nach oben gerundet!)

edge
@@ -387,7 +390,7 @@ Methods Entfernt angegebenen IO. __getattr__ -Verwaltet geloeschte IOs. +Verwaltet geloeschte IOs (Attribute, die nicht existieren). __getitem__ Ruft angegebenen IO ab. @@ -395,7 +398,7 @@ Methods __iter__ Gibt Iterator aller IOs zurueck. -__replace_oldio_with_newio +__private_replace_oldio_with_newio Ersetzt bestehende IOs durch den neu Registrierten. __setattr__ @@ -404,7 +407,10 @@ Methods __setitem__ Setzt IO Wert. -_register_new_io_object +_getdict + + +_private_register_new_io_object Registriert neues IO Objekt unabhaenging von __setattr__. _testme @@ -454,7 +460,7 @@ IO zum entfernen IOList.__getattr__ __getattr__(key)

-Verwaltet geloeschte IOs. +Verwaltet geloeschte IOs (Attribute, die nicht existieren).

key
@@ -492,10 +498,10 @@ Gibt Iterator aller IOs zurueck.
Iterator aller IOs
-
+

-IOList.__replace_oldio_with_newio

-__replace_oldio_with_newio(io) +IOList.__private_replace_oldio_with_newio +__private_replace_oldio_with_newio(io)

Ersetzt bestehende IOs durch den neu Registrierten.

@@ -531,10 +537,14 @@ IO Name oder Byte
Wert, auf den der IO gesetzt wird
-
+

-IOList._register_new_io_object

-_register_new_io_object(new_io) +IOList._getdict +_getdict() + +

+IOList._private_register_new_io_object

+_private_register_new_io_object(new_io)

Registriert neues IO Objekt unabhaenging von __setattr__.

@@ -694,7 +704,7 @@ IOBase

Class Attributes

- +
byteorder
value
signed
value

Class Methods

@@ -708,6 +718,9 @@ Methods StructIO Erstellt einen IO mit struct-Formatierung. +_get_signed +Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll. + get_structvalue Gibt den Wert mit struct Formatierung zurueck. @@ -723,7 +736,7 @@ Static Methods

StructIO (Constructor)

-StructIO(parentio, name, iotype, byteorder, frm, **kwargs) +StructIO(parentio, name, frm, **kwargs)

Erstellt einen IO mit struct-Formatierung.

@@ -733,12 +746,6 @@ ParentIO Objekt, welches ersetzt wird
name
Name des neuen IO -
iotype
-
-IOType() Wert -
byteorder
-
-Byteorder 'little' / 'big' fuer int() Berechnung
frm
struct() formatierung (1 Zeichen) @@ -747,8 +754,20 @@ struct() formatierung (1 Zeichen) Weitere Parameter: - bmk: Bezeichnung fuer Output - bit: Registriert Outputs als bool() am angegebenen Bit im Byte + - byteorder: Byteorder fuer den Input, Standardwert=little - defaultvalue: Standardwert fuer Output, Standard ist 0
+
+

+StructIO._get_signed

+_get_signed() +

+Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll. +

+
Returns:
+
+True, wenn Vorzeichenbehaftet +

StructIO.get_structvalue

diff --git a/doc/revpimodio2.modio.html b/doc/revpimodio2.modio.html index 3edb328..865b710 100644 --- a/doc/revpimodio2.modio.html +++ b/doc/revpimodio2.modio.html @@ -54,7 +54,7 @@ object

Class Attributes

- +
configrsc
cycletime
length
monitoring
procimg
simulator
configrsc
cycletime
ioerrors
length
maxioerrors
monitoring
procimg
simulator

Class Methods

@@ -86,9 +86,15 @@ Methods _get_cycletime Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus. +_get_ioerrors +Getter function. + _get_length Getter function. +_get_maxioerrors +Getter function. + _get_monitoring Getter function. @@ -98,23 +104,26 @@ Methods _get_simulator Getter function. +_gotioerror +IOError Verwaltung fuer Prozessabbildzugriff. + _set_cycletime Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung. -auto_refresh_maxioerrors -Maximale IO Fehler fuer auto_refresh. +_set_maxioerrors +Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff. -auto_refresh_resetioerrors -Setzt aktuellen IOError-Zaehler auf 0 zurueck. +autorefresh_all +Setzt alle Devices in autorefresh Funktion. cleanup -Beendet auto_refresh und alle Threads. +Beendet autorefresh und alle Threads. cycleloop Startet den Cycleloop. exit -Beendet mainloop() und optional auto_refresh. +Beendet mainloop() und optional autorefresh. get_jconfigrsc Laed die piCotry Konfiguration und erstellt ein dict(). @@ -128,6 +137,9 @@ Methods readprocimg Einlesen aller Inputs aller/eines Devices vom Prozessabbild. +resetioerrors +Setzt aktuellen IOError-Zaehler auf 0 zurueck. + setdefaultvalues Alle Outputbuffer werden auf die piCtory default Werte gesetzt. @@ -156,7 +168,7 @@ Instantiiert die Grundfunktionen.
kwargs
Weitere Parameter: - - auto_refresh: Wenn True, alle Devices zu auto_refresh hinzufuegen + - autorefresh: Wenn True, alle Devices zu autorefresh hinzufuegen - configrsc: Pfad zur piCtory Konfigurationsdatei - procimg: Pfad zum Prozessabbild - monitoring: In- und Outputs werden gelesen, niemals geschrieben @@ -218,6 +230,17 @@ Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.
Millisekunden
+
+

+RevPiModIO._get_ioerrors

+_get_ioerrors() +

+Getter function. +

+
Returns:
+
+Aktuelle Anzahl gezaehlter Fehler +

RevPiModIO._get_length

@@ -229,6 +252,17 @@ Getter function.
Laenge in Bytes der Devices
+ +

+RevPiModIO._get_maxioerrors

+_get_maxioerrors() +

+Getter function. +

+
Returns:
+
+Anzahl erlaubte Fehler +

RevPiModIO._get_monitoring

@@ -262,7 +296,13 @@ Getter function.
True, wenn als Simulator gestartet
- + +

+RevPiModIO._gotioerror

+_gotioerror(action) +

+IOError Verwaltung fuer Prozessabbildzugriff. +

RevPiModIO._set_cycletime

_set_cycletime(milliseconds) @@ -273,34 +313,29 @@ Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.
int() in Millisekunden
- +

-RevPiModIO.auto_refresh_maxioerrors

-auto_refresh_maxioerrors(value=None) +RevPiModIO._set_maxioerrors +_set_maxioerrors(value)

-Maximale IO Fehler fuer auto_refresh. +Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.

value
-Setzt maximale Anzahl bis exception ausgeloest wird +Anzahl erlaubte Fehler
-
-
Returns:
-
-Maximale Anzahl bis exception ausgeloest wird -
-
+

-RevPiModIO.auto_refresh_resetioerrors

-auto_refresh_resetioerrors() +RevPiModIO.autorefresh_all +autorefresh_all()

-Setzt aktuellen IOError-Zaehler auf 0 zurueck. +Setzt alle Devices in autorefresh Funktion.

RevPiModIO.cleanup

cleanup()

-Beendet auto_refresh und alle Threads. +Beendet autorefresh und alle Threads.

RevPiModIO.cycleloop

@@ -321,19 +356,18 @@ Startet den Cycleloop. revpimodio.exit().

HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen - die eingestellte auto_refresh Zeit, bzw. uebergebene cycletime nicht + die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht ueberschreiten!

- Ueber den Parameter cycletime kann die Aktualisierungsrate fuer das - Prozessabbild gesetzt werden (selbe Funktion wie - set_refreshtime(milliseconds)). + Ueber das Attribut cycletime kann die Aktualisierungsrate fuer das + Prozessabbild gesetzt werden.

func
Funktion, die ausgefuehrt werden soll
cycletime
-auto_refresh Wert in Millisekunden +autorefresh Wert in Millisekunden
Returns:
@@ -345,18 +379,18 @@ None RevPiModIO.exit exit(full=True)

-Beendet mainloop() und optional auto_refresh. +Beendet mainloop() und optional autorefresh.

Wenn sich das Programm im mainloop() befindet, wird durch Aufruf von exit() die Kontrolle wieder an das Hauptprogramm zurueckgegeben.

Der Parameter full ist mit True vorbelegt und entfernt alle Devices aus - dem auto_refresh. Der Thread fuer die Prozessabbildsynchronisierung + dem autorefresh. Der Thread fuer die Prozessabbildsynchronisierung wird dann gestoppt und das Programm kann sauber beendet werden.

full
-Entfernt auch alle Devices aus auto_refresh +Entfernt auch alle Devices aus autorefresh

@@ -452,7 +486,13 @@ nur auf einzelnes Device anwenden
True, wenn Arbeiten an allen Devices erfolgreich waren
-

+ +

+RevPiModIO.resetioerrors

+resetioerrors() +

+Setzt aktuellen IOError-Zaehler auf 0 zurueck. +

RevPiModIO.setdefaultvalues

setdefaultvalues(force=False, device=None) diff --git a/eric-revpimodio.api b/eric-revpimodio.api index c1c8100..b06c493 100644 --- a/eric-revpimodio.api +++ b/eric-revpimodio.api @@ -32,7 +32,7 @@ revpimodio2.device.Core.temperatur?4() revpimodio2.device.Core.unconfdevice?4() revpimodio2.device.Device._buildio?5(dict_io, iotype) revpimodio2.device.Device._devconfigure?5() -revpimodio2.device.Device.auto_refresh?4(remove=False) +revpimodio2.device.Device.autorefresh?4(remove=False) revpimodio2.device.Device.get_allios?4() revpimodio2.device.Device.get_inps?4() revpimodio2.device.Device.get_mems?4() @@ -52,18 +52,24 @@ revpimodio2.helper.Cycletools?1() revpimodio2.helper.EventCallback.run?4() revpimodio2.helper.EventCallback.stop?4() revpimodio2.helper.EventCallback?1(func, name, value) +revpimodio2.helper.ProcimgWriter._get_ioerrors?5() revpimodio2.helper.ProcimgWriter._gotioerror?5() +revpimodio2.helper.ProcimgWriter.get_maxioerrors?4() revpimodio2.helper.ProcimgWriter.get_refresh?4() +revpimodio2.helper.ProcimgWriter.ioerrors?7 +revpimodio2.helper.ProcimgWriter.maxioerrors?7 revpimodio2.helper.ProcimgWriter.refresh?7 revpimodio2.helper.ProcimgWriter.run?4() +revpimodio2.helper.ProcimgWriter.set_maxioerrors?4(value) revpimodio2.helper.ProcimgWriter.set_refresh?4(value) revpimodio2.helper.ProcimgWriter.stop?4() revpimodio2.helper.ProcimgWriter?1(parentmodio) +revpimodio2.io.IOBase._get_address?5() revpimodio2.io.IOBase._get_byteorder?5() +revpimodio2.io.IOBase._get_length?5() +revpimodio2.io.IOBase._get_name?5() revpimodio2.io.IOBase.address?7 -revpimodio2.io.IOBase.get_address?4() -revpimodio2.io.IOBase.get_length?4() -revpimodio2.io.IOBase.get_name?4() +revpimodio2.io.IOBase.byteorder?7 revpimodio2.io.IOBase.get_value?4() revpimodio2.io.IOBase.length?7 revpimodio2.io.IOBase.name?7 @@ -73,8 +79,9 @@ revpimodio2.io.IOBase.set_value?4(value) revpimodio2.io.IOBase.unreg_event?4(func=None, edge=None) revpimodio2.io.IOBase.value?7 revpimodio2.io.IOBase.wait?4(edge=BOTH, exitevent=None, okvalue=None, timeout=0) -revpimodio2.io.IOBase?1(parentdevice, valuelist, iotype, byteorder) -revpimodio2.io.IOList._register_new_io_object?5(new_io) +revpimodio2.io.IOBase?1(parentdevice, valuelist, iotype, byteorder, signed) +revpimodio2.io.IOList._getdict?5() +revpimodio2.io.IOList._private_register_new_io_object?5(new_io) revpimodio2.io.IOList._testme?5() revpimodio2.io.IOList?1() revpimodio2.io.IntIO._get_signed?5() @@ -85,22 +92,26 @@ revpimodio2.io.IntIO.get_int?4() revpimodio2.io.IntIO.set_int?4(value) revpimodio2.io.IntIO.signed?7 revpimodio2.io.IntIO.value?7 -revpimodio2.io.StructIO.byteorder?7 +revpimodio2.io.StructIO._get_signed?5() revpimodio2.io.StructIO.get_structvalue?4() revpimodio2.io.StructIO.set_structvalue?4(value) +revpimodio2.io.StructIO.signed?7 revpimodio2.io.StructIO.value?7 -revpimodio2.io.StructIO?1(parentio, name, iotype, byteorder, frm, **kwargs) +revpimodio2.io.StructIO?1(parentio, name, frm, **kwargs) revpimodio2.modio.RevPiModIO._configure?5() revpimodio2.modio.RevPiModIO._create_myfh?5() revpimodio2.modio.RevPiModIO._get_configrsc?5() revpimodio2.modio.RevPiModIO._get_cycletime?5() +revpimodio2.modio.RevPiModIO._get_ioerrors?5() revpimodio2.modio.RevPiModIO._get_length?5() +revpimodio2.modio.RevPiModIO._get_maxioerrors?5() revpimodio2.modio.RevPiModIO._get_monitoring?5() revpimodio2.modio.RevPiModIO._get_procimg?5() revpimodio2.modio.RevPiModIO._get_simulator?5() +revpimodio2.modio.RevPiModIO._gotioerror?5(action) revpimodio2.modio.RevPiModIO._set_cycletime?5(milliseconds) -revpimodio2.modio.RevPiModIO.auto_refresh_maxioerrors?4(value=None) -revpimodio2.modio.RevPiModIO.auto_refresh_resetioerrors?4() +revpimodio2.modio.RevPiModIO._set_maxioerrors?5(value) +revpimodio2.modio.RevPiModIO.autorefresh_all?4() revpimodio2.modio.RevPiModIO.cleanup?4() revpimodio2.modio.RevPiModIO.configrsc?7 revpimodio2.modio.RevPiModIO.cycleloop?4(func, cycletime=50) @@ -108,11 +119,14 @@ revpimodio2.modio.RevPiModIO.cycletime?7 revpimodio2.modio.RevPiModIO.exit?4(full=True) revpimodio2.modio.RevPiModIO.get_jconfigrsc?4() revpimodio2.modio.RevPiModIO.handlesignalend?4(cleanupfunc=None) +revpimodio2.modio.RevPiModIO.ioerrors?7 revpimodio2.modio.RevPiModIO.length?7 revpimodio2.modio.RevPiModIO.mainloop?4(freeze=False, blocking=True) +revpimodio2.modio.RevPiModIO.maxioerrors?7 revpimodio2.modio.RevPiModIO.monitoring?7 revpimodio2.modio.RevPiModIO.procimg?7 revpimodio2.modio.RevPiModIO.readprocimg?4(force=False, device=None) +revpimodio2.modio.RevPiModIO.resetioerrors?4() revpimodio2.modio.RevPiModIO.setdefaultvalues?4(force=False, device=None) revpimodio2.modio.RevPiModIO.simulator?7 revpimodio2.modio.RevPiModIO.syncoutputs?4(force=False, device=None) diff --git a/revpimodio2.e4p b/revpimodio2.e4p index e71ed34..6ac1a3e 100644 --- a/revpimodio2.e4p +++ b/revpimodio2.e4p @@ -1,7 +1,7 @@ - + en_US @@ -25,6 +25,7 @@ test/test_dio_while2.py test/test_dio_mainloop.py test/test_dio_cycleloop.py + revpimodio2/net.py @@ -173,6 +174,7 @@ setup.py + net.py @@ -219,6 +221,7 @@ setup.py + net.py diff --git a/revpimodio2/device.py b/revpimodio2/device.py index 4a161d0..9f6307b 100644 --- a/revpimodio2/device.py +++ b/revpimodio2/device.py @@ -25,8 +25,10 @@ class DeviceList(object): @return True, wenn Device vorhanden""" if type(key) == int: return key in self.__dict_position - else: + elif type(key) == str: return hasattr(self, key) + else: + return key in self.__dict_position.values() def __getitem__(self, key): """Gibt angegebenes Device zurueck. @@ -61,13 +63,11 @@ class DeviceList(object): class Device(object): - """Basisklasse fuer alle Device-Objekte der RevPiDevicelist()-Klasse. + """Basisklasse fuer alle Device-Objekte. Die Basisfunktionalitaet generiert bei Instantiierung alle IOs und - erweitert den Prozessabbildpuffer um die benoetigten Bytes. Ueber diese - Klasse oder von dieser abgeleiteten Klassen, werden alle IOs angesprochen. - Sie verwaltet ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung - der IO-Werte. + erweitert den Prozessabbildpuffer um die benoetigten Bytes. Sie verwaltet + ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung der IO-Werte. """ @@ -78,7 +78,7 @@ class Device(object): @param dict_device dict() fuer dieses Device aus piCotry Konfiguration @param kwargs Weitere Parameter: - autoupdate: Wenn True fuehrt dieses Device Arbeiten am - Prozessabbild bei Aufruf der RevPiDevicelist-Funktionen aus + Prozessabbild bei Aufruf der read- writeprocimg Funktionen aus - simulator: Laed das Modul als Simulator und vertauscht IOs """ @@ -87,7 +87,6 @@ class Device(object): self._dict_events = {} self._filelock = Lock() self._length = 0 - self._lst_io = [] self._selfupdate = False self.autoupdate = kwargs.get("autoupdate", True) @@ -98,11 +97,7 @@ class Device(object): self.position = int(dict_device.pop("position")) self.producttype = int(dict_device.pop("productType")) - # Neues bytearray und Kopie für mainloop anlegen - self._ba_devdata = bytearray() - self._ba_datacp = bytearray() - - # Erst inp/out/mem poppen, dann in Klasse einfügen + # IOM-Objekte erstellen und Adressen in SLCs speichern if kwargs.get("simulator", False): self.slc_inp = self._buildio(dict_device.pop("out"), IOType.INP) self.slc_out = self._buildio(dict_device.pop("inp"), IOType.OUT) @@ -123,6 +118,11 @@ class Device(object): self.slc_mem.start + self.offset, self.slc_mem.stop + self.offset ) + # Neues bytearray und Kopie für mainloop anlegen + # NOTE: Testen + self._ba_devdata = bytearray(self._length) + self._ba_datacp = bytearray() + # Alle restlichen attribute an Klasse anhängen self.__dict__.update(dict_device) @@ -156,8 +156,8 @@ class Device(object): def __iter__(self): """Gibt Iterator aller IOs zurueck. @return iter() aller IOs""" - for i_byte in range(self.slc_devoff.start, self.slc_devoff.stop): - for io in self._modio.io[i_byte]: + for lst_io in self._modio.io[self.slc_devoff]: + for io in lst_io: yield io def __len__(self): @@ -178,52 +178,45 @@ class Device(object): @return slice()-Objekt mit Start und Stop Position dieser IOs """ - if len(dict_io) > 0: - int_min, int_max = 4096, 0 - for key in sorted(dict_io, key=lambda x: int(x)): - - # Neuen IO anlegen - if bool(dict_io[key][7]) or self.producttype == 95: - # Bei Bitwerten oder Core RevPiIOBase verwenden - io_new = iomodule.IOBase( - self, - dict_io[key], - iotype, - byteorder="little" - ) - else: - io_new = iomodule.IntIO( - self, - dict_io[key], - iotype, - byteorder="little" - ) - - # IO registrieren - self._modio.io._register_new_io_object(io_new) - - # Speicherbereich zuweisen - self._ba_devdata.extend(bytes(io_new._length)) - - 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 - - return slice(int_min, int_max) - - else: + if len(dict_io) <= 0: return slice(0, 0) + int_min, int_max = 4096, 0 + for key in sorted(dict_io, key=lambda x: int(x)): + + # Neuen IO anlegen + if bool(dict_io[key][7]) or self.producttype == 95: + # Bei Bitwerten oder Core RevPiIOBase verwenden + io_new = iomodule.IOBase( + self, dict_io[key], iotype, "little", False + ) + else: + io_new = iomodule.IntIO( + self, dict_io[key], + iotype, + "little", + self.producttype == 103 + ) + + # IO registrieren + self._modio.io._private_register_new_io_object(io_new) + + 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 + + return slice(int_min, int_max) + def _devconfigure(self): """Funktion zum ueberschreiben von abgeleiteten Klassen.""" pass - def auto_refresh(self, remove=False): - """Registriert ein Device fuer die automatische Synchronisierung. + def autorefresh(self, remove=False): + """Registriert dieses Device fuer die automatische Synchronisierung. @param remove bool() True entfernt Device aus Synchronisierung""" if not remove and self not in self._modio._lst_refresh: @@ -266,36 +259,37 @@ class Device(object): self._modio.writeprocimg(True, self) def get_allios(self): - """Gibt eine Liste aller Inputs und Outputs zurueck. + """Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs. @return list() Input und Output, keine MEMs""" - return [ - io for io in self._modio.io - if io._parentdevice == self and io._iotype != IOType.MEM - ] + lst_return = [] + for lst_io in self._modio.io[ + self.slc_inpoff.start:self.slc_outoff.stop]: + lst_return += lst_io + return lst_return def get_inps(self): """Gibt eine Liste aller Inputs zurueck. @return list() Inputs""" - return [ - io for io in self._modio.io - if io._parentdevice == self and io._iotype == IOType.INP - ] + lst_return = [] + for lst_io in self._modio.io[self.slc_inpoff]: + lst_return += lst_io + return lst_return def get_outs(self): """Gibt eine Liste aller Outputs zurueck. @return list() Outputs""" - return [ - io for io in self._modio.io - if io._parentdevice == self and io._iotype == IOType.OUT - ] + lst_return = [] + for lst_io in self._modio.io[self.slc_outoff]: + lst_return += lst_io + return lst_return def get_mems(self): """Gibt eine Liste aller mems zurueck. @return list() Mems""" - return [ - io for io in self._modio.io - if io._parentdevice == self and io._iotype == IOType.MEM - ] + lst_return = [] + for lst_io in self._modio.io[self.slc_memoff]: + lst_return += lst_io + return lst_return class Core(Device): diff --git a/revpimodio2/helper.py b/revpimodio2/helper.py index 638930b..1fe916e 100644 --- a/revpimodio2/helper.py +++ b/revpimodio2/helper.py @@ -228,22 +228,27 @@ class ProcimgWriter(Thread): super().__init__() self._adjwait = 0 self._ioerror = 0 + self._maxioerrors = 0 self._modio = parentmodio self._refresh = 0.05 self._work = Event() self.daemon = True self.lck_refresh = Lock() - self.maxioerrors = 0 self.newdata = Event() + def _get_ioerrors(self): + """Ruft aktuelle Anzahl der Fehler ab. + @return Aktuelle Fehleranzahl""" + return self._ioerror + def _gotioerror(self): - """IOError Verwaltung fuer auto_refresh.""" + """IOError Verwaltung fuer autorefresh.""" self._ioerror += 1 - if self.maxioerrors != 0 and self._ioerror >= self.maxioerrors: + if self._maxioerrors != 0 and self._ioerror >= self._maxioerrors: raise RuntimeError( "reach max io error count {} on process image".format( - self.maxioerrors + self._maxioerrors ) ) warnings.warn( @@ -251,6 +256,11 @@ class ProcimgWriter(Thread): RuntimeWarning ) + def get_maxioerrors(self): + """Gibt die Anzahl der maximal erlaubten Fehler zurueck. + @return Anzahl erlaubte Fehler""" + return self._maxioerrors + def get_refresh(self): """Gibt Zykluszeit zurueck. @return int() Zykluszeit in Millisekunden""" @@ -342,15 +352,26 @@ class ProcimgWriter(Thread): """Beendet die automatische Prozessabbildsynchronisierung.""" self._work.set() + def set_maxioerrors(self, value): + """Setzt die Anzahl der maximal erlaubten Fehler. + @param value Anzahl erlaubte Fehler""" + if type(value) == int and value >= 0: + self._maxioerrors = value + else: + raise ValueError("value must be 0 or a positive integer") + def set_refresh(self, value): """Setzt die Zykluszeit in Millisekunden. @param value int() Millisekunden""" - if value >= 10 and value < 2000: + if type(value) == int and 10 <= value <= 2000: + waitdiff = self._refresh - self._adjwait self._refresh = value / 1000 - self._adjwait = self._refresh + self._adjwait = self._refresh - waitdiff else: raise ValueError( "refresh time must be 10 to 2000 milliseconds" ) + ioerrors = property(_get_ioerrors) + maxioerrors = property(get_maxioerrors, set_maxioerrors) refresh = property(get_refresh, set_refresh) diff --git a/revpimodio2/io.py b/revpimodio2/io.py index 3bfcc45..06b57ba 100644 --- a/revpimodio2/io.py +++ b/revpimodio2/io.py @@ -46,7 +46,7 @@ class IOList(object): object.__delattr__(self, key) def __getattr__(self, key): - """Verwaltet geloeschte IOs. + """Verwaltet geloeschte IOs (Attribute, die nicht existieren). @param key Wert eines alten IOs @return Alten IO, wenn in Ref-Listen""" if key in self.__dict_iorefname: @@ -65,6 +65,11 @@ class IOList(object): return self.__dict_iobyte[key] else: raise KeyError("byte '{}' does not exist".format(key)) + elif type(key) == slice: + return [ + self.__dict_iobyte[int_io] + for int_io in range(key.start, key.stop) + ] else: return getattr(self, key) @@ -105,12 +110,11 @@ class IOList(object): "_IOList__dict_iorefbyte" ]: object.__setattr__(self, key, value) - else: # Setzt Wert bei Zuweisung getattr(self, key).value = value - def __replace_oldio_with_newio(self, io): + def __private_replace_oldio_with_newio(self, io): """Ersetzt bestehende IOs durch den neu Registrierten. @param io Neuer IO der eingefuegt werden soll""" for i in range(io.slc_address.start, io.slc_address.stop): @@ -125,7 +129,6 @@ class IOList(object): io._bitaddress, oldio._name ) ) - else: # Bereits überschriebene bytes() sind ungültig raise MemoryError( @@ -133,7 +136,6 @@ class IOList(object): io._name, oldio._name ) ) - elif oldio is not None: # IOs im Speicherbereich des neuen IO merken if io._bitaddress >= 0: @@ -144,7 +146,7 @@ class IOList(object): # ios aus listen entfernen delattr(self, oldio.name) - def _register_new_io_object(self, new_io): + def _private_register_new_io_object(self, new_io): """Registriert neues IO Objekt unabhaenging von __setattr__. @param new_io Neues IO Objekt""" if issubclass(type(new_io), IOBase): @@ -156,7 +158,7 @@ class IOList(object): ) if type(new_io) is StructIO: - self.__replace_oldio_with_newio(new_io) + self.__private_replace_oldio_with_newio(new_io) object.__setattr__(self, new_io.name, new_io) @@ -181,6 +183,10 @@ class IOList(object): print(self.__dict_iorefname) print(self.__dict_iorefbyte) + def _getdict(self): + # NOTE: Nur Debugging + return self.__dict_iobyte.copy() + class IOBase(object): @@ -196,13 +202,14 @@ class IOBase(object): """ - def __init__(self, parentdevice, valuelist, iotype, byteorder): + def __init__(self, parentdevice, valuelist, iotype, byteorder, signed): """Instantiierung der IOBase()-Klasse. @param parentdevice Parentdevice auf dem der IO liegt @param valuelist Datenliste fuer Instantiierung @param iotype IOType() Wert @param byteorder Byteorder 'little' / 'big' fuer int() Berechnung + @param sigend Intberechnung mit Vorzeichen durchfuehren """ self._parentdevice = parentdevice @@ -217,7 +224,7 @@ class IOBase(object): self._byteorder = byteorder self._iotype = iotype self._name = valuelist[0] - self._signed = False + self._signed = signed self.bmk = valuelist[6] int_startaddress = int(valuelist[3]) @@ -274,22 +281,22 @@ class IOBase(object): @return Namen des IOs""" return self._name + def _get_address(self): + """Gibt die absolute Byteadresse im Prozessabbild zurueck. + @return Absolute Byteadresse""" + return self._parentdevice.offset + self.slc_address.start + def _get_byteorder(self): """Gibt konfigurierte Byteorder zurueck. @return str() Byteorder""" return self._byteorder - def get_address(self): - """Gibt die absolute Byteadresse im Prozessabbild zurueck. - @return Absolute Byteadresse""" - return self._parentdevice.offset + self.slc_address.start - - def get_length(self): + def _get_length(self): """Gibt die Bytelaenge des IO zurueck. @return Bytelaenge des IO""" return self._length - def get_name(self): + def _get_name(self): """Gibt den Namen des IOs zurueck. @return IO Name""" return self._name @@ -384,12 +391,10 @@ class IOBase(object): io_new = StructIO( self, name, - self._iotype, - kwargs.get("byteorder", "little"), frm, **kwargs ) - self._parentdevice._modio.io._register_new_io_object(io_new) + self._parentdevice._modio.io._private_register_new_io_object(io_new) # Optional Event eintragen reg_event = kwargs.get("event", None) @@ -473,7 +478,7 @@ class IOBase(object): """Wartet auf Wertaenderung eines IOs. Die Wertaenderung wird immer uerberprueft, wenn fuer Devices - in Devicelist.auto_refresh() neue Daten gelesen wurden. + mit aktiviertem autorefresh neue Daten gelesen wurden. Bei Wertaenderung, wird das Warten mit 0 als Rueckgabewert beendet. @@ -493,7 +498,7 @@ class IOBase(object): Der Timeoutwert bricht beim Erreichen das Warten sofort mit Wert 2 Rueckgabewert ab. (Das Timeout wird ueber die Zykluszeit - der auto_refresh Funktion berechnet, entspricht also nicht exact den + der autorefresh Funktion berechnet, entspricht also nicht exact den angegeben Millisekunden! Es wird immer nach oben gerundet!) @param edge Flanke RISING, FALLING, BOTH bei der mit True beendet wird @@ -510,10 +515,10 @@ class IOBase(object): Wert 100: Devicelist.exit() wurde aufgerufen """ - # Prüfen ob Device in auto_refresh ist + # Prüfen ob Device in autorefresh ist if not self._parentdevice._selfupdate: raise RuntimeError( - "auto_refresh is not activated for device '{}|{}' - there " + "autorefresh is not activated for device '{}|{}' - there " "will never be new data".format( self._parentdevice.position, self._parentdevice.name ) @@ -570,9 +575,10 @@ class IOBase(object): # Timeout abgelaufen return 2 - address = property(get_address) - length = property(get_length) - name = property(get_name) + address = property(_get_address) + byteorder = property(_get_byteorder) + length = property(_get_length) + name = property(_get_name) value = property(get_value, set_value) @@ -651,29 +657,28 @@ class StructIO(IOBase): """ - def __init__(self, parentio, name, iotype, byteorder, frm, **kwargs): + def __init__(self, parentio, name, frm, **kwargs): """Erstellt einen IO mit struct-Formatierung. @param parentio ParentIO Objekt, welches ersetzt wird @param name Name des neuen IO - @param iotype IOType() Wert - @param byteorder Byteorder 'little' / 'big' fuer int() Berechnung @param frm struct() formatierung (1 Zeichen) @param kwargs Weitere Parameter: - bmk: Bezeichnung fuer Output - bit: Registriert Outputs als bool() am angegebenen Bit im Byte + - byteorder: Byteorder fuer den Input, Standardwert=little - defaultvalue: Standardwert fuer Output, Standard ist 0 """ if len(frm) == 1: # Byteorder prüfen und übernehmen + byteorder = kwargs.get("byteorder", "little") if not (byteorder == "little" or byteorder == "big"): raise ValueError("byteorder must be 'little' or 'big'") bofrm = "<" if byteorder == "little" else ">" bitaddress = "" if frm != "?" else str(kwargs.get("bit", 0)) - if bitaddress == "" or \ - (int(bitaddress) >= 0 and int(bitaddress) < 8): + if bitaddress == "" or (0 <= int(bitaddress) < 8): bitlength = "1" if bitaddress.isnumeric() else \ struct.calcsize(bofrm + frm) * 8 @@ -698,19 +703,31 @@ class StructIO(IOBase): raise AttributeError("parameter frm has to be a single sign") # Basisklasse instantiieren - super().__init__(parentio._parentdevice, valuelist, iotype, byteorder) + # parentdevice, valuelist, iotype, byteorder, signed + super().__init__( + parentio._parentdevice, + valuelist, + parentio._iotype, + byteorder, + frm == frm.lower() + ) self.frm = frm # Platz für neuen IO prüfen if not (self.slc_address.start >= - parentio._parentdevice._dict_slc[iotype].start and + parentio._parentdevice._dict_slc[parentio._iotype].start and self.slc_address.stop <= - parentio._parentdevice._dict_slc[iotype].stop): + parentio._parentdevice._dict_slc[parentio._iotype].stop): raise BufferError( "registered value does not fit process image scope" ) + def _get_signed(self): + """Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll. + @return True, wenn Vorzeichenbehaftet""" + return self._signed + def get_structvalue(self): """Gibt den Wert mit struct Formatierung zurueck. @return Wert vom Typ der struct-Formatierung""" @@ -727,7 +744,7 @@ class StructIO(IOBase): else: self.set_value(struct.pack(self.frm, value)) - byteorder = property(IOBase._get_byteorder) + signed = property(_get_signed) value = property(get_structvalue, set_structvalue) diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index 32fa755..4b8842c 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -37,7 +37,7 @@ class RevPiModIO(object): """Instantiiert die Grundfunktionen. @param kwargs Weitere Parameter: - - auto_refresh: Wenn True, alle Devices zu auto_refresh hinzufuegen + - autorefresh: Wenn True, alle Devices zu autorefresh hinzufuegen - configrsc: Pfad zur piCtory Konfigurationsdatei - procimg: Pfad zum Prozessabbild - monitoring: In- und Outputs werden gelesen, niemals geschrieben @@ -45,7 +45,7 @@ class RevPiModIO(object): - syncoutputs: Aktuell gesetzte Outputs vom Prozessabbild einlesen """ - self._auto_refresh = kwargs.get("auto_refresh", False) + self._autorefresh = kwargs.get("autorefresh", False) self._configrsc = kwargs.get("configrsc", None) self._monitoring = kwargs.get("monitoring", False) self._procimg = kwargs.get("procimg", "/dev/piControl0") @@ -59,10 +59,12 @@ class RevPiModIO(object): self._buffedwrite = False self._exit = Event() self._imgwriter = None + self._ioerror = 0 self._length = 0 self._looprunning = False self._lst_devselect = [] self._lst_refresh = [] + self._maxioerrors = 0 self._myfh = self._create_myfh() self._th_mainloop = None self._waitexit = Event() @@ -209,10 +211,9 @@ class RevPiModIO(object): if self._syncoutputs: self.syncoutputs(force=True) - # Optional ins auto_refresh aufnehmen - if self._auto_refresh: - for dev in self.device: - dev.auto_refresh() + # Optional ins autorefresh aufnehmen + if self._autorefresh: + self.autorefresh_all() # Summary Klasse instantiieren self.summary = summarymodule.Summary(jconfigrsc["Summary"]) @@ -233,11 +234,21 @@ class RevPiModIO(object): @return Millisekunden""" return self._imgwriter.refresh + def _get_ioerrors(self): + """Getter function. + @return Aktuelle Anzahl gezaehlter Fehler""" + return self._ioerror + def _get_length(self): """Getter function. @return Laenge in Bytes der Devices""" return self._length + def _get_maxioerrors(self): + """Getter function. + @return Anzahl erlaubte Fehler""" + return self._maxioerrors + def _get_monitoring(self): """Getter function. @return True, wenn als Monitoring gestartet""" @@ -253,26 +264,43 @@ class RevPiModIO(object): @return True, wenn als Simulator gestartet""" return self._simulator + def _gotioerror(self, action): + """IOError Verwaltung fuer Prozessabbildzugriff.""" + self._ioerror += 1 + if self._maxioerrors != 0 and self._ioerror >= self._maxioerrors: + raise RuntimeError( + "reach max io error count {} on process image".format( + self._maxioerrors + ) + ) + warnings.warn( + "got io error during {} and count {} errors now".format( + self._ioerror, self._ioerror + ), + RuntimeWarning + ) + def _set_cycletime(self, milliseconds): """Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung. @param milliseconds int() in Millisekunden""" self._imgwriter.refresh = milliseconds - def auto_refresh_maxioerrors(self, value=None): - """Maximale IO Fehler fuer auto_refresh. - @param value Setzt maximale Anzahl bis exception ausgeloest wird - @return Maximale Anzahl bis exception ausgeloest wird""" - if value is None: - return self._imgwriter.maxioerrors - elif type(value) == int and value >= 0: + def _set_maxioerrors(self, value): + """Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff. + @param value Anzahl erlaubte Fehler""" + if type(value) == int and value >= 0: + self._maxioerrors = value self._imgwriter.maxioerrors = value + else: + raise ValueError("value must be 0 or a positive integer") - def auto_refresh_resetioerrors(self): - """Setzt aktuellen IOError-Zaehler auf 0 zurueck.""" - self._imgwriter.maxioerrors = 0 + def autorefresh_all(self): + """Setzt alle Devices in autorefresh Funktion.""" + for dev in self.device: + dev.autorefresh() def cleanup(self): - """Beendet auto_refresh und alle Threads.""" + """Beendet autorefresh und alle Threads.""" self.exit(full=True) self._myfh.close() self.app = None @@ -297,15 +325,14 @@ class RevPiModIO(object): revpimodio.exit(). HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen - die eingestellte auto_refresh Zeit, bzw. uebergebene cycletime nicht + die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht ueberschreiten! - Ueber den Parameter cycletime kann die Aktualisierungsrate fuer das - Prozessabbild gesetzt werden (selbe Funktion wie - set_refreshtime(milliseconds)). + Ueber das Attribut cycletime kann die Aktualisierungsrate fuer das + Prozessabbild gesetzt werden. @param func Funktion, die ausgefuehrt werden soll - @param cycletime auto_refresh Wert in Millisekunden + @param cycletime autorefresh Wert in Millisekunden @return None """ @@ -315,9 +342,9 @@ class RevPiModIO(object): "can not start multiple loops mainloop/cycleloop" ) - # Prüfen ob Devices in auto_refresh sind + # Prüfen ob Devices in autorefresh sind if len(self._lst_refresh) == 0: - raise RuntimeError("no device with auto_refresh activated") + raise RuntimeError("no device with autorefresh activated") # Prüfen ob Funktion callable ist if not callable(func): @@ -337,18 +364,18 @@ class RevPiModIO(object): # Auf neue Daten warten und nur ausführen wenn set() if not self._imgwriter.newdata.wait(2.5): if not self._exit.is_set() and not self._imgwriter.is_alive(): - raise RuntimeError("auto_refresh thread not running") + raise RuntimeError("autorefresh thread not running") continue self._imgwriter.newdata.clear() - # Vor Aufruf der Funktion auto_refresh sperren + # Vor Aufruf der Funktion autorefresh sperren self._imgwriter.lck_refresh.acquire() # Funktion aufrufen und auswerten ec = func(cycleinfo) cycleinfo._docycle() - # auto_refresh freigeben + # autorefresh freigeben self._imgwriter.lck_refresh.release() # Cycleloop beenden @@ -357,16 +384,16 @@ class RevPiModIO(object): return ec def exit(self, full=True): - """Beendet mainloop() und optional auto_refresh. + """Beendet mainloop() und optional autorefresh. Wenn sich das Programm im mainloop() befindet, wird durch Aufruf von exit() die Kontrolle wieder an das Hauptprogramm zurueckgegeben. Der Parameter full ist mit True vorbelegt und entfernt alle Devices aus - dem auto_refresh. Der Thread fuer die Prozessabbildsynchronisierung + dem autorefresh. Der Thread fuer die Prozessabbildsynchronisierung wird dann gestoppt und das Programm kann sauber beendet werden. - @param full Entfernt auch alle Devices aus auto_refresh""" + @param full Entfernt auch alle Devices aus autorefresh""" self._exit.set() self._waitexit.set() if full: @@ -469,9 +496,9 @@ class RevPiModIO(object): "can not start multiple loops mainloop/cycleloop" ) - # Prüfen ob Devices in auto_refresh sind + # Prüfen ob Devices in autorefresh sind if len(self._lst_refresh) == 0: - raise RuntimeError("no device with auto_refresh activated") + raise RuntimeError("no device with autorefresh activated") # Thread erstellen, wenn nicht blockieren soll if not blocking: @@ -498,7 +525,7 @@ class RevPiModIO(object): # Auf neue Daten warten und nur ausführen wenn set() if not self._imgwriter.newdata.wait(2.5): if not self._exit.is_set() and not self._imgwriter.is_alive(): - raise RuntimeError("auto_refresh thread not running") + raise RuntimeError("autorefresh thread not running") continue self._imgwriter.newdata.clear() @@ -593,7 +620,7 @@ class RevPiModIO(object): if dev._selfupdate: raise RuntimeError( "can not read process image, while device '{}|{}'" - "is in auto_refresh mode".format(dev.position, dev.name) + "is in autorefresh mode".format(dev.position, dev.name) ) mylist = [dev] @@ -602,10 +629,7 @@ class RevPiModIO(object): self._myfh.seek(0) bytesbuff = self._myfh.read(self._length) except IOError: - warnings.warn( - "read error on process image '{}'".format(self.myfh.name), - RuntimeWarning - ) + self._gotioerror("read") return False for dev in mylist: @@ -628,6 +652,11 @@ class RevPiModIO(object): return True + def resetioerrors(self): + """Setzt aktuellen IOError-Zaehler auf 0 zurueck.""" + self._ioerror = 0 + self._imgwriter._ioerror = 0 + def setdefaultvalues(self, force=False, device=None): """Alle Outputbuffer werden auf die piCtory default Werte gesetzt. @param force auch Devices mit autoupdate=False @@ -667,7 +696,7 @@ class RevPiModIO(object): if dev._selfupdate: raise RuntimeError( "can not sync process image, while device '{}|{}'" - "is in auto_refresh mode".format(dev.position, dev.name) + "is in autorefresh mode".format(dev.position, dev.name) ) mylist = [dev] @@ -675,10 +704,7 @@ class RevPiModIO(object): self._myfh.seek(0) bytesbuff = self._myfh.read(self._length) except IOError: - warnings.warn( - "read error on process image '{}'".format(self._myfh.name), - RuntimeWarning - ) + self._gotioerror("read") return False for dev in mylist: @@ -731,11 +757,7 @@ class RevPiModIO(object): if self._buffedwrite: self._myfh.flush() except IOError: - warnings.warn( - "write error on process image '{}'" - "".format(self._myfh.name), - RuntimeWarning - ) + self._gotioerror("write") workokay = False dev._filelock.release() @@ -764,7 +786,7 @@ class RevPiModIO(object): if dev._selfupdate: raise RuntimeError( "can not write process image, while device '{}|{}'" - "is in auto_refresh mode".format(dev.position, dev.name) + "is in autorefresh mode".format(dev.position, dev.name) ) mylist = [dev] @@ -789,17 +811,15 @@ class RevPiModIO(object): workokay = False if not workokay: - warnings.warn( - "write error on process image '{}'" - "".format(self._myfh.name), - RuntimeWarning - ) + self._gotioerror("write") return workokay configrsc = property(_get_configrsc) cycletime = property(_get_cycletime, _set_cycletime) + ioerrors = property(_get_ioerrors) length = property(_get_length) + maxioerrors = property(_get_maxioerrors, _set_maxioerrors) monitoring = property(_get_monitoring) procimg = property(_get_procimg) simulator = property(_get_simulator)