Neue Base Klasse eingefügt von der Core / Connect erben

Sollten neue Base-Devices von Kunbus hinzugefügt werden, wird Base verwendet
IntIOReplaceable Klasse erstellt für IOs von Gateways und virtuellen Devices
Leere IntIOCounter Klasse für Counter IOs hinzugefügt
This commit is contained in:
2018-12-08 17:32:03 +01:00
parent 65a0186efb
commit 1e309091e8
7 changed files with 273 additions and 129 deletions

View File

@@ -253,11 +253,20 @@ class Device(object):
for key in sorted(dict_io, key=lambda x: int(x)):
# Neuen IO anlegen
if bool(dict_io[key][7]) or isinstance(self, Core):
# Bei Bitwerten oder Core RevPiIOBase verwenden
if bool(dict_io[key][7]) or isinstance(self, Base):
# Bei Bitwerten oder Base IOBase verwenden
io_new = IOBase(
self, dict_io[key], iotype, "little", False
)
elif isinstance(self, Gateway) and iotype != MEM:
# Ersetzbare IOs erzeugen
io_new = IntIOReplaceable(
self, dict_io[key],
iotype,
"little",
# Bei AIO (103) signed auf True setzen
self._producttype == 103
)
else:
io_new = IntIO(
self, dict_io[key],
@@ -441,7 +450,16 @@ class Device(object):
producttype = property(_get_producttype)
class Core(Device):
class Base(Device):
"""Klasse fuer alle Base-Devices wie Core / Connect usw."""
__slots__ = ()
pass
class Core(Base):
"""Klasse fuer den RevPi Core.
@@ -849,7 +867,7 @@ class Gateway(Device):
zur verfuegung, ueber die eigene IOs definiert werden, die ein
RevPiStructIO-Objekt abbilden.
Dieser IO-Typ kann Werte ueber mehrere Bytes verarbeiten und zurueckgeben.
@see revpimodio2.io#IOBase.replace_io replace_io(name, frm, **kwargs)
@see revpimodio2.io#IntIOReplaceable.replace_io replace_io(...)
"""
@@ -925,5 +943,5 @@ class Virtual(Gateway):
# Nachträglicher Import
from .io import IOBase, IntIO
from .io import IOBase, IntIO, IntIOReplaceable
from revpimodio2 import INP, OUT, MEM

View File

@@ -231,7 +231,7 @@ class DeadIO(object):
def replace_io(self, name, frm, **kwargs):
"""Stellt Funktion fuer weiter Bit-Ersetzungen bereit.
@see #IOBase.replace_io replace_io(...)"""
@see #IntIOReplaceable.replace_io replace_io(...)"""
self.__deadio.replace_io(name, frm, **kwargs)
_parentdevice = property(lambda self: None)
@@ -496,70 +496,6 @@ class IOBase(object):
"""
self.__reg_xevent(func, delay, edge, as_thread, False)
def replace_io(self, name, frm, **kwargs):
"""Ersetzt bestehenden IO mit Neuem.
Wenn die kwargs fuer byteorder und defaultvalue nicht angegeben werden,
uebernimmt das System die Daten aus dem ersetzten IO.
Es darf nur ein einzelnes Formatzeichen 'frm' uebergeben werden. Daraus
wird dann die benoetigte Laenge an Bytes berechnet und der Datentyp
festgelegt.
Eine Ausnahme ist die Formatierung 's'. Hier koennen mehrere Bytes
zu einem langen IO zusammengefasst werden. Die Formatierung muss
'8s' fuer z.B. 8 Bytes sein - NICHT 'ssssssss'!
Wenn durch die Formatierung mehr Bytes benoetigt werden, als
der urspruenglige IO hat, werden die nachfolgenden IOs ebenfalls
verwendet und entfernt.
@param name Name des neuen Inputs
@param frm struct formatierung (1 Zeichen) oder 'ANZAHLs' z.B. '8s'
@param kwargs Weitere Parameter:
- bmk: interne Bezeichnung fuer IO
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
- byteorder: Byteorder fuer den IO, Standardwert=little
- defaultvalue: Standardwert fuer IO
- event: Funktion fuer Eventhandling registrieren
- delay: Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
- edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung
- as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus
@see <a target="_blank"
href="https://docs.python.org/3/library/struct.html#format-characters"
>Python3 struct</a>
"""
if not isinstance(self._parentdevice, Gateway):
raise RuntimeError(
"this function can be used for ios on gatway or virtual "
"devices only"
)
if type(self) == StructIO:
raise RuntimeError(
"this io is already a replaced one"
)
# StructIO erzeugen
io_new = StructIO(
self,
name,
frm,
**kwargs
)
# StructIO in IO-Liste einfügen
self._parentdevice._modio.io._private_register_new_io_object(io_new)
# Optional Event eintragen
reg_event = kwargs.get("event", None)
if reg_event is not None:
io_new.reg_event(
reg_event,
kwargs.get("delay", 0),
kwargs.get("edge", BOTH),
kwargs.get("as_thread", False)
)
def set_value(self, value):
"""Setzt den Wert des IOs.
@param value IO-Wert als <class bytes'> oder <class 'bool'>"""
@@ -849,6 +785,80 @@ class IntIO(IOBase):
value = property(get_intvalue, set_intvalue)
class IntIOCounter(IntIO):
"""Erweitert die IntIO-Klasse um die .reset() Funktion fuer Counter."""
__slots__ = ()
def reset(self):
"""Setzt den Counter des Inputs zurueck."""
# TODO: Counter ID ermitteln
# TODO: Counter reset durchführen
pass
class IntIOReplaceable(IntIO):
"""Erweitert die IntIO-Klasse um die .replace_io Funktion."""
__slots__ = ()
def replace_io(self, name, frm, **kwargs):
"""Ersetzt bestehenden IO mit Neuem.
Wenn die kwargs fuer byteorder und defaultvalue nicht angegeben werden,
uebernimmt das System die Daten aus dem ersetzten IO.
Es darf nur ein einzelnes Formatzeichen 'frm' uebergeben werden. Daraus
wird dann die benoetigte Laenge an Bytes berechnet und der Datentyp
festgelegt.
Eine Ausnahme ist die Formatierung 's'. Hier koennen mehrere Bytes
zu einem langen IO zusammengefasst werden. Die Formatierung muss
'8s' fuer z.B. 8 Bytes sein - NICHT 'ssssssss'!
Wenn durch die Formatierung mehr Bytes benoetigt werden, als
der urspruenglige IO hat, werden die nachfolgenden IOs ebenfalls
verwendet und entfernt.
@param name Name des neuen Inputs
@param frm struct formatierung (1 Zeichen) oder 'ANZAHLs' z.B. '8s'
@param kwargs Weitere Parameter:
- bmk: interne Bezeichnung fuer IO
- bit: Registriert IO als <class 'bool'> am angegebenen Bit im Byte
- byteorder: Byteorder fuer den IO, Standardwert=little
- defaultvalue: Standardwert fuer IO
- event: Funktion fuer Eventhandling registrieren
- delay: Verzoegerung in ms zum Ausloesen wenn Wert gleich bleibt
- edge: Event ausfuehren bei RISING, FALLING or BOTH Wertaenderung
- as_thread: Fuehrt die event-Funktion als RevPiCallback-Thread aus
@see <a target="_blank"
href="https://docs.python.org/3/library/struct.html#format-characters"
>Python3 struct</a>
"""
# StructIO erzeugen
io_new = StructIO(
self,
name,
frm,
**kwargs
)
# StructIO in IO-Liste einfügen
self._parentdevice._modio.io._private_register_new_io_object(io_new)
# Optional Event eintragen
reg_event = kwargs.get("event", None)
if reg_event is not None:
io_new.reg_event(
reg_event,
kwargs.get("delay", 0),
kwargs.get("edge", BOTH),
kwargs.get("as_thread", False)
)
class StructIO(IOBase):
"""Klasse fuer den Zugriff auf Daten ueber ein definierten struct.
@@ -980,7 +990,3 @@ class StructIO(IOBase):
frm = property(_get_frm)
signed = property(_get_signed)
value = property(get_structvalue, set_structvalue)
# Nachträglicher Import
from .device import Gateway

View File

@@ -162,14 +162,19 @@ class RevPiModIO(object):
if device["type"] == "BASE":
pt = int(device["productType"])
if pt == 105:
if pt == 95:
# RevPi Core
dev_new = devicemodule.Core(
self, device, simulator=self._simulator
)
elif pt == 105:
# RevPi Connect
dev_new = devicemodule.Connect(
self, device, simulator=self._simulator
)
else:
# RevPi Core immer als Fallback verwenden
dev_new = devicemodule.Core(
# Base immer als Fallback verwenden
dev_new = devicemodule.Base(
self, device, simulator=self._simulator
)
self.core = dev_new