mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
Docstrings optimieren 1
This commit is contained in:
3
.idea/dictionaries/akira.xml
generated
Normal file
3
.idea/dictionaries/akira.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="akira" />
|
||||||
|
</component>
|
||||||
1
.idea/inspectionProfiles/profiles_settings.xml
generated
1
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,5 +1,6 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<settings>
|
<settings>
|
||||||
|
<option name="PROJECT_PROFILE" value="Default" />
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
<version value="1.0" />
|
<version value="1.0" />
|
||||||
</settings>
|
</settings>
|
||||||
|
|||||||
4
.idea/revpimodio2.iml
generated
4
.idea/revpimodio2.iml
generated
@@ -1,7 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module type="PYTHON_MODULE" version="4">
|
<module type="PYTHON_MODULE" version="4">
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/revpimodio2" isTestSource="false" />
|
||||||
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.6" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.6" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
7
docs/revpimodio2.app.rst
Normal file
7
docs/revpimodio2.app.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.app module
|
||||||
|
=======================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.app
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
7
docs/revpimodio2.device.rst
Normal file
7
docs/revpimodio2.device.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.device module
|
||||||
|
==========================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.device
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
7
docs/revpimodio2.helper.rst
Normal file
7
docs/revpimodio2.helper.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.helper module
|
||||||
|
==========================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.helper
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
7
docs/revpimodio2.io.rst
Normal file
7
docs/revpimodio2.io.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.io module
|
||||||
|
======================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.io
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
7
docs/revpimodio2.modio.rst
Normal file
7
docs/revpimodio2.modio.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.modio module
|
||||||
|
=========================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.modio
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
7
docs/revpimodio2.netio.rst
Normal file
7
docs/revpimodio2.netio.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.netio module
|
||||||
|
=========================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.netio
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
@@ -4,62 +4,15 @@ revpimodio2 package
|
|||||||
Submodules
|
Submodules
|
||||||
----------
|
----------
|
||||||
|
|
||||||
revpimodio2\.app module
|
.. toctree::
|
||||||
-----------------------
|
|
||||||
|
|
||||||
.. 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:
|
|
||||||
|
|
||||||
|
revpimodio2.app
|
||||||
|
revpimodio2.device
|
||||||
|
revpimodio2.helper
|
||||||
|
revpimodio2.io
|
||||||
|
revpimodio2.modio
|
||||||
|
revpimodio2.netio
|
||||||
|
revpimodio2.summary
|
||||||
|
|
||||||
Module contents
|
Module contents
|
||||||
---------------
|
---------------
|
||||||
|
|||||||
7
docs/revpimodio2.summary.rst
Normal file
7
docs/revpimodio2.summary.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
revpimodio2\.summary module
|
||||||
|
===========================
|
||||||
|
|
||||||
|
.. automodule:: revpimodio2.summary
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.
|
"""
|
||||||
|
Stellt alle Klassen fuer den RevolutionPi zur Verfuegung.
|
||||||
|
|
||||||
Webpage: https://revpimodio.org/
|
Webpage: https://revpimodio.org/
|
||||||
|
|
||||||
@@ -10,11 +11,10 @@ gemacht. Fuer Gateways sind eigene IOs ueber mehrere Bytes konfigurierbar
|
|||||||
Mit den definierten Namen greift man direkt auf die gewuenschten Daten zu.
|
Mit den definierten Namen greift man direkt auf die gewuenschten Daten zu.
|
||||||
Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese
|
Auf alle IOs kann der Benutzer Funktionen als Events registrieren. Diese
|
||||||
fuehrt das Modul bei Datenaenderung aus.
|
fuehrt das Modul bei Datenaenderung aus.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"RevPiModIO", "RevPiModIOSelected", "RevPiModIODriver",
|
"RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected",
|
||||||
"RevPiNetIO", "RevPiNetIOSelected", "RevPiNetIODriver",
|
"RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected",
|
||||||
"Cycletools",
|
"Cycletools",
|
||||||
]
|
]
|
||||||
__author__ = "Sven Sager <akira@revpimodio.org>"
|
__author__ = "Sven Sager <akira@revpimodio.org>"
|
||||||
@@ -36,27 +36,25 @@ MEM = 302
|
|||||||
|
|
||||||
|
|
||||||
class DeviceNotFoundError(Exception):
|
class DeviceNotFoundError(Exception):
|
||||||
|
|
||||||
"""Fehler wenn ein Device nicht gefunden wird."""
|
"""Fehler wenn ein Device nicht gefunden wird."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def acheck(check_type, **kwargs):
|
def acheck(check_type, **kwargs) -> None:
|
||||||
"""Check type of given arguments.
|
"""
|
||||||
|
Check type of given arguments.
|
||||||
|
|
||||||
Use the argument name as keyword and the argument itself as value.
|
Use the argument name as keyword and the argument itself as value.
|
||||||
|
|
||||||
@param check_type Type to check
|
:param check_type: Type to check
|
||||||
@param kwargs Arguments to check
|
:param kwargs: Arguments to check
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for var_name in kwargs:
|
for var_name in kwargs:
|
||||||
none_okay = var_name.endswith("_noneok")
|
none_okay = var_name.endswith("_noneok")
|
||||||
|
|
||||||
if not (isinstance(kwargs[var_name], check_type) or
|
if not (isinstance(kwargs[var_name], check_type) or
|
||||||
none_okay and kwargs[var_name] is None):
|
none_okay and kwargs[var_name] is None):
|
||||||
|
|
||||||
msg = "Argument '{0}' must be {1}{2}".format(
|
msg = "Argument '{0}' must be {1}{2}".format(
|
||||||
var_name.rstrip("_noneok"), str(check_type),
|
var_name.rstrip("_noneok"), str(check_type),
|
||||||
" or <class 'NoneType'>" if none_okay else ""
|
" or <class 'NoneType'>" if none_okay else ""
|
||||||
@@ -64,14 +62,14 @@ def acheck(check_type, **kwargs):
|
|||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
|
||||||
def consttostr(value):
|
def consttostr(value) -> str:
|
||||||
"""Gibt <class 'str'> fuer Konstanten zurueck.
|
"""
|
||||||
|
Gibt <class 'str'> fuer Konstanten zurueck.
|
||||||
|
|
||||||
Diese Funktion ist erforderlich, da enum in Python 3.2 nicht existiert.
|
Diese Funktion ist erforderlich, da enum in Python 3.2 nicht existiert.
|
||||||
|
|
||||||
@param value Konstantenwert
|
:param value: Konstantenwert
|
||||||
@return <class 'str'> Name der Konstanten
|
:return: <class 'str'> Name der Konstanten
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if value == 0:
|
if value == 0:
|
||||||
return "OFF"
|
return "OFF"
|
||||||
@@ -97,5 +95,5 @@ def consttostr(value):
|
|||||||
|
|
||||||
# Benötigte Klassen importieren
|
# Benötigte Klassen importieren
|
||||||
from .helper import Cycletools
|
from .helper import Cycletools
|
||||||
from .modio import RevPiModIO, RevPiModIOSelected, RevPiModIODriver
|
from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected
|
||||||
from .netio import RevPiNetIO, RevPiNetIOSelected, RevPiNetIODriver
|
from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected
|
||||||
|
|||||||
@@ -1,27 +1,36 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Bildet die App Sektion von piCtory ab."""
|
"""Bildet die App Sektion von piCtory ab."""
|
||||||
|
from time import strptime
|
||||||
|
|
||||||
__author__ = "Sven Sager"
|
__author__ = "Sven Sager"
|
||||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||||
__license__ = "LGPLv3"
|
__license__ = "LGPLv3"
|
||||||
|
|
||||||
from time import strptime
|
|
||||||
|
|
||||||
|
|
||||||
class App(object):
|
class App(object):
|
||||||
|
|
||||||
"""Bildet die App Sektion der config.rsc ab."""
|
"""Bildet die App Sektion der config.rsc ab."""
|
||||||
|
|
||||||
__slots__ = "name", "version", "language", "layout", "savets"
|
__slots__ = "name", "version", "language", "layout", "savets"
|
||||||
|
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
"""Instantiiert die App-Klasse.
|
"""
|
||||||
@param app piCtory Appinformationen"""
|
Instantiiert die App-Klasse.
|
||||||
|
|
||||||
|
:param app: piCtory Appinformationen
|
||||||
|
"""
|
||||||
self.name = app["name"]
|
self.name = app["name"]
|
||||||
|
"""Name of creating app"""
|
||||||
|
|
||||||
self.version = app["version"]
|
self.version = app["version"]
|
||||||
|
"""Version of creating app"""
|
||||||
|
|
||||||
self.language = app["language"]
|
self.language = app["language"]
|
||||||
|
"""Language of creating app"""
|
||||||
|
|
||||||
# Speicherungszeitpunkt laden, wenn vorhanden
|
# Speicherungszeitpunkt laden, wenn vorhanden
|
||||||
self.savets = app.get("saveTS", None)
|
self.savets = app.get("saveTS", None)
|
||||||
|
"""Timestamp of configuraiton"""
|
||||||
|
|
||||||
if self.savets is not None:
|
if self.savets is not None:
|
||||||
try:
|
try:
|
||||||
self.savets = strptime(self.savets, "%Y%m%d%H%M%S")
|
self.savets = strptime(self.savets, "%Y%m%d%H%M%S")
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Modul fuer die Verwaltung der Devices."""
|
"""Modul fuer die Verwaltung der Devices."""
|
||||||
|
from threading import Event, Lock, Thread
|
||||||
|
|
||||||
|
from .helper import ProcimgWriter
|
||||||
|
|
||||||
__author__ = "Sven Sager"
|
__author__ = "Sven Sager"
|
||||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||||
__license__ = "LGPLv3"
|
__license__ = "LGPLv3"
|
||||||
|
|
||||||
from threading import Thread, Event, Lock
|
|
||||||
from .helper import ProcimgWriter
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceList(object):
|
class DeviceList(object):
|
||||||
|
|
||||||
"""Basisklasse fuer direkten Zugriff auf Device Objekte."""
|
"""Basisklasse fuer direkten Zugriff auf Device Objekte."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -17,9 +17,12 @@ class DeviceList(object):
|
|||||||
self.__dict_position = {}
|
self.__dict_position = {}
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
"""Prueft ob Device existiert.
|
"""
|
||||||
@param key DeviceName <class 'str'> / Positionsnummer <class 'int'>
|
Prueft ob Device existiert.
|
||||||
@return True, wenn Device vorhanden"""
|
|
||||||
|
:param key: DeviceName <class 'str'> / Positionsnummer <class 'int'>
|
||||||
|
:return: True, wenn Device vorhanden
|
||||||
|
"""
|
||||||
if type(key) == int:
|
if type(key) == int:
|
||||||
return key in self.__dict_position
|
return key in self.__dict_position
|
||||||
elif type(key) == str:
|
elif type(key) == str:
|
||||||
@@ -28,9 +31,12 @@ class DeviceList(object):
|
|||||||
return key in self.__dict_position.values()
|
return key in self.__dict_position.values()
|
||||||
|
|
||||||
def __delattr__(self, key, delcomplete=True):
|
def __delattr__(self, key, delcomplete=True):
|
||||||
"""Entfernt angegebenes Device.
|
"""
|
||||||
@param key Device zum entfernen
|
Entfernt angegebenes Device.
|
||||||
@param delcomplete Wenn True wird Device komplett entfernt"""
|
|
||||||
|
:param key: Device zum entfernen
|
||||||
|
:param delcomplete: Wenn True wird Device komplett entfernt
|
||||||
|
"""
|
||||||
if delcomplete:
|
if delcomplete:
|
||||||
# Device finden
|
# Device finden
|
||||||
if type(key) == int:
|
if type(key) == int:
|
||||||
@@ -51,16 +57,22 @@ class DeviceList(object):
|
|||||||
object.__delattr__(self, key)
|
object.__delattr__(self, key)
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
"""Entfernt Device an angegebener Position.
|
"""
|
||||||
@param key Deviceposition zum entfernen"""
|
Entfernt Device an angegebener Position.
|
||||||
|
|
||||||
|
:param key: Deviceposition zum entfernen
|
||||||
|
"""
|
||||||
if isinstance(key, Device):
|
if isinstance(key, Device):
|
||||||
key = key._position
|
key = key._position
|
||||||
self.__delattr__(key)
|
self.__delattr__(key)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""Gibt angegebenes Device zurueck.
|
"""
|
||||||
@param key DeviceName <class 'str'> / Positionsnummer <class 'int'>
|
Gibt angegebenes Device zurueck.
|
||||||
@return Gefundenes <class 'Device'>-Objekt"""
|
|
||||||
|
:param key: DeviceName <class 'str'> / Positionsnummer <class 'int'>
|
||||||
|
:return: Gefundenes <class 'Device'>-Objekt
|
||||||
|
"""
|
||||||
if type(key) == int:
|
if type(key) == int:
|
||||||
if key not in self.__dict_position:
|
if key not in self.__dict_position:
|
||||||
raise IndexError("no device on position {0}".format(key))
|
raise IndexError("no device on position {0}".format(key))
|
||||||
@@ -69,26 +81,33 @@ class DeviceList(object):
|
|||||||
return getattr(self, key)
|
return getattr(self, key)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Gibt Iterator aller Devices zurueck.
|
"""
|
||||||
|
Gibt Iterator aller Devices zurueck.
|
||||||
|
|
||||||
Die Reihenfolge ist nach Position im Prozessabbild sortiert und nicht
|
Die Reihenfolge ist nach Position im Prozessabbild sortiert und nicht
|
||||||
nach Positionsnummer (Dies entspricht der Positionierung aus piCtory)!
|
nach Positionsnummer (Dies entspricht der Positionierung aus piCtory)!
|
||||||
|
|
||||||
@return <class 'iter'> aller Devices"""
|
:return: <class 'iter'> aller Devices
|
||||||
|
"""
|
||||||
for dev in sorted(
|
for dev in sorted(
|
||||||
self.__dict_position,
|
self.__dict_position,
|
||||||
key=lambda key: self.__dict_position[key]._offset):
|
key=lambda key: self.__dict_position[key]._offset):
|
||||||
yield self.__dict_position[dev]
|
yield self.__dict_position[dev]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""Gibt Anzahl der Devices zurueck.
|
"""
|
||||||
return Anzahl der Devices"""
|
Gibt Anzahl der Devices zurueck.
|
||||||
|
|
||||||
|
:return: Anzahl der Devices"""
|
||||||
return len(self.__dict_position)
|
return len(self.__dict_position)
|
||||||
|
|
||||||
def __setattr__(self, key, value):
|
def __setattr__(self, key, value):
|
||||||
"""Setzt Attribute nur wenn Device.
|
"""
|
||||||
@param key Attributname
|
Setzt Attribute nur wenn Device.
|
||||||
@param value Attributobjekt"""
|
|
||||||
|
:param key: Attributname
|
||||||
|
:param value: Attributobjekt
|
||||||
|
"""
|
||||||
if isinstance(value, Device):
|
if isinstance(value, Device):
|
||||||
object.__setattr__(self, key, value)
|
object.__setattr__(self, key, value)
|
||||||
self.__dict_position[value._position] = value
|
self.__dict_position[value._position] = value
|
||||||
@@ -97,13 +116,12 @@ class DeviceList(object):
|
|||||||
|
|
||||||
|
|
||||||
class Device(object):
|
class Device(object):
|
||||||
|
"""
|
||||||
"""Basisklasse fuer alle Device-Objekte.
|
Basisklasse fuer alle Device-Objekte.
|
||||||
|
|
||||||
Die Basisfunktionalitaet generiert bei Instantiierung alle IOs und
|
Die Basisfunktionalitaet generiert bei Instantiierung alle IOs und
|
||||||
erweitert den Prozessabbildpuffer um die benoetigten Bytes. Sie verwaltet
|
erweitert den Prozessabbildpuffer um die benoetigten Bytes. Sie verwaltet
|
||||||
ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung der IO-Werte.
|
ihren Prozessabbildpuffer und sorgt fuer die Aktualisierung der IO-Werte.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \
|
__slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \
|
||||||
@@ -114,12 +132,12 @@ class Device(object):
|
|||||||
"guid", "id", "inpvariant", "outvariant", "type"
|
"guid", "id", "inpvariant", "outvariant", "type"
|
||||||
|
|
||||||
def __init__(self, parentmodio, dict_device, simulator=False):
|
def __init__(self, parentmodio, dict_device, simulator=False):
|
||||||
"""Instantiierung der Device-Klasse.
|
"""
|
||||||
|
Instantiierung der Device-Klasse.
|
||||||
@param parent RevpiModIO parent object
|
|
||||||
@param dict_device <class 'dict'> fuer dieses Device aus piCotry
|
|
||||||
@param simulator: Laedt das Modul als Simulator und vertauscht IOs
|
|
||||||
|
|
||||||
|
:param parentmodio: RevpiModIO parent object
|
||||||
|
:param dict_device: <class 'dict'> fuer dieses Device aus piCotry
|
||||||
|
:param simulator: Laedt das Modul als Simulator und vertauscht IOs
|
||||||
"""
|
"""
|
||||||
self._modio = parentmodio
|
self._modio = parentmodio
|
||||||
|
|
||||||
@@ -187,14 +205,20 @@ class Device(object):
|
|||||||
self._update_my_io_list()
|
self._update_my_io_list()
|
||||||
|
|
||||||
def __bytes__(self):
|
def __bytes__(self):
|
||||||
"""Gibt alle Daten des Devices als <class 'bytes'> zurueck.
|
"""
|
||||||
@return Devicedaten als <class 'bytes'>"""
|
Gibt alle Daten des Devices als <class 'bytes'> zurueck.
|
||||||
|
|
||||||
|
:return: Devicedaten als <class 'bytes'>
|
||||||
|
"""
|
||||||
return bytes(self._ba_devdata)
|
return bytes(self._ba_devdata)
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
"""Prueft ob IO auf diesem Device liegt.
|
"""
|
||||||
@param key IO-Name <class 'str'> / IO-Bytenummer <class 'int'>
|
Prueft ob IO auf diesem Device liegt.
|
||||||
@return True, wenn IO auf Device vorhanden"""
|
|
||||||
|
:param key: IO-Name <class 'str'> / IO-Bytenummer <class 'int'>
|
||||||
|
:return: True, wenn IO auf Device vorhanden
|
||||||
|
"""
|
||||||
if isinstance(key, IOBase):
|
if isinstance(key, IOBase):
|
||||||
# Umwandlung für key
|
# Umwandlung für key
|
||||||
key = key._name
|
key = key._name
|
||||||
@@ -210,51 +234,66 @@ class Device(object):
|
|||||||
and getattr(self._modio.io, key)._parentdevice == self
|
and getattr(self._modio.io, key)._parentdevice == self
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""Gibt IO an angegebener Stelle zurueck.
|
"""
|
||||||
@param key Index des IOs auf dem device als <class 'int'>
|
Gibt IO an angegebener Stelle zurueck.
|
||||||
@return Gefundenes IO-Objekt"""
|
|
||||||
|
:param key: Index des IOs auf dem device als <class 'int'>
|
||||||
|
:return: Gefundenes IO-Objekt
|
||||||
|
"""
|
||||||
return self.__my_io_list[key]
|
return self.__my_io_list[key]
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
"""Gibt die Positon im RevPi Bus zurueck.
|
"""
|
||||||
@return Positionsnummer"""
|
Gibt die Positon im RevPi Bus zurueck.
|
||||||
|
|
||||||
|
:return: Positionsnummer
|
||||||
|
"""
|
||||||
return self._position
|
return self._position
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Gibt Iterator aller IOs zurueck.
|
"""
|
||||||
@return <class 'iter'> aller IOs"""
|
Gibt Iterator aller IOs zurueck.
|
||||||
|
|
||||||
|
:return: <class 'iter'> aller IOs
|
||||||
|
"""
|
||||||
return self.__getioiter(self._slc_devoff, None)
|
return self.__getioiter(self._slc_devoff, None)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""Gibt Anzahl der Bytes zurueck, die dieses Device belegt.
|
"""
|
||||||
@return <class 'int'>"""
|
Gibt Anzahl der Bytes zurueck, die dieses Device belegt.
|
||||||
|
|
||||||
|
:return: <class 'int'>
|
||||||
|
"""
|
||||||
return self._length
|
return self._length
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Gibt den Namen des Devices zurueck.
|
"""
|
||||||
@return Devicename"""
|
Gibt den Namen des Devices zurueck.
|
||||||
|
|
||||||
|
:return: Devicename
|
||||||
|
"""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def __getioiter(self, ioslc, export):
|
def __getioiter(self, ioslc: slice, export):
|
||||||
"""Gibt <class 'iter'> mit allen IOs zurueck.
|
"""
|
||||||
|
Gibt <class 'iter'> mit allen IOs zurueck.
|
||||||
@param ioslc IO Abschnitt <class 'slice'>
|
|
||||||
@param export Filter fuer 'Export' Flag in piCtory
|
|
||||||
@return IOs als Iterator
|
|
||||||
|
|
||||||
|
:param ioslc: IO Abschnitt <class 'slice'>
|
||||||
|
:param export: Filter fuer 'Export' Flag in piCtory
|
||||||
|
:return: IOs als Iterator
|
||||||
"""
|
"""
|
||||||
for lst_io in self._modio.io[ioslc]:
|
for lst_io in self._modio.io[ioslc]:
|
||||||
for io in lst_io:
|
for io in lst_io:
|
||||||
if io is not None and (export is None or io.export == export):
|
if io is not None and (export is None or io.export == export):
|
||||||
yield io
|
yield io
|
||||||
|
|
||||||
def _buildio(self, dict_io, iotype):
|
def _buildio(self, dict_io: dict, iotype: int) -> slice:
|
||||||
"""Erstellt aus der piCtory-Liste die IOs fuer dieses Device.
|
"""
|
||||||
|
Erstellt aus der piCtory-Liste die IOs fuer dieses Device.
|
||||||
@param dict_io <class 'dict'>-Objekt aus piCtory Konfiguration
|
|
||||||
@param iotype <class 'int'> Wert
|
|
||||||
@return <class 'slice'> mit Start und Stop Position dieser IOs
|
|
||||||
|
|
||||||
|
:param dict_io: <class 'dict'>-Objekt aus piCtory Konfiguration
|
||||||
|
:param iotype: <class 'int'> Wert
|
||||||
|
:return: <class 'slice'> mit Start und Stop Position dieser IOs
|
||||||
"""
|
"""
|
||||||
if len(dict_io) <= 0:
|
if len(dict_io) <= 0:
|
||||||
return slice(0, 0)
|
return slice(0, 0)
|
||||||
@@ -312,23 +351,32 @@ class Device(object):
|
|||||||
"""Funktion zum ueberschreiben von abgeleiteten Klassen."""
|
"""Funktion zum ueberschreiben von abgeleiteten Klassen."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _get_offset(self):
|
def _get_offset(self) -> int:
|
||||||
"""Gibt den Deviceoffset im Prozessabbild zurueck.
|
"""
|
||||||
@return Deviceoffset"""
|
Gibt den Deviceoffset im Prozessabbild zurueck.
|
||||||
|
|
||||||
|
:return: Deviceoffset
|
||||||
|
"""
|
||||||
return self._offset
|
return self._offset
|
||||||
|
|
||||||
def _get_producttype(self):
|
def _get_producttype(self) -> int:
|
||||||
"""Gibt den Produkttypen des device zurueck.
|
"""
|
||||||
@return Deviceprodukttyp"""
|
Gibt den Produkttypen des device zurueck.
|
||||||
|
|
||||||
|
:return: Deviceprodukttyp
|
||||||
|
"""
|
||||||
return self._producttype
|
return self._producttype
|
||||||
|
|
||||||
def _update_my_io_list(self):
|
def _update_my_io_list(self) -> None:
|
||||||
"""Erzeugt eine neue IO Liste fuer schnellen Zugriff."""
|
"""Erzeugt eine neue IO Liste fuer schnellen Zugriff."""
|
||||||
self.__my_io_list = list(self.__iter__())
|
self.__my_io_list = list(self.__iter__())
|
||||||
|
|
||||||
def autorefresh(self, activate=True):
|
def autorefresh(self, activate=True) -> None:
|
||||||
"""Registriert dieses Device fuer die automatische Synchronisierung.
|
"""
|
||||||
@param activate Default True fuegt Device zur Synchronisierung hinzu"""
|
Registriert dieses Device fuer die automatische Synchronisierung.
|
||||||
|
|
||||||
|
:param activate: Default True fuegt Device zur Synchronisierung hinzu
|
||||||
|
"""
|
||||||
if activate and self not in self._modio._lst_refresh:
|
if activate and self not in self._modio._lst_refresh:
|
||||||
|
|
||||||
# Daten bei Aufnahme direkt einlesen!
|
# Daten bei Aufnahme direkt einlesen!
|
||||||
@@ -346,7 +394,6 @@ class Device(object):
|
|||||||
|
|
||||||
# Thread starten, wenn er noch nicht läuft
|
# Thread starten, wenn er noch nicht läuft
|
||||||
if not self._modio._imgwriter.is_alive():
|
if not self._modio._imgwriter.is_alive():
|
||||||
|
|
||||||
# Alte Einstellungen speichern
|
# Alte Einstellungen speichern
|
||||||
imgrefresh = self._modio._imgwriter.refresh
|
imgrefresh = self._modio._imgwriter.refresh
|
||||||
|
|
||||||
@@ -369,98 +416,97 @@ class Device(object):
|
|||||||
if not self._modio._monitoring:
|
if not self._modio._monitoring:
|
||||||
self._modio.writeprocimg(self)
|
self._modio.writeprocimg(self)
|
||||||
|
|
||||||
def get_allios(self, export=None):
|
def get_allios(self, export=None) -> list:
|
||||||
"""Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
|
"""
|
||||||
|
Gibt eine Liste aller Inputs und Outputs zurueck, keine MEMs.
|
||||||
|
|
||||||
Bleibt Parameter 'export' auf None werden alle Inputs und Outputs
|
Bleibt Parameter 'export' auf None werden alle Inputs und Outputs
|
||||||
zurueckgegeben. Wird 'export' auf True/False gesetzt, werden nur Inputs
|
zurueckgegeben. Wird 'export' auf True/False gesetzt, werden nur Inputs
|
||||||
und Outputs zurueckgegeben, bei denen der Wert 'Export' in piCtory
|
und Outputs zurueckgegeben, bei denen der Wert 'Export' in piCtory
|
||||||
uebereinstimmt.
|
uebereinstimmt.
|
||||||
|
|
||||||
@param export Nur In-/Outputs mit angegebenen 'Export' Wert in piCtory
|
:param export: Nur In-/Outputs mit angegebenen 'Export' Wert in piCtory
|
||||||
@return <class 'list'> Input und Output, keine MEMs
|
:return: <class 'list'> Input und Output, keine MEMs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return list(self.__getioiter(
|
return list(self.__getioiter(
|
||||||
slice(self._slc_inpoff.start, self._slc_outoff.stop), export
|
slice(self._slc_inpoff.start, self._slc_outoff.stop), export
|
||||||
))
|
))
|
||||||
|
|
||||||
def get_inputs(self, export=None):
|
def get_inputs(self, export=None) -> list:
|
||||||
"""Gibt eine Liste aller Inputs zurueck.
|
"""
|
||||||
|
Gibt eine Liste aller Inputs zurueck.
|
||||||
|
|
||||||
Bleibt Parameter 'export' auf None werden alle Inputs zurueckgegeben.
|
Bleibt Parameter 'export' auf None werden alle Inputs zurueckgegeben.
|
||||||
Wird 'export' auf True/False gesetzt, werden nur Inputs zurueckgegeben,
|
Wird 'export' auf True/False gesetzt, werden nur Inputs zurueckgegeben,
|
||||||
bei denen der Wert 'Export' in piCtory uebereinstimmt.
|
bei denen der Wert 'Export' in piCtory uebereinstimmt.
|
||||||
|
|
||||||
@param export Nur Inputs mit angegebenen 'Export' Wert in piCtory
|
:param export: Nur Inputs mit angegebenen 'Export' Wert in piCtory
|
||||||
@return <class 'list'> Inputs
|
:return: <class 'list'> Inputs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return list(self.__getioiter(self._slc_inpoff, export))
|
return list(self.__getioiter(self._slc_inpoff, export))
|
||||||
|
|
||||||
def get_outputs(self, export=None):
|
def get_outputs(self, export=None) -> list:
|
||||||
"""Gibt eine Liste aller Outputs zurueck.
|
"""
|
||||||
|
Gibt eine Liste aller Outputs zurueck.
|
||||||
|
|
||||||
Bleibt Parameter 'export' auf None werden alle Outputs zurueckgegeben.
|
Bleibt Parameter 'export' auf None werden alle Outputs zurueckgegeben.
|
||||||
Wird 'export' auf True/False gesetzt, werden nur Outputs
|
Wird 'export' auf True/False gesetzt, werden nur Outputs
|
||||||
zurueckgegeben, bei denen der Wert 'Export' in piCtory uebereinstimmt.
|
zurueckgegeben, bei denen der Wert 'Export' in piCtory uebereinstimmt.
|
||||||
|
|
||||||
@param export Nur Outputs mit angegebenen 'Export' Wert in piCtory
|
:param export: Nur Outputs mit angegebenen 'Export' Wert in piCtory
|
||||||
@return <class 'list'> Outputs
|
:return: <class 'list'> Outputs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return list(self.__getioiter(self._slc_outoff, export))
|
return list(self.__getioiter(self._slc_outoff, export))
|
||||||
|
|
||||||
def get_memories(self, export=None):
|
def get_memories(self, export=None) -> list:
|
||||||
"""Gibt eine Liste aller Memoryobjekte zurueck.
|
"""
|
||||||
|
Gibt eine Liste aller Memoryobjekte zurueck.
|
||||||
|
|
||||||
Bleibt Parameter 'export' auf None werden alle Mems zurueckgegeben.
|
Bleibt Parameter 'export' auf None werden alle Mems zurueckgegeben.
|
||||||
Wird 'export' auf True/False gesetzt, werden nur Mems zurueckgegeben,
|
Wird 'export' auf True/False gesetzt, werden nur Mems zurueckgegeben,
|
||||||
bei denen der Wert 'Export' in piCtory uebereinstimmt.
|
bei denen der Wert 'Export' in piCtory uebereinstimmt.
|
||||||
|
|
||||||
@param export Nur Mems mit angegebenen 'Export' Wert in piCtory
|
:param export: Nur Mems mit angegebenen 'Export' Wert in piCtory
|
||||||
@return <class 'list'> Mems
|
:return: <class 'list'> Mems
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return list(self.__getioiter(self._slc_memoff, export))
|
return list(self.__getioiter(self._slc_memoff, export))
|
||||||
|
|
||||||
def readprocimg(self):
|
def readprocimg(self) -> bool:
|
||||||
"""Alle Inputs fuer dieses Device vom Prozessabbild einlesen.
|
"""
|
||||||
|
Alle Inputs fuer dieses Device vom Prozessabbild einlesen.
|
||||||
|
|
||||||
@return True, wenn erfolgreich ausgefuehrt
|
|
||||||
@see revpimodio2.modio#RevPiModIO.readprocimg
|
|
||||||
RevPiModIO.readprocimg()
|
|
||||||
|
|
||||||
|
Same see
|
||||||
|
|
||||||
|
:return: True, wenn erfolgreich ausgefuehrt
|
||||||
|
:ref: :func:`revpimodio2.modio.RevPiModIO.readprocimg()`
|
||||||
"""
|
"""
|
||||||
return self._modio.readprocimg(self)
|
return self._modio.readprocimg(self)
|
||||||
|
|
||||||
def setdefaultvalues(self):
|
def setdefaultvalues(self) -> None:
|
||||||
"""Alle Outputbuffer fuer dieses Device auf default Werte setzen.
|
"""
|
||||||
|
Alle Outputbuffer fuer dieses Device auf default Werte setzen.
|
||||||
@return True, wenn erfolgreich ausgefuehrt
|
|
||||||
@see revpimodio2.modio#RevPiModIO.setdefaultvalues
|
|
||||||
RevPiModIO.setdefaultvalues()
|
|
||||||
|
|
||||||
|
:return: True, wenn erfolgreich ausgefuehrt
|
||||||
|
:ref: :func:`revpimodio2.modio.RevPiModIO.setdefaultvalues()`
|
||||||
"""
|
"""
|
||||||
self._modio.setdefaultvalues(self)
|
self._modio.setdefaultvalues(self)
|
||||||
|
|
||||||
def syncoutputs(self):
|
def syncoutputs(self) -> bool:
|
||||||
"""Lesen aller Outputs im Prozessabbild fuer dieses Device.
|
"""
|
||||||
|
Lesen aller Outputs im Prozessabbild fuer dieses Device.
|
||||||
@return True, wenn erfolgreich ausgefuehrt
|
|
||||||
@see revpimodio2.modio#RevPiModIO.syncoutputs
|
|
||||||
RevPiModIO.syncoutputs()
|
|
||||||
|
|
||||||
|
:return: True, wenn erfolgreich ausgefuehrt
|
||||||
|
:ref: :func:`revpimodio2.modio.RevPiModIO.syncoutputs()`
|
||||||
"""
|
"""
|
||||||
return self._modio.syncoutputs(self)
|
return self._modio.syncoutputs(self)
|
||||||
|
|
||||||
def writeprocimg(self):
|
def writeprocimg(self) -> bool:
|
||||||
"""Schreiben aller Outputs dieses Devices ins Prozessabbild.
|
"""
|
||||||
|
Schreiben aller Outputs dieses Devices ins Prozessabbild.
|
||||||
@return True, wenn erfolgreich ausgefuehrt
|
|
||||||
@see revpimodio2.modio#RevPiModIO.writeprocimg
|
|
||||||
RevPiModIO.writeprocimg()
|
|
||||||
|
|
||||||
|
:return: True, wenn erfolgreich ausgefuehrt
|
||||||
|
:ref: :func:`revpimodio2.modio.RevPiModIO.writeprocimg()`
|
||||||
"""
|
"""
|
||||||
return self._modio.writeprocimg(self)
|
return self._modio.writeprocimg(self)
|
||||||
|
|
||||||
@@ -472,7 +518,6 @@ class Device(object):
|
|||||||
|
|
||||||
|
|
||||||
class Base(Device):
|
class Base(Device):
|
||||||
|
|
||||||
"""Klasse fuer alle Base-Devices wie Core / Connect usw."""
|
"""Klasse fuer alle Base-Devices wie Core / Connect usw."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
@@ -481,11 +526,10 @@ class Base(Device):
|
|||||||
|
|
||||||
|
|
||||||
class Core(Base):
|
class Core(Base):
|
||||||
|
"""
|
||||||
"""Klasse fuer den RevPi Core.
|
Klasse fuer den RevPi Core.
|
||||||
|
|
||||||
Stellt Funktionen fuer die LEDs und den Status zur Verfuegung.
|
Stellt Funktionen fuer die LEDs und den Status zur Verfuegung.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \
|
__slots__ = "_slc_cycle", "_slc_errorcnt", "_slc_statusbyte", \
|
||||||
@@ -502,7 +546,7 @@ class Core(Base):
|
|||||||
else:
|
else:
|
||||||
object.__setattr__(self, key, value)
|
object.__setattr__(self, key, value)
|
||||||
|
|
||||||
def _devconfigure(self):
|
def _devconfigure(self) -> None:
|
||||||
"""Core-Klasse vorbereiten."""
|
"""Core-Klasse vorbereiten."""
|
||||||
|
|
||||||
# Statische IO Verknüpfungen je nach Core-Variante
|
# Statische IO Verknüpfungen je nach Core-Variante
|
||||||
@@ -564,10 +608,13 @@ class Core(Base):
|
|||||||
exp_a2red, None, "LED_A2_RED", "3"
|
exp_a2red, None, "LED_A2_RED", "3"
|
||||||
], OUT, "little", False)
|
], OUT, "little", False)
|
||||||
|
|
||||||
def __errorlimit(self, slc_io, errorlimit):
|
def __errorlimit(self, slc_io: slice, errorlimit: int) -> None:
|
||||||
"""Verwaltet das Schreiben der ErrorLimits.
|
"""
|
||||||
@param slc_io Byte Slice vom ErrorLimit
|
Verwaltet das Schreiben der ErrorLimits.
|
||||||
@return Aktuellen ErrorLimit oder None wenn nicht verfuegbar"""
|
|
||||||
|
:param slc_io: Byte Slice vom ErrorLimit
|
||||||
|
:return: Aktuellen ErrorLimit oder None wenn nicht verfuegbar
|
||||||
|
"""
|
||||||
if 0 <= errorlimit <= 65535:
|
if 0 <= errorlimit <= 65535:
|
||||||
self._ba_devdata[slc_io] = \
|
self._ba_devdata[slc_io] = \
|
||||||
errorlimit.to_bytes(2, byteorder="little")
|
errorlimit.to_bytes(2, byteorder="little")
|
||||||
@@ -576,16 +623,22 @@ class Core(Base):
|
|||||||
"errorlimit value must be between 0 and 65535"
|
"errorlimit value must be between 0 and 65535"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_status(self):
|
def _get_status(self) -> int:
|
||||||
"""Gibt den RevPi Core Status zurueck.
|
"""
|
||||||
@return Status als <class 'int'>"""
|
Gibt den RevPi Core Status zurueck.
|
||||||
|
|
||||||
|
:return: Status als <class 'int'>
|
||||||
|
"""
|
||||||
return int.from_bytes(
|
return int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_leda1(self):
|
def _get_leda1(self) -> int:
|
||||||
"""Gibt den Zustand der LED A1 vom Core zurueck.
|
"""
|
||||||
@return 0=aus, 1=gruen, 2=rot"""
|
Gibt den Zustand der LED A1 vom Core zurueck.
|
||||||
|
|
||||||
|
:return: 0=aus, 1=gruen, 2=rot
|
||||||
|
"""
|
||||||
int_led = int.from_bytes(
|
int_led = int.from_bytes(
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
self._ba_devdata[self._slc_led], byteorder="little"
|
||||||
)
|
)
|
||||||
@@ -593,9 +646,12 @@ class Core(Base):
|
|||||||
led += int_led & 2
|
led += int_led & 2
|
||||||
return led
|
return led
|
||||||
|
|
||||||
def _get_leda2(self):
|
def _get_leda2(self) -> int:
|
||||||
"""Gibt den Zustand der LED A2 vom Core zurueck.
|
"""
|
||||||
@return 0=aus, 1=gruen, 2=rot"""
|
Gibt den Zustand der LED A2 vom Core zurueck.
|
||||||
|
|
||||||
|
:return: 0=aus, 1=gruen, 2=rot
|
||||||
|
"""
|
||||||
int_led = int.from_bytes(
|
int_led = int.from_bytes(
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
self._ba_devdata[self._slc_led], byteorder="little"
|
||||||
) >> 2
|
) >> 2
|
||||||
@@ -603,10 +659,14 @@ class Core(Base):
|
|||||||
led += int_led & 2
|
led += int_led & 2
|
||||||
return led
|
return led
|
||||||
|
|
||||||
def _set_calculatedled(self, addresslist, shifted_value):
|
def _set_calculatedled(self, addresslist, shifted_value) -> None:
|
||||||
"""Berechnet und setzt neuen Bytewert fuer LED byte.
|
"""
|
||||||
@param addresslist Liste der Vergleicher
|
Berechnet und setzt neuen Bytewert fuer LED byte.
|
||||||
@param shifed_value Bits vergleichen"""
|
|
||||||
|
:param addresslist: Liste der Vergleicher
|
||||||
|
:param shifted_value: Bits vergleichen
|
||||||
|
"""
|
||||||
|
# TODO: Docstring
|
||||||
# Byte als int holen
|
# Byte als int holen
|
||||||
int_led = int.from_bytes(
|
int_led = int.from_bytes(
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
self._ba_devdata[self._slc_led], byteorder="little"
|
||||||
@@ -625,17 +685,23 @@ class Core(Base):
|
|||||||
self._ba_devdata[self._slc_led] = \
|
self._ba_devdata[self._slc_led] = \
|
||||||
int_led.to_bytes(length=1, byteorder="little")
|
int_led.to_bytes(length=1, byteorder="little")
|
||||||
|
|
||||||
def _set_leda1(self, value):
|
def _set_leda1(self, value: int) -> None:
|
||||||
"""Setzt den Zustand der LED A1 vom Core.
|
"""
|
||||||
@param value 0=aus, 1=gruen, 2=rot"""
|
Setzt den Zustand der LED A1 vom Core.
|
||||||
|
|
||||||
|
:param value: 0=aus, 1=gruen, 2=rot
|
||||||
|
"""
|
||||||
if 0 <= value <= 3:
|
if 0 <= value <= 3:
|
||||||
self._set_calculatedled([1, 2], value)
|
self._set_calculatedled([1, 2], value)
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
raise ValueError("led status must be between 0 and 3")
|
||||||
|
|
||||||
def _set_leda2(self, value):
|
def _set_leda2(self, value: int) -> None:
|
||||||
"""Setzt den Zustand der LED A2 vom Core.
|
"""
|
||||||
@param value 0=aus, 1=gruen, 2=rot"""
|
Setzt den Zustand der LED A2 vom Core.
|
||||||
|
|
||||||
|
:param value: 0=aus, 1=gruen, 2=rot
|
||||||
|
"""
|
||||||
if 0 <= value <= 3:
|
if 0 <= value <= 3:
|
||||||
self._set_calculatedled([4, 8], value << 2)
|
self._set_calculatedled([4, 8], value << 2)
|
||||||
else:
|
else:
|
||||||
@@ -646,97 +712,133 @@ class Core(Base):
|
|||||||
status = property(_get_status)
|
status = property(_get_status)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def picontrolrunning(self):
|
def picontrolrunning(self) -> bool:
|
||||||
"""Statusbit fuer piControl-Treiber laeuft.
|
"""
|
||||||
@return True, wenn Treiber laeuft"""
|
Statusbit fuer piControl-Treiber laeuft.
|
||||||
|
|
||||||
|
:return: True, wenn Treiber laeuft
|
||||||
|
"""
|
||||||
return bool(int.from_bytes(
|
return bool(int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
) & 1)
|
) & 1)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unconfdevice(self):
|
def unconfdevice(self) -> bool:
|
||||||
"""Statusbit fuer ein IO-Modul nicht mit PiCtory konfiguriert.
|
"""
|
||||||
@return True, wenn IO Modul nicht konfiguriert"""
|
Statusbit fuer ein IO-Modul nicht mit PiCtory konfiguriert.
|
||||||
|
|
||||||
|
:return: True, wenn IO Modul nicht konfiguriert
|
||||||
|
"""
|
||||||
return bool(int.from_bytes(
|
return bool(int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
) & 2)
|
) & 2)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def missingdeviceorgate(self):
|
def missingdeviceorgate(self) -> bool:
|
||||||
"""Statusbit fuer ein IO-Modul fehlt oder piGate konfiguriert.
|
"""
|
||||||
@return True, wenn IO-Modul fehlt oder piGate konfiguriert"""
|
Statusbit fuer ein IO-Modul fehlt oder piGate konfiguriert.
|
||||||
|
|
||||||
|
:return: True, wenn IO-Modul fehlt oder piGate konfiguriert
|
||||||
|
"""
|
||||||
return bool(int.from_bytes(
|
return bool(int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
) & 4)
|
) & 4)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def overunderflow(self):
|
def overunderflow(self) -> bool:
|
||||||
"""Statusbit Modul belegt mehr oder weniger Speicher als konfiguriert.
|
"""
|
||||||
@return True, wenn falscher Speicher belegt ist"""
|
Statusbit Modul belegt mehr oder weniger Speicher als konfiguriert.
|
||||||
|
|
||||||
|
:return: True, wenn falscher Speicher belegt ist
|
||||||
|
"""
|
||||||
return bool(int.from_bytes(
|
return bool(int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
) & 8)
|
) & 8)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def leftgate(self):
|
def leftgate(self) -> bool:
|
||||||
"""Statusbit links vom RevPi ist ein piGate Modul angeschlossen.
|
"""
|
||||||
@return True, wenn piGate links existiert"""
|
Statusbit links vom RevPi ist ein piGate Modul angeschlossen.
|
||||||
|
|
||||||
|
:return: True, wenn piGate links existiert
|
||||||
|
"""
|
||||||
return bool(int.from_bytes(
|
return bool(int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
) & 16)
|
) & 16)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rightgate(self):
|
def rightgate(self) -> bool:
|
||||||
"""Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.
|
"""
|
||||||
@return True, wenn piGate rechts existiert"""
|
Statusbit rechts vom RevPi ist ein piGate Modul angeschlossen.
|
||||||
|
|
||||||
|
:return: True, wenn piGate rechts existiert
|
||||||
|
"""
|
||||||
return bool(int.from_bytes(
|
return bool(int.from_bytes(
|
||||||
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
self._ba_devdata[self._slc_statusbyte], byteorder="little"
|
||||||
) & 32)
|
) & 32)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def iocycle(self):
|
def iocycle(self) -> int:
|
||||||
"""Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck.
|
"""
|
||||||
@return Zykluszeit in ms"""
|
Gibt Zykluszeit der Prozessabbildsynchronisierung zurueck.
|
||||||
return None if self._slc_cycle is None else int.from_bytes(
|
|
||||||
|
:return: Zykluszeit in ms ( -1 wenn nicht verfuegbar)
|
||||||
|
"""
|
||||||
|
return -1 if self._slc_cycle is None else int.from_bytes(
|
||||||
self._ba_devdata[self._slc_cycle], byteorder="little"
|
self._ba_devdata[self._slc_cycle], byteorder="little"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature(self):
|
def temperature(self) -> int:
|
||||||
"""Gibt CPU-Temperatur zurueck.
|
"""
|
||||||
@return CPU-Temperatur in Celsius"""
|
Gibt CPU-Temperatur zurueck.
|
||||||
return None if self._slc_temperature is None else int.from_bytes(
|
|
||||||
|
:return: CPU-Temperatur in Celsius (-273 wenn nich verfuegbar)
|
||||||
|
"""
|
||||||
|
return -273 if self._slc_temperature is None else int.from_bytes(
|
||||||
self._ba_devdata[self._slc_temperature], byteorder="little"
|
self._ba_devdata[self._slc_temperature], byteorder="little"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def frequency(self):
|
def frequency(self) -> int:
|
||||||
"""Gibt CPU Taktfrequenz zurueck.
|
"""
|
||||||
@return CPU Taktfrequenz in MHz"""
|
Gibt CPU Taktfrequenz zurueck.
|
||||||
return None if self._slc_frequency is None else int.from_bytes(
|
|
||||||
|
:return: CPU Taktfrequenz in MHz (-1 wenn nicht verfuegbar)
|
||||||
|
"""
|
||||||
|
return -1 if self._slc_frequency is None else int.from_bytes(
|
||||||
self._ba_devdata[self._slc_frequency], byteorder="little"
|
self._ba_devdata[self._slc_frequency], byteorder="little"
|
||||||
) * 10
|
) * 10
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ioerrorcount(self):
|
def ioerrorcount(self) -> int:
|
||||||
"""Gibt Fehleranzahl auf RS485 piBridge Bus zurueck.
|
"""
|
||||||
@return Fehleranzahl der piBridge"""
|
Gibt Fehleranzahl auf RS485 piBridge Bus zurueck.
|
||||||
return None if self._slc_errorcnt is None else int.from_bytes(
|
|
||||||
|
:return: Fehleranzahl der piBridge (-1 wenn nicht verfuegbar)
|
||||||
|
"""
|
||||||
|
return -1 if self._slc_errorcnt is None else int.from_bytes(
|
||||||
self._ba_devdata[self._slc_errorcnt], byteorder="little"
|
self._ba_devdata[self._slc_errorcnt], byteorder="little"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def errorlimit1(self):
|
def errorlimit1(self) -> int:
|
||||||
"""Gibt RS485 ErrorLimit1 Wert zurueck.
|
"""
|
||||||
@return Aktueller Wert fuer ErrorLimit1"""
|
Gibt RS485 ErrorLimit1 Wert zurueck.
|
||||||
return None if self._slc_errorlimit1 is None else int.from_bytes(
|
|
||||||
|
:return: Aktueller Wert fuer ErrorLimit1 (-1 wenn nicht verfuegbar)
|
||||||
|
"""
|
||||||
|
return -1 if self._slc_errorlimit1 is None else int.from_bytes(
|
||||||
self._ba_devdata[self._slc_errorlimit1], byteorder="little"
|
self._ba_devdata[self._slc_errorlimit1], byteorder="little"
|
||||||
)
|
)
|
||||||
|
|
||||||
@errorlimit1.setter
|
@errorlimit1.setter
|
||||||
def errorlimit1(self, value):
|
def errorlimit1(self, value: int) -> None:
|
||||||
"""Setzt RS485 ErrorLimit1 auf neuen Wert.
|
"""
|
||||||
@param value Neuer ErrorLimit1 Wert"""
|
Setzt RS485 ErrorLimit1 auf neuen Wert.
|
||||||
|
|
||||||
|
:param value: Neuer ErrorLimit1 Wert
|
||||||
|
"""
|
||||||
if self._slc_errorlimit1 is None:
|
if self._slc_errorlimit1 is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"selected core item in piCtory does not support errorlimit1"
|
"selected core item in piCtory does not support errorlimit1"
|
||||||
@@ -745,17 +847,23 @@ class Core(Base):
|
|||||||
self.__errorlimit(self._slc_errorlimit1, value)
|
self.__errorlimit(self._slc_errorlimit1, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def errorlimit2(self):
|
def errorlimit2(self) -> int:
|
||||||
"""Gibt RS485 ErrorLimit2 Wert zurueck.
|
"""
|
||||||
@return Aktueller Wert fuer ErrorLimit2"""
|
Gibt RS485 ErrorLimit2 Wert zurueck.
|
||||||
return None if self._slc_errorlimit2 is None else int.from_bytes(
|
|
||||||
|
:return: Aktueller Wert fuer ErrorLimit2 (-1 wenn nicht verfuegbar)
|
||||||
|
"""
|
||||||
|
return -1 if self._slc_errorlimit2 is None else int.from_bytes(
|
||||||
self._ba_devdata[self._slc_errorlimit2], byteorder="little"
|
self._ba_devdata[self._slc_errorlimit2], byteorder="little"
|
||||||
)
|
)
|
||||||
|
|
||||||
@errorlimit2.setter
|
@errorlimit2.setter
|
||||||
def errorlimit2(self, value):
|
def errorlimit2(self, value: int) -> None:
|
||||||
"""Setzt RS485 ErrorLimit2 auf neuen Wert.
|
"""
|
||||||
@param value Neuer ErrorLimit2 Wert"""
|
Setzt RS485 ErrorLimit2 auf neuen Wert.
|
||||||
|
|
||||||
|
:param value: Neuer ErrorLimit2 Wert
|
||||||
|
"""
|
||||||
if self._slc_errorlimit2 is None:
|
if self._slc_errorlimit2 is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"selected core item in piCtory does not support errorlimit2"
|
"selected core item in piCtory does not support errorlimit2"
|
||||||
@@ -765,11 +873,9 @@ class Core(Base):
|
|||||||
|
|
||||||
|
|
||||||
class Connect(Core):
|
class Connect(Core):
|
||||||
|
|
||||||
"""Klasse fuer den RevPi Connect.
|
"""Klasse fuer den RevPi Connect.
|
||||||
|
|
||||||
Stellt Funktionen fuer die LEDs, Watchdog und den Status zur Verfuegung.
|
Stellt Funktionen fuer die LEDs, Watchdog und den Status zur Verfuegung.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", "wd", \
|
__slots__ = "__evt_wdtoggle", "__th_wdtoggle", "a3green", "a3red", "wd", \
|
||||||
@@ -786,12 +892,12 @@ class Connect(Core):
|
|||||||
else:
|
else:
|
||||||
object.__setattr__(self, key, value)
|
object.__setattr__(self, key, value)
|
||||||
|
|
||||||
def __wdtoggle(self):
|
def __wdtoggle(self) -> None:
|
||||||
"""WD Ausgang alle 10 Sekunden automatisch toggeln."""
|
"""WD Ausgang alle 10 Sekunden automatisch toggeln."""
|
||||||
while not self.__evt_wdtoggle.wait(10):
|
while not self.__evt_wdtoggle.wait(10):
|
||||||
self.wd.value = not self.wd.value
|
self.wd.value = not self.wd.value
|
||||||
|
|
||||||
def _devconfigure(self):
|
def _devconfigure(self) -> None:
|
||||||
"""Connect-Klasse vorbereiten."""
|
"""Connect-Klasse vorbereiten."""
|
||||||
super()._devconfigure()
|
super()._devconfigure()
|
||||||
|
|
||||||
@@ -841,9 +947,12 @@ class Connect(Core):
|
|||||||
exp_x2out, None, "Connect_X2_OUT", "6"
|
exp_x2out, None, "Connect_X2_OUT", "6"
|
||||||
], OUT, "little", False)
|
], OUT, "little", False)
|
||||||
|
|
||||||
def _get_leda3(self):
|
def _get_leda3(self) -> int:
|
||||||
"""Gibt den Zustand der LED A3 vom Connect zurueck.
|
"""
|
||||||
@return 0=aus, 1=gruen, 2=rot"""
|
Gibt den Zustand der LED A3 vom Connect zurueck.
|
||||||
|
|
||||||
|
:return: 0=aus, 1=gruen, 2=rot
|
||||||
|
"""
|
||||||
int_led = int.from_bytes(
|
int_led = int.from_bytes(
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
self._ba_devdata[self._slc_led], byteorder="little"
|
||||||
) >> 4
|
) >> 4
|
||||||
@@ -851,22 +960,28 @@ class Connect(Core):
|
|||||||
led += int_led & 2
|
led += int_led & 2
|
||||||
return led
|
return led
|
||||||
|
|
||||||
def _get_wdtoggle(self):
|
def _get_wdtoggle(self) -> bool:
|
||||||
"""Ruft den Wert fuer Autowatchdog ab.
|
"""
|
||||||
@return True, wenn Autowatchdog aktiv ist"""
|
Ruft den Wert fuer Autowatchdog ab.
|
||||||
return self.__th_wdtoggle is not None \
|
|
||||||
and self.__th_wdtoggle.is_alive()
|
|
||||||
|
|
||||||
def _set_leda3(self, value):
|
:return: True, wenn Autowatchdog aktiv ist
|
||||||
"""Setzt den Zustand der LED A3 vom Connect.
|
"""
|
||||||
@param value 0=aus, 1=gruen, 2=rot"""
|
return self.__th_wdtoggle is not None and self.__th_wdtoggle.is_alive()
|
||||||
|
|
||||||
|
def _set_leda3(self, value: int) -> None:
|
||||||
|
"""
|
||||||
|
Setzt den Zustand der LED A3 vom Connect.
|
||||||
|
|
||||||
|
:param: value 0=aus, 1=gruen, 2=rot
|
||||||
|
"""
|
||||||
if 0 <= value <= 3:
|
if 0 <= value <= 3:
|
||||||
self._set_calculatedled([16, 32], value << 4)
|
self._set_calculatedled([16, 32], value << 4)
|
||||||
else:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
raise ValueError("led status must be between 0 and 3")
|
||||||
|
|
||||||
def _set_wdtoggle(self, value):
|
def _set_wdtoggle(self, value: bool) -> None:
|
||||||
"""Setzt den Wert fuer Autowatchdog.
|
"""
|
||||||
|
Setzt den Wert fuer Autowatchdog.
|
||||||
|
|
||||||
Wird dieser Wert auf True gesetzt, wechselt im Hintergrund das noetige
|
Wird dieser Wert auf True gesetzt, wechselt im Hintergrund das noetige
|
||||||
Bit zum toggeln des Watchdogs alle 10 Sekunden zwichen True und False.
|
Bit zum toggeln des Watchdogs alle 10 Sekunden zwichen True und False.
|
||||||
@@ -877,7 +992,8 @@ class Connect(Core):
|
|||||||
.writeprocimg() aufgerufen werden, um den Wert in das
|
.writeprocimg() aufgerufen werden, um den Wert in das
|
||||||
Prozessabbild zu schreiben!!!
|
Prozessabbild zu schreiben!!!
|
||||||
|
|
||||||
@param value True zum aktivieren, Fals zum beenden"""
|
:param value: True zum aktivieren, Fals zum beenden
|
||||||
|
"""
|
||||||
if self._modio._monitoring:
|
if self._modio._monitoring:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"can not toggle watchdog, while system is in monitoring mode"
|
"can not toggle watchdog, while system is in monitoring mode"
|
||||||
@@ -901,15 +1017,16 @@ class Connect(Core):
|
|||||||
|
|
||||||
|
|
||||||
class DioModule(Device):
|
class DioModule(Device):
|
||||||
|
|
||||||
"""Stellt ein DIO / DI / DO Modul dar."""
|
"""Stellt ein DIO / DI / DO Modul dar."""
|
||||||
|
|
||||||
__slots__ = ("_lst_counter")
|
__slots__ = "_lst_counter"
|
||||||
|
|
||||||
def __init__(self, parentmodio, dict_device, simulator=False):
|
def __init__(self, parentmodio, dict_device, simulator=False):
|
||||||
"""Erweitert Device-Klasse zum Erkennen von IntIOCounter.
|
"""
|
||||||
@see #Device.__init__ Device.__init__(...)"""
|
Erweitert Device-Klasse zum Erkennen von IntIOCounter.
|
||||||
|
|
||||||
|
:rev: :func:`Device.__init__()`
|
||||||
|
"""
|
||||||
# Stringliste der Byteadressen (alle Module sind gleich)
|
# Stringliste der Byteadressen (alle Module sind gleich)
|
||||||
self._lst_counter = list(map(str, range(6, 70, 4)))
|
self._lst_counter = list(map(str, range(6, 70, 4)))
|
||||||
|
|
||||||
@@ -918,23 +1035,26 @@ class DioModule(Device):
|
|||||||
|
|
||||||
|
|
||||||
class Gateway(Device):
|
class Gateway(Device):
|
||||||
|
"""
|
||||||
"""Klasse fuer die RevPi Gateway-Devices.
|
Klasse fuer die RevPi Gateway-Devices.
|
||||||
|
|
||||||
Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die
|
Stellt neben den Funktionen von RevPiDevice weitere Funktionen fuer die
|
||||||
Gateways bereit. IOs auf diesem Device stellen die replace_io Funktion
|
Gateways bereit. IOs auf diesem Device stellen die replace_io Funktion
|
||||||
zur verfuegung, ueber die eigene IOs definiert werden, die ein
|
zur verfuegung, ueber die eigene IOs definiert werden, die ein
|
||||||
RevPiStructIO-Objekt abbilden.
|
RevPiStructIO-Objekt abbilden.
|
||||||
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
|
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
|
||||||
@see revpimodio2.io#IntIOReplaceable.replace_io replace_io(...)
|
|
||||||
|
|
||||||
|
:ref: :func:`revpimodio2.io.IntIOReplaceable.replace_io()`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "_dict_slc"
|
__slots__ = "_dict_slc"
|
||||||
|
|
||||||
def __init__(self, parent, dict_device, simulator=False):
|
def __init__(self, parent, dict_device, simulator=False):
|
||||||
"""Erweitert Device-Klasse um get_rawbytes-Funktionen.
|
"""
|
||||||
@see #Device.__init__ Device.__init__(...)"""
|
Erweitert Device-Klasse um get_rawbytes-Funktionen.
|
||||||
|
|
||||||
|
:ref: :func:`Device.__init__()`
|
||||||
|
"""
|
||||||
super().__init__(parent, dict_device, simulator)
|
super().__init__(parent, dict_device, simulator)
|
||||||
|
|
||||||
self._dict_slc = {
|
self._dict_slc = {
|
||||||
@@ -943,28 +1063,32 @@ class Gateway(Device):
|
|||||||
MEM: self._slc_mem
|
MEM: self._slc_mem
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_rawbytes(self):
|
def get_rawbytes(self) -> bytes:
|
||||||
"""Gibt die Bytes aus, die dieses Device verwendet.
|
"""
|
||||||
@return <class 'bytes'> des Devices"""
|
Gibt die Bytes aus, die dieses Device verwendet.
|
||||||
|
|
||||||
|
:return: <class 'bytes'> des Devices
|
||||||
|
"""
|
||||||
return bytes(self._ba_devdata)
|
return bytes(self._ba_devdata)
|
||||||
|
|
||||||
|
|
||||||
class Virtual(Gateway):
|
class Virtual(Gateway):
|
||||||
|
"""
|
||||||
"""Klasse fuer die RevPi Virtual-Devices.
|
Klasse fuer die RevPi Virtual-Devices.
|
||||||
|
|
||||||
Stellt die selben Funktionen wie Gateway zur Verfuegung. Es koennen
|
Stellt die selben Funktionen wie Gateway zur Verfuegung. Es koennen
|
||||||
ueber die reg_*-Funktionen eigene IOs definiert werden, die ein
|
ueber die reg_*-Funktionen eigene IOs definiert werden, die ein
|
||||||
RevPiStructIO-Objekt abbilden.
|
RevPiStructIO-Objekt abbilden.
|
||||||
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
|
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
|
||||||
@see #Gateway Gateway
|
|
||||||
|
|
||||||
|
:ref: :func:`Gateway`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def writeinputdefaults(self):
|
def writeinputdefaults(self):
|
||||||
"""Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.
|
"""
|
||||||
|
Schreibt fuer ein virtuelles Device piCtory Defaultinputwerte.
|
||||||
|
|
||||||
Sollten in piCtory Defaultwerte fuer Inputs eines virtuellen Devices
|
Sollten in piCtory Defaultwerte fuer Inputs eines virtuellen Devices
|
||||||
angegeben sein, werden diese nur beim Systemstart oder einem piControl
|
angegeben sein, werden diese nur beim Systemstart oder einem piControl
|
||||||
@@ -972,8 +1096,7 @@ class Virtual(Gateway):
|
|||||||
gehen diese Werte verloren.
|
gehen diese Werte verloren.
|
||||||
Diese Funktion kann nur auf virtuelle Devices angewendet werden!
|
Diese Funktion kann nur auf virtuelle Devices angewendet werden!
|
||||||
|
|
||||||
@return True, wenn Arbeiten am virtuellen Device erfolgreich waren
|
:return: True, wenn Arbeiten am virtuellen Device erfolgreich waren
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if self._modio._monitoring:
|
if self._modio._monitoring:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""RevPiModIO Helperklassen und Tools."""
|
"""RevPiModIO Helperklassen und Tools."""
|
||||||
__author__ = "Sven Sager"
|
|
||||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
|
||||||
__license__ = "LGPLv3"
|
|
||||||
|
|
||||||
import queue
|
import queue
|
||||||
import warnings
|
import warnings
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from threading import Event, Lock, Thread
|
from threading import Event, Lock, Thread
|
||||||
from timeit import default_timer
|
from timeit import default_timer
|
||||||
from revpimodio2 import RISING, FALLING, BOTH
|
|
||||||
|
from revpimodio2 import BOTH, FALLING, RISING
|
||||||
|
|
||||||
|
__author__ = "Sven Sager"
|
||||||
|
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||||
|
__license__ = "LGPLv3"
|
||||||
|
|
||||||
|
|
||||||
class EventCallback(Thread):
|
class EventCallback(Thread):
|
||||||
|
|
||||||
"""Thread fuer das interne Aufrufen von Event-Funktionen.
|
"""Thread fuer das interne Aufrufen von Event-Funktionen.
|
||||||
|
|
||||||
Der Eventfunktion, welche dieser Thread aufruft, wird der Thread selber
|
Der Eventfunktion, welche dieser Thread aufruft, wird der Thread selber
|
||||||
@@ -34,18 +34,17 @@ class EventCallback(Thread):
|
|||||||
while not th.exit.is_set():
|
while not th.exit.is_set():
|
||||||
# IO-Arbeiten
|
# IO-Arbeiten
|
||||||
th.exit.wait(0.5)
|
th.exit.wait(0.5)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "daemon", "exit", "func", "ioname", "iovalue"
|
__slots__ = "daemon", "exit", "func", "ioname", "iovalue"
|
||||||
|
|
||||||
def __init__(self, func, name, value):
|
def __init__(self, func, name: str, value):
|
||||||
"""Init EventCallback class.
|
"""
|
||||||
|
Init EventCallback class.
|
||||||
@param func Funktion die beim Start aufgerufen werden soll
|
|
||||||
@param name IO-Name
|
|
||||||
@param value IO-Value zum Zeitpunkt des Events
|
|
||||||
|
|
||||||
|
:param func: Funktion die beim Start aufgerufen werden soll
|
||||||
|
:param name: IO-Name
|
||||||
|
:param value: IO-Value zum Zeitpunkt des Events
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
@@ -63,9 +62,9 @@ class EventCallback(Thread):
|
|||||||
self.exit.set()
|
self.exit.set()
|
||||||
|
|
||||||
|
|
||||||
class Cycletools():
|
class Cycletools:
|
||||||
|
"""
|
||||||
"""Werkzeugkasten fuer Cycleloop-Funktion.
|
Werkzeugkasten fuer Cycleloop-Funktion.
|
||||||
|
|
||||||
Diese Klasse enthaelt Werkzeuge fuer Zyklusfunktionen, wie Taktmerker
|
Diese Klasse enthaelt Werkzeuge fuer Zyklusfunktionen, wie Taktmerker
|
||||||
und Flankenmerker.
|
und Flankenmerker.
|
||||||
@@ -84,7 +83,6 @@ class Cycletools():
|
|||||||
|
|
||||||
Diese Merker koennen z.B. verwendet werden um, an Outputs angeschlossene,
|
Diese Merker koennen z.B. verwendet werden um, an Outputs angeschlossene,
|
||||||
Lampen synchron blinken zu lassen.
|
Lampen synchron blinken zu lassen.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__cycle", "__cycletime", "__ucycle", \
|
__slots__ = "__cycle", "__cycletime", "__ucycle", \
|
||||||
@@ -117,10 +115,13 @@ class Cycletools():
|
|||||||
|
|
||||||
# Benutzerdaten
|
# Benutzerdaten
|
||||||
class Var:
|
class Var:
|
||||||
|
"""Hier remanente Variablen anfuegen."""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.var = Var()
|
self.var = Var()
|
||||||
|
|
||||||
def _docycle(self):
|
def _docycle(self) -> None:
|
||||||
"""Zyklusarbeiten."""
|
"""Zyklusarbeiten."""
|
||||||
# Einschaltverzoegerung
|
# Einschaltverzoegerung
|
||||||
for tof in self.__dict_tof:
|
for tof in self.__dict_tof:
|
||||||
@@ -174,54 +175,66 @@ class Cycletools():
|
|||||||
self.flag5c = not self.flag5c
|
self.flag5c = not self.flag5c
|
||||||
self.__cycle = 0
|
self.__cycle = 0
|
||||||
|
|
||||||
def get_tof(self, name):
|
def get_tof(self, name: str) -> bool:
|
||||||
"""Wert der Ausschaltverzoegerung.
|
"""
|
||||||
@param name Eindeutiger Name des Timers
|
Wert der Ausschaltverzoegerung.
|
||||||
@return Wert <class 'bool'> der Ausschaltverzoegerung"""
|
|
||||||
|
:param name: Eindeutiger Name des Timers
|
||||||
|
:return: Wert <class 'bool'> der Ausschaltverzoegerung
|
||||||
|
"""
|
||||||
return self.__dict_tof.get(name, 0) > 0
|
return self.__dict_tof.get(name, 0) > 0
|
||||||
|
|
||||||
def get_tofc(self, name):
|
def get_tofc(self, name: str) -> bool:
|
||||||
"""Wert der Ausschaltverzoegerung.
|
"""
|
||||||
@param name Eindeutiger Name des Timers
|
Wert der Ausschaltverzoegerung.
|
||||||
@return Wert <class 'bool'> der Ausschaltverzoegerung"""
|
|
||||||
|
:param name: Eindeutiger Name des Timers
|
||||||
|
:return: Wert <class 'bool'> der Ausschaltverzoegerung
|
||||||
|
"""
|
||||||
return self.__dict_tof.get(name, 0) > 0
|
return self.__dict_tof.get(name, 0) > 0
|
||||||
|
|
||||||
def set_tof(self, name, milliseconds):
|
def set_tof(self, name: str, milliseconds: int) -> None:
|
||||||
"""Startet bei Aufruf einen ausschaltverzoegerten Timer.
|
"""
|
||||||
|
Startet bei Aufruf einen ausschaltverzoegerten Timer.
|
||||||
@param name Eindeutiger Name fuer Zugriff auf Timer
|
|
||||||
@param milliseconds Verzoegerung in Millisekunden
|
|
||||||
|
|
||||||
|
:param name: Eindeutiger Name fuer Zugriff auf Timer
|
||||||
|
:param milliseconds: Verzoegerung in Millisekunden
|
||||||
"""
|
"""
|
||||||
self.__dict_tof[name] = ceil(milliseconds / self.__cycletime)
|
self.__dict_tof[name] = ceil(milliseconds / self.__cycletime)
|
||||||
|
|
||||||
def set_tofc(self, name, cycles):
|
def set_tofc(self, name: str, cycles: int) -> None:
|
||||||
"""Startet bei Aufruf einen ausschaltverzoegerten Timer.
|
"""
|
||||||
|
Startet bei Aufruf einen ausschaltverzoegerten Timer.
|
||||||
@param name Eindeutiger Name fuer Zugriff auf Timer
|
|
||||||
@param cycles Zyklusanzahl, der Verzoegerung wenn nicht neu gestartet
|
|
||||||
|
|
||||||
|
:param name: Eindeutiger Name fuer Zugriff auf Timer
|
||||||
|
:param cycles: Zyklusanzahl, der Verzoegerung wenn nicht neu gestartet
|
||||||
"""
|
"""
|
||||||
self.__dict_tof[name] = cycles
|
self.__dict_tof[name] = cycles
|
||||||
|
|
||||||
def get_ton(self, name):
|
def get_ton(self, name: str) -> bool:
|
||||||
"""Einschaltverzoegerung.
|
"""
|
||||||
@param name Eindeutiger Name des Timers
|
Einschaltverzoegerung.
|
||||||
@return Wert <class 'bool'> der Einschaltverzoegerung"""
|
|
||||||
|
:param name: Eindeutiger Name des Timers
|
||||||
|
:return: Wert <class 'bool'> der Einschaltverzoegerung
|
||||||
|
"""
|
||||||
return self.__dict_ton.get(name, [-1])[0] == 0
|
return self.__dict_ton.get(name, [-1])[0] == 0
|
||||||
|
|
||||||
def get_tonc(self, name):
|
def get_tonc(self, name: str) -> bool:
|
||||||
"""Einschaltverzoegerung.
|
"""
|
||||||
@param name Eindeutiger Name des Timers
|
Einschaltverzoegerung.
|
||||||
@return Wert <class 'bool'> der Einschaltverzoegerung"""
|
|
||||||
|
:param name: Eindeutiger Name des Timers
|
||||||
|
:return: Wert <class 'bool'> der Einschaltverzoegerung
|
||||||
|
"""
|
||||||
return self.__dict_ton.get(name, [-1])[0] == 0
|
return self.__dict_ton.get(name, [-1])[0] == 0
|
||||||
|
|
||||||
def set_ton(self, name, milliseconds):
|
def set_ton(self, name: str, milliseconds: int) -> None:
|
||||||
"""Startet einen einschaltverzoegerten Timer.
|
"""
|
||||||
|
Startet einen einschaltverzoegerten Timer.
|
||||||
@param name Eindeutiger Name fuer Zugriff auf Timer
|
|
||||||
@param milliseconds Millisekunden, der Verzoegerung wenn neu gestartet
|
|
||||||
|
|
||||||
|
:param name: Eindeutiger Name fuer Zugriff auf Timer
|
||||||
|
:param milliseconds: Millisekunden, der Verzoegerung wenn neu gestartet
|
||||||
"""
|
"""
|
||||||
if self.__dict_ton.get(name, [-1])[0] == -1:
|
if self.__dict_ton.get(name, [-1])[0] == -1:
|
||||||
self.__dict_ton[name] = \
|
self.__dict_ton[name] = \
|
||||||
@@ -229,36 +242,42 @@ class Cycletools():
|
|||||||
else:
|
else:
|
||||||
self.__dict_ton[name][1] = True
|
self.__dict_ton[name][1] = True
|
||||||
|
|
||||||
def set_tonc(self, name, cycles):
|
def set_tonc(self, name: str, cycles: int) -> None:
|
||||||
"""Startet einen einschaltverzoegerten Timer.
|
"""
|
||||||
|
Startet einen einschaltverzoegerten Timer.
|
||||||
@param name Eindeutiger Name fuer Zugriff auf Timer
|
|
||||||
@param cycles Zyklusanzahl, der Verzoegerung wenn neu gestartet
|
|
||||||
|
|
||||||
|
:param name: Eindeutiger Name fuer Zugriff auf Timer
|
||||||
|
:param cycles: Zyklusanzahl, der Verzoegerung wenn neu gestartet
|
||||||
"""
|
"""
|
||||||
if self.__dict_ton.get(name, [-1])[0] == -1:
|
if self.__dict_ton.get(name, [-1])[0] == -1:
|
||||||
self.__dict_ton[name] = [cycles, True]
|
self.__dict_ton[name] = [cycles, True]
|
||||||
else:
|
else:
|
||||||
self.__dict_ton[name][1] = True
|
self.__dict_ton[name][1] = True
|
||||||
|
|
||||||
def get_tp(self, name):
|
def get_tp(self, name: str) -> bool:
|
||||||
"""Impulstimer.
|
"""
|
||||||
@param name Eindeutiger Name des Timers
|
Impulstimer.
|
||||||
@return Wert <class 'bool'> des Impulses"""
|
|
||||||
|
:param name: Eindeutiger Name des Timers
|
||||||
|
:return: Wert <class 'bool'> des Impulses
|
||||||
|
"""
|
||||||
return self.__dict_tp.get(name, [-1])[0] > 0
|
return self.__dict_tp.get(name, [-1])[0] > 0
|
||||||
|
|
||||||
def get_tpc(self, name):
|
def get_tpc(self, name: str) -> bool:
|
||||||
"""Impulstimer.
|
"""
|
||||||
@param name Eindeutiger Name des Timers
|
Impulstimer.
|
||||||
@return Wert <class 'bool'> des Impulses"""
|
|
||||||
|
:param name: Eindeutiger Name des Timers
|
||||||
|
:return: Wert <class 'bool'> des Impulses
|
||||||
|
"""
|
||||||
return self.__dict_tp.get(name, [-1])[0] > 0
|
return self.__dict_tp.get(name, [-1])[0] > 0
|
||||||
|
|
||||||
def set_tp(self, name, milliseconds):
|
def set_tp(self, name: str, milliseconds: int) -> None:
|
||||||
"""Startet einen Impuls Timer.
|
"""
|
||||||
|
Startet einen Impuls Timer.
|
||||||
@param name Eindeutiger Name fuer Zugriff auf Timer
|
|
||||||
@param milliseconds Millisekunden, die der Impuls anstehen soll
|
|
||||||
|
|
||||||
|
:param name: Eindeutiger Name fuer Zugriff auf Timer
|
||||||
|
:param milliseconds: Millisekunden, die der Impuls anstehen soll
|
||||||
"""
|
"""
|
||||||
if self.__dict_tp.get(name, [-1])[0] == -1:
|
if self.__dict_tp.get(name, [-1])[0] == -1:
|
||||||
self.__dict_tp[name] = \
|
self.__dict_tp[name] = \
|
||||||
@@ -266,12 +285,12 @@ class Cycletools():
|
|||||||
else:
|
else:
|
||||||
self.__dict_tp[name][1] = True
|
self.__dict_tp[name][1] = True
|
||||||
|
|
||||||
def set_tpc(self, name, cycles):
|
def set_tpc(self, name: str, cycles: int) -> None:
|
||||||
"""Startet einen Impuls Timer.
|
"""
|
||||||
|
Startet einen Impuls Timer.
|
||||||
@param name Eindeutiger Name fuer Zugriff auf Timer
|
|
||||||
@param cycles Zyklusanzahl, die der Impuls anstehen soll
|
|
||||||
|
|
||||||
|
:param name: Eindeutiger Name fuer Zugriff auf Timer
|
||||||
|
:param cycles: Zyklusanzahl, die der Impuls anstehen soll
|
||||||
"""
|
"""
|
||||||
if self.__dict_tp.get(name, [-1])[0] == -1:
|
if self.__dict_tp.get(name, [-1])[0] == -1:
|
||||||
self.__dict_tp[name] = [cycles, True]
|
self.__dict_tp[name] = [cycles, True]
|
||||||
@@ -280,13 +299,12 @@ class Cycletools():
|
|||||||
|
|
||||||
|
|
||||||
class ProcimgWriter(Thread):
|
class ProcimgWriter(Thread):
|
||||||
|
"""
|
||||||
"""Klasse fuer Synchroniseriungs-Thread.
|
Klasse fuer Synchroniseriungs-Thread.
|
||||||
|
|
||||||
Diese Klasse wird als Thread gestartet, wenn das Prozessabbild zyklisch
|
Diese Klasse wird als Thread gestartet, wenn das Prozessabbild zyklisch
|
||||||
synchronisiert werden soll. Diese Funktion wird hauptsaechlich fuer das
|
synchronisiert werden soll. Diese Funktion wird hauptsaechlich fuer das
|
||||||
Event-Handling verwendet.
|
Event-Handling verwendet.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \
|
__slots__ = "__dict_delay", "__eventth", "_eventqth", "__eventwork", \
|
||||||
@@ -294,8 +312,7 @@ class ProcimgWriter(Thread):
|
|||||||
"_refresh", "_work", "daemon", "lck_refresh", "newdata"
|
"_refresh", "_work", "daemon", "lck_refresh", "newdata"
|
||||||
|
|
||||||
def __init__(self, parentmodio):
|
def __init__(self, parentmodio):
|
||||||
"""Init ProcimgWriter class.
|
"""Init ProcimgWriter class."""
|
||||||
@param parentmodio Parent Object"""
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.__dict_delay = {}
|
self.__dict_delay = {}
|
||||||
self.__eventth = Thread(target=self.__exec_th)
|
self.__eventth = Thread(target=self.__exec_th)
|
||||||
@@ -311,7 +328,7 @@ class ProcimgWriter(Thread):
|
|||||||
self.lck_refresh = Lock()
|
self.lck_refresh = Lock()
|
||||||
self.newdata = Event()
|
self.newdata = Event()
|
||||||
|
|
||||||
def __check_change(self, dev):
|
def __check_change(self, dev) -> None:
|
||||||
"""Findet Aenderungen fuer die Eventueberwachung."""
|
"""Findet Aenderungen fuer die Eventueberwachung."""
|
||||||
for io_event in dev._dict_events:
|
for io_event in dev._dict_events:
|
||||||
|
|
||||||
@@ -386,7 +403,7 @@ class ProcimgWriter(Thread):
|
|||||||
# Nach Verarbeitung aller IOs die Bytes kopieren (Lock ist noch drauf)
|
# Nach Verarbeitung aller IOs die Bytes kopieren (Lock ist noch drauf)
|
||||||
dev._ba_datacp = dev._ba_devdata[:]
|
dev._ba_datacp = dev._ba_devdata[:]
|
||||||
|
|
||||||
def __exec_th(self):
|
def __exec_th(self) -> None:
|
||||||
"""Laeuft als Thread, der Events als Thread startet."""
|
"""Laeuft als Thread, der Events als Thread startet."""
|
||||||
while self.__eventwork:
|
while self.__eventwork:
|
||||||
try:
|
try:
|
||||||
@@ -398,10 +415,13 @@ class ProcimgWriter(Thread):
|
|||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _collect_events(self, value):
|
def _collect_events(self, value: bool) -> bool:
|
||||||
"""Aktiviert oder Deaktiviert die Eventueberwachung.
|
"""
|
||||||
@param value True aktiviert / False deaktiviert
|
Aktiviert oder Deaktiviert die Eventueberwachung.
|
||||||
@return True, wenn Anforderung erfolgreich war"""
|
|
||||||
|
:param value: True aktiviert / False deaktiviert
|
||||||
|
:return: True, wenn Anforderung erfolgreich war
|
||||||
|
"""
|
||||||
if type(value) != bool:
|
if type(value) != bool:
|
||||||
raise TypeError("value must be <class 'bool'>")
|
raise TypeError("value must be <class 'bool'>")
|
||||||
|
|
||||||
@@ -427,9 +447,12 @@ class ProcimgWriter(Thread):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_refresh(self):
|
def get_refresh(self) -> int:
|
||||||
"""Gibt Zykluszeit zurueck.
|
"""
|
||||||
@return <class 'int'> Zykluszeit in Millisekunden"""
|
Gibt Zykluszeit zurueck.
|
||||||
|
|
||||||
|
:return: <class 'int'> Zykluszeit in Millisekunden
|
||||||
|
"""
|
||||||
return int(self._refresh * 1000)
|
return int(self._refresh * 1000)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@@ -472,7 +495,7 @@ class ProcimgWriter(Thread):
|
|||||||
with dev._filelock:
|
with dev._filelock:
|
||||||
dev._ba_devdata[dev._slc_inp] = \
|
dev._ba_devdata[dev._slc_inp] = \
|
||||||
bytesbuff[dev._slc_inpoff]
|
bytesbuff[dev._slc_inpoff]
|
||||||
if self.__eventwork\
|
if self.__eventwork \
|
||||||
and len(dev._dict_events) > 0 \
|
and len(dev._dict_events) > 0 \
|
||||||
and dev._ba_datacp != dev._ba_devdata:
|
and dev._ba_datacp != dev._ba_devdata:
|
||||||
self.__check_change(dev)
|
self.__check_change(dev)
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""RevPiModIO Modul fuer die Verwaltung der IOs."""
|
"""RevPiModIO Modul fuer die Verwaltung der IOs."""
|
||||||
|
import struct
|
||||||
|
from re import match as rematch
|
||||||
|
from threading import Event
|
||||||
|
|
||||||
|
from revpimodio2 import BOTH, FALLING, INP, MEM, RISING, consttostr
|
||||||
|
|
||||||
__author__ = "Sven Sager"
|
__author__ = "Sven Sager"
|
||||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||||
__license__ = "LGPLv3"
|
__license__ = "LGPLv3"
|
||||||
|
|
||||||
import struct
|
|
||||||
from re import match as rematch
|
|
||||||
from threading import Event
|
|
||||||
from revpimodio2 import RISING, FALLING, BOTH, INP, MEM, consttostr
|
|
||||||
try:
|
try:
|
||||||
# Funktioniert nur auf Unix
|
# Funktioniert nur auf Unix
|
||||||
from fcntl import ioctl
|
from fcntl import ioctl
|
||||||
@@ -16,7 +18,6 @@ except Exception:
|
|||||||
|
|
||||||
|
|
||||||
class IOEvent(object):
|
class IOEvent(object):
|
||||||
|
|
||||||
"""Basisklasse fuer IO-Events."""
|
"""Basisklasse fuer IO-Events."""
|
||||||
|
|
||||||
__slots__ = "as_thread", "delay", "edge", "func", "overwrite", "prefire"
|
__slots__ = "as_thread", "delay", "edge", "func", "overwrite", "prefire"
|
||||||
@@ -32,7 +33,6 @@ class IOEvent(object):
|
|||||||
|
|
||||||
|
|
||||||
class IOList(object):
|
class IOList(object):
|
||||||
|
|
||||||
"""Basisklasse fuer direkten Zugriff auf IO Objekte."""
|
"""Basisklasse fuer direkten Zugriff auf IO Objekte."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -41,17 +41,23 @@ class IOList(object):
|
|||||||
self.__dict_iorefname = {}
|
self.__dict_iorefname = {}
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
"""Prueft ob IO existiert.
|
"""
|
||||||
@param key IO-Name <class 'str'> oder Bytenummer <class 'int'>
|
Prueft ob IO existiert.
|
||||||
@return True, wenn IO vorhanden / Byte belegt"""
|
|
||||||
|
:param key: IO-Name <class 'str'> oder Bytenummer <class 'int'>
|
||||||
|
:return: True, wenn IO vorhanden / Byte belegt
|
||||||
|
"""
|
||||||
if type(key) == int:
|
if type(key) == int:
|
||||||
return len(self.__dict_iobyte.get(key, [])) > 0
|
return len(self.__dict_iobyte.get(key, [])) > 0
|
||||||
else:
|
else:
|
||||||
return hasattr(self, key) and type(getattr(self, key)) != DeadIO
|
return hasattr(self, key) and type(getattr(self, key)) != DeadIO
|
||||||
|
|
||||||
def __delattr__(self, key):
|
def __delattr__(self, key):
|
||||||
"""Entfernt angegebenen IO.
|
"""
|
||||||
@param key IO zum entfernen"""
|
Entfernt angegebenen IO.
|
||||||
|
|
||||||
|
:param key: IO zum entfernen
|
||||||
|
"""
|
||||||
io_del = object.__getattribute__(self, key)
|
io_del = object.__getattribute__(self, key)
|
||||||
|
|
||||||
# Alte Events vom Device löschen
|
# Alte Events vom Device löschen
|
||||||
@@ -70,16 +76,20 @@ class IOList(object):
|
|||||||
io_del._parentdevice._update_my_io_list()
|
io_del._parentdevice._update_my_io_list()
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
"""Verwaltet geloeschte IOs (Attribute, die nicht existieren).
|
"""
|
||||||
@param key Name oder Byte eines alten IOs
|
Verwaltet geloeschte IOs (Attribute, die nicht existieren).
|
||||||
@return Alten IO, wenn in Ref-Listen"""
|
|
||||||
|
:param key: Name oder Byte eines alten IOs
|
||||||
|
:return: Alten IO, wenn in Ref-Listen
|
||||||
|
"""
|
||||||
if key in self.__dict_iorefname:
|
if key in self.__dict_iorefname:
|
||||||
return self.__dict_iorefname[key]
|
return self.__dict_iorefname[key]
|
||||||
else:
|
else:
|
||||||
raise AttributeError("can not find io '{0}'".format(key))
|
raise AttributeError("can not find io '{0}'".format(key))
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""Ruft angegebenen IO ab.
|
"""
|
||||||
|
Ruft angegebenen IO ab.
|
||||||
|
|
||||||
Wenn der Key <class 'str'> ist, wird ein einzelner IO geliefert. Wird
|
Wenn der Key <class 'str'> ist, wird ein einzelner IO geliefert. Wird
|
||||||
der Key als <class 'int'> uebergeben, wird eine <class 'list'>
|
der Key als <class 'int'> uebergeben, wird eine <class 'list'>
|
||||||
@@ -87,9 +97,8 @@ class IOList(object):
|
|||||||
Wird als Key <class 'slice'> gegeben, werden die Listen in einer Liste
|
Wird als Key <class 'slice'> gegeben, werden die Listen in einer Liste
|
||||||
zurueckgegeben.
|
zurueckgegeben.
|
||||||
|
|
||||||
@param key IO Name als <class 'str> oder Byte als <class 'int'>.
|
:param key: IO Name als <class 'str> oder Byte als <class 'int'>.
|
||||||
@return IO Objekt oder Liste der IOs
|
:return: IO Objekt oder Liste der IOs
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if type(key) == int:
|
if type(key) == int:
|
||||||
if key not in self.__dict_iobyte:
|
if key not in self.__dict_iobyte:
|
||||||
@@ -106,16 +115,22 @@ class IOList(object):
|
|||||||
return getattr(self, key)
|
return getattr(self, key)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Gibt Iterator aller IOs zurueck.
|
"""
|
||||||
@return Iterator aller IOs"""
|
Gibt Iterator aller IOs zurueck.
|
||||||
|
|
||||||
|
:return: Iterator aller IOs
|
||||||
|
"""
|
||||||
for int_io in sorted(self.__dict_iobyte):
|
for int_io in sorted(self.__dict_iobyte):
|
||||||
for io in self.__dict_iobyte[int_io]:
|
for io in self.__dict_iobyte[int_io]:
|
||||||
if io is not None:
|
if io is not None:
|
||||||
yield io
|
yield io
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""Gibt die Anzahl aller IOs zurueck.
|
"""
|
||||||
@return Anzahl aller IOs"""
|
Gibt die Anzahl aller IOs zurueck.
|
||||||
|
|
||||||
|
:return: Anzahl aller IOs
|
||||||
|
"""
|
||||||
int_ios = 0
|
int_ios = 0
|
||||||
for int_io in self.__dict_iobyte:
|
for int_io in self.__dict_iobyte:
|
||||||
for io in self.__dict_iobyte[int_io]:
|
for io in self.__dict_iobyte[int_io]:
|
||||||
@@ -135,10 +150,12 @@ class IOList(object):
|
|||||||
"direct assignment is not supported - use .value Attribute"
|
"direct assignment is not supported - use .value Attribute"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __private_replace_oldio_with_newio(self, io):
|
def __private_replace_oldio_with_newio(self, io) -> None:
|
||||||
"""Ersetzt bestehende IOs durch den neu Registrierten.
|
"""
|
||||||
@param io Neuer IO der eingefuegt werden soll"""
|
Ersetzt bestehende IOs durch den neu Registrierten.
|
||||||
|
|
||||||
|
:param io: Neuer IO der eingefuegt werden soll
|
||||||
|
"""
|
||||||
# Scanbereich festlegen
|
# Scanbereich festlegen
|
||||||
if io._bitaddress < 0:
|
if io._bitaddress < 0:
|
||||||
scan_start = io.address
|
scan_start = io.address
|
||||||
@@ -195,9 +212,12 @@ class IOList(object):
|
|||||||
io._parentio_address - io.address
|
io._parentio_address - io.address
|
||||||
] & (1 << io._bitaddress))
|
] & (1 << io._bitaddress))
|
||||||
|
|
||||||
def _private_register_new_io_object(self, new_io):
|
def _private_register_new_io_object(self, new_io) -> None:
|
||||||
"""Registriert neues IO Objekt unabhaenging von __setattr__.
|
"""
|
||||||
@param new_io Neues IO Objekt"""
|
Registriert neues IO Objekt unabhaenging von __setattr__.
|
||||||
|
|
||||||
|
:param new_io: Neues IO Objekt
|
||||||
|
"""
|
||||||
if isinstance(new_io, IOBase):
|
if isinstance(new_io, IOBase):
|
||||||
if hasattr(self, new_io._name):
|
if hasattr(self, new_io._name):
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
@@ -229,27 +249,32 @@ class IOList(object):
|
|||||||
|
|
||||||
|
|
||||||
class DeadIO(object):
|
class DeadIO(object):
|
||||||
|
|
||||||
"""Klasse, mit der ersetzte IOs verwaltet werden."""
|
"""Klasse, mit der ersetzte IOs verwaltet werden."""
|
||||||
|
|
||||||
__slots__ = "__deadio"
|
__slots__ = "__deadio"
|
||||||
|
|
||||||
def __init__(self, deadio):
|
def __init__(self, deadio):
|
||||||
"""Instantiierung der DeadIO-Klasse.
|
"""
|
||||||
@param deadio IO, der ersetzt wurde"""
|
Instantiierung der DeadIO-Klasse.
|
||||||
|
|
||||||
|
:param deadio: IO, der ersetzt wurde
|
||||||
|
"""
|
||||||
self.__deadio = deadio
|
self.__deadio = deadio
|
||||||
|
|
||||||
def replace_io(self, name, frm, **kwargs):
|
def replace_io(self, name: str, frm: str, **kwargs) -> None:
|
||||||
"""Stellt Funktion fuer weiter Bit-Ersetzungen bereit.
|
"""
|
||||||
@see #IntIOReplaceable.replace_io replace_io(...)"""
|
Stellt Funktion fuer weiter Bit-Ersetzungen bereit.
|
||||||
|
|
||||||
|
:ref: :func:IntIOReplaceable.replace_io()
|
||||||
|
"""
|
||||||
self.__deadio.replace_io(name, frm, **kwargs)
|
self.__deadio.replace_io(name, frm, **kwargs)
|
||||||
|
|
||||||
_parentdevice = property(lambda self: None)
|
_parentdevice = property(lambda self: None)
|
||||||
|
|
||||||
|
|
||||||
class IOBase(object):
|
class IOBase(object):
|
||||||
|
"""
|
||||||
"""Basisklasse fuer alle IO-Objekte.
|
Basisklasse fuer alle IO-Objekte.
|
||||||
|
|
||||||
Die Basisfunktionalitaet ermoeglicht das Lesen und Schreiben der Werte
|
Die Basisfunktionalitaet ermoeglicht das Lesen und Schreiben der Werte
|
||||||
als <class bytes'> oder <class 'bool'>. Dies entscheidet sich bei der
|
als <class bytes'> oder <class 'bool'>. Dies entscheidet sich bei der
|
||||||
@@ -259,7 +284,6 @@ class IOBase(object):
|
|||||||
|
|
||||||
Diese Klasse dient als Basis fuer andere IO-Klassen mit denen die Werte
|
Diese Klasse dient als Basis fuer andere IO-Klassen mit denen die Werte
|
||||||
auch als <class 'int'> verwendet werden koennen.
|
auch als <class 'int'> verwendet werden koennen.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__bit_ioctl_off", "__bit_ioctl_on", \
|
__slots__ = "__bit_ioctl_off", "__bit_ioctl_on", \
|
||||||
@@ -267,16 +291,16 @@ class IOBase(object):
|
|||||||
"_iotype", "_length", "_name", "_parentdevice", \
|
"_iotype", "_length", "_name", "_parentdevice", \
|
||||||
"_signed", "_slc_address", "bmk", "export"
|
"_signed", "_slc_address", "bmk", "export"
|
||||||
|
|
||||||
def __init__(self, parentdevice, valuelist, iotype, byteorder, signed):
|
def __init__(self, parentdevice, valuelist: list, iotype: int, byteorder: str, signed: bool):
|
||||||
"""Instantiierung der IOBase-Klasse.
|
"""
|
||||||
|
Instantiierung der IOBase-Klasse.
|
||||||
|
|
||||||
@param parentdevice Parentdevice auf dem der IO liegt
|
:param parentdevice: Parentdevice auf dem der IO liegt
|
||||||
@param valuelist Datenliste fuer Instantiierung
|
:param valuelist: Datenliste fuer Instantiierung
|
||||||
["name","defval","bitlen","startaddrdev",exp,"idx","bmk","bitaddr"]
|
["name","defval","bitlen","startaddrdev",exp,"idx","bmk","bitaddr"]
|
||||||
@param iotype <class 'int'> Wert
|
:param iotype: <class 'int'> Wert
|
||||||
@param byteorder Byteorder 'little'/'big' fuer <class 'int'> Berechnung
|
:param byteorder: Byteorder 'little'/'big' fuer <class 'int'> Berechnung
|
||||||
@param sigend Intberechnung mit Vorzeichen durchfuehren
|
:param signed: Intberechnung mit Vorzeichen durchfuehren
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# ["name","defval","bitlen","startaddrdev",exp,"idx","bmk","bitaddr"]
|
# ["name","defval","bitlen","startaddrdev",exp,"idx","bmk","bitaddr"]
|
||||||
# [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ]
|
# [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ]
|
||||||
@@ -358,8 +382,11 @@ class IOBase(object):
|
|||||||
self.__bit_ioctl_on = self.__bit_ioctl_off + b'\x01'
|
self.__bit_ioctl_on = self.__bit_ioctl_off + b'\x01'
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
"""<class 'bool'>-Wert der Klasse.
|
"""
|
||||||
@return <class 'bool'> Nur False wenn False oder 0 sonst True"""
|
<class 'bool'>-Wert der Klasse.
|
||||||
|
|
||||||
|
:return: <class 'bool'> Nur False wenn False oder 0 sonst True
|
||||||
|
"""
|
||||||
if self._bitaddress >= 0:
|
if self._bitaddress >= 0:
|
||||||
int_byte = int.from_bytes(
|
int_byte = int.from_bytes(
|
||||||
self._parentdevice._ba_devdata[self._slc_address],
|
self._parentdevice._ba_devdata[self._slc_address],
|
||||||
@@ -371,25 +398,31 @@ class IOBase(object):
|
|||||||
bytearray(self._length)
|
bytearray(self._length)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""Gibt die Bytelaenge des IO zurueck.
|
"""
|
||||||
@return Bytelaenge des IO - 0 bei BITs"""
|
Gibt die Bytelaenge des IO zurueck.
|
||||||
|
|
||||||
|
:return: Bytelaenge des IO - 0 bei BITs
|
||||||
|
"""
|
||||||
return 0 if self._bitaddress > 0 else self._length
|
return 0 if self._bitaddress > 0 else self._length
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""<class 'str'>-Wert der Klasse.
|
"""
|
||||||
@return Namen des IOs"""
|
<class 'str'>-Wert der Klasse.
|
||||||
|
|
||||||
|
:return: Namen des IOs
|
||||||
|
"""
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def __reg_xevent(self, func, delay, edge, as_thread, overwrite, prefire):
|
def __reg_xevent(self, func, delay: int, edge: int, as_thread: bool, overwrite: bool, prefire: bool) -> None:
|
||||||
"""Verwaltet reg_event und reg_timerevent.
|
"""
|
||||||
|
Verwaltet reg_event und reg_timerevent.
|
||||||
@param func Funktion die bei Aenderung aufgerufen werden soll
|
|
||||||
@param delay Verzoegerung in ms zum Ausloesen - auch bei Wertaenderung
|
|
||||||
@param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
|
||||||
@param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren
|
|
||||||
@param overwrite Wenn True, wird Event bei ueberschrieben
|
|
||||||
@param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet
|
|
||||||
|
|
||||||
|
:param func: Funktion die bei Aenderung aufgerufen werden soll
|
||||||
|
:param delay: Verzoegerung in ms zum Ausloesen - auch bei Wertaenderung
|
||||||
|
:param edge: Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
||||||
|
:param as_thread: Bei True, Funktion als EventCallback-Thread ausfuehren
|
||||||
|
:param overwrite: Wenn True, wird Event bei ueberschrieben
|
||||||
|
:param prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet
|
||||||
"""
|
"""
|
||||||
# Prüfen ob Funktion callable ist
|
# Prüfen ob Funktion callable ist
|
||||||
if not callable(func):
|
if not callable(func):
|
||||||
@@ -449,29 +482,44 @@ class IOBase(object):
|
|||||||
IOEvent(func, edge, as_thread, delay, overwrite, prefire)
|
IOEvent(func, edge, as_thread, delay, overwrite, prefire)
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_address(self):
|
def _get_address(self) -> int:
|
||||||
"""Gibt die absolute Byteadresse im Prozessabbild zurueck.
|
"""
|
||||||
@return Absolute Byteadresse"""
|
Gibt die absolute Byteadresse im Prozessabbild zurueck.
|
||||||
|
|
||||||
|
:return: Absolute Byteadresse
|
||||||
|
"""
|
||||||
return self._parentdevice._offset + self._slc_address.start
|
return self._parentdevice._offset + self._slc_address.start
|
||||||
|
|
||||||
def _get_byteorder(self):
|
def _get_byteorder(self) -> str:
|
||||||
"""Gibt konfigurierte Byteorder zurueck.
|
"""
|
||||||
@return <class 'str'> Byteorder"""
|
Gibt konfigurierte Byteorder zurueck.
|
||||||
|
|
||||||
|
:return: <class 'str'> Byteorder
|
||||||
|
"""
|
||||||
return self._byteorder
|
return self._byteorder
|
||||||
|
|
||||||
def _get_iotype(self):
|
def _get_iotype(self) -> int:
|
||||||
"""Gibt io type zurueck.
|
"""
|
||||||
@return <class 'int'> io type"""
|
Gibt io type zurueck.
|
||||||
|
|
||||||
|
:return: <class 'int'> io type
|
||||||
|
"""
|
||||||
return self._iotype
|
return self._iotype
|
||||||
|
|
||||||
def get_defaultvalue(self):
|
def get_defaultvalue(self):
|
||||||
"""Gibt die Defaultvalue von piCtory zurueck.
|
"""
|
||||||
@return Defaultvalue als <class 'byte'> oder <class 'bool'>"""
|
Gibt die Defaultvalue von piCtory zurueck.
|
||||||
|
|
||||||
|
:return: Defaultvalue als <class 'byte'> oder <class 'bool'>
|
||||||
|
"""
|
||||||
return self._defaultvalue
|
return self._defaultvalue
|
||||||
|
|
||||||
def get_value(self):
|
def get_value(self):
|
||||||
"""Gibt den Wert des IOs zurueck.
|
"""
|
||||||
@return IO-Wert als <class 'bytes'> oder <class 'bool'>"""
|
Gibt den Wert des IOs zurueck.
|
||||||
|
|
||||||
|
:return: IO-Wert als <class 'bytes'> oder <class 'bool'>
|
||||||
|
"""
|
||||||
if self._bitaddress >= 0:
|
if self._bitaddress >= 0:
|
||||||
int_byte = int.from_bytes(
|
int_byte = int.from_bytes(
|
||||||
self._parentdevice._ba_devdata[self._slc_address],
|
self._parentdevice._ba_devdata[self._slc_address],
|
||||||
@@ -483,7 +531,8 @@ class IOBase(object):
|
|||||||
|
|
||||||
def reg_event(
|
def reg_event(
|
||||||
self, func, delay=0, edge=BOTH, as_thread=False, prefire=False):
|
self, func, delay=0, edge=BOTH, as_thread=False, prefire=False):
|
||||||
"""Registriert fuer IO ein Event bei der Eventueberwachung.
|
"""
|
||||||
|
Registriert fuer IO ein Event bei der Eventueberwachung.
|
||||||
|
|
||||||
Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert
|
Die uebergebene Funktion wird ausgefuehrt, wenn sich der IO Wert
|
||||||
aendert. Mit Angabe von optionalen Parametern kann das
|
aendert. Mit Angabe von optionalen Parametern kann das
|
||||||
@@ -492,17 +541,17 @@ class IOBase(object):
|
|||||||
HINWEIS: Die delay-Zeit muss in die .cycletime passen, ist dies nicht
|
HINWEIS: Die delay-Zeit muss in die .cycletime passen, ist dies nicht
|
||||||
der Fall, wird IMMER aufgerundet!
|
der Fall, wird IMMER aufgerundet!
|
||||||
|
|
||||||
@param func Funktion die bei Aenderung aufgerufen werden soll
|
:param func: Funktion die bei Aenderung aufgerufen werden soll
|
||||||
@param delay Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
|
:param delay; Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
|
||||||
@param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
:param edge: Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
||||||
@param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren
|
:param as_thread: Bei True, Funktion als EventCallback-Thread ausfuehren
|
||||||
@param prefire Ausloesen mit aktuellem Wert, wenn mainloop startet
|
:param prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.__reg_xevent(func, delay, edge, as_thread, True, prefire)
|
self.__reg_xevent(func, delay, edge, as_thread, True, prefire)
|
||||||
|
|
||||||
def reg_timerevent(self, func, delay, edge=BOTH, as_thread=False):
|
def reg_timerevent(self, func, delay, edge=BOTH, as_thread=False):
|
||||||
"""Registriert fuer IO einen Timer, welcher nach delay func ausfuehrt.
|
"""
|
||||||
|
Registriert fuer IO einen Timer, welcher nach delay func ausfuehrt.
|
||||||
|
|
||||||
Der Timer wird gestartet, wenn sich der IO Wert aendert und fuehrt die
|
Der Timer wird gestartet, wenn sich der IO Wert aendert und fuehrt die
|
||||||
uebergebene Funktion aus - auch wenn sich der IO Wert in der
|
uebergebene Funktion aus - auch wenn sich der IO Wert in der
|
||||||
@@ -514,17 +563,19 @@ class IOBase(object):
|
|||||||
HINWEIS: Die delay-Zeit muss in die .cycletime passen, ist dies nicht
|
HINWEIS: Die delay-Zeit muss in die .cycletime passen, ist dies nicht
|
||||||
der Fall, wird IMMER aufgerundet!
|
der Fall, wird IMMER aufgerundet!
|
||||||
|
|
||||||
@param func Funktion die bei Aenderung aufgerufen werden soll
|
:param func: Funktion die bei Aenderung aufgerufen werden soll
|
||||||
@param delay Verzoegerung in ms zum Ausloesen - auch bei Wertaenderung
|
:param delay: Verzoegerung in ms zum Ausloesen - auch bei Wertaenderung
|
||||||
@param edge Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
:param edge: Ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
||||||
@param as_thread Bei True, Funktion als EventCallback-Thread ausfuehren
|
:param as_thread: Bei True, Funktion als EventCallback-Thread ausfuehren
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.__reg_xevent(func, delay, edge, as_thread, False, False)
|
self.__reg_xevent(func, delay, edge, as_thread, False, False)
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value) -> None:
|
||||||
"""Setzt den Wert des IOs.
|
"""
|
||||||
@param value IO-Wert als <class bytes'> oder <class 'bool'>"""
|
Setzt den Wert des IOs.
|
||||||
|
|
||||||
|
:param value: IO-Wert als <class bytes'> oder <class 'bool'>
|
||||||
|
"""
|
||||||
if self._iotype == INP:
|
if self._iotype == INP:
|
||||||
if self._parentdevice._modio._simulator:
|
if self._parentdevice._modio._simulator:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
@@ -643,12 +694,12 @@ class IOBase(object):
|
|||||||
else:
|
else:
|
||||||
self._parentdevice._ba_devdata[self._slc_address] = value
|
self._parentdevice._ba_devdata[self._slc_address] = value
|
||||||
|
|
||||||
def unreg_event(self, func=None, edge=None):
|
def unreg_event(self, func=None, edge=None) -> None:
|
||||||
"""Entfernt ein Event aus der Eventueberwachung.
|
"""
|
||||||
|
Entfernt ein Event aus der Eventueberwachung.
|
||||||
@param func Nur Events mit angegebener Funktion
|
|
||||||
@param edge Nur Events mit angegebener Funktion und angegebener Edge
|
|
||||||
|
|
||||||
|
:param func: Nur Events mit angegebener Funktion
|
||||||
|
:param edge: Nur Events mit angegebener Funktion und angegebener Edge
|
||||||
"""
|
"""
|
||||||
if self in self._parentdevice._dict_events:
|
if self in self._parentdevice._dict_events:
|
||||||
if func is None:
|
if func is None:
|
||||||
@@ -659,7 +710,6 @@ class IOBase(object):
|
|||||||
for regfunc in self._parentdevice._dict_events[self]:
|
for regfunc in self._parentdevice._dict_events[self]:
|
||||||
if regfunc.func != func or edge is not None \
|
if regfunc.func != func or edge is not None \
|
||||||
and regfunc.edge != edge:
|
and regfunc.edge != edge:
|
||||||
|
|
||||||
newlist.append(regfunc)
|
newlist.append(regfunc)
|
||||||
|
|
||||||
# Wenn Funktionen übrig bleiben, diese übernehmen
|
# Wenn Funktionen übrig bleiben, diese übernehmen
|
||||||
@@ -669,8 +719,9 @@ class IOBase(object):
|
|||||||
else:
|
else:
|
||||||
del self._parentdevice._dict_events[self]
|
del self._parentdevice._dict_events[self]
|
||||||
|
|
||||||
def wait(self, edge=BOTH, exitevent=None, okvalue=None, timeout=0):
|
def wait(self, edge=BOTH, exitevent=None, okvalue=None, timeout=0) -> int:
|
||||||
"""Wartet auf Wertaenderung eines IOs.
|
"""
|
||||||
|
Wartet auf Wertaenderung eines IOs.
|
||||||
|
|
||||||
Die Wertaenderung wird immer uerberprueft, wenn fuer Devices
|
Die Wertaenderung wird immer uerberprueft, wenn fuer Devices
|
||||||
mit aktiviertem autorefresh neue Daten gelesen wurden.
|
mit aktiviertem autorefresh neue Daten gelesen wurden.
|
||||||
@@ -696,19 +747,18 @@ class IOBase(object):
|
|||||||
der autorefresh Funktion berechnet, entspricht also nicht exakt den
|
der autorefresh Funktion berechnet, entspricht also nicht exakt den
|
||||||
angegeben Millisekunden! Es wird immer nach oben gerundet!)
|
angegeben Millisekunden! Es wird immer nach oben gerundet!)
|
||||||
|
|
||||||
@param edge Flanke RISING, FALLING, BOTH die eintreten muss
|
:param edge: Flanke RISING, FALLING, BOTH die eintreten muss
|
||||||
@param exitevent <class 'thrading.Event'> fuer vorzeitiges Beenden
|
:param exitevent: <class 'thrading.Event'> fuer vorzeitiges Beenden
|
||||||
@param okvalue IO-Wert, bei dem das Warten sofort beendet wird
|
:param okvalue: IO-Wert, bei dem das Warten sofort beendet wird
|
||||||
@param timeout Zeit in ms nach der abgebrochen wird
|
:param timeout: Zeit in ms nach der abgebrochen wird
|
||||||
@return <class 'int'> erfolgreich Werte <= 0
|
:return: <class 'int'> erfolgreich Werte <= 0
|
||||||
- Erfolgreich gewartet
|
* Erfolgreich gewartet
|
||||||
Wert 0: IO hat den Wert gewechselt
|
** Wert 0: IO hat den Wert gewechselt
|
||||||
Wert -1: okvalue stimmte mit IO ueberein
|
** Wert -1: okvalue stimmte mit IO ueberein
|
||||||
- Fehlerhaft gewartet
|
* Fehlerhaft gewartet
|
||||||
Wert 1: exitevent wurde gesetzt
|
** Wert 1: exitevent wurde gesetzt
|
||||||
Wert 2: timeout abgelaufen
|
** Wert 2: timeout abgelaufen
|
||||||
Wert 100: Devicelist.exit() wurde aufgerufen
|
** Wert 100: Devicelist.exit() wurde aufgerufen
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Prüfen ob Device in autorefresh ist
|
# Prüfen ob Device in autorefresh ist
|
||||||
if not self._parentdevice._selfupdate:
|
if not self._parentdevice._selfupdate:
|
||||||
@@ -791,68 +841,89 @@ class IOBase(object):
|
|||||||
|
|
||||||
|
|
||||||
class IntIO(IOBase):
|
class IntIO(IOBase):
|
||||||
|
"""
|
||||||
"""Klasse fuer den Zugriff auf die Daten mit Konvertierung in int.
|
Klasse fuer den Zugriff auf die Daten mit Konvertierung in int.
|
||||||
|
|
||||||
Diese Klasse erweitert die Funktion von <class 'IOBase'> um Funktionen,
|
Diese Klasse erweitert die Funktion von <class 'IOBase'> um Funktionen,
|
||||||
ueber die mit <class 'int'> Werten gearbeitet werden kann. Fuer die
|
ueber die mit <class 'int'> Werten gearbeitet werden kann. Fuer die
|
||||||
Umwandlung koennen 'Byteorder' (Default 'little') und 'signed' (Default
|
Umwandlung koennen 'Byteorder' (Default 'little') und 'signed' (Default
|
||||||
False) als Parameter gesetzt werden.
|
False) als Parameter gesetzt werden.
|
||||||
@see #IOBase IOBase
|
|
||||||
|
|
||||||
|
:ref:`IOBase`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
"""Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
|
"""
|
||||||
@return IO-Wert als <class 'int'>"""
|
Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
|
||||||
|
|
||||||
|
:return: IO-Wert als <class 'int'>
|
||||||
|
"""
|
||||||
return int.from_bytes(
|
return int.from_bytes(
|
||||||
self._parentdevice._ba_devdata[self._slc_address],
|
self._parentdevice._ba_devdata[self._slc_address],
|
||||||
byteorder=self._byteorder,
|
byteorder=self._byteorder,
|
||||||
signed=self._signed
|
signed=self._signed
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_signed(self):
|
def _get_signed(self) -> bool:
|
||||||
"""Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
|
"""
|
||||||
@return True, wenn Vorzeichenbehaftet"""
|
Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
|
||||||
|
|
||||||
|
:return: True, wenn Vorzeichenbehaftet
|
||||||
|
"""
|
||||||
return self._signed
|
return self._signed
|
||||||
|
|
||||||
def _set_byteorder(self, value):
|
def _set_byteorder(self, value: str) -> None:
|
||||||
"""Setzt Byteorder fuer <class 'int'> Umwandlung.
|
"""
|
||||||
@param value <class 'str'> 'little' or 'big'"""
|
Setzt Byteorder fuer <class 'int'> Umwandlung.
|
||||||
|
|
||||||
|
:param value: <class 'str'> 'little' or 'big'
|
||||||
|
"""
|
||||||
if not (value == "little" or value == "big"):
|
if not (value == "little" or value == "big"):
|
||||||
raise ValueError("byteorder must be 'little' or 'big'")
|
raise ValueError("byteorder must be 'little' or 'big'")
|
||||||
if self._byteorder != value:
|
if self._byteorder != value:
|
||||||
self._byteorder = value
|
self._byteorder = value
|
||||||
self._defaultvalue = self._defaultvalue[::-1]
|
self._defaultvalue = self._defaultvalue[::-1]
|
||||||
|
|
||||||
def _set_signed(self, value):
|
def _set_signed(self, value: bool) -> None:
|
||||||
"""Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.
|
"""
|
||||||
@param value True, wenn mit Vorzeichen behandel"""
|
Left fest, ob der Wert Vorzeichenbehaftet behandelt werden soll.
|
||||||
|
|
||||||
|
:param value: True, wenn mit Vorzeichen behandel
|
||||||
|
"""
|
||||||
if type(value) != bool:
|
if type(value) != bool:
|
||||||
raise TypeError("signed must be <class 'bool'> True or False")
|
raise TypeError("signed must be <class 'bool'> True or False")
|
||||||
self._signed = value
|
self._signed = value
|
||||||
|
|
||||||
def get_intdefaultvalue(self):
|
def get_intdefaultvalue(self) -> int:
|
||||||
"""Gibt die Defaultvalue als <class 'int'> zurueck.
|
"""
|
||||||
@return <class 'int'> Defaultvalue"""
|
Gibt die Defaultvalue als <class 'int'> zurueck.
|
||||||
|
|
||||||
|
:return: <class 'int'> Defaultvalue
|
||||||
|
"""
|
||||||
return int.from_bytes(
|
return int.from_bytes(
|
||||||
self._defaultvalue, byteorder=self._byteorder, signed=self._signed
|
self._defaultvalue, byteorder=self._byteorder, signed=self._signed
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_intvalue(self):
|
def get_intvalue(self) -> int:
|
||||||
"""Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
|
"""
|
||||||
@return IO-Wert als <class 'int'>"""
|
Gibt IO-Wert zurueck mit Beachtung byteorder/signed.
|
||||||
|
|
||||||
|
:return: IO-Wert als <class 'int'>
|
||||||
|
"""
|
||||||
return int.from_bytes(
|
return int.from_bytes(
|
||||||
self._parentdevice._ba_devdata[self._slc_address],
|
self._parentdevice._ba_devdata[self._slc_address],
|
||||||
byteorder=self._byteorder,
|
byteorder=self._byteorder,
|
||||||
signed=self._signed
|
signed=self._signed
|
||||||
)
|
)
|
||||||
|
|
||||||
def set_intvalue(self, value):
|
def set_intvalue(self, value: int) -> None:
|
||||||
"""Setzt IO mit Beachtung byteorder/signed.
|
"""
|
||||||
@param value <class 'int'> Wert"""
|
Setzt IO mit Beachtung byteorder/signed.
|
||||||
|
|
||||||
|
:param value: <class 'int'> Wert
|
||||||
|
"""
|
||||||
if type(value) == int:
|
if type(value) == int:
|
||||||
self.set_value(value.to_bytes(
|
self.set_value(value.to_bytes(
|
||||||
self._length,
|
self._length,
|
||||||
@@ -872,19 +943,18 @@ class IntIO(IOBase):
|
|||||||
|
|
||||||
|
|
||||||
class IntIOCounter(IntIO):
|
class IntIOCounter(IntIO):
|
||||||
|
|
||||||
"""Erweitert die IntIO-Klasse um die .reset() Funktion fuer Counter."""
|
"""Erweitert die IntIO-Klasse um die .reset() Funktion fuer Counter."""
|
||||||
|
|
||||||
__slots__ = ("__ioctl_arg")
|
__slots__ = ("__ioctl_arg", )
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, counter_id,
|
self, counter_id,
|
||||||
parentdevice, valuelist, iotype, byteorder, signed):
|
parentdevice, valuelist, iotype, byteorder, signed):
|
||||||
"""Instantiierung der IntIOCounter-Klasse.
|
"""
|
||||||
|
Instantiierung der IntIOCounter-Klasse.
|
||||||
@param counter_id ID fuer den Counter, zu dem der IO gehoert (0-15)
|
|
||||||
@see #IOBase.__init__ IOBase.__init__(...)
|
|
||||||
|
|
||||||
|
:param counter_id: ID fuer den Counter, zu dem der IO gehoert (0-15)
|
||||||
|
:ref: :func:`IOBase.__init__(...)`
|
||||||
"""
|
"""
|
||||||
if not isinstance(counter_id, int):
|
if not isinstance(counter_id, int):
|
||||||
raise TypeError("counter_id must be <class 'int'>")
|
raise TypeError("counter_id must be <class 'int'>")
|
||||||
@@ -912,7 +982,7 @@ class IntIOCounter(IntIO):
|
|||||||
# Basisklasse laden
|
# Basisklasse laden
|
||||||
super().__init__(parentdevice, valuelist, iotype, byteorder, signed)
|
super().__init__(parentdevice, valuelist, iotype, byteorder, signed)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self) -> None:
|
||||||
"""Setzt den Counter des Inputs zurueck."""
|
"""Setzt den Counter des Inputs zurueck."""
|
||||||
if self._parentdevice._modio._monitoring:
|
if self._parentdevice._modio._monitoring:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
@@ -957,13 +1027,13 @@ class IntIOCounter(IntIO):
|
|||||||
|
|
||||||
|
|
||||||
class IntIOReplaceable(IntIO):
|
class IntIOReplaceable(IntIO):
|
||||||
|
|
||||||
"""Erweitert die IntIO-Klasse um die .replace_io Funktion."""
|
"""Erweitert die IntIO-Klasse um die .replace_io Funktion."""
|
||||||
|
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
||||||
def replace_io(self, name, frm, **kwargs):
|
def replace_io(self, name: str, frm: str, **kwargs) -> None:
|
||||||
"""Ersetzt bestehenden IO mit Neuem.
|
"""
|
||||||
|
Ersetzt bestehenden IO mit Neuem.
|
||||||
|
|
||||||
Wenn die kwargs fuer byteorder und defaultvalue nicht angegeben werden,
|
Wenn die kwargs fuer byteorder und defaultvalue nicht angegeben werden,
|
||||||
uebernimmt das System die Daten aus dem ersetzten IO.
|
uebernimmt das System die Daten aus dem ersetzten IO.
|
||||||
@@ -983,9 +1053,9 @@ class IntIOReplaceable(IntIO):
|
|||||||
der urspruenglige IO hat, werden die nachfolgenden IOs ebenfalls
|
der urspruenglige IO hat, werden die nachfolgenden IOs ebenfalls
|
||||||
verwendet und entfernt.
|
verwendet und entfernt.
|
||||||
|
|
||||||
@param name Name des neuen Inputs
|
:param name: Name des neuen Inputs
|
||||||
@param frm struct formatierung (1 Zeichen) oder 'ANZAHLs' z.B. '8s'
|
:param frm: struct formatierung (1 Zeichen) oder 'ANZAHLs' z.B. '8s'
|
||||||
@param kwargs Weitere Parameter:
|
:param kwargs: Weitere Parameter:
|
||||||
- bmk: interne Bezeichnung fuer IO
|
- bmk: interne Bezeichnung fuer IO
|
||||||
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
|
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
|
||||||
- byteorder: Byteorder fuer den IO, Standardwert=little
|
- byteorder: Byteorder fuer den IO, Standardwert=little
|
||||||
@@ -995,10 +1065,7 @@ class IntIOReplaceable(IntIO):
|
|||||||
- edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
- edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung
|
||||||
- as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus
|
- as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus
|
||||||
- prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet
|
- prefire: Ausloesen mit aktuellem Wert, wenn mainloop startet
|
||||||
@see <a target="_blank"
|
`https://docs.python.org/3/library/struct.html#format-characters`
|
||||||
href="https://docs.python.org/3/library/struct.html#format-characters"
|
|
||||||
>Python3 struct</a>
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# StructIO erzeugen
|
# StructIO erzeugen
|
||||||
io_new = StructIO(
|
io_new = StructIO(
|
||||||
@@ -1023,30 +1090,29 @@ class IntIOReplaceable(IntIO):
|
|||||||
|
|
||||||
|
|
||||||
class StructIO(IOBase):
|
class StructIO(IOBase):
|
||||||
|
"""
|
||||||
"""Klasse fuer den Zugriff auf Daten ueber ein definierten struct.
|
Klasse fuer den Zugriff auf Daten ueber ein definierten struct.
|
||||||
|
|
||||||
Sie stellt ueber struct die Werte in der gewuenschten Formatierung
|
Sie stellt ueber struct die Werte in der gewuenschten Formatierung
|
||||||
bereit. Der struct-Formatwert wird bei der Instantiierung festgelegt.
|
bereit. Der struct-Formatwert wird bei der Instantiierung festgelegt.
|
||||||
@see #IOBase IOBase
|
:ref:`IOBase`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "__frm", "_parentio_address", "_parentio_defaultvalue", \
|
__slots__ = "__frm", "_parentio_address", "_parentio_defaultvalue", \
|
||||||
"_parentio_length", "_parentio_name"
|
"_parentio_length", "_parentio_name"
|
||||||
|
|
||||||
def __init__(self, parentio, name, frm, **kwargs):
|
def __init__(self, parentio, name: str, frm: str, **kwargs):
|
||||||
"""Erstellt einen IO mit struct-Formatierung.
|
"""
|
||||||
|
Erstellt einen IO mit struct-Formatierung.
|
||||||
|
|
||||||
@param parentio ParentIO Objekt, welches ersetzt wird
|
:param parentio: ParentIO Objekt, welches ersetzt wird
|
||||||
@param name Name des neuen IO
|
:param name: Name des neuen IO
|
||||||
@param frm struct formatierung (1 Zeichen) oder 'ANZAHLs' z.B. '8s'
|
:param frm: struct formatierung (1 Zeichen) oder 'ANZAHLs' z.B. '8s'
|
||||||
@param kwargs Weitere Parameter:
|
:param kwargs: Weitere Parameter:
|
||||||
- bmk: Bezeichnung fuer IO
|
- bmk: Bezeichnung fuer IO
|
||||||
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
|
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
|
||||||
- byteorder: Byteorder fuer IO, Standardwert vom ersetzten IO
|
- byteorder: Byteorder fuer IO, Standardwert vom ersetzten IO
|
||||||
- defaultvalue: Standardwert fuer IO, Standard vom ersetzten IO
|
- defaultvalue: Standardwert fuer IO, Standard vom ersetzten IO
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Structformatierung prüfen
|
# Structformatierung prüfen
|
||||||
regex = rematch("^([0-9]*s|[cbB?hHiIlLqQefd])$", frm)
|
regex = rematch("^([0-9]*s|[cbB?hHiIlLqQefd])$", frm)
|
||||||
@@ -1118,40 +1184,54 @@ class StructIO(IOBase):
|
|||||||
parentio._parentdevice._dict_slc[parentio._iotype].start and
|
parentio._parentdevice._dict_slc[parentio._iotype].start and
|
||||||
self._slc_address.stop <=
|
self._slc_address.stop <=
|
||||||
parentio._parentdevice._dict_slc[parentio._iotype].stop):
|
parentio._parentdevice._dict_slc[parentio._iotype].stop):
|
||||||
|
|
||||||
raise BufferError(
|
raise BufferError(
|
||||||
"registered value does not fit process image scope"
|
"registered value does not fit process image scope"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_frm(self):
|
def _get_frm(self) -> str:
|
||||||
"""Ruft die struct Formatierung ab.
|
"""
|
||||||
@return struct Formatierung"""
|
Ruft die struct Formatierung ab.
|
||||||
|
|
||||||
|
:return: struct Formatierung
|
||||||
|
"""
|
||||||
return self.__frm[1:]
|
return self.__frm[1:]
|
||||||
|
|
||||||
def _get_signed(self):
|
def _get_signed(self) -> bool:
|
||||||
"""Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
|
"""
|
||||||
@return True, wenn Vorzeichenbehaftet"""
|
Ruft ab, ob der Wert Vorzeichenbehaftet behandelt werden soll.
|
||||||
|
|
||||||
|
:return: True, wenn Vorzeichenbehaftet
|
||||||
|
"""
|
||||||
return self._signed
|
return self._signed
|
||||||
|
|
||||||
def get_structdefaultvalue(self):
|
def get_structdefaultvalue(self):
|
||||||
"""Gibt die Defaultvalue mit struct Formatierung zurueck.
|
"""
|
||||||
@return Defaultvalue vom Typ der struct-Formatierung"""
|
Gibt die Defaultvalue mit struct Formatierung zurueck.
|
||||||
|
|
||||||
|
:return: Defaultvalue vom Typ der struct-Formatierung
|
||||||
|
"""
|
||||||
if self._bitaddress >= 0:
|
if self._bitaddress >= 0:
|
||||||
return self._defaultvalue
|
return self._defaultvalue
|
||||||
else:
|
else:
|
||||||
return struct.unpack(self.__frm, self._defaultvalue)[0]
|
return struct.unpack(self.__frm, self._defaultvalue)[0]
|
||||||
|
|
||||||
def get_structvalue(self):
|
def get_structvalue(self):
|
||||||
"""Gibt den Wert mit struct Formatierung zurueck.
|
"""
|
||||||
@return Wert vom Typ der struct-Formatierung"""
|
Gibt den Wert mit struct Formatierung zurueck.
|
||||||
|
|
||||||
|
:return: Wert vom Typ der struct-Formatierung
|
||||||
|
"""
|
||||||
if self._bitaddress >= 0:
|
if self._bitaddress >= 0:
|
||||||
return self.get_value()
|
return self.get_value()
|
||||||
else:
|
else:
|
||||||
return struct.unpack(self.__frm, self.get_value())[0]
|
return struct.unpack(self.__frm, self.get_value())[0]
|
||||||
|
|
||||||
def set_structvalue(self, value):
|
def set_structvalue(self, value):
|
||||||
"""Setzt den Wert mit struct Formatierung.
|
"""
|
||||||
@param value Wert vom Typ der struct-Formatierung"""
|
Setzt den Wert mit struct Formatierung.
|
||||||
|
|
||||||
|
:param value: Wert vom Typ der struct-Formatierung
|
||||||
|
"""
|
||||||
if self._bitaddress >= 0:
|
if self._bitaddress >= 0:
|
||||||
self.set_value(value)
|
self.set_value(value)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user