Merge branch 'master' into develop

This commit is contained in:
2019-10-20 14:55:30 +02:00
34 changed files with 977 additions and 5720 deletions

118
.gitignore vendored Normal file
View File

@@ -0,0 +1,118 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
/test/
/make.conf

View File

@@ -1,23 +0,0 @@
glob:.eric6project
glob:_eric6project
glob:.eric5project
glob:_eric5project
glob:.eric4project
glob:_eric4project
glob:.ropeproject
glob:_ropeproject
glob:.directory
glob:**.pyc
glob:**.pyo
glob:**.orig
glob:**.bak
glob:**.rej
glob:**~
glob:cur
glob:tmp
glob:__pycache__
glob:**.DS_Store
syntax: glob
test/*
deb/*
dist/*

17
.idea/$CACHE_FILE$ generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State />
</expanded-state>
<selected-state>
<State>
<id>Angular</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
</project>

2
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/revpimodio2.iml" filepath="$PROJECT_DIR$/.idea/revpimodio2.iml" />
</modules>
</component>
</project>

11
.idea/revpimodio2.iml generated Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.6" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,53 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000">
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2</h1>
<p>
Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.
</p><p>
Webpage: https://revpimodio.org/
</p><p>
Stellt Klassen fuer die einfache Verwendung des Revolution Pis der
Kunbus GmbH (https://revolution.kunbus.de/) zur Verfuegung. Alle I/Os werden
aus der piCtory Konfiguration eingelesen und mit deren Namen direkt zugreifbar
gemacht. Fuer Gateways sind eigene IOs ueber mehrere Bytes konfigurierbar
Mit den definierten Namen greift man direkt auf die gewuenschten Daten zu.
Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese
fuehrt das Modul bei Datenaenderung aus.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Modules</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="revpimodio2.__init__.html">revpimodio2</a></td>
<td>Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.app.html">app</a></td>
<td>Bildet die App Sektion von piCtory ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.device.html">device</a></td>
<td>Modul fuer die Verwaltung der Devices.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.helper.html">helper</a></td>
<td>RevPiModIO Helperklassen und Tools.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.io.html">io</a></td>
<td>RevPiModIO Modul fuer die Verwaltung der IOs.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.modio.html">modio</a></td>
<td>RevPiModIO Hauptklasse fuer piControl0 Zugriff.</td>
</tr><tr>
<td><a style="color:#0000FF" href="revpimodio2.netio.html">netio</a></td>
<td>RevPiModIO Hauptklasse fuer Netzwerkzugriff.</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>
</table>
</body></html>

View File

@@ -1,20 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>Table of contents</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000">
<h1 style="background-color:#FFFFFF;color:#0000FF">
Table of contents</h1>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Packages</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="index-revpimodio2.html">revpimodio2</a></td>
<td>Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.</td>
</tr>
</table>
</body></html>

View File

@@ -1,116 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2.__init__</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2.__init__</h1>
<p>
Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.
</p><p>
Webpage: https://revpimodio.org/
</p><p>
Stellt Klassen fuer die einfache Verwendung des Revolution Pis der
Kunbus GmbH (https://revolution.kunbus.de/) zur Verfuegung. Alle I/Os werden
aus der piCtory Konfiguration eingelesen und mit deren Namen direkt zugreifbar
gemacht. Fuer Gateways sind eigene IOs ueber mehrere Bytes konfigurierbar
Mit den definierten Namen greift man direkt auf die gewuenschten Daten zu.
Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese
fuehrt das Modul bei Datenaenderung aus.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>BOTH</td></tr><tr><td>FALLING</td></tr><tr><td>GREEN</td></tr><tr><td>INP</td></tr><tr><td>MEM</td></tr><tr><td>OFF</td></tr><tr><td>OUT</td></tr><tr><td>RED</td></tr><tr><td>RISING</td></tr><tr><td>__all__</td></tr><tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr><tr><td>__name__</td></tr><tr><td>__version__</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#DeviceNotFoundError">DeviceNotFoundError</a></td>
<td>Fehler wenn ein Device nicht gefunden wird.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#acheck">acheck</a></td>
<td>Check type of given arguments.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#consttostr">consttostr</a></td>
<td>Gibt <class 'str'> fuer Konstanten zurueck.</td>
</tr>
</table>
<hr /><hr />
<a NAME="DeviceNotFoundError" ID="DeviceNotFoundError"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">DeviceNotFoundError</h2>
<p>
Fehler wenn ein Device nicht gefunden wird.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Exception
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="acheck" ID="acheck"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">acheck</h2>
<b>acheck</b>(<i>check_type, **kwargs</i>)
<p>
Check type of given arguments.
</p><p>
Use the argument name as keyword and the argument itself as value.
</p><dl>
<dt><i>check_type</i></dt>
<dd>
Type to check
</dd><dt><i>kwargs</i></dt>
<dd>
Arguments to check
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="consttostr" ID="consttostr"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">consttostr</h2>
<b>consttostr</b>(<i>value</i>)
<p>
Gibt <class 'str'> fuer Konstanten zurueck.
</p><p>
Diese Funktion ist erforderlich, da enum in Python 3.2 nicht existiert.
</p><dl>
<dt><i>value</i></dt>
<dd>
Konstantenwert
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
<class 'str'> Name der Konstanten
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -1,76 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2.app</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2.app</h1>
<p>
Bildet die App Sektion von piCtory ab.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#App">App</a></td>
<td>Bildet die App Sektion der config.rsc ab.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="App" ID="App"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">App</h2>
<p>
Bildet die App Sektion der config.rsc ab.
</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>__slots__</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="#App.__init__">App</a></td>
<td>Instantiiert die App-Klasse.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="App.__init__" ID="App.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
App (Constructor)</h3>
<b>App</b>(<i>app</i>)
<p>
Instantiiert die App-Klasse.
</p><dl>
<dt><i>app</i></dt>
<dd>
piCtory Appinformationen
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,634 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2.helper</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2.helper</h1>
<p>
RevPiModIO Helperklassen und Tools.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#Cycletools">Cycletools</a></td>
<td>Werkzeugkasten fuer Cycleloop-Funktion.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#EventCallback">EventCallback</a></td>
<td>Thread fuer das interne Aufrufen von Event-Funktionen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter">ProcimgWriter</a></td>
<td>Klasse fuer Synchroniseriungs-Thread.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Var">Var</a></td>
<td></td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="Cycletools" ID="Cycletools"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">Cycletools</h2>
<p>
Werkzeugkasten fuer Cycleloop-Funktion.
</p><p>
Diese Klasse enthaelt Werkzeuge fuer Zyklusfunktionen, wie Taktmerker
und Flankenmerker.
Zu beachten ist, dass die Flankenmerker beim ersten Zyklus alle den Wert
True haben! Ueber den Merker Cycletools.first kann ermittelt werden,
ob es sich um den ersten Zyklus handelt.
</p><p>
Taktmerker flag1c, flag5c, flag10c, usw. haben den als Zahl angegebenen
Wert an Zyklen jeweils False und True.
Beispiel: flag5c hat 5 Zyklen den Wert False und in den naechsten 5 Zyklen
den Wert True.
</p><p>
Flankenmerker flank5c, flank10c, usw. haben immer im, als Zahl angebenen
Zyklus fuer einen Zyklusdurchlauf den Wert True, sonst False.
Beispiel: flank5c hat immer alle 5 Zyklen den Wert True.
</p><p>
Diese Merker koennen z.B. verwendet werden um, an Outputs angeschlossene,
Lampen synchron blinken zu lassen.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#Cycletools.__init__">Cycletools</a></td>
<td>Init Cycletools class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools._docycle">_docycle</a></td>
<td>Zyklusarbeiten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.get_tof">get_tof</a></td>
<td>Wert der Ausschaltverzoegerung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.get_tofc">get_tofc</a></td>
<td>Wert der Ausschaltverzoegerung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.get_ton">get_ton</a></td>
<td>Einschaltverzoegerung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.get_tonc">get_tonc</a></td>
<td>Einschaltverzoegerung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.get_tp">get_tp</a></td>
<td>Impulstimer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.get_tpc">get_tpc</a></td>
<td>Impulstimer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.set_tof">set_tof</a></td>
<td>Startet bei Aufruf einen ausschaltverzoegerten Timer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.set_tofc">set_tofc</a></td>
<td>Startet bei Aufruf einen ausschaltverzoegerten Timer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.set_ton">set_ton</a></td>
<td>Startet einen einschaltverzoegerten Timer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.set_tonc">set_tonc</a></td>
<td>Startet einen einschaltverzoegerten Timer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.set_tp">set_tp</a></td>
<td>Startet einen Impuls Timer.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#Cycletools.set_tpc">set_tpc</a></td>
<td>Startet einen Impuls Timer.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="Cycletools.__init__" ID="Cycletools.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools (Constructor)</h3>
<b>Cycletools</b>(<i>cycletime</i>)
<p>
Init Cycletools class.
</p><a NAME="Cycletools._docycle" ID="Cycletools._docycle"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools._docycle</h3>
<b>_docycle</b>(<i></i>)
<p>
Zyklusarbeiten.
</p><a NAME="Cycletools.get_tof" ID="Cycletools.get_tof"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.get_tof</h3>
<b>get_tof</b>(<i>name</i>)
<p>
Wert der Ausschaltverzoegerung.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name des Timers
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Wert <class 'bool'> der Ausschaltverzoegerung
</dd>
</dl><a NAME="Cycletools.get_tofc" ID="Cycletools.get_tofc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.get_tofc</h3>
<b>get_tofc</b>(<i>name</i>)
<p>
Wert der Ausschaltverzoegerung.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name des Timers
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Wert <class 'bool'> der Ausschaltverzoegerung
</dd>
</dl><a NAME="Cycletools.get_ton" ID="Cycletools.get_ton"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.get_ton</h3>
<b>get_ton</b>(<i>name</i>)
<p>
Einschaltverzoegerung.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name des Timers
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Wert <class 'bool'> der Einschaltverzoegerung
</dd>
</dl><a NAME="Cycletools.get_tonc" ID="Cycletools.get_tonc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.get_tonc</h3>
<b>get_tonc</b>(<i>name</i>)
<p>
Einschaltverzoegerung.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name des Timers
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Wert <class 'bool'> der Einschaltverzoegerung
</dd>
</dl><a NAME="Cycletools.get_tp" ID="Cycletools.get_tp"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.get_tp</h3>
<b>get_tp</b>(<i>name</i>)
<p>
Impulstimer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name des Timers
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Wert <class 'bool'> des Impulses
</dd>
</dl><a NAME="Cycletools.get_tpc" ID="Cycletools.get_tpc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.get_tpc</h3>
<b>get_tpc</b>(<i>name</i>)
<p>
Impulstimer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name des Timers
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Wert <class 'bool'> des Impulses
</dd>
</dl><a NAME="Cycletools.set_tof" ID="Cycletools.set_tof"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.set_tof</h3>
<b>set_tof</b>(<i>name, milliseconds</i>)
<p>
Startet bei Aufruf einen ausschaltverzoegerten Timer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name fuer Zugriff auf Timer
</dd><dt><i>milliseconds</i></dt>
<dd>
Verzoegerung in Millisekunden
</dd>
</dl><a NAME="Cycletools.set_tofc" ID="Cycletools.set_tofc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.set_tofc</h3>
<b>set_tofc</b>(<i>name, cycles</i>)
<p>
Startet bei Aufruf einen ausschaltverzoegerten Timer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name fuer Zugriff auf Timer
</dd><dt><i>cycles</i></dt>
<dd>
Zyklusanzahl, der Verzoegerung wenn nicht neu gestartet
</dd>
</dl><a NAME="Cycletools.set_ton" ID="Cycletools.set_ton"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.set_ton</h3>
<b>set_ton</b>(<i>name, milliseconds</i>)
<p>
Startet einen einschaltverzoegerten Timer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name fuer Zugriff auf Timer
</dd><dt><i>milliseconds</i></dt>
<dd>
Millisekunden, der Verzoegerung wenn neu gestartet
</dd>
</dl><a NAME="Cycletools.set_tonc" ID="Cycletools.set_tonc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.set_tonc</h3>
<b>set_tonc</b>(<i>name, cycles</i>)
<p>
Startet einen einschaltverzoegerten Timer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name fuer Zugriff auf Timer
</dd><dt><i>cycles</i></dt>
<dd>
Zyklusanzahl, der Verzoegerung wenn neu gestartet
</dd>
</dl><a NAME="Cycletools.set_tp" ID="Cycletools.set_tp"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.set_tp</h3>
<b>set_tp</b>(<i>name, milliseconds</i>)
<p>
Startet einen Impuls Timer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name fuer Zugriff auf Timer
</dd><dt><i>milliseconds</i></dt>
<dd>
Millisekunden, die der Impuls anstehen soll
</dd>
</dl><a NAME="Cycletools.set_tpc" ID="Cycletools.set_tpc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Cycletools.set_tpc</h3>
<b>set_tpc</b>(<i>name, cycles</i>)
<p>
Startet einen Impuls Timer.
</p><dl>
<dt><i>name</i></dt>
<dd>
Eindeutiger Name fuer Zugriff auf Timer
</dd><dt><i>cycles</i></dt>
<dd>
Zyklusanzahl, die der Impuls anstehen soll
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="EventCallback" ID="EventCallback"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">EventCallback</h2>
<p>
Thread fuer das interne Aufrufen von Event-Funktionen.
</p><p>
Der Eventfunktion, welche dieser Thread aufruft, wird der Thread selber
als Parameter uebergeben. Darauf muss bei der definition der Funktion
geachtet werden z.B. "def event(th):". Bei umfangreichen Funktionen kann
dieser ausgewertet werden um z.B. doppeltes Starten zu verhindern.
Ueber EventCallback.ioname kann der Name des IO-Objekts abgerufen werden,
welches das Event ausgeloest hast. EventCallback.iovalue gibt den Wert des
IO-Objekts zum Ausloesezeitpunkt zurueck.
Der Thread stellt das EventCallback.exit Event als Abbruchbedingung fuer
die aufgerufene Funktion zur Verfuegung.
Durch Aufruf der Funktion EventCallback.stop() wird das exit-Event gesetzt
und kann bei Schleifen zum Abbrechen verwendet werden.
Mit dem .exit() Event auch eine Wartefunktion realisiert
werden: "th.exit.wait(0.5)" - Wartet 500ms oder bricht sofort ab, wenn
fuer den Thread .stop() aufgerufen wird.
</p><p>
while not th.exit.is_set():
# IO-Arbeiten
th.exit.wait(0.5)
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#EventCallback.__init__">EventCallback</a></td>
<td>Init EventCallback class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#EventCallback.run">run</a></td>
<td>Ruft die registrierte Funktion auf.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#EventCallback.stop">stop</a></td>
<td>Setzt das exit-Event mit dem die Funktion beendet werden kann.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="EventCallback.__init__" ID="EventCallback.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
EventCallback (Constructor)</h3>
<b>EventCallback</b>(<i>func, name, value</i>)
<p>
Init EventCallback class.
</p><dl>
<dt><i>func</i></dt>
<dd>
Funktion die beim Start aufgerufen werden soll
</dd><dt><i>name</i></dt>
<dd>
IO-Name
</dd><dt><i>value</i></dt>
<dd>
IO-Value zum Zeitpunkt des Events
</dd>
</dl><a NAME="EventCallback.run" ID="EventCallback.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
EventCallback.run</h3>
<b>run</b>(<i></i>)
<p>
Ruft die registrierte Funktion auf.
</p><a NAME="EventCallback.stop" ID="EventCallback.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
EventCallback.stop</h3>
<b>stop</b>(<i></i>)
<p>
Setzt das exit-Event mit dem die Funktion beendet werden kann.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="ProcimgWriter" ID="ProcimgWriter"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">ProcimgWriter</h2>
<p>
Klasse fuer Synchroniseriungs-Thread.
</p><p>
Diese Klasse wird als Thread gestartet, wenn das Prozessabbild zyklisch
synchronisiert werden soll. Diese Funktion wird hauptsaechlich fuer das
Event-Handling verwendet.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</td></tr><tr><td>ioerrors</td></tr><tr><td>maxioerrors</td></tr><tr><td>refresh</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.__init__">ProcimgWriter</a></td>
<td>Init ProcimgWriter class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.__check_change">__check_change</a></td>
<td>Findet Aenderungen fuer die Eventueberwachung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.__exec_th">__exec_th</a></td>
<td>Laeuft als Thread, der Events als Thread startet.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter._collect_events">_collect_events</a></td>
<td>Aktiviert oder Deaktiviert die Eventueberwachung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter._get_ioerrors">_get_ioerrors</a></td>
<td>Ruft aktuelle Anzahl der Fehler ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter._gotioerror">_gotioerror</a></td>
<td>IOError Verwaltung fuer autorefresh.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.get_maxioerrors">get_maxioerrors</a></td>
<td>Gibt die Anzahl der maximal erlaubten Fehler zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.get_refresh">get_refresh</a></td>
<td>Gibt Zykluszeit zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.run">run</a></td>
<td>Startet die automatische Prozessabbildsynchronisierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.set_maxioerrors">set_maxioerrors</a></td>
<td>Setzt die Anzahl der maximal erlaubten Fehler.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.set_refresh">set_refresh</a></td>
<td>Setzt die Zykluszeit in Millisekunden.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#ProcimgWriter.stop">stop</a></td>
<td>Beendet die automatische Prozessabbildsynchronisierung.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="ProcimgWriter.__init__" ID="ProcimgWriter.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter (Constructor)</h3>
<b>ProcimgWriter</b>(<i>parentmodio</i>)
<p>
Init ProcimgWriter class.
</p><dl>
<dt><i>parentmodio</i></dt>
<dd>
Parent Object
</dd>
</dl><a NAME="ProcimgWriter.__check_change" ID="ProcimgWriter.__check_change"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.__check_change</h3>
<b>__check_change</b>(<i>dev</i>)
<p>
Findet Aenderungen fuer die Eventueberwachung.
</p><a NAME="ProcimgWriter.__exec_th" ID="ProcimgWriter.__exec_th"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.__exec_th</h3>
<b>__exec_th</b>(<i></i>)
<p>
Laeuft als Thread, der Events als Thread startet.
</p><a NAME="ProcimgWriter._collect_events" ID="ProcimgWriter._collect_events"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter._collect_events</h3>
<b>_collect_events</b>(<i>value</i>)
<p>
Aktiviert oder Deaktiviert die Eventueberwachung.
</p><dl>
<dt><i>value</i></dt>
<dd>
True aktiviert / False deaktiviert
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Anforderung erfolgreich war
</dd>
</dl><a NAME="ProcimgWriter._get_ioerrors" ID="ProcimgWriter._get_ioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter._get_ioerrors</h3>
<b>_get_ioerrors</b>(<i></i>)
<p>
Ruft aktuelle Anzahl der Fehler ab.
</p><dl>
<dt>Returns:</dt>
<dd>
Aktuelle Fehleranzahl
</dd>
</dl><a NAME="ProcimgWriter._gotioerror" ID="ProcimgWriter._gotioerror"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter._gotioerror</h3>
<b>_gotioerror</b>(<i>e=None</i>)
<p>
IOError Verwaltung fuer autorefresh.
</p><dl>
<dt><i>e</i></dt>
<dd>
Exception to log if debug is enabled
</dd>
</dl><a NAME="ProcimgWriter.get_maxioerrors" ID="ProcimgWriter.get_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.get_maxioerrors</h3>
<b>get_maxioerrors</b>(<i></i>)
<p>
Gibt die Anzahl der maximal erlaubten Fehler zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="ProcimgWriter.get_refresh" ID="ProcimgWriter.get_refresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.get_refresh</h3>
<b>get_refresh</b>(<i></i>)
<p>
Gibt Zykluszeit zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'int'> Zykluszeit in Millisekunden
</dd>
</dl><a NAME="ProcimgWriter.run" ID="ProcimgWriter.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.run</h3>
<b>run</b>(<i></i>)
<p>
Startet die automatische Prozessabbildsynchronisierung.
</p><a NAME="ProcimgWriter.set_maxioerrors" ID="ProcimgWriter.set_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.set_maxioerrors</h3>
<b>set_maxioerrors</b>(<i>value</i>)
<p>
Setzt die Anzahl der maximal erlaubten Fehler.
</p><dl>
<dt><i>value</i></dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="ProcimgWriter.set_refresh" ID="ProcimgWriter.set_refresh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.set_refresh</h3>
<b>set_refresh</b>(<i>value</i>)
<p>
Setzt die Zykluszeit in Millisekunden.
</p><dl>
<dt><i>value</i></dt>
<dd>
<class 'int'> Millisekunden
</dd>
</dl><a NAME="ProcimgWriter.stop" ID="ProcimgWriter.stop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
ProcimgWriter.stop</h3>
<b>stop</b>(<i></i>)
<p>
Beendet die automatische Prozessabbildsynchronisierung.
</p>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="Var" ID="Var"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">Var</h2>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
None
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,763 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2.modio</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2.modio</h1>
<p>
RevPiModIO Hauptklasse fuer piControl0 Zugriff.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#RevPiModIO">RevPiModIO</a></td>
<td>Klasse fuer die Verwaltung der piCtory Konfiguration.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIODriver">RevPiModIODriver</a></td>
<td>Klasse um eigene Treiber fuer die virtuellen Devices zu erstellen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIOSelected">RevPiModIOSelected</a></td>
<td>Klasse fuer die Verwaltung einzelner Devices aus piCtory.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="RevPiModIO" ID="RevPiModIO"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiModIO</h2>
<p>
Klasse fuer die Verwaltung der piCtory Konfiguration.
</p><p>
Diese Klasse uebernimmt die gesamte Konfiguration aus piCtory und bilded
die Devices und IOs ab. Sie uebernimmt die exklusive Verwaltung des
Prozessabbilds und stellt sicher, dass die Daten synchron sind.
Sollten nur einzelne Devices gesteuert werden, verwendet man
RevPiModIOSelected() und uebergibt bei Instantiierung eine Liste mit
Device Positionen oder Device Namen.
</p><p>
</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>__slots__</td></tr><tr><td>configrsc</td></tr><tr><td>cycletime</td></tr><tr><td>debug</td></tr><tr><td>ioerrors</td></tr><tr><td>length</td></tr><tr><td>maxioerrors</td></tr><tr><td>monitoring</td></tr><tr><td>procimg</td></tr><tr><td>replace_io_file</td></tr><tr><td>simulator</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="#RevPiModIO.__init__">RevPiModIO</a></td>
<td>Instantiiert die Grundfunktionen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.__del__">__del__</a></td>
<td>Zerstoert alle Klassen um aufzuraeumen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.__evt_exit">__evt_exit</a></td>
<td>Eventhandler fuer Programmende.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._configure">_configure</a></td>
<td>Verarbeitet die piCtory Konfigurationsdatei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._configure_replace_io">_configure_replace_io</a></td>
<td>Importiert ersetzte IOs in diese Instanz.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._create_myfh">_create_myfh</a></td>
<td>Erstellt FileObject mit Pfad zum procimg.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_configrsc">_get_configrsc</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_cycletime">_get_cycletime</a></td>
<td>Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_debug">_get_debug</a></td>
<td>Gibt Status des Debugflags zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_ioerrors">_get_ioerrors</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_length">_get_length</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_maxioerrors">_get_maxioerrors</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_monitoring">_get_monitoring</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_procimg">_get_procimg</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_replace_io_file">_get_replace_io_file</a></td>
<td>Gibt Pfad zur verwendeten replace IO Datei aus.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._get_simulator">_get_simulator</a></td>
<td>Getter function.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._gotioerror">_gotioerror</a></td>
<td>IOError Verwaltung fuer Prozessabbildzugriff.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._set_cycletime">_set_cycletime</a></td>
<td>Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._set_maxioerrors">_set_maxioerrors</a></td>
<td>Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO._simulate_ioctl">_simulate_ioctl</a></td>
<td>Simuliert IOCTL Funktionen auf procimg Datei.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.autorefresh_all">autorefresh_all</a></td>
<td>Setzt alle Devices in autorefresh Funktion.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.cleanup">cleanup</a></td>
<td>Beendet autorefresh und alle Threads.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.cycleloop">cycleloop</a></td>
<td>Startet den Cycleloop.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.exit">exit</a></td>
<td>Beendet mainloop() und optional autorefresh.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.export_replaced_ios">export_replaced_ios</a></td>
<td>Exportiert ersetzte IOs dieser Instanz.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.get_jconfigrsc">get_jconfigrsc</a></td>
<td>Laedt die piCtory Konfiguration und erstellt ein <class 'dict'>.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.handlesignalend">handlesignalend</a></td>
<td>Signalhandler fuer Programmende verwalten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.mainloop">mainloop</a></td>
<td>Startet den Mainloop mit Eventueberwachung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.readprocimg">readprocimg</a></td>
<td>Einlesen aller Inputs aller/eines Devices vom Prozessabbild.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.resetioerrors">resetioerrors</a></td>
<td>Setzt aktuellen IOError-Zaehler auf 0 zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiModIO.setdefaultvalues">setdefaultvalues</a></td>
<td>Alle Outputbuffer werden auf die piCtory default Werte gesetzt.</td>
</tr><tr>
<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.writeprocimg">writeprocimg</a></td>
<td>Schreiben aller Outputs aller Devices ins Prozessabbild.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiModIO.__init__" ID="RevPiModIO.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO (Constructor)</h3>
<b>RevPiModIO</b>(<i>autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
<p>
Instantiiert die Grundfunktionen.
</p><dl>
<dt><i>autorefresh</i></dt>
<dd>
Wenn True, alle Devices zu autorefresh hinzufuegen
</dd><dt><i>monitoring</i></dt>
<dd>
In- und Outputs werden gelesen, niemals geschrieben
</dd><dt><i>syncoutputs</i></dt>
<dd>
Aktuell gesetzte Outputs vom Prozessabbild einlesen
</dd><dt><i>procimg</i></dt>
<dd>
Abweichender Pfad zum Prozessabbild
</dd><dt><i>configrsc</i></dt>
<dd>
Abweichender Pfad zur piCtory Konfigurationsdatei
</dd><dt><i>simulator</i></dt>
<dd>
Laedt das Modul als Simulator und vertauscht IOs
</dd><dt><i>debug</i></dt>
<dd>
Gibt bei allen Fehlern komplette Meldungen aus
</dd><dt><i>replace_io_file</i></dt>
<dd>
Replace IO Konfiguration aus Datei laden
</dd><dt><i>direct_output</i></dt>
<dd>
Write outputs immediately to process image (slow)
</dd>
</dl><a NAME="RevPiModIO.__del__" ID="RevPiModIO.__del__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.__del__</h3>
<b>__del__</b>(<i></i>)
<p>
Zerstoert alle Klassen um aufzuraeumen.
</p><a NAME="RevPiModIO.__evt_exit" ID="RevPiModIO.__evt_exit"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.__evt_exit</h3>
<b>__evt_exit</b>(<i>signum, sigframe</i>)
<p>
Eventhandler fuer Programmende.
</p><dl>
<dt><i>signum</i></dt>
<dd>
Signalnummer
</dd><dt><i>sigframe</i></dt>
<dd>
Signalframe
</dd>
</dl><a NAME="RevPiModIO._configure" ID="RevPiModIO._configure"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._configure</h3>
<b>_configure</b>(<i>jconfigrsc</i>)
<p>
Verarbeitet die piCtory Konfigurationsdatei.
</p><a NAME="RevPiModIO._configure_replace_io" ID="RevPiModIO._configure_replace_io"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._configure_replace_io</h3>
<b>_configure_replace_io</b>(<i></i>)
<p>
Importiert ersetzte IOs in diese Instanz.
</p><p>
Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...)
in eine Datei exportiert worden sind. Diese IOs werden in dieser
Instanz wiederhergestellt.
</p><p>
</p><a NAME="RevPiModIO._create_myfh" ID="RevPiModIO._create_myfh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._create_myfh</h3>
<b>_create_myfh</b>(<i></i>)
<p>
Erstellt FileObject mit Pfad zum procimg.
return FileObject
</p><a NAME="RevPiModIO._get_configrsc" ID="RevPiModIO._get_configrsc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_configrsc</h3>
<b>_get_configrsc</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Pfad der verwendeten piCtory Konfiguration
</dd>
</dl><a NAME="RevPiModIO._get_cycletime" ID="RevPiModIO._get_cycletime"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_cycletime</h3>
<b>_get_cycletime</b>(<i></i>)
<p>
Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.
</p><dl>
<dt>Returns:</dt>
<dd>
Millisekunden
</dd>
</dl><a NAME="RevPiModIO._get_debug" ID="RevPiModIO._get_debug"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_debug</h3>
<b>_get_debug</b>(<i></i>)
<p>
Gibt Status des Debugflags zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
Status des Debugflags
</dd>
</dl><a NAME="RevPiModIO._get_ioerrors" ID="RevPiModIO._get_ioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_ioerrors</h3>
<b>_get_ioerrors</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Aktuelle Anzahl gezaehlter Fehler
</dd>
</dl><a NAME="RevPiModIO._get_length" ID="RevPiModIO._get_length"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_length</h3>
<b>_get_length</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Laenge in Bytes der Devices
</dd>
</dl><a NAME="RevPiModIO._get_maxioerrors" ID="RevPiModIO._get_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_maxioerrors</h3>
<b>_get_maxioerrors</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="RevPiModIO._get_monitoring" ID="RevPiModIO._get_monitoring"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_monitoring</h3>
<b>_get_monitoring</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn als Monitoring gestartet
</dd>
</dl><a NAME="RevPiModIO._get_procimg" ID="RevPiModIO._get_procimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_procimg</h3>
<b>_get_procimg</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
Pfad des verwendeten Prozessabbilds
</dd>
</dl><a NAME="RevPiModIO._get_replace_io_file" ID="RevPiModIO._get_replace_io_file"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_replace_io_file</h3>
<b>_get_replace_io_file</b>(<i></i>)
<p>
Gibt Pfad zur verwendeten replace IO Datei aus.
</p><dl>
<dt>Returns:</dt>
<dd>
Pfad zur replace IO Datei
</dd>
</dl><a NAME="RevPiModIO._get_simulator" ID="RevPiModIO._get_simulator"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._get_simulator</h3>
<b>_get_simulator</b>(<i></i>)
<p>
Getter function.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn als Simulator gestartet
</dd>
</dl><a NAME="RevPiModIO._gotioerror" ID="RevPiModIO._gotioerror"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._gotioerror</h3>
<b>_gotioerror</b>(<i>action, e=None</i>)
<p>
IOError Verwaltung fuer Prozessabbildzugriff.
</p><dl>
<dt><i>action</i></dt>
<dd>
Zusatzinformationen zum loggen
</dd><dt><i>e</i></dt>
<dd>
Exception to log if debug is enabled
</dd>
</dl><a NAME="RevPiModIO._set_cycletime" ID="RevPiModIO._set_cycletime"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._set_cycletime</h3>
<b>_set_cycletime</b>(<i>milliseconds</i>)
<p>
Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.
</p><dl>
<dt><i>milliseconds</i></dt>
<dd>
<class 'int'> in Millisekunden
</dd>
</dl><a NAME="RevPiModIO._set_maxioerrors" ID="RevPiModIO._set_maxioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._set_maxioerrors</h3>
<b>_set_maxioerrors</b>(<i>value</i>)
<p>
Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.
</p><dl>
<dt><i>value</i></dt>
<dd>
Anzahl erlaubte Fehler
</dd>
</dl><a NAME="RevPiModIO._simulate_ioctl" ID="RevPiModIO._simulate_ioctl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO._simulate_ioctl</h3>
<b>_simulate_ioctl</b>(<i>request, arg=b''</i>)
<p>
Simuliert IOCTL Funktionen auf procimg Datei.
</p><dl>
<dt><i>request</i></dt>
<dd>
IO Request
</dd><dt><i>arg:</i></dt>
<dd>
Request argument
</dd>
</dl><a NAME="RevPiModIO.autorefresh_all" ID="RevPiModIO.autorefresh_all"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.autorefresh_all</h3>
<b>autorefresh_all</b>(<i></i>)
<p>
Setzt alle Devices in autorefresh Funktion.
</p><a NAME="RevPiModIO.cleanup" ID="RevPiModIO.cleanup"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.cleanup</h3>
<b>cleanup</b>(<i></i>)
<p>
Beendet autorefresh und alle Threads.
</p><a NAME="RevPiModIO.cycleloop" ID="RevPiModIO.cycleloop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.cycleloop</h3>
<b>cycleloop</b>(<i>func, cycletime=50</i>)
<p>
Startet den Cycleloop.
</p><p>
Der aktuelle Programmthread wird hier bis Aufruf von
.exit() "gefangen". Er fuehrt nach jeder Aktualisierung
des Prozessabbilds die uebergebene Funktion "func" aus und arbeitet sie
ab. Waehrend der Ausfuehrung der Funktion wird das Prozessabbild nicht
weiter aktualisiert. Die Inputs behalten bis zum Ende den aktuellen
Wert. Gesetzte Outputs werden nach Ende des Funktionsdurchlaufs in das
Prozessabbild geschrieben.
</p><p>
Verlassen wird der Cycleloop, wenn die aufgerufene Funktion einen
Rueckgabewert nicht gleich None liefert (z.B. return True), oder durch
Aufruf von .exit().
</p><p>
HINWEIS: Die Aktualisierungszeit und die Laufzeit der Funktion duerfen
die eingestellte autorefresh Zeit, bzw. uebergebene cycletime nicht
ueberschreiten!
</p><p>
Ueber den Parameter cycletime wird die gewuenschte Zukluszeit der
uebergebenen Funktion gesetzt. Der Standardwert betraegt
50 Millisekunden, in denen das Prozessabild eingelesen, die uebergebene
Funktion ausgefuert und das Prozessabbild geschrieben wird.
</p><dl>
<dt><i>func</i></dt>
<dd>
Funktion, die ausgefuehrt werden soll
</dd><dt><i>cycletime</i></dt>
<dd>
Zykluszeit in Millisekunden - Standardwert 50 ms
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiModIO.exit" ID="RevPiModIO.exit"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.exit</h3>
<b>exit</b>(<i>full=True</i>)
<p>
Beendet mainloop() und optional autorefresh.
</p><p>
Wenn sich das Programm im mainloop() befindet, wird durch Aufruf
von exit() die Kontrolle wieder an das Hauptprogramm zurueckgegeben.
</p><p>
Der Parameter full ist mit True vorbelegt und entfernt alle Devices aus
dem autorefresh. Der Thread fuer die Prozessabbildsynchronisierung
wird dann gestoppt und das Programm kann sauber beendet werden.
</p><dl>
<dt><i>full</i></dt>
<dd>
Entfernt auch alle Devices aus autorefresh
</dd>
</dl><a NAME="RevPiModIO.export_replaced_ios" ID="RevPiModIO.export_replaced_ios"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.export_replaced_ios</h3>
<b>export_replaced_ios</b>(<i>filename</i>)
<p>
Exportiert ersetzte IOs dieser Instanz.
</p><p>
Exportiert alle ersetzten IOs, welche mit .replace_io(...) angelegt
wurden. Die Datei kann z.B. fuer RevPiPyLoad verwndet werden um Daten
in den neuen Formaten per MQTT zu uebertragen oder mit RevPiPyControl
anzusehen.
</p><dl>
<dt><i>filename</i></dt>
<dd>
Dateiname fuer Exportdatei
</dd>
</dl><a NAME="RevPiModIO.get_jconfigrsc" ID="RevPiModIO.get_jconfigrsc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.get_jconfigrsc</h3>
<b>get_jconfigrsc</b>(<i></i>)
<p>
Laedt die piCtory Konfiguration und erstellt ein <class 'dict'>.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'dict'> der piCtory Konfiguration
</dd>
</dl><a NAME="RevPiModIO.handlesignalend" ID="RevPiModIO.handlesignalend"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.handlesignalend</h3>
<b>handlesignalend</b>(<i>cleanupfunc=None</i>)
<p>
Signalhandler fuer Programmende verwalten.
</p><p>
Wird diese Funktion aufgerufen, uebernimmt RevPiModIO die SignalHandler
fuer SIGINT und SIGTERM. Diese werden Empfangen, wenn das
Betriebssystem oder der Benutzer das Steuerungsprogramm sauber beenden
will.
</p><p>
Die optionale Funktion "cleanupfunc" wird als letztes nach dem letzten
Einlesen der Inputs ausgefuehrt. Dort gesetzte Outputs werden nach
Ablauf der Funktion ein letztes Mal geschrieben.
Gedacht ist dies fuer Aufraeumarbeiten, wie z.B. das abschalten der
LEDs am RevPi-Core.
</p><p>
Nach einmaligem Empfangen eines der Signale und dem Beenden der
RevPiModIO Thrads / Funktionen werden die SignalHandler wieder
freigegeben.
</p><dl>
<dt><i>cleanupfunc</i></dt>
<dd>
Funktion wird nach dem letzten Lesen der Inputs
ausgefuehrt, gefolgt vom letzten Schreiben der Outputs
</dd>
</dl><a NAME="RevPiModIO.mainloop" ID="RevPiModIO.mainloop"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.mainloop</h3>
<b>mainloop</b>(<i>blocking=True, no_warn=False</i>)
<p>
Startet den Mainloop mit Eventueberwachung.
</p><p>
Der aktuelle Programmthread wird hier bis Aufruf von
RevPiDevicelist.exit() "gefangen" (es sei denn blocking=False). Er
durchlaeuft die Eventueberwachung und prueft Aenderungen der, mit
einem Event registrierten, IOs. Wird eine Veraenderung erkannt,
fuert das Programm die dazugehoerigen Funktionen der Reihe nach aus.
</p><p>
Wenn der Parameter "blocking" mit False angegeben wird, aktiviert
dies die Eventueberwachung und blockiert das Programm NICHT an der
Stelle des Aufrufs. Eignet sich gut fuer die GUI Programmierung, wenn
Events vom RevPi benoetigt werden, aber das Programm weiter ausgefuehrt
werden soll.
</p><dl>
<dt><i>blocking</i></dt>
<dd>
Wenn False, blockiert das Programm NICHT
</dd><dt><i>no_warn</i></dt>
<dd>
Keine Warnungen bei langsamen Funktionen ausgeben
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
None
</dd>
</dl><a NAME="RevPiModIO.readprocimg" ID="RevPiModIO.readprocimg"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.readprocimg</h3>
<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>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Arbeiten an allen Devices erfolgreich waren
</dd>
</dl><a NAME="RevPiModIO.resetioerrors" ID="RevPiModIO.resetioerrors"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.resetioerrors</h3>
<b>resetioerrors</b>(<i></i>)
<p>
Setzt aktuellen IOError-Zaehler auf 0 zurueck.
</p><a NAME="RevPiModIO.setdefaultvalues" ID="RevPiModIO.setdefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIO.setdefaultvalues</h3>
<b>setdefaultvalues</b>(<i>device=None</i>)
<p>
Alle Outputbuffer werden auf die piCtory default Werte gesetzt.
</p><dl>
<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>device=None</i>)
<p>
Lesen aller aktuell gesetzten Outputs im Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Arbeiten an allen Devices 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>device=None</i>)
<p>
Schreiben aller Outputs aller Devices ins Prozessabbild.
</p><p>
Devices mit aktiverem autorefresh werden ausgenommen!
</p><dl>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
True, wenn Arbeiten an allen Devices erfolgreich waren
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiModIODriver" ID="RevPiModIODriver"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiModIODriver</h2>
<p>
Klasse um eigene Treiber fuer die virtuellen Devices zu erstellen.
</p><p>
Mit dieser Klasse werden nur angegebene Virtuelle Devices mit RevPiModIO
verwaltet. Bei Instantiierung werden automatisch die Inputs und Outputs
verdreht, um das Schreiben der Inputs zu ermoeglichen. Die Daten koennen
dann ueber logiCAD an den Devices abgerufen werden.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
RevPiModIOSelected
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#RevPiModIODriver.__init__">RevPiModIODriver</a></td>
<td>Instantiiert die Grundfunktionen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiModIODriver.__init__" ID="RevPiModIODriver.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIODriver (Constructor)</h3>
<b>RevPiModIODriver</b>(<i>virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None, direct_output=False</i>)
<p>
Instantiiert die Grundfunktionen.
</p><p>
Parameter 'monitoring' und 'simulator' stehen hier nicht zur
Verfuegung, da diese automatisch gesetzt werden.
</p><dl>
<dt><i>virtdev</i></dt>
<dd>
Virtuelles Device oder mehrere als <class 'list'>
</dd>
</dl><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#RevPiModIO.__init__">RevPiModIO.__init__(...)</a>
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiModIOSelected" ID="RevPiModIOSelected"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiModIOSelected</h2>
<p>
Klasse fuer die Verwaltung einzelner Devices aus piCtory.
</p><p>
Diese Klasse uebernimmt nur angegebene Devices der piCtory Konfiguration
und bilded sie inkl. IOs ab. Sie uebernimmt die exklusive Verwaltung des
Adressbereichs im Prozessabbild an dem sich die angegebenen Devices
befinden und stellt sicher, dass die Daten synchron sind.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
RevPiModIO
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#RevPiModIOSelected.__init__">RevPiModIOSelected</a></td>
<td>Instantiiert nur fuer angegebene Devices die Grundfunktionen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiModIOSelected.__init__" ID="RevPiModIOSelected.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiModIOSelected (Constructor)</h3>
<b>RevPiModIOSelected</b>(<i>deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
<p>
Instantiiert nur fuer angegebene Devices die Grundfunktionen.
</p><p>
Der Parameter deviceselection kann eine einzelne
Device Position / einzelner Device Name sein oder eine Liste mit
mehreren Positionen / Namen
</p><dl>
<dt><i>deviceselection</i></dt>
<dd>
Positionsnummer oder Devicename
</dd>
</dl><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#RevPiModIO.__init__">RevPiModIO.__init__(...)</a>
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -1,631 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2.netio</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2.netio</h1>
<p>
RevPiModIO Hauptklasse fuer Netzwerkzugriff.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr><tr><td>_sysdeldirty</td></tr><tr><td>_sysexit</td></tr><tr><td>_sysflush</td></tr><tr><td>_syspictory</td></tr><tr><td>_syssync</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#NetFH">NetFH</a></td>
<td>Netzwerk File Handler fuer das Prozessabbild.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO">RevPiNetIO</a></td>
<td>Klasse fuer die Verwaltung der piCtory Konfiguration ueber das Netzwerk.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIODriver">RevPiNetIODriver</a></td>
<td>Klasse um eigene Treiber fuer die virtuellen Devices zu erstellen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIOSelected">RevPiNetIOSelected</a></td>
<td>Klasse fuer die Verwaltung einzelner Devices aus piCtory.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="NetFH" ID="NetFH"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">NetFH</h2>
<p>
Netzwerk File Handler fuer das Prozessabbild.
</p><p>
Dieses FileObject-like Object verwaltet das Lesen und Schriben des
Prozessabbilds ueber das Netzwerk. Ein entfernter Revolution Pi kann
so gesteuert werden.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
Thread
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</td></tr><tr><td>closed</td></tr><tr><td>name</td></tr><tr><td>timeout</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="#NetFH.__init__">NetFH</a></td>
<td>Init NetFH-class.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.__check_acl">__check_acl</a></td>
<td>Pueft ob ACL auf RevPi den Vorgang erlaubt oder wirft exception.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.__del__">__del__</a></td>
<td>NetworkFileHandler beenden.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.__set_systimeout">__set_systimeout</a></td>
<td>Systemfunktion fuer Timeoutberechnung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH._connect">_connect</a></td>
<td>Stellt die Verbindung zu einem RevPiSlave her.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH._direct_send">_direct_send</a></td>
<td>Fuer debugging direktes Senden von Daten.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.clear_dirtybytes">clear_dirtybytes</a></td>
<td>Entfernt die konfigurierten Dirtybytes vom RevPi Slave.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.close">close</a></td>
<td>Verbindung trennen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.flush">flush</a></td>
<td>Schreibpuffer senden.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.get_closed">get_closed</a></td>
<td>Pruefen ob Verbindung geschlossen ist.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.get_name">get_name</a></td>
<td>Verbindugnsnamen zurueckgeben.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.get_timeout">get_timeout</a></td>
<td>Gibt aktuellen Timeout zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.ioctl">ioctl</a></td>
<td>IOCTL Befehle ueber das Netzwerk senden.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.read">read</a></td>
<td>Daten ueber das Netzwerk lesen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.readpictory">readpictory</a></td>
<td>Ruft die piCtory Konfiguration ab.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.run">run</a></td>
<td>Handler fuer Synchronisierung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.seek">seek</a></td>
<td>Springt an angegebene Position.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.set_dirtybytes">set_dirtybytes</a></td>
<td>Konfiguriert Dirtybytes fuer Prozessabbild bei Verbindungsfehler.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.set_timeout">set_timeout</a></td>
<td>Setzt Timeoutwert fuer Verbindung.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.tell">tell</a></td>
<td>Gibt aktuelle Position zurueck.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#NetFH.write">write</a></td>
<td>Daten ueber das Netzwerk schreiben.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="NetFH.__init__" ID="NetFH.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH (Constructor)</h3>
<b>NetFH</b>(<i>address, timeout=500</i>)
<p>
Init NetFH-class.
</p><dl>
<dt><i>address</i></dt>
<dd>
IP Adresse, Port des RevPi als <class 'tuple'>
</dd><dt><i>timeout</i></dt>
<dd>
Timeout in Millisekunden der Verbindung
</dd>
</dl><a NAME="NetFH.__check_acl" ID="NetFH.__check_acl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.__check_acl</h3>
<b>__check_acl</b>(<i>bytecode</i>)
<p>
Pueft ob ACL auf RevPi den Vorgang erlaubt oder wirft exception.
</p><a NAME="NetFH.__del__" ID="NetFH.__del__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.__del__</h3>
<b>__del__</b>(<i></i>)
<p>
NetworkFileHandler beenden.
</p><a NAME="NetFH.__set_systimeout" ID="NetFH.__set_systimeout"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.__set_systimeout</h3>
<b>__set_systimeout</b>(<i>value</i>)
<p>
Systemfunktion fuer Timeoutberechnung.
</p><dl>
<dt><i>value</i></dt>
<dd>
Timeout in Millisekunden 100 - 60000
</dd>
</dl><a NAME="NetFH._connect" ID="NetFH._connect"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH._connect</h3>
<b>_connect</b>(<i></i>)
<p>
Stellt die Verbindung zu einem RevPiSlave her.
</p><a NAME="NetFH._direct_send" ID="NetFH._direct_send"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH._direct_send</h3>
<b>_direct_send</b>(<i>send_bytes, recv_count</i>)
<p>
Fuer debugging direktes Senden von Daten.
</p><dl>
<dt><i>send_bytes</i></dt>
<dd>
Bytes, die gesendet werden sollen
</dd><dt><i>recv_count</i></dt>
<dd>
Anzahl der Empfangsbytes
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Empfangende Bytes
</dd>
</dl><a NAME="NetFH.clear_dirtybytes" ID="NetFH.clear_dirtybytes"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.clear_dirtybytes</h3>
<b>clear_dirtybytes</b>(<i>position=None</i>)
<p>
Entfernt die konfigurierten Dirtybytes vom RevPi Slave.
</p><dl>
<dt><i>position</i></dt>
<dd>
Startposition der Dirtybytes
</dd>
</dl><a NAME="NetFH.close" ID="NetFH.close"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.close</h3>
<b>close</b>(<i></i>)
<p>
Verbindung trennen.
</p><a NAME="NetFH.flush" ID="NetFH.flush"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.flush</h3>
<b>flush</b>(<i></i>)
<p>
Schreibpuffer senden.
</p><a NAME="NetFH.get_closed" ID="NetFH.get_closed"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.get_closed</h3>
<b>get_closed</b>(<i></i>)
<p>
Pruefen ob Verbindung geschlossen ist.
</p><dl>
<dt>Returns:</dt>
<dd>
True, wenn Verbindung geschlossen ist
</dd>
</dl><a NAME="NetFH.get_name" ID="NetFH.get_name"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.get_name</h3>
<b>get_name</b>(<i></i>)
<p>
Verbindugnsnamen zurueckgeben.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'str'> IP:PORT
</dd>
</dl><a NAME="NetFH.get_timeout" ID="NetFH.get_timeout"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.get_timeout</h3>
<b>get_timeout</b>(<i></i>)
<p>
Gibt aktuellen Timeout zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'int'> in Millisekunden
</dd>
</dl><a NAME="NetFH.ioctl" ID="NetFH.ioctl"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.ioctl</h3>
<b>ioctl</b>(<i>request, arg=b''</i>)
<p>
IOCTL Befehle ueber das Netzwerk senden.
</p><dl>
<dt><i>request</i></dt>
<dd>
Request as <class 'int'>
</dd><dt><i>arg</i></dt>
<dd>
Argument as <class 'byte'>
</dd>
</dl><a NAME="NetFH.read" ID="NetFH.read"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.read</h3>
<b>read</b>(<i>length</i>)
<p>
Daten ueber das Netzwerk lesen.
</p><dl>
<dt><i>length</i></dt>
<dd>
Anzahl der Bytes
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
Gelesene <class 'bytes'>
</dd>
</dl><a NAME="NetFH.readpictory" ID="NetFH.readpictory"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.readpictory</h3>
<b>readpictory</b>(<i></i>)
<p>
Ruft die piCtory Konfiguration ab.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'bytes'> piCtory Datei
</dd>
</dl><a NAME="NetFH.run" ID="NetFH.run"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.run</h3>
<b>run</b>(<i></i>)
<p>
Handler fuer Synchronisierung.
</p><a NAME="NetFH.seek" ID="NetFH.seek"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.seek</h3>
<b>seek</b>(<i>position</i>)
<p>
Springt an angegebene Position.
</p><dl>
<dt><i>position</i></dt>
<dd>
An diese Position springen
</dd>
</dl><a NAME="NetFH.set_dirtybytes" ID="NetFH.set_dirtybytes"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.set_dirtybytes</h3>
<b>set_dirtybytes</b>(<i>position, dirtybytes</i>)
<p>
Konfiguriert Dirtybytes fuer Prozessabbild bei Verbindungsfehler.
</p><dl>
<dt><i>positon</i></dt>
<dd>
Startposition zum Schreiben
</dd><dt><i>dirtybytes</i></dt>
<dd>
<class 'bytes'> die geschrieben werden sollen
</dd>
</dl><a NAME="NetFH.set_timeout" ID="NetFH.set_timeout"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.set_timeout</h3>
<b>set_timeout</b>(<i>value</i>)
<p>
Setzt Timeoutwert fuer Verbindung.
</p><dl>
<dt><i>value</i></dt>
<dd>
Timeout in Millisekunden
</dd>
</dl><a NAME="NetFH.tell" ID="NetFH.tell"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.tell</h3>
<b>tell</b>(<i></i>)
<p>
Gibt aktuelle Position zurueck.
</p><dl>
<dt>Returns:</dt>
<dd>
int aktuelle Position
</dd>
</dl><a NAME="NetFH.write" ID="NetFH.write"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
NetFH.write</h3>
<b>write</b>(<i>bytebuff</i>)
<p>
Daten ueber das Netzwerk schreiben.
</p><dl>
<dt><i>bytebuff</i></dt>
<dd>
Bytes zum schreiben
</dd>
</dl><dl>
<dt>Returns:</dt>
<dd>
<class 'int'> Anzahl geschriebener bytes
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiNetIO" ID="RevPiNetIO"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiNetIO</h2>
<p>
Klasse fuer die Verwaltung der piCtory Konfiguration ueber das Netzwerk.
</p><p>
Diese Klasse uebernimmt die gesamte Konfiguration aus piCtory und bilded
die Devices und IOs ab. Sie uebernimmt die exklusive Verwaltung des
Prozessabbilds und stellt sicher, dass die Daten synchron sind.
Sollten nur einzelne Devices gesteuert werden, verwendet man
RevPiModIOSelected() und uebergibt bei Instantiierung eine Liste mit
Device Positionen oder Device Namen.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
_RevPiModIO
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#RevPiNetIO.__init__">RevPiNetIO</a></td>
<td>Instantiiert die Grundfunktionen.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO._create_myfh">_create_myfh</a></td>
<td>Erstellt NetworkFileObject.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO.disconnect">disconnect</a></td>
<td>Trennt Verbindungen und beendet autorefresh inkl.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO.get_jconfigrsc">get_jconfigrsc</a></td>
<td>Laedt die piCotry Konfiguration und erstellt ein <class 'dict'>.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO.net_cleardefaultvalues">net_cleardefaultvalues</a></td>
<td>Loescht Defaultwerte vom PLC Slave.</td>
</tr><tr>
<td><a style="color:#0000FF" href="#RevPiNetIO.net_setdefaultvalues">net_setdefaultvalues</a></td>
<td>Konfiguriert den PLC Slave mit den piCtory Defaultwerten.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiNetIO.__init__" ID="RevPiNetIO.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO (Constructor)</h3>
<b>RevPiNetIO</b>(<i>address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
<p>
Instantiiert die Grundfunktionen.
</p><dl>
<dt><i>address:</i></dt>
<dd>
IP-Adresse <class 'str'> / (IP, Port) <class 'tuple'>
</dd><dt><i>autorefresh</i></dt>
<dd>
Wenn True, alle Devices zu autorefresh hinzufuegen
</dd><dt><i>monitoring</i></dt>
<dd>
In- und Outputs werden gelesen, niemals geschrieben
</dd><dt><i>syncoutputs</i></dt>
<dd>
Aktuell gesetzte Outputs vom Prozessabbild einlesen
</dd><dt><i>simulator</i></dt>
<dd>
Laedt das Modul als Simulator und vertauscht IOs
</dd><dt><i>debug</i></dt>
<dd>
Gibt bei allen Fehlern komplette Meldungen aus
</dd><dt><i>replace_io_file</i></dt>
<dd>
Replace IO Konfiguration aus Datei laden
</dd><dt><i>direct_output</i></dt>
<dd>
Write outputs immediately to process image (slow)
</dd>
</dl><a NAME="RevPiNetIO._create_myfh" ID="RevPiNetIO._create_myfh"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO._create_myfh</h3>
<b>_create_myfh</b>(<i></i>)
<p>
Erstellt NetworkFileObject.
return FileObject
</p><a NAME="RevPiNetIO.disconnect" ID="RevPiNetIO.disconnect"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO.disconnect</h3>
<b>disconnect</b>(<i></i>)
<p>
Trennt Verbindungen und beendet autorefresh inkl. alle Threads.
</p><a NAME="RevPiNetIO.get_jconfigrsc" ID="RevPiNetIO.get_jconfigrsc"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO.get_jconfigrsc</h3>
<b>get_jconfigrsc</b>(<i></i>)
<p>
Laedt die piCotry Konfiguration und erstellt ein <class 'dict'>.
</p><dl>
<dt>Returns:</dt>
<dd>
<class 'dict'> der piCtory Konfiguration
</dd>
</dl><a NAME="RevPiNetIO.net_cleardefaultvalues" ID="RevPiNetIO.net_cleardefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO.net_cleardefaultvalues</h3>
<b>net_cleardefaultvalues</b>(<i>device=None</i>)
<p>
Loescht Defaultwerte vom PLC Slave.
</p><dl>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden, sonst auf Alle
</dd>
</dl><a NAME="RevPiNetIO.net_setdefaultvalues" ID="RevPiNetIO.net_setdefaultvalues"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIO.net_setdefaultvalues</h3>
<b>net_setdefaultvalues</b>(<i>device=None</i>)
<p>
Konfiguriert den PLC Slave mit den piCtory Defaultwerten.
</p><dl>
<dt><i>device</i></dt>
<dd>
nur auf einzelnes Device anwenden, sonst auf Alle
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiNetIODriver" ID="RevPiNetIODriver"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiNetIODriver</h2>
<p>
Klasse um eigene Treiber fuer die virtuellen Devices zu erstellen.
</p><p>
Mit dieser Klasse werden nur angegebene Virtuelle Devices mit RevPiModIO
verwaltet. Bei Instantiierung werden automatisch die Inputs und Outputs
verdreht, um das Schreiben der Inputs zu ermoeglichen. Die Daten koennen
dann ueber logiCAD an den Devices abgerufen werden.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
RevPiNetIOSelected
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#RevPiNetIODriver.__init__">RevPiNetIODriver</a></td>
<td>Instantiiert die Grundfunktionen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiNetIODriver.__init__" ID="RevPiNetIODriver.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIODriver (Constructor)</h3>
<b>RevPiNetIODriver</b>(<i>address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None, direct_output=False</i>)
<p>
Instantiiert die Grundfunktionen.
</p><p>
Parameter 'monitoring' und 'simulator' stehen hier nicht zur
Verfuegung, da diese automatisch gesetzt werden.
</p><dl>
<dt><i>address:</i></dt>
<dd>
IP-Adresse <class 'str'> / (IP, Port) <class 'tuple'>
</dd><dt><i>virtdev</i></dt>
<dd>
Virtuelles Device oder mehrere als <class 'list'>
</dd>
</dl><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#RevPiModIO.__init__">RevPiModIO.__init__(...)</a>
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr /><hr />
<a NAME="RevPiNetIOSelected" ID="RevPiNetIOSelected"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">RevPiNetIOSelected</h2>
<p>
Klasse fuer die Verwaltung einzelner Devices aus piCtory.
</p><p>
Diese Klasse uebernimmt nur angegebene Devices der piCtory Konfiguration
und bilded sie inkl. IOs ab. Sie uebernimmt die exklusive Verwaltung des
Adressbereichs im Prozessabbild an dem sich die angegebenen Devices
befinden und stellt sicher, dass die Daten synchron sind.
</p><p>
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Derived from</h3>
RevPiNetIO
<h3 style="background-color:#FFFFFF;color:#FF0000">
Class Attributes</h3>
<table>
<tr><td>__slots__</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="#RevPiNetIOSelected.__init__">RevPiNetIOSelected</a></td>
<td>Instantiiert nur fuer angegebene Devices die Grundfunktionen.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="RevPiNetIOSelected.__init__" ID="RevPiNetIOSelected.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
RevPiNetIOSelected (Constructor)</h3>
<b>RevPiNetIOSelected</b>(<i>address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
<p>
Instantiiert nur fuer angegebene Devices die Grundfunktionen.
</p><p>
Der Parameter deviceselection kann eine einzelne
Device Position / einzelner Device Name sein oder eine Liste mit
mehreren Positionen / Namen
</p><dl>
<dt><i>address:</i></dt>
<dd>
IP-Adresse <class 'str'> / (IP, Port) <class 'tuple'>
</dd><dt><i>deviceselection</i></dt>
<dd>
Positionsnummer oder Devicename
</dd>
</dl><dl>
<dt><b>See Also:</b></dt>
<dd>
<a style="color:#0000FF" href="#RevPiNetIO.__init__">RevPiNetIO.__init__(...)</a>
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

View File

@@ -1,76 +0,0 @@
<!DOCTYPE html>
<html><head>
<title>revpimodio2.summary</title>
<meta charset="UTF-8">
</head>
<body style="background-color:#FFFFFF;color:#000000"><a NAME="top" ID="top"></a>
<h1 style="background-color:#FFFFFF;color:#0000FF">
revpimodio2.summary</h1>
<p>
Bildet die Summary-Sektion von piCtory ab.
</p>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Global Attributes</h3>
<table>
<tr><td>__author__</td></tr><tr><td>__copyright__</td></tr><tr><td>__license__</td></tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Classes</h3>
<table>
<tr>
<td><a style="color:#0000FF" href="#Summary">Summary</a></td>
<td>Bildet die Summary-Sektion der config.rsc ab.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Functions</h3>
<table>
<tr><td>None</td></tr>
</table>
<hr /><hr />
<a NAME="Summary" ID="Summary"></a>
<h2 style="background-color:#FFFFFF;color:#0000FF">Summary</h2>
<p>
Bildet die Summary-Sektion der config.rsc ab.
</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>__slots__</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="#Summary.__init__">Summary</a></td>
<td>Instantiiert die RevPiSummary-Klasse.</td>
</tr>
</table>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Static Methods</h3>
<table>
<tr><td>None</td></tr>
</table>
<a NAME="Summary.__init__" ID="Summary.__init__"></a>
<h3 style="background-color:#FFFFFF;color:#FF0000">
Summary (Constructor)</h3>
<b>Summary</b>(<i>summary</i>)
<p>
Instantiiert die RevPiSummary-Klasse.
</p><dl>
<dt><i>summary</i></dt>
<dd>
piCtory Summaryinformationen
</dd>
</dl>
<div align="right"><a style="color:#0000FF" href="#top">Up</a></div>
<hr />
</body></html>

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = RevPiModIO2
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

174
docs/conf.py Normal file
View File

@@ -0,0 +1,174 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# RevPiModIO2 documentation build configuration file, created by
# sphinx-quickstart on Sun Oct 20 12:38:53 2019.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('../'))
from revpimodio2 import __version__
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.viewcode'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'RevPiModIO2'
copyright = '2019, Sven Sager (NaruX)'
author = 'Sven Sager (NaruX)'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = __version__
# The full version, including alpha/beta/rc tags.
# release = ''
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
html_sidebars = {
'**': [
'relations.html', # needs 'show_related': True theme option to display
'searchbox.html',
]
}
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'RevPiModIO2doc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'RevPiModIO2.tex', 'RevPiModIO2 Documentation',
'Sven Sager (NaruX)', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'revpimodio2', 'RevPiModIO2 Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'RevPiModIO2', 'RevPiModIO2 Documentation',
author, 'RevPiModIO2', 'One line description of project.',
'Miscellaneous'),
]

20
docs/index.rst Normal file
View File

@@ -0,0 +1,20 @@
.. RevPiModIO2 documentation master file, created by
sphinx-quickstart on Sun Oct 20 12:38:53 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to RevPiModIO2's documentation!
=======================================
.. toctree::
:maxdepth: 2
:caption: Contents:
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

7
docs/modules.rst Normal file
View File

@@ -0,0 +1,7 @@
revpimodio2
===========
.. toctree::
:maxdepth: 4
revpimodio2

70
docs/revpimodio2.rst Normal file
View File

@@ -0,0 +1,70 @@
revpimodio2 package
===================
Submodules
----------
revpimodio2\.app module
-----------------------
.. automodule:: revpimodio2.app
:members:
:undoc-members:
:show-inheritance:
revpimodio2\.device module
--------------------------
.. automodule:: revpimodio2.device
:members:
:undoc-members:
:show-inheritance:
revpimodio2\.helper module
--------------------------
.. automodule:: revpimodio2.helper
:members:
:undoc-members:
:show-inheritance:
revpimodio2\.io module
----------------------
.. automodule:: revpimodio2.io
:members:
:undoc-members:
:show-inheritance:
revpimodio2\.modio module
-------------------------
.. automodule:: revpimodio2.modio
:members:
:undoc-members:
:show-inheritance:
revpimodio2\.netio module
-------------------------
.. automodule:: revpimodio2.netio
:members:
:undoc-members:
:show-inheritance:
revpimodio2\.summary module
---------------------------
.. automodule:: revpimodio2.summary
:members:
:undoc-members:
:show-inheritance:
Module contents
---------------
.. automodule:: revpimodio2
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,221 +0,0 @@
revpimodio2.BOTH?7
revpimodio2.FALLING?7
revpimodio2.GREEN?7
revpimodio2.INP?7
revpimodio2.MEM?7
revpimodio2.OFF?7
revpimodio2.OUT?7
revpimodio2.RED?7
revpimodio2.RISING?7
revpimodio2.acheck?4(check_type, **kwargs)
revpimodio2.app.App?1(app)
revpimodio2.consttostr?4(value)
revpimodio2.device.Connect.A3?7
revpimodio2.device.Connect._devconfigure?5()
revpimodio2.device.Connect._get_leda3?5()
revpimodio2.device.Connect._get_wdtoggle?5()
revpimodio2.device.Connect._set_leda3?5(value)
revpimodio2.device.Connect._set_wdtoggle?5(value)
revpimodio2.device.Connect.wdautotoggle?7
revpimodio2.device.Core.A1?7
revpimodio2.device.Core.A2?7
revpimodio2.device.Core._devconfigure?5()
revpimodio2.device.Core._get_leda1?5()
revpimodio2.device.Core._get_leda2?5()
revpimodio2.device.Core._get_status?5()
revpimodio2.device.Core._set_calculatedled?5(addresslist, shifted_value)
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.iocycle?4()
revpimodio2.device.Core.ioerrorcount?4()
revpimodio2.device.Core.leftgate?4()
revpimodio2.device.Core.missingdeviceorgate?4()
revpimodio2.device.Core.overunderflow?4()
revpimodio2.device.Core.picontrolrunning?4()
revpimodio2.device.Core.rightgate?4()
revpimodio2.device.Core.status?7
revpimodio2.device.Core.temperature?4()
revpimodio2.device.Core.unconfdevice?4()
revpimodio2.device.Device._buildio?5(dict_io, iotype)
revpimodio2.device.Device._devconfigure?5()
revpimodio2.device.Device._get_offset?5()
revpimodio2.device.Device._get_producttype?5()
revpimodio2.device.Device._update_my_io_list?5()
revpimodio2.device.Device.autorefresh?4(activate=True)
revpimodio2.device.Device.get_allios?4(export=None)
revpimodio2.device.Device.get_inputs?4(export=None)
revpimodio2.device.Device.get_memories?4(export=None)
revpimodio2.device.Device.get_outputs?4(export=None)
revpimodio2.device.Device.length?7
revpimodio2.device.Device.name?7
revpimodio2.device.Device.offset?7
revpimodio2.device.Device.position?7
revpimodio2.device.Device.producttype?7
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.DioModule?1(parentmodio, dict_device, simulator=False)
revpimodio2.device.Gateway.get_rawbytes?4()
revpimodio2.device.Gateway?1(parent, dict_device, simulator=False)
revpimodio2.device.Virtual.writeinputdefaults?4()
revpimodio2.helper.Cycletools._docycle?5()
revpimodio2.helper.Cycletools.get_tof?4(name)
revpimodio2.helper.Cycletools.get_tofc?4(name)
revpimodio2.helper.Cycletools.get_ton?4(name)
revpimodio2.helper.Cycletools.get_tonc?4(name)
revpimodio2.helper.Cycletools.get_tp?4(name)
revpimodio2.helper.Cycletools.get_tpc?4(name)
revpimodio2.helper.Cycletools.set_tof?4(name, milliseconds)
revpimodio2.helper.Cycletools.set_tofc?4(name, cycles)
revpimodio2.helper.Cycletools.set_ton?4(name, milliseconds)
revpimodio2.helper.Cycletools.set_tonc?4(name, cycles)
revpimodio2.helper.Cycletools.set_tp?4(name, milliseconds)
revpimodio2.helper.Cycletools.set_tpc?4(name, cycles)
revpimodio2.helper.Cycletools?1(cycletime)
revpimodio2.helper.EventCallback.run?4()
revpimodio2.helper.EventCallback.stop?4()
revpimodio2.helper.EventCallback?1(func, name, value)
revpimodio2.helper.ProcimgWriter._collect_events?5(value)
revpimodio2.helper.ProcimgWriter._get_ioerrors?5()
revpimodio2.helper.ProcimgWriter._gotioerror?5(e=None)
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.DeadIO._parentdevice?8
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()
revpimodio2.io.IOBase.address?7
revpimodio2.io.IOBase.byteorder?7
revpimodio2.io.IOBase.defaultvalue?7
revpimodio2.io.IOBase.get_defaultvalue?4()
revpimodio2.io.IOBase.get_value?4()
revpimodio2.io.IOBase.length?7
revpimodio2.io.IOBase.name?7
revpimodio2.io.IOBase.reg_event?4(func, delay=0, edge=BOTH, as_thread=False, prefire=False)
revpimodio2.io.IOBase.reg_timerevent?4(func, delay, edge=BOTH, as_thread=False)
revpimodio2.io.IOBase.set_value?4(value)
revpimodio2.io.IOBase.type?7
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, signed)
revpimodio2.io.IOEvent?1(func, edge, as_thread, delay, overwrite, prefire)
revpimodio2.io.IOList._private_register_new_io_object?5(new_io)
revpimodio2.io.IOList?1()
revpimodio2.io.IntIO._get_signed?5()
revpimodio2.io.IntIO._set_byteorder?5(value)
revpimodio2.io.IntIO._set_signed?5(value)
revpimodio2.io.IntIO.byteorder?7
revpimodio2.io.IntIO.defaultvalue?7
revpimodio2.io.IntIO.get_intdefaultvalue?4()
revpimodio2.io.IntIO.get_intvalue?4()
revpimodio2.io.IntIO.set_intvalue?4(value)
revpimodio2.io.IntIO.signed?7
revpimodio2.io.IntIO.value?7
revpimodio2.io.IntIOCounter.reset?4()
revpimodio2.io.IntIOCounter?1(counter_id, parentdevice, valuelist, iotype, byteorder, signed)
revpimodio2.io.IntIOReplaceable.replace_io?4(name, frm, **kwargs)
revpimodio2.io.StructIO._get_frm?5()
revpimodio2.io.StructIO._get_signed?5()
revpimodio2.io.StructIO.defaultvalue?7
revpimodio2.io.StructIO.frm?7
revpimodio2.io.StructIO.get_structdefaultvalue?4()
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, frm, **kwargs)
revpimodio2.modio.RevPiModIO._configure?5(jconfigrsc)
revpimodio2.modio.RevPiModIO._configure_replace_io?5()
revpimodio2.modio.RevPiModIO._create_myfh?5()
revpimodio2.modio.RevPiModIO._get_configrsc?5()
revpimodio2.modio.RevPiModIO._get_cycletime?5()
revpimodio2.modio.RevPiModIO._get_debug?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_replace_io_file?5()
revpimodio2.modio.RevPiModIO._get_simulator?5()
revpimodio2.modio.RevPiModIO._gotioerror?5(action, e=None)
revpimodio2.modio.RevPiModIO._set_cycletime?5(milliseconds)
revpimodio2.modio.RevPiModIO._set_maxioerrors?5(value)
revpimodio2.modio.RevPiModIO._simulate_ioctl?5(request, arg=b'')
revpimodio2.modio.RevPiModIO.autorefresh_all?4()
revpimodio2.modio.RevPiModIO.cleanup?4()
revpimodio2.modio.RevPiModIO.configrsc?7
revpimodio2.modio.RevPiModIO.cycleloop?4(func, cycletime=50)
revpimodio2.modio.RevPiModIO.cycletime?7
revpimodio2.modio.RevPiModIO.debug?7
revpimodio2.modio.RevPiModIO.exit?4(full=True)
revpimodio2.modio.RevPiModIO.export_replaced_ios?4(filename)
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(blocking=True, no_warn=False)
revpimodio2.modio.RevPiModIO.maxioerrors?7
revpimodio2.modio.RevPiModIO.monitoring?7
revpimodio2.modio.RevPiModIO.procimg?7
revpimodio2.modio.RevPiModIO.readprocimg?4(device=None)
revpimodio2.modio.RevPiModIO.replace_io_file?7
revpimodio2.modio.RevPiModIO.resetioerrors?4()
revpimodio2.modio.RevPiModIO.setdefaultvalues?4(device=None)
revpimodio2.modio.RevPiModIO.simulator?7
revpimodio2.modio.RevPiModIO.syncoutputs?4(device=None)
revpimodio2.modio.RevPiModIO.writeprocimg?4(device=None)
revpimodio2.modio.RevPiModIO?1(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False)
revpimodio2.modio.RevPiModIODriver?1(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None, direct_output=False)
revpimodio2.modio.RevPiModIOSelected?1(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False)
revpimodio2.netio.NetFH._connect?5()
revpimodio2.netio.NetFH._direct_send?5(send_bytes, recv_count)
revpimodio2.netio.NetFH.clear_dirtybytes?4(position=None)
revpimodio2.netio.NetFH.close?4()
revpimodio2.netio.NetFH.closed?7
revpimodio2.netio.NetFH.flush?4()
revpimodio2.netio.NetFH.get_closed?4()
revpimodio2.netio.NetFH.get_name?4()
revpimodio2.netio.NetFH.get_timeout?4()
revpimodio2.netio.NetFH.ioctl?4(request, arg=b'')
revpimodio2.netio.NetFH.name?7
revpimodio2.netio.NetFH.read?4(length)
revpimodio2.netio.NetFH.readpictory?4()
revpimodio2.netio.NetFH.run?4()
revpimodio2.netio.NetFH.seek?4(position)
revpimodio2.netio.NetFH.set_dirtybytes?4(position, dirtybytes)
revpimodio2.netio.NetFH.set_timeout?4(value)
revpimodio2.netio.NetFH.tell?4()
revpimodio2.netio.NetFH.timeout?7
revpimodio2.netio.NetFH.write?4(bytebuff)
revpimodio2.netio.NetFH?1(address, timeout=500)
revpimodio2.netio.RevPiNetIO._create_myfh?5()
revpimodio2.netio.RevPiNetIO.disconnect?4()
revpimodio2.netio.RevPiNetIO.get_jconfigrsc?4()
revpimodio2.netio.RevPiNetIO.net_cleardefaultvalues?4(device=None)
revpimodio2.netio.RevPiNetIO.net_setdefaultvalues?4(device=None)
revpimodio2.netio.RevPiNetIO?1(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False)
revpimodio2.netio.RevPiNetIODriver?1(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None, direct_output=False)
revpimodio2.netio.RevPiNetIOSelected?1(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False)
revpimodio2.netio._sysdeldirty?8
revpimodio2.netio._sysexit?8
revpimodio2.netio._sysflush?8
revpimodio2.netio._syspictory?8
revpimodio2.netio._syssync?8
revpimodio2.summary.Summary?1(summary)

View File

@@ -1,19 +0,0 @@
Base Device
Connect Core
Core Base
DeviceNotFoundError Exception
DioModule Device
EventCallback Thread
Gateway Device
IntIO IOBase
IntIOCounter IntIO
IntIOReplaceable IntIO
NetFH Thread
ProcimgWriter Thread
RevPiModIODriver RevPiModIOSelected
RevPiModIOSelected RevPiModIO
RevPiNetIO _RevPiModIO
RevPiNetIODriver RevPiNetIOSelected
RevPiNetIOSelected RevPiNetIO
StructIO IOBase
Virtual Gateway

View File

@@ -1,428 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-5.1.dtd">
<!-- eric project file for project revpimodio2 -->
<!-- Saved: 2019-06-11, 09:25:45 -->
<!-- Copyright (C) 2019 Sven Sager, akira@narux.de -->
<Project version="5.1">
<Language>en_US</Language>
<Hash>7ea159534ad3516e9069331120048abf9b00151e</Hash>
<ProgLanguage mixed="0">Python3</ProgLanguage>
<ProjectType>Console</ProjectType>
<Description>Das Modul stellt alle Devices und IOs aus der piCtory Konfiguration in Python3 zur Verfügung. Es ermöglicht den direkten Zugriff auf die Werte über deren vergebenen Namen. Lese- und Schreibaktionen mit dem Prozessabbild werden von dem Modul selbst verwaltet, ohne dass sich der Programmierer um Offsets und Adressen kümmern muss. Für die Gatewaymodule wie ModbusTCP oder Profinet sind eigene 'Inputs' und 'Outputs' über einen bestimmten Adressbereich definierbar. Auf diese IOs kann mit Python3 über den Namen direkt auf die Werte zugegriffen werden.</Description>
<Version>2.3.3</Version>
<Author>Sven Sager</Author>
<Email>akira@narux.de</Email>
<Eol index="1"/>
<Sources>
<Source>revpimodio2/__init__.py</Source>
<Source>revpimodio2/app.py</Source>
<Source>revpimodio2/device.py</Source>
<Source>revpimodio2/devicecon.py</Source>
<Source>revpimodio2/helper.py</Source>
<Source>revpimodio2/io.py</Source>
<Source>revpimodio2/modio.py</Source>
<Source>revpimodio2/netio.py</Source>
<Source>revpimodio2/summary.py</Source>
<Source>setup.py</Source>
<Source>test/test_dio_cycleloop.py</Source>
<Source>test/test_dio_mainloop.py</Source>
<Source>test/test_dio_while2.py</Source>
<Source>test/test_net_leistung.py</Source>
<Source>test/test_netio_brett.py</Source>
<Source>test/test_unit.py</Source>
<Source>test/test_unit_fh.py</Source>
<Source>test/test_unitnet.py</Source>
<Source>test/web_benniesrun.py</Source>
<Source>test/web_benniesrunxxl.py</Source>
<Source>test/web_cycleloop.py</Source>
<Source>test/web_mainloop.py</Source>
<Source>test/web_rpidaten.py</Source>
<Source>test/web_rpii2c.py</Source>
<Source>test/web_startseite.py</Source>
<Source>test/web_virtdevdriver.py</Source>
</Sources>
<Forms/>
<Translations/>
<Resources/>
<Interfaces/>
<Others>
<Other>.hgignore</Other>
<Other>LICENSE.txt</Other>
<Other>MANIFEST.in</Other>
<Other>README.md</Other>
<Other>doc</Other>
<Other>eric-revpimodio2.api</Other>
</Others>
<MainScript>test/test_unit.py</MainScript>
<Vcs>
<VcsType>Mercurial</VcsType>
<VcsOptions>
<dict>
<key>
<string>add</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>checkout</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>commit</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>diff</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>export</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>global</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>history</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>log</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>remove</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>status</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>tag</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
<key>
<string>update</string>
</key>
<value>
<list>
<string></string>
</list>
</value>
</dict>
</VcsOptions>
</Vcs>
<FiletypeAssociations>
<FiletypeAssociation pattern="*.idl" type="INTERFACES"/>
<FiletypeAssociation pattern="*.py" type="SOURCES"/>
<FiletypeAssociation pattern="*.py3" type="SOURCES"/>
<FiletypeAssociation pattern="*.pyw" type="SOURCES"/>
<FiletypeAssociation pattern="*.pyw3" type="SOURCES"/>
</FiletypeAssociations>
<Documentation>
<DocumentationParams>
<dict>
<key>
<string>ERIC4API</string>
</key>
<value>
<dict>
<key>
<string>ignoreDirectories</string>
</key>
<value>
<list>
<string>deb</string>
<string>dist</string>
<string>doc</string>
<string>test</string>
</list>
</value>
<key>
<string>ignoreFilePatterns</string>
</key>
<value>
<list>
<string>setup.py</string>
<string>devicecon.py</string>
</list>
</value>
<key>
<string>languages</string>
</key>
<value>
<list>
<string>Python3</string>
</list>
</value>
<key>
<string>outputFile</string>
</key>
<value>
<string>eric-revpimodio2.api</string>
</value>
<key>
<string>useRecursion</string>
</key>
<value>
<bool>True</bool>
</value>
</dict>
</value>
<key>
<string>ERIC4DOC</string>
</key>
<value>
<dict>
<key>
<string>ignoreDirectories</string>
</key>
<value>
<list>
<string>deb</string>
<string>dist</string>
<string>doc</string>
<string>test</string>
</list>
</value>
<key>
<string>ignoreFilePatterns</string>
</key>
<value>
<list>
<string>setup.py</string>
<string>devicecon.py</string>
</list>
</value>
<key>
<string>outputDirectory</string>
</key>
<value>
<string>doc</string>
</value>
<key>
<string>qtHelpEnabled</string>
</key>
<value>
<bool>False</bool>
</value>
<key>
<string>useRecursion</string>
</key>
<value>
<bool>True</bool>
</value>
</dict>
</value>
</dict>
</DocumentationParams>
</Documentation>
<Checkers>
<CheckersParams>
<dict>
<key>
<string>Pep8Checker</string>
</key>
<value>
<dict>
<key>
<string>BuiltinsChecker</string>
</key>
<value>
<dict>
<key>
<string>chr</string>
</key>
<value>
<list>
<string>unichr</string>
</list>
</value>
<key>
<string>str</string>
</key>
<value>
<list>
<string>unicode</string>
</list>
</value>
</dict>
</value>
<key>
<string>CopyrightAuthor</string>
</key>
<value>
<string></string>
</value>
<key>
<string>CopyrightMinFileSize</string>
</key>
<value>
<int>0</int>
</value>
<key>
<string>DocstringType</string>
</key>
<value>
<string>pep257</string>
</value>
<key>
<string>ExcludeFiles</string>
</key>
<value>
<string>*/test/*</string>
</value>
<key>
<string>ExcludeMessages</string>
</key>
<value>
<string>E123,E226,E24,C101,E402,C111</string>
</value>
<key>
<string>FixCodes</string>
</key>
<value>
<string></string>
</value>
<key>
<string>FixIssues</string>
</key>
<value>
<bool>False</bool>
</value>
<key>
<string>FutureChecker</string>
</key>
<value>
<string></string>
</value>
<key>
<string>HangClosing</string>
</key>
<value>
<bool>False</bool>
</value>
<key>
<string>IncludeMessages</string>
</key>
<value>
<string></string>
</value>
<key>
<string>LineComplexity</string>
</key>
<value>
<int>15</int>
</value>
<key>
<string>LineComplexityScore</string>
</key>
<value>
<int>10</int>
</value>
<key>
<string>MaxCodeComplexity</string>
</key>
<value>
<int>10</int>
</value>
<key>
<string>MaxLineLength</string>
</key>
<value>
<int>79</int>
</value>
<key>
<string>NoFixCodes</string>
</key>
<value>
<string>E501</string>
</value>
<key>
<string>RepeatMessages</string>
</key>
<value>
<bool>True</bool>
</value>
<key>
<string>ShowIgnored</string>
</key>
<value>
<bool>False</bool>
</value>
<key>
<string>ValidEncodings</string>
</key>
<value>
<string>latin-1, utf-8</string>
</value>
</dict>
</value>
</dict>
</CheckersParams>
</Checkers>
<OtherTools>
<OtherToolsParams>
<dict>
<key>
<string>CodeMetrics</string>
</key>
<value>
<dict>
<key>
<string>ExcludeFiles</string>
</key>
<value>
<string>*/test/*,*/setup.py,*/test_unit.py</string>
</value>
</dict>
</value>
</dict>
</OtherToolsParams>
</OtherTools>
</Project>

View File

@@ -12,17 +12,16 @@ Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese
fuehrt das Modul bei Datenaenderung aus.
"""
import warnings
__all__ = [
"RevPiModIO", "RevPiModIOSelected", "RevPiModIODriver",
"RevPiNetIO", "RevPiNetIOSelected", "RevPiNetIODriver"
"RevPiNetIO", "RevPiNetIOSelected", "RevPiNetIODriver",
"Cycletools",
]
__author__ = "Sven Sager <akira@revpimodio.org>"
__copyright__ = "Copyright (C) 2018 Sven Sager"
__license__ = "LGPLv3"
__name__ = "revpimodio2"
__version__ = "2.3.3"
__version__ = "2.4.2"
# Global package values
OFF = 0
@@ -35,8 +34,6 @@ INP = 300
OUT = 301
MEM = 302
warnings.simplefilter(action="always")
class DeviceNotFoundError(Exception):
@@ -99,5 +96,6 @@ def consttostr(value):
# Benötigte Klassen importieren
from .helper import Cycletools
from .modio import RevPiModIO, RevPiModIOSelected, RevPiModIODriver
from .netio import RevPiNetIO, RevPiNetIOSelected, RevPiNetIODriver

View File

@@ -348,12 +348,10 @@ class Device(object):
if not self._modio._imgwriter.is_alive():
# Alte Einstellungen speichern
imgmaxioerrors = self._modio._imgwriter.maxioerrors
imgrefresh = self._modio._imgwriter.refresh
# ImgWriter mit alten Einstellungen erstellen
self._modio._imgwriter = ProcimgWriter(self._modio)
self._modio._imgwriter.maxioerrors = imgmaxioerrors
self._modio._imgwriter.refresh = imgrefresh
self._modio._imgwriter.start()
@@ -494,6 +492,16 @@ class Core(Base):
"_slc_temperature", "_slc_errorlimit1", "_slc_errorlimit2", \
"_slc_frequency", "_slc_led", "a1green", "a1red", "a2green", "a2red"
def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der LEDs."""
if hasattr(self, key) and key in (
"a1green", "a1red", "a2green", "a2red"):
raise AttributeError(
"direct assignment is not supported - use .value Attribute"
)
else:
object.__setattr__(self, key, value)
def _devconfigure(self):
"""Core-Klasse vorbereiten."""
@@ -767,6 +775,17 @@ class Connect(Core):
__slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", "wd", \
"x2in", "x2out"
def __setattr__(self, key, value):
"""Verhindert Ueberschreibung der LEDs."""
if hasattr(self, key) and key in (
"a1green", "a1red", "a2green", "a2red", "a3green", "a3red",
"wd", "x2in", "x2out"):
raise AttributeError(
"direct assignment is not supported - use .value Attribute"
)
else:
object.__setattr__(self, key, value)
def __wdtoggle(self):
"""WD Ausgang alle 10 Sekunden automatisch toggeln."""
while not self.__evt_wdtoggle.wait(10):

View File

@@ -289,8 +289,8 @@ class ProcimgWriter(Thread):
"""
__slots__ = "__dict_delay", "__eventth", "__eventqth", "__eventwork", \
"_adjwait", "_eventq", "_ioerror", "_maxioerrors", "_modio", \
__slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \
"_adjwait", "_eventq", "_modio", \
"_refresh", "_work", "daemon", "lck_refresh", "newdata"
def __init__(self, parentmodio):
@@ -299,12 +299,10 @@ class ProcimgWriter(Thread):
super().__init__()
self.__dict_delay = {}
self.__eventth = Thread(target=self.__exec_th)
self.__eventqth = queue.Queue()
self._eventqth = queue.Queue()
self.__eventwork = False
self._adjwait = 0
self._eventq = queue.Queue()
self._ioerror = 0
self._maxioerrors = 0
self._modio = parentmodio
self._refresh = 0.05
self._work = Event()
@@ -340,7 +338,7 @@ class ProcimgWriter(Thread):
or regfunc.edge == FALLING and not boolor:
if regfunc.delay == 0:
if regfunc.as_thread:
self.__eventqth.put(
self._eventqth.put(
(regfunc, io_event._name, io_event.value),
False
)
@@ -351,19 +349,20 @@ class ProcimgWriter(Thread):
)
else:
# Verzögertes Event in dict einfügen
tupfire = (
regfunc, io_event._name, io_event.value
tup_fire = (
regfunc, io_event._name, io_event.value,
io_event,
)
if regfunc.overwrite \
or tupfire not in self.__dict_delay:
self.__dict_delay[tupfire] = ceil(
or tup_fire not in self.__dict_delay:
self.__dict_delay[tup_fire] = ceil(
regfunc.delay / 1000 / self._refresh
)
else:
for regfunc in dev._dict_events[io_event]:
if regfunc.delay == 0:
if regfunc.as_thread:
self.__eventqth.put(
self._eventqth.put(
(regfunc, io_event._name, io_event.value),
False
)
@@ -374,12 +373,13 @@ class ProcimgWriter(Thread):
)
else:
# Verzögertes Event in dict einfügen
tupfire = (
regfunc, io_event._name, io_event.value
tup_fire = (
regfunc, io_event._name, io_event.value,
io_event,
)
if regfunc.overwrite \
or tupfire not in self.__dict_delay:
self.__dict_delay[tupfire] = ceil(
or tup_fire not in self.__dict_delay:
self.__dict_delay[tup_fire] = ceil(
regfunc.delay / 1000 / self._refresh
)
@@ -390,7 +390,7 @@ class ProcimgWriter(Thread):
"""Laeuft als Thread, der Events als Thread startet."""
while self.__eventwork:
try:
tup_fireth = self.__eventqth.get(timeout=1)
tup_fireth = self._eventqth.get(timeout=1)
th = EventCallback(
tup_fireth[0].func, tup_fireth[1], tup_fireth[2]
)
@@ -415,7 +415,7 @@ class ProcimgWriter(Thread):
self.__eventwork = value
if not value:
# Nur leeren beim deaktivieren
self.__eventqth = queue.Queue()
self._eventqth = queue.Queue()
self._eventq = queue.Queue()
self.__dict_delay = {}
@@ -427,34 +427,6 @@ class ProcimgWriter(Thread):
return True
def _get_ioerrors(self):
"""Ruft aktuelle Anzahl der Fehler ab.
@return Aktuelle Fehleranzahl"""
return self._ioerror
def _gotioerror(self, e=None):
"""IOError Verwaltung fuer autorefresh.
@param e Exception to log if debug is enabled
"""
self._ioerror += 1
if self._maxioerrors != 0 and self._ioerror >= self._maxioerrors:
raise RuntimeError(
"reach max io error count {0} on process image".format(
self._maxioerrors
)
)
warnings.warn(
"count {0} io errors on process image".format(self._ioerror),
RuntimeWarning
)
if self._modio._debug and e is not None:
warnings.warn(str(e), 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 <class 'int'> Zykluszeit in Millisekunden"""
@@ -465,18 +437,19 @@ class ProcimgWriter(Thread):
fh = self._modio._create_myfh()
self._adjwait = self._refresh
mrk_warn = True
while not self._work.is_set():
ot = default_timer()
# Lockobjekt holen und Fehler werfen, wenn nicht schnell genug
if not self.lck_refresh.acquire(timeout=self._adjwait):
warnings.warn(
"cycle time of {0} ms exceeded on lock".format(
int(self._refresh * 1000)
),
"cycle time of {0} ms exceeded during executing function"
"".format(int(self._refresh * 1000)),
RuntimeWarning
)
# Verzögerte Events pausieren an dieser Stelle
# Nur durch cycleloop erreichbar - keine verzögerten Events
continue
try:
@@ -511,11 +484,27 @@ class ProcimgWriter(Thread):
fh.flush()
except IOError as e:
self._gotioerror(e)
self._modio._gotioerror("autorefresh", e, mrk_warn)
mrk_warn = self._modio._debug == -1
self.lck_refresh.release()
continue
else:
if not mrk_warn:
if self._modio._debug == 0:
warnings.warn(
"recover from io errors on process image",
RuntimeWarning
)
else:
warnings.warn(
"recover from io errors on process image - total "
"count of {0} errors now"
"".format(self._modio._ioerror),
RuntimeWarning
)
mrk_warn = True
# Alle aufwecken
self.lck_refresh.release()
self.newdata.set()
@@ -525,15 +514,14 @@ class ProcimgWriter(Thread):
if self.__eventwork:
for tup_fire in tuple(self.__dict_delay.keys()):
if tup_fire[0].overwrite and \
getattr(self._modio.io, tup_fire[1]).value != \
tup_fire[2]:
tup_fire[3].value != tup_fire[2]:
del self.__dict_delay[tup_fire]
else:
self.__dict_delay[tup_fire] -= 1
if self.__dict_delay[tup_fire] <= 0:
# Verzögertes Event übernehmen und löschen
if tup_fire[0].as_thread:
self.__eventqth.put(tup_fire, False)
self._eventqth.put(tup_fire, False)
else:
self._eventq.put(tup_fire, False)
del self.__dict_delay[tup_fire]
@@ -546,9 +534,8 @@ class ProcimgWriter(Thread):
self._adjwait -= 0.001
if self._adjwait < 0:
warnings.warn(
"cycle time of {0} ms exceeded".format(
int(self._refresh * 1000)
),
"cycle time of {0} ms exceeded several times - can not"
" hold cycle time!".format(int(self._refresh * 1000)),
RuntimeWarning
)
self._adjwait = 0
@@ -564,17 +551,6 @@ 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:
if value >= 0:
self._maxioerrors = value
else:
raise ValueError("value must be 0 or a positive integer")
else:
raise TypeError("value must be <class 'int'>")
def set_refresh(self, value):
"""Setzt die Zykluszeit in Millisekunden.
@param value <class 'int'> Millisekunden"""
@@ -587,6 +563,4 @@ class ProcimgWriter(Thread):
"refresh time must be 5 to 2000 milliseconds"
)
ioerrors = property(_get_ioerrors)
maxioerrors = property(get_maxioerrors, set_maxioerrors)
refresh = property(get_refresh, set_refresh)

View File

@@ -994,18 +994,12 @@ class IntIOReplaceable(IntIO):
- delay: Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
- edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung
- as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus
- prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet
@see <a target="_blank"
href="https://docs.python.org/3/library/struct.html#format-characters"
>Python3 struct</a>
"""
# Sperre prüfen
if self._parentdevice._modio._lck_replace_io:
raise RuntimeError(
"can not use this function while using an external "
"replace_io_file"
)
# StructIO erzeugen
io_new = StructIO(
self,

View File

@@ -37,11 +37,11 @@ class RevPiModIO(object):
"_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \
"_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \
"core", "app", "device", "exitsignal", "io", "summary", "_debug", \
"_lck_replace_io", "_replace_io_file", "_run_on_pi"
"_replace_io_file", "_run_on_pi"
def __init__(
self, autorefresh=False, monitoring=False, syncoutputs=True,
procimg=None, configrsc=None, simulator=False, debug=False,
procimg=None, configrsc=None, simulator=False, debug=True,
replace_io_file=None, direct_output=False):
"""Instantiiert die Grundfunktionen.
@@ -51,7 +51,7 @@ class RevPiModIO(object):
@param procimg Abweichender Pfad zum Prozessabbild
@param configrsc Abweichender Pfad zur piCtory Konfigurationsdatei
@param simulator Laedt das Modul als Simulator und vertauscht IOs
@param debug Gibt bei allen Fehlern komplette Meldungen aus
@param debug Gibt alle Warnungen inkl. Zyklusprobleme aus
@param replace_io_file Replace IO Konfiguration aus Datei laden
@param direct_output Write outputs immediately to process image (slow)
@@ -80,12 +80,11 @@ class RevPiModIO(object):
# Private Variablen
self.__cleanupfunc = None
self._buffedwrite = False
self._debug = debug
self._debug = 1
self._exit = Event()
self._imgwriter = None
self._ioerror = 0
self._length = 0
self._lck_replace_io = False
self._looprunning = False
self._lst_devselect = []
self._lst_refresh = []
@@ -108,6 +107,9 @@ class RevPiModIO(object):
# Event für Benutzeraktionen
self.exitsignal = Event()
# Wert über setter setzen
self.debug = debug
try:
self._run_on_pi = S_ISCHR(osstat(self._procimg).st_mode)
except Exception:
@@ -116,6 +118,7 @@ class RevPiModIO(object):
# Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiModIO:
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
def __del__(self):
"""Zerstoert alle Klassen um aufzuraeumen."""
@@ -138,7 +141,8 @@ class RevPiModIO(object):
self.writeprocimg()
def _configure(self, jconfigrsc):
"""Verarbeitet die piCtory Konfigurationsdatei."""
"""Verarbeitet die piCtory Konfigurationsdatei.
@param jconfigrsc: Data to build IOs as <class 'dict'> of JSON"""
# Filehandler konfigurieren, wenn er noch nicht existiert
if self._myfh is None:
@@ -233,7 +237,8 @@ class RevPiModIO(object):
else:
# Device-Type nicht gefunden
warnings.warn(
"device type '{0}' unknown".format(device["type"]),
"device type '{0}' on position {1} unknown"
"".format(device["type"], device["position"]),
Warning
)
dev_new = None
@@ -262,11 +267,6 @@ class RevPiModIO(object):
Warning
)
# Replace IO aus Datei verarbeiten
if self._replace_io_file is not None:
self._configure_replace_io()
self._lck_replace_io = True
# ImgWriter erstellen
self._imgwriter = helpermodule.ProcimgWriter(self)
@@ -301,85 +301,74 @@ class RevPiModIO(object):
# Summary Klasse instantiieren
self.summary = summarymodule.Summary(jconfigrsc["Summary"])
def _configure_replace_io(self):
def _configure_replace_io(self, creplaceio):
"""Importiert ersetzte IOs in diese Instanz.
Importiert ersetzte IOs, welche vorher mit .export_replaced_ios(...)
in eine Datei exportiert worden sind. Diese IOs werden in dieser
Instanz wiederhergestellt.
@param ireplaceio: Data to replace ios as <class 'ConfigParser'>
"""
cp = ConfigParser()
try:
with open(self._replace_io_file, "r") as fh:
cp.read_file(fh)
except Exception as e:
raise RuntimeError(
"replace_io_file: could not read file '{0}' | {1}"
"".format(self._replace_io_file, e)
)
for io in cp:
for io in creplaceio:
if io == "DEFAULT":
continue
# IO prüfen
parentio = cp[io].get("replace", "")
parentio = creplaceio[io].get("replace", "")
# Funktionsaufruf vorbereiten
dict_replace = {
"frm": cp[io].get("frm"),
"frm": creplaceio[io].get("frm"),
"byteorder": creplaceio[io].get("byteorder", "little"),
"bmk": creplaceio[io].get("bmk", ""),
}
# Convert defaultvalue from config file
if "defaultvalue" in cp[io]:
if dict_replace["frm"] == "?":
try:
dict_replace["defaultvalue"] = \
cp[io].getboolean("defaultvalue")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"defaultvalue '{1}' to boolean"
"".format(io, cp[io].get("defaultvalue"))
)
else:
try:
dict_replace["defaultvalue"] = \
cp[io].getint("defaultvalue")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"defaultvalue '{1}' to integer"
"".format(io, cp[io].get("bit"))
)
# Get bitaddress from config file
if "bit" in cp[io]:
if "bit" in creplaceio[io]:
try:
dict_replace["bit"] = cp[io].getint("bit", 0)
dict_replace["bit"] = creplaceio[io].getint("bit")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"bit '{1}' to integer"
"".format(io, cp[io].get("bit"))
"".format(io, creplaceio[io]["bit"])
)
# Sonstige Werte laden, wenn vorhanden
if "bmk" in cp[io]:
dict_replace["bmk"] = cp[io].get("bmk")
if "byteorder" in cp[io]:
dict_replace["byteorder"] = cp[io].get("byteorder")
# Convert defaultvalue from config file
if "defaultvalue" in creplaceio[io]:
if dict_replace["frm"] == "?":
try:
dict_replace["defaultvalue"] = \
creplaceio[io].getboolean("defaultvalue")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"defaultvalue '{1}' to boolean"
"".format(io, creplaceio[io]["defaultvalue"])
)
else:
try:
dict_replace["defaultvalue"] = \
creplaceio[io].getint("defaultvalue")
except Exception:
raise ValueError(
"replace_io_file: could not convert '{0}' "
"defaultvalue '{1}' to integer"
"".format(io, creplaceio[io]["defaultvalue"])
)
# IO ersetzen
try:
self.io[parentio].replace_io(name=io, **dict_replace)
except Exception as e:
raise RuntimeError(
"replace_io_file: can not replace '{0}' with '{1}' "
"| RevPiModIO message: {2}".format(parentio, io, e)
)
# NOTE: Bei Selected/Driver kann nicht geprüft werden
if len(self._lst_devselect) == 0:
raise RuntimeError(
"replace_io_file: can not replace '{0}' with '{1}' "
"| RevPiModIO message: {2}".format(parentio, io, e)
)
def _create_myfh(self):
"""Erstellt FileObject mit Pfad zum procimg.
@@ -392,6 +381,25 @@ class RevPiModIO(object):
@return Pfad der verwendeten piCtory Konfiguration"""
return self._configrsc
def _get_cpreplaceio(self):
"""Laed die replace_io_file Konfiguration und verarbeitet sie.
@return <class 'ConfigParser'> der replace io daten"""
cp = ConfigParser()
# TODO: verfeinern!
if self._replace_io_file:
try:
with open(self._replace_io_file, "r") as fh:
cp.read_file(fh)
except Exception as e:
raise RuntimeError(
"replace_io_file: could not read/parse file '{0}' | {1}"
"".format(self._replace_io_file, e)
)
return cp
def _get_cycletime(self):
"""Gibt Aktualisierungsrate in ms der Prozessabbildsynchronisierung aus.
@return Millisekunden"""
@@ -400,15 +408,12 @@ class RevPiModIO(object):
def _get_debug(self):
"""Gibt Status des Debugflags zurueck.
@return Status des Debugflags"""
return self._debug
return self._debug == 1
def _get_ioerrors(self):
"""Getter function.
@return Aktuelle Anzahl gezaehlter Fehler"""
if self._looprunning:
return self._imgwriter._ioerror
else:
return self._ioerror
return self._ioerror
def _get_length(self):
"""Getter function.
@@ -440,11 +445,12 @@ class RevPiModIO(object):
@return True, wenn als Simulator gestartet"""
return self._simulator
def _gotioerror(self, action, e=None):
def _gotioerror(self, action, e=None, show_warn=True):
"""IOError Verwaltung fuer Prozessabbildzugriff.
@param action Zusatzinformationen zum loggen
@param e Exception to log if debug is enabled
@param show_warn Warnung anzeigen
"""
self._ioerror += 1
@@ -453,13 +459,21 @@ class RevPiModIO(object):
"reach max io error count {0} on process image"
"".format(self._maxioerrors)
)
warnings.warn(
"got io error during {0} and count {1} errors now"
"".format(action, self._ioerror),
RuntimeWarning
)
if self._debug and e is not None:
warnings.warn(str(e), RuntimeWarning)
if not show_warn or self._debug == -1:
return
if self._debug == 0:
warnings.warn(
"got io error on process image",
RuntimeWarning
)
else:
warnings.warn(
"got io error during '{0}' and count {1} errors now | {2}"
"".format(action, self._ioerror, str(e)),
RuntimeWarning
)
def _set_cycletime(self, milliseconds):
"""Setzt Aktualisierungsrate der Prozessabbild-Synchronisierung.
@@ -472,12 +486,31 @@ class RevPiModIO(object):
else:
self._imgwriter.refresh = milliseconds
def _set_debug(self, value):
"""Setzt debugging Status um mehr Meldungen zu erhalten oder nicht.
@param value Wenn True, werden umfangreiche Medungen angezeigt"""
if type(value) == bool:
value = int(value)
if not type(value) == int:
# Wert -1 ist zum kompletten deaktivieren versteckt
raise TypeError("value must be <class 'bool'> or <class 'int'>")
if not -1 <= value <= 1:
raise ValueError("value must be True/False or -1, 0, 1")
self._debug = value
if value == -1:
warnings.filterwarnings("ignore", module="revpimodio2")
elif value == 0:
warnings.filterwarnings("default", module="revpimodio2")
else:
warnings.filterwarnings("always", module="revpimodio2")
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")
@@ -511,7 +544,6 @@ class RevPiModIO(object):
self._myfh.flush()
elif request == 19220:
# FIXME: Implement
# Counterwert auf 0 setzen
dev_position = arg[0]
bit_field = int.from_bytes(arg[2:], byteorder="little")
@@ -524,7 +556,7 @@ class RevPiModIO(object):
break
if io_byte == -1:
raise RuntimeError("count not reset counter io in file")
raise RuntimeError("could not reset counter io in file")
with self._myfh_lck:
self._myfh.seek(io_byte)
@@ -573,7 +605,7 @@ class RevPiModIO(object):
@param func Funktion, die ausgefuehrt werden soll
@param cycletime Zykluszeit in Millisekunden - Standardwert 50 ms
@return None
@return None or the return value of the cycle function
"""
# Prüfen ob ein Loop bereits läuft
@@ -682,7 +714,7 @@ class RevPiModIO(object):
if not self._monitoring:
self.writeprocimg(dev)
def export_replaced_ios(self, filename):
def export_replaced_ios(self, filename="replace_ios.conf"):
"""Exportiert ersetzte IOs dieser Instanz.
Exportiert alle ersetzten IOs, welche mit .replace_io(...) angelegt
@@ -705,8 +737,10 @@ class RevPiModIO(object):
# Optional values
if io._bitaddress >= 0:
cp[io.name]["bit"] = str(io._bitaddress)
cp[io.name]["byteorder"] = io._byteorder
cp[io.name]["defaultvalue"] = str(io.defaultvalue)
if io._byteorder != "little":
cp[io.name]["byteorder"] = io._byteorder
if io.defaultvalue != 0:
cp[io.name]["defaultvalue"] = str(io.defaultvalue)
if io.bmk != "":
cp[io.name]["bmk"] = io.bmk
@@ -784,7 +818,7 @@ class RevPiModIO(object):
signal(SIGINT, self.__evt_exit)
signal(SIGTERM, self.__evt_exit)
def mainloop(self, blocking=True, no_warn=False):
def mainloop(self, blocking=True):
"""Startet den Mainloop mit Eventueberwachung.
Der aktuelle Programmthread wird hier bis Aufruf von
@@ -799,8 +833,7 @@ class RevPiModIO(object):
Events vom RevPi benoetigt werden, aber das Programm weiter ausgefuehrt
werden soll.
@param blocking Wenn False, blockiert das Programm NICHT
@param no_warn Keine Warnungen bei langsamen Funktionen ausgeben
@param blocking Wenn False, blockiert das Programm hier NICHT
@return None
"""
@@ -847,7 +880,7 @@ class RevPiModIO(object):
or regfunc.edge == RISING and io.value \
or regfunc.edge == FALLING and not io.value:
if regfunc.as_thread:
self._imgwriter.__eventqth.put(
self._imgwriter._eventqth.put(
(regfunc, io._name, io.value), False
)
else:
@@ -858,13 +891,13 @@ class RevPiModIO(object):
# ImgWriter mit Eventüberwachung aktivieren
self._imgwriter._collect_events(True)
e = None
runtime = -1 if no_warn else 0
runtime = -1 if self._debug == -1 else 0
while not self._exit.is_set():
# Laufzeit der Eventqueue auf 0 setzen
if self._imgwriter._eventq.qsize() == 0:
runtime = -1 if no_warn else 0
runtime = -1 if self._debug == -1 else 0
try:
tup_fire = self._imgwriter._eventq.get(timeout=1)
@@ -882,7 +915,7 @@ class RevPiModIO(object):
runtime = -1
warnings.warn(
"can not execute all event functions in one cycle - "
"rise .cycletime or optimize your event functions",
"optimize your event functions or rise .cycletime",
RuntimeWarning
)
except Empty:
@@ -958,7 +991,6 @@ class RevPiModIO(object):
def resetioerrors(self):
"""Setzt aktuellen IOError-Zaehler auf 0 zurueck."""
self._ioerror = 0
self._imgwriter._ioerror = 0
def setdefaultvalues(self, device=None):
"""Alle Outputbuffer werden auf die piCtory default Werte gesetzt.
@@ -1082,7 +1114,7 @@ class RevPiModIO(object):
return workokay
debug = property(_get_debug)
debug = property(_get_debug, _set_debug)
configrsc = property(_get_configrsc)
cycletime = property(_get_cycletime, _set_cycletime)
ioerrors = property(_get_ioerrors)
@@ -1110,7 +1142,7 @@ class RevPiModIOSelected(RevPiModIO):
def __init__(
self, deviceselection, autorefresh=False, monitoring=False,
syncoutputs=True, procimg=None, configrsc=None,
simulator=False, debug=False, replace_io_file=None,
simulator=False, debug=True, replace_io_file=None,
direct_output=False):
"""Instantiiert nur fuer angegebene Devices die Grundfunktionen.
@@ -1142,6 +1174,7 @@ class RevPiModIOSelected(RevPiModIO):
)
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
if len(self.device) == 0:
if type(self) == RevPiModIODriver:
@@ -1178,7 +1211,7 @@ class RevPiModIODriver(RevPiModIOSelected):
def __init__(
self, virtdev, autorefresh=False, monitoring=False,
syncoutputs=True, procimg=None, configrsc=None, debug=False,
syncoutputs=True, procimg=None, configrsc=None, debug=True,
replace_io_file=None, direct_output=False):
"""Instantiiert die Grundfunktionen.

View File

@@ -5,6 +5,7 @@ __copyright__ = "Copyright (C) 2018 Sven Sager"
__license__ = "LGPLv3"
import socket
import warnings
from configparser import ConfigParser
from json import loads as jloads
from re import compile
from revpimodio2 import DeviceNotFoundError
@@ -21,8 +22,28 @@ _sysexit = b'\x01EX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
_sysdeldirty = b'\x01EY\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x17'
# piCtory Konfiguration laden
_syspictory = b'\x01PI\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
_syspictoryh = b'\x01PH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
# ReplaceIO Konfiguration laden
_sysreplaceio = b'\x01RP\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
_sysreplaceioh = b'\x01RH\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
# Übertragene Bytes schreiben
_sysflush = b'\x01SD\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x17'
# Hashvalues
HASH_FAIL = b'\xff' * 16
class AclException(Exception):
"""Probleme mit Berechtigungen."""
pass
class ConfigChanged(Exception):
"""Aenderung der piCtory oder replace_ios Datei."""
pass
class NetFH(Thread):
@@ -35,26 +56,34 @@ class NetFH(Thread):
"""
__slots__ = "__by_buff", "__int_buff", "__dictdirty", "__flusherr", \
"__position", "__sockact", "__sockerr", "__sockend", "__socklock", \
"__timeout", "__trigger", "__waitsync", \
"_address", "_slavesock", \
"daemon"
__slots__ = "__by_buff", "__check_replace_ios", "__config_changed", \
"__int_buff", "__dictdirty", "__flusherr", "__replace_ios_h", \
"__pictory_h", "__position", "__sockact", "__sockerr", "__sockend", \
"__socklock", "__timeout", "__trigger", "__waitsync", "_address", \
"_slavesock", "daemon"
def __init__(self, address, timeout=500):
def __init__(self, address, check_replace_ios, timeout=500):
"""Init NetFH-class.
@param address IP Adresse, Port des RevPi als <class 'tuple'>
@param timeout Timeout in Millisekunden der Verbindung"""
@param check_replace_ios Prueft auf Veraenderungen der Datei
@param timeout Timeout in Millisekunden der Verbindung
"""
super().__init__()
self.daemon = True
self.__by_buff = b''
self.__check_replace_ios = check_replace_ios
self.__config_changed = False
self.__int_buff = 0
self.__dictdirty = {}
self.__flusherr = False
self.__replace_ios_h = b''
self.__pictory_h = b''
self.__sockact = False
self.__sockerr = Event()
self.__sockend = False
self.__sockend = Event()
self.__socklock = Lock()
self.__timeout = None
self.__trigger = False
@@ -90,10 +119,10 @@ class NetFH(Thread):
if bytecode == b'\x18':
# Alles beenden, wenn nicht erlaubt
self.__sockend = True
self.__sockend.set()
self.__sockerr.set()
self._slavesock.close()
raise RuntimeError(
raise AclException(
"write access to the process image is not permitted - use "
"monitoring=True or check aclplcslave.conf on RevPi and "
"reload revpipyload!"
@@ -124,6 +153,46 @@ class NetFH(Thread):
so = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
so.connect(self._address)
# Hashwerte anfordern
recv_len = 16
so.sendall(_syspictoryh)
if self.__check_replace_ios:
so.sendall(_sysreplaceioh)
recv_len += 16
# Hashwerte empfangen
byte_buff = bytearray()
zero_byte = 0
while not self.__sockend.is_set() and len(byte_buff) < recv_len:
data = so.recv(recv_len)
if data == b'':
zero_byte += 1
if zero_byte == 100:
raise OSError("too many zero bytes on hash load")
byte_buff += data
# Änderung an piCtory prüfen
if self.__pictory_h and byte_buff[:16] != self.__pictory_h:
self.__config_changed = True
self.close()
raise ConfigChanged(
"configuration on revolution pi was changed")
else:
self.__pictory_h = byte_buff[:16]
# Änderung an replace_ios prüfen
if self.__check_replace_ios and self.__replace_ios_h \
and byte_buff[16:] != self.__replace_ios_h:
self.__config_changed = True
self.close()
raise ConfigChanged(
"configuration on revolution pi was changed")
else:
self.__replace_ios_h = byte_buff[16:]
except ConfigChanged:
so.close()
raise
except Exception:
so.close()
else:
@@ -151,11 +220,12 @@ class NetFH(Thread):
@returns Empfangende Bytes
"""
if self.__sockend:
if self.__sockend.is_set():
raise ValueError("I/O operation on closed file")
with self.__socklock:
self._slavesock.sendall(send_bytes)
# FIXME: Schleife bis Daten empfangen sind einbauen
recv = self._slavesock.recv(recv_count)
self.__trigger = True
return recv
@@ -163,10 +233,15 @@ class NetFH(Thread):
def clear_dirtybytes(self, position=None):
"""Entfernt die konfigurierten Dirtybytes vom RevPi Slave.
@param position Startposition der Dirtybytes"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("I/O operation on closed file")
with self.__socklock:
error = False
try:
self.__socklock.acquire()
if position is None:
# Alle Dirtybytes löschen
self._slavesock.sendall(_sysdeldirty)
@@ -184,40 +259,54 @@ class NetFH(Thread):
# ACL prüfen und ggf Fehler werfen
self.__check_acl(check)
self.__sockerr.set()
raise IOError("clear dirtybytes error on network")
except AclException:
raise
except Exception:
error = True
finally:
self.__socklock.release()
# Daten bei Erfolg übernehmen
# Daten immer übernehmen
if position is None:
self.__dictdirty = {}
elif position in self.__dictdirty:
del self.__dictdirty[position]
if error:
# Fehler nach übernahme der Daten auslösen um diese zu setzen
self.__sockerr.set()
self.__trigger = True
def close(self):
"""Verbindung trennen."""
if self.__sockend:
if self.__sockend.is_set():
return
self.__sockend = True
self.__sockend.set()
self.__sockerr.set()
# Vom Socket sauber trennen
if self._slavesock is not None:
with self.__socklock:
try:
if self.__sockend:
self._slavesock.send(_sysexit)
else:
self._slavesock.shutdown(socket.SHUT_RDWR)
except Exception:
pass
try:
self.__socklock.acquire()
self._slavesock.send(_sysexit)
# NOTE: Wird das benötigt?
self._slavesock.shutdown(socket.SHUT_RDWR)
except Exception:
pass
finally:
self.__socklock.release()
self._slavesock.close()
def flush(self):
"""Schreibpuffer senden."""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("flush of closed file")
with self.__socklock:
@@ -248,13 +337,23 @@ class NetFH(Thread):
def get_closed(self):
"""Pruefen ob Verbindung geschlossen ist.
@return True, wenn Verbindung geschlossen ist"""
return self.__sockend
return self.__sockend.is_set()
def get_config_changed(self):
"""Pruefen ob RevPi Konfiguration geaendert wurde.
@return True, wenn RevPi Konfiguration geaendert ist"""
return self.__config_changed
def get_name(self):
"""Verbindugnsnamen zurueckgeben.
@return <class 'str'> IP:PORT"""
return "{0}:{1}".format(*self._address)
def get_reconnecting(self):
"""Interner reconnect aktiv wegen Netzwerkfehlern.
@return True, wenn reconnect aktiv"""
return self.__sockerr.is_set()
def get_timeout(self):
"""Gibt aktuellen Timeout zurueck.
@return <class 'int'> in Millisekunden"""
@@ -264,7 +363,9 @@ class NetFH(Thread):
"""IOCTL Befehle ueber das Netzwerk senden.
@param request Request as <class 'int'>
@param arg Argument as <class 'byte'>"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("read of closed file")
if not (isinstance(arg, bytes) and len(arg) <= 1024):
@@ -295,7 +396,9 @@ class NetFH(Thread):
"""Daten ueber das Netzwerk lesen.
@param length Anzahl der Bytes
@return Gelesene <class 'bytes'>"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("read of closed file")
with self.__socklock:
@@ -307,8 +410,8 @@ class NetFH(Thread):
)
bytesbuff = bytearray()
while not self.__sockend and len(bytesbuff) < length:
rbytes = self._slavesock.recv(1024)
while not self.__sockend.is_set() and len(bytesbuff) < length:
rbytes = self._slavesock.recv(256)
if rbytes == b'':
self.__sockerr.set()
@@ -323,56 +426,108 @@ class NetFH(Thread):
def readpictory(self):
"""Ruft die piCtory Konfiguration ab.
@return <class 'bytes'> piCtory Datei"""
if self.__sockend:
if self.__sockend.is_set():
raise ValueError("read of closed file")
if self.__pictory_h == HASH_FAIL:
raise RuntimeError(
"could not read/parse piCtory configuration over network"
)
with self.__socklock:
self._slavesock.send(_syspictory)
byte_buff = bytearray()
while not self.__sockend:
data = self._slavesock.recv(1024)
zero_byte = 0
while not self.__sockend.is_set() and zero_byte < 100:
data = self._slavesock.recv(128)
if data == b'':
zero_byte += 1
byte_buff += data
if data.find(b'\x04') >= 0:
self.__trigger = True
# NOTE: Nur suchen oder Ende prüfen?
return byte_buff[:-1]
return bytes(byte_buff[:-1])
self.__sockerr.set()
raise IOError("readpictory error on network")
self.__trigger = True
def readreplaceio(self):
"""Ruft die replace_io Konfiguration ab.
@return <class 'bytes'> replace_io_file"""
if self.__sockend.is_set():
raise ValueError("read of closed file")
if self.__replace_ios_h == HASH_FAIL:
raise RuntimeError(
"replace_io_file: could not read/parse over network"
)
with self.__socklock:
self._slavesock.send(_sysreplaceio)
byte_buff = bytearray()
zero_byte = 0
while not self.__sockend.is_set() and zero_byte < 100:
data = self._slavesock.recv(128)
if data == b'':
zero_byte += 1
byte_buff += data
if data.find(b'\x04') >= 0:
self.__trigger = True
# NOTE: Nur suchen oder Ende prüfen?
return bytes(byte_buff[:-1])
self.__sockerr.set()
raise IOError("readreplaceio error on network")
def run(self):
"""Handler fuer Synchronisierung."""
while not self.__sockend:
state_reconnect = False
while not self.__sockend.is_set():
# Bei Fehlermeldung neu verbinden
if self.__sockerr.is_set():
if not state_reconnect:
state_reconnect = True
warnings.warn(
"got a network error and try to reconnect",
RuntimeWarning
)
self._connect()
if self.__sockerr.is_set():
# Verhindert bei Scheitern 100% CPU last
self.__sockend.wait(self.__waitsync)
else:
state_reconnect = False
warnings.warn(
"successfully reconnected after network error",
RuntimeWarning
)
else:
# Kein Fehler aufgetreten, sync durchführen wenn socket frei
if not self.__trigger and \
self.__socklock.acquire(blocking=False):
try:
self._slavesock.send(_syssync)
data = self._slavesock.recv(2)
except IOError as e:
# Kein Fehler aufgetreten, sync durchführen wenn socket frei
if not self.__trigger and \
self.__socklock.acquire(blocking=False):
try:
self._slavesock.send(_syssync)
data = self._slavesock.recv(2)
except IOError:
self.__sockerr.set()
else:
if data != b'\x06\x16':
warnings.warn(
"network error in sync of NetFH", RuntimeWarning
"data error on network sync",
RuntimeWarning
)
self.__sockerr.set()
else:
if data != b'\x06\x16':
warnings.warn(
"data error in sync of NetFH", RuntimeWarning
)
self.__sockerr.set()
self.__socklock.release()
self.__socklock.release()
self.__trigger = False
self.__trigger = False
# Warten nach Sync damit Instantiierung funktioniert
self.__sockerr.wait(self.__waitsync)
@@ -380,7 +535,9 @@ class NetFH(Thread):
def seek(self, position):
"""Springt an angegebene Position.
@param position An diese Position springen"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("seek of closed file")
self.__position = int(position)
@@ -388,10 +545,15 @@ class NetFH(Thread):
"""Konfiguriert Dirtybytes fuer Prozessabbild bei Verbindungsfehler.
@param positon Startposition zum Schreiben
@param dirtybytes <class 'bytes'> die geschrieben werden sollen"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("I/O operation on closed file")
with self.__socklock:
error = False
try:
self.__socklock.acquire()
self._slavesock.sendall(
b'\x01EY' +
position.to_bytes(length=2, byteorder="little") +
@@ -406,24 +568,35 @@ class NetFH(Thread):
# ACL prüfen und ggf Fehler werfen
self.__check_acl(check)
self.__sockerr.set()
raise IOError("set dirtybytes error on network")
except AclException:
raise
except Exception:
error = True
finally:
self.__socklock.release()
# Daten erfolgreich übernehmen
self.__dictdirty[position] = dirtybytes
# Daten immer übernehmen
self.__dictdirty[position] = dirtybytes
self.__trigger = True
if error:
# Fehler nach übernahme der Daten auslösen um diese zu setzen
self.__sockerr.set()
self.__trigger = True
def set_timeout(self, value):
"""Setzt Timeoutwert fuer Verbindung.
@param value Timeout in Millisekunden"""
if self.__sockend:
if self.__sockend.is_set():
raise ValueError("I/O operation on closed file")
# Timeoutwert verarbeiten (könnte Exception auslösen)
self.__set_systimeout(value)
with self.__socklock:
try:
self.__socklock.acquire()
self._slavesock.send(
b'\x01CF' +
value.to_bytes(length=2, byteorder="little") +
@@ -431,15 +604,20 @@ class NetFH(Thread):
)
check = self._slavesock.recv(1)
if check != b'\x1e':
self.__sockerr.set()
raise IOError("set timeout error on network")
except Exception:
self.__sockerr.set()
finally:
self.__socklock.release()
self.__trigger = True
self.__trigger = True
def tell(self):
"""Gibt aktuelle Position zurueck.
@return int aktuelle Position"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("I/O operation on closed file")
return self.__position
@@ -447,7 +625,9 @@ class NetFH(Thread):
"""Daten ueber das Netzwerk schreiben.
@param bytebuff Bytes zum schreiben
@return <class 'int'> Anzahl geschriebener bytes"""
if self.__sockend:
if self.__config_changed:
raise ConfigChanged("configuration on revolution pi was changed")
if self.__sockend.is_set():
raise ValueError("write to closed file")
if self.__flusherr:
@@ -468,7 +648,9 @@ class NetFH(Thread):
return len(bytebuff)
closed = property(get_closed)
config_changed = property(get_config_changed)
name = property(get_name)
reconnecting = property(get_reconnecting)
timeout = property(get_timeout, set_timeout)
@@ -489,7 +671,7 @@ class RevPiNetIO(_RevPiModIO):
def __init__(
self, address, autorefresh=False, monitoring=False,
syncoutputs=True, simulator=False, debug=False,
syncoutputs=True, simulator=False, debug=True,
replace_io_file=None, direct_output=False):
"""Instantiiert die Grundfunktionen.
@@ -543,15 +725,15 @@ class RevPiNetIO(_RevPiModIO):
# Vererben
super().__init__(
autorefresh,
monitoring,
syncoutputs,
"{0}:{1}".format(*self._address),
None,
simulator,
debug,
replace_io_file,
direct_output
autorefresh=autorefresh,
monitoring=monitoring,
syncoutputs=syncoutputs,
procimg="{0}:{1}".format(*self._address),
configrsc=None,
simulator=simulator,
debug=debug,
replace_io_file=replace_io_file,
direct_output=direct_output,
)
# Netzwerkfilehandler anlegen
@@ -560,25 +742,73 @@ class RevPiNetIO(_RevPiModIO):
# Nur Konfigurieren, wenn nicht vererbt
if type(self) == RevPiNetIO:
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
def _create_myfh(self):
"""Erstellt NetworkFileObject.
return FileObject"""
self._buffedwrite = True
return NetFH(self._address)
return NetFH(self._address, self._replace_io_file == ":network:")
def _get_cpreplaceio(self):
"""Laed die replace_io Konfiguration ueber das Netzwerk.
@return <class 'ConfigParser'> der replace io daten"""
# Normale Verwendung über Elternklasse erledigen
if self._replace_io_file != ":network:":
return super()._get_cpreplaceio()
# Replace IO Daten über das Netzwerk beziehen
byte_buff = self._myfh.readreplaceio()
cp = ConfigParser()
try:
cp.read_string(byte_buff.decode("utf-8"))
except Exception as e:
raise RuntimeError(
"replace_io_file: could not read/parse network data | {0}"
"".format(e)
)
return cp
def disconnect(self):
"""Trennt Verbindungen und beendet autorefresh inkl. alle Threads."""
self.cleanup()
def exit(self, full=True):
"""Beendet mainloop() und optional autorefresh.
@see #RevPiModIO.exit(...)"""
try:
super().exit(full)
except ConfigChanged:
pass
def get_config_changed(self):
"""Pruefen ob RevPi Konfiguration geaendert wurde.
In diesem Fall ist die Verbindung geschlossen und RevPiNetIO muss
neu instanziert werden.
@return True, wenn RevPi Konfiguration geaendert ist"""
return self._myfh.config_changed
def get_jconfigrsc(self):
"""Laedt die piCotry Konfiguration und erstellt ein <class 'dict'>.
@return <class 'dict'> der piCtory Konfiguration"""
mynh = NetFH(self._address)
mynh = NetFH(self._address, False)
byte_buff = mynh.readpictory()
mynh.close()
return jloads(byte_buff.decode("utf-8"))
def get_reconnecting(self):
"""Interner reconnect aktiv wegen Netzwerkfehlern.
Das Modul versucht intern die Verbindung neu herzustellen. Es ist
kein weiteres Zutun noetig.
@return True, wenn reconnect aktiv"""
return self._myfh.reconnecting
def net_cleardefaultvalues(self, device=None):
"""Loescht Defaultwerte vom PLC Slave.
@param device nur auf einzelnes Device anwenden, sonst auf Alle"""
@@ -646,6 +876,9 @@ class RevPiNetIO(_RevPiModIO):
dev._offset + dev._slc_out.start, dirtybytes
)
config_changed = property(get_config_changed)
reconnecting = property(get_reconnecting)
class RevPiNetIOSelected(RevPiNetIO):
@@ -662,7 +895,7 @@ class RevPiNetIOSelected(RevPiNetIO):
def __init__(
self, address, deviceselection, autorefresh=False,
monitoring=False, syncoutputs=True, simulator=False, debug=False,
monitoring=False, syncoutputs=True, simulator=False, debug=True,
replace_io_file=None, direct_output=False):
"""Instantiiert nur fuer angegebene Devices die Grundfunktionen.
@@ -695,6 +928,7 @@ class RevPiNetIOSelected(RevPiNetIO):
)
self._configure(self.get_jconfigrsc())
self._configure_replace_io(self._get_cpreplaceio())
if len(self.device) == 0:
if type(self) == RevPiNetIODriver:
@@ -731,7 +965,7 @@ class RevPiNetIODriver(RevPiNetIOSelected):
def __init__(
self, address, virtdev, autorefresh=False, monitoring=False,
syncoutputs=True, debug=False, replace_io_file=None,
syncoutputs=True, debug=True, replace_io_file=None,
direct_output=False):
"""Instantiiert die Grundfunktionen.

View File

@@ -17,7 +17,7 @@ setup(
license="LGPLv3",
name="revpimodio2",
version="2.3.3",
version="2.4.2",
packages=["revpimodio2"],
python_requires="~=3.2",