mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 13:53:53 +01:00
Add support for RevPi Compact, better calculation of A1, A2, A3 on core object
This commit is contained in:
@@ -15,13 +15,13 @@ fuehrt das Modul bei Datenaenderung aus.
|
||||
__all__ = [
|
||||
"RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected",
|
||||
"RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected",
|
||||
"Cycletools",
|
||||
"Cycletools", "EventCallback"
|
||||
]
|
||||
__author__ = "Sven Sager <akira@revpimodio.org>"
|
||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||
__license__ = "LGPLv3"
|
||||
__name__ = "revpimodio2"
|
||||
__version__ = "2.4.5"
|
||||
__version__ = "2.4.5c"
|
||||
|
||||
# Global package values
|
||||
OFF = 0
|
||||
@@ -94,6 +94,6 @@ def consttostr(value) -> str:
|
||||
|
||||
|
||||
# Benötigte Klassen importieren
|
||||
from .helper import Cycletools
|
||||
from .helper import Cycletools, EventCallback
|
||||
from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected
|
||||
from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected
|
||||
|
||||
@@ -647,12 +647,8 @@ class Core(Base):
|
||||
|
||||
:return: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
int_led = int.from_bytes(
|
||||
self._ba_devdata[self._slc_led], byteorder="little"
|
||||
)
|
||||
led = int_led & 1
|
||||
led += int_led & 2
|
||||
return led
|
||||
# 0b00000011 = 3
|
||||
return self._ba_devdata[self._slc_led.start] & 3
|
||||
|
||||
def _get_leda2(self) -> int:
|
||||
"""
|
||||
@@ -660,37 +656,8 @@ class Core(Base):
|
||||
|
||||
:return: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
int_led = int.from_bytes(
|
||||
self._ba_devdata[self._slc_led], byteorder="little"
|
||||
) >> 2
|
||||
led = int_led & 1
|
||||
led += int_led & 2
|
||||
return led
|
||||
|
||||
def _set_calculatedled(self, addresslist: list, shifted_value: int) -> None:
|
||||
"""
|
||||
Berechnet und setzt neuen Bytewert fuer LED byte.
|
||||
|
||||
:param addresslist: Liste der Vergleicher
|
||||
:param shifted_value: Bits vergleichen
|
||||
"""
|
||||
# Byte als int holen
|
||||
int_led = int.from_bytes(
|
||||
self._ba_devdata[self._slc_led], byteorder="little"
|
||||
)
|
||||
|
||||
for int_bit in addresslist:
|
||||
value = bool(shifted_value & int_bit)
|
||||
if bool(int_led & int_bit) != value:
|
||||
# Berechnen, wenn verändert
|
||||
if value:
|
||||
int_led += int_bit
|
||||
else:
|
||||
int_led -= int_bit
|
||||
|
||||
# Zurückschreiben wenn verändert
|
||||
self._ba_devdata[self._slc_led] = \
|
||||
int_led.to_bytes(length=1, byteorder="little")
|
||||
# 0b00001100 = 12
|
||||
return (self._ba_devdata[self._slc_led.start] & 12) >> 2
|
||||
|
||||
def _set_leda1(self, value: int) -> None:
|
||||
"""
|
||||
@@ -699,7 +666,13 @@ class Core(Base):
|
||||
:param value: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
if 0 <= value <= 3:
|
||||
self._set_calculatedled([1, 2], value)
|
||||
proc_value = self._ba_devdata[self._slc_led.start]
|
||||
proc_value_calc = proc_value & 3
|
||||
if proc_value_calc == value:
|
||||
return
|
||||
# Set new value
|
||||
self._ba_devdata[self._slc_led.start] = \
|
||||
proc_value - proc_value_calc + value
|
||||
else:
|
||||
raise ValueError("led status must be between 0 and 3")
|
||||
|
||||
@@ -710,7 +683,14 @@ class Core(Base):
|
||||
:param value: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
if 0 <= value <= 3:
|
||||
self._set_calculatedled([4, 8], value << 2)
|
||||
value <<= 2
|
||||
proc_value = self._ba_devdata[self._slc_led.start]
|
||||
proc_value_calc = proc_value & 12
|
||||
if proc_value_calc == value:
|
||||
return
|
||||
# Set new value
|
||||
self._ba_devdata[self._slc_led.start] = \
|
||||
proc_value - proc_value_calc + value
|
||||
else:
|
||||
raise ValueError("led status must be between 0 and 3")
|
||||
|
||||
@@ -960,12 +940,8 @@ class Connect(Core):
|
||||
|
||||
:return: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
int_led = int.from_bytes(
|
||||
self._ba_devdata[self._slc_led], byteorder="little"
|
||||
) >> 4
|
||||
led = int_led & 1
|
||||
led += int_led & 2
|
||||
return led
|
||||
# 0b00110000 = 48
|
||||
return (self._ba_devdata[self._slc_led.start] & 48) >> 4
|
||||
|
||||
def _get_wdtoggle(self) -> bool:
|
||||
"""
|
||||
@@ -982,7 +958,14 @@ class Connect(Core):
|
||||
:param: value 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
if 0 <= value <= 3:
|
||||
self._set_calculatedled([16, 32], value << 4)
|
||||
value <<= 4
|
||||
proc_value = self._ba_devdata[self._slc_led.start]
|
||||
proc_value_calc = proc_value & 48
|
||||
if proc_value_calc == value:
|
||||
return
|
||||
# Set new value
|
||||
self._ba_devdata[self._slc_led.start] = \
|
||||
proc_value - proc_value_calc + value
|
||||
else:
|
||||
raise ValueError("led status must be between 0 and 3")
|
||||
|
||||
@@ -1023,6 +1006,145 @@ class Connect(Core):
|
||||
wdautotoggle = property(_get_wdtoggle, _set_wdtoggle)
|
||||
|
||||
|
||||
class Compact(Base):
|
||||
"""
|
||||
Klasse fuer den RevPi Connect.
|
||||
|
||||
Stellt Funktionen fuer die LEDs zur Verfuegung. Auf IOs wird ueber das .io
|
||||
Objekt zugegriffen.
|
||||
"""
|
||||
|
||||
__slots__ = "_slc_temperature", "_slc_frequency", "_slc_led", \
|
||||
"a1green", "a1red", "a2green", "a2red"
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
"""Verhindert Ueberschreibung der LEDs."""
|
||||
if hasattr(self, key) and key in (
|
||||
"a1green", "a1red", "a2green", "a2red"):
|
||||
raise AttributeError(
|
||||
"direct assignment is not supported - use .value Attribute"
|
||||
)
|
||||
else:
|
||||
object.__setattr__(self, key, value)
|
||||
|
||||
def _devconfigure(self) -> None:
|
||||
"""Core-Klasse vorbereiten."""
|
||||
|
||||
# Statische IO Verknüpfungen des Compacts
|
||||
self._slc_led = slice(23, 24)
|
||||
self._slc_temperature = slice(0, 1)
|
||||
self._slc_frequency = slice(1, 2)
|
||||
|
||||
# Exportflags prüfen (Byte oder Bit)
|
||||
lst_led = self._modio.io[self._slc_devoff][self._slc_led.start]
|
||||
if len(lst_led) == 8:
|
||||
exp_a1green = lst_led[0].export
|
||||
exp_a1red = lst_led[1].export
|
||||
exp_a2green = lst_led[2].export
|
||||
exp_a2red = lst_led[3].export
|
||||
else:
|
||||
exp_a1green = lst_led[0].export
|
||||
exp_a1red = exp_a1green
|
||||
exp_a2green = exp_a1green
|
||||
exp_a2red = exp_a1green
|
||||
|
||||
# Echte IOs erzeugen
|
||||
self.a1green = IOBase(self, [
|
||||
"core.a1green", 0, 1, self._slc_led.start,
|
||||
exp_a1green, None, "LED_A1_GREEN", "0"
|
||||
], OUT, "little", False)
|
||||
self.a1red = IOBase(self, [
|
||||
"core.a1red", 0, 1, self._slc_led.start,
|
||||
exp_a1red, None, "LED_A1_RED", "1"
|
||||
], OUT, "little", False)
|
||||
self.a2green = IOBase(self, [
|
||||
"core.a2green", 0, 1, self._slc_led.start,
|
||||
exp_a2green, None, "LED_A2_GREEN", "2"
|
||||
], OUT, "little", False)
|
||||
self.a2red = IOBase(self, [
|
||||
"core.a2red", 0, 1, self._slc_led.start,
|
||||
exp_a2red, None, "LED_A2_RED", "3"
|
||||
], OUT, "little", False)
|
||||
|
||||
def _get_leda1(self) -> int:
|
||||
"""
|
||||
Gibt den Zustand der LED A1 vom Compact zurueck.
|
||||
|
||||
:return: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
# 0b00000011 = 3
|
||||
return self._ba_devdata[self._slc_led.start] & 3
|
||||
|
||||
def _get_leda2(self) -> int:
|
||||
"""
|
||||
Gibt den Zustand der LED A2 vom Compact zurueck.
|
||||
|
||||
:return: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
# 0b00001100 = 12
|
||||
return (self._ba_devdata[self._slc_led.start] & 12) >> 2
|
||||
|
||||
def _set_leda1(self, value: int) -> None:
|
||||
"""
|
||||
Setzt den Zustand der LED A1 vom Compact.
|
||||
|
||||
:param value: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
if 0 <= value <= 3:
|
||||
proc_value = self._ba_devdata[self._slc_led.start]
|
||||
proc_value_calc = proc_value & 3
|
||||
if proc_value_calc == value:
|
||||
return
|
||||
# Set new value
|
||||
self._ba_devdata[self._slc_led.start] = \
|
||||
proc_value - proc_value_calc + value
|
||||
else:
|
||||
raise ValueError("led status must be between 0 and 3")
|
||||
|
||||
def _set_leda2(self, value: int) -> None:
|
||||
"""
|
||||
Setzt den Zustand der LED A2 vom Compact.
|
||||
|
||||
:param value: 0=aus, 1=gruen, 2=rot
|
||||
"""
|
||||
if 0 <= value <= 3:
|
||||
value <<= 2
|
||||
proc_value = self._ba_devdata[self._slc_led.start]
|
||||
proc_value_calc = proc_value & 12
|
||||
if proc_value_calc == value:
|
||||
return
|
||||
# Set new value
|
||||
self._ba_devdata[self._slc_led.start] = \
|
||||
proc_value - proc_value_calc + value
|
||||
else:
|
||||
raise ValueError("led status must be between 0 and 3")
|
||||
|
||||
A1 = property(_get_leda1, _set_leda1)
|
||||
A2 = property(_get_leda2, _set_leda2)
|
||||
|
||||
@property
|
||||
def temperature(self) -> int:
|
||||
"""
|
||||
Gibt CPU-Temperatur zurueck.
|
||||
|
||||
: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"
|
||||
)
|
||||
|
||||
@property
|
||||
def frequency(self) -> int:
|
||||
"""
|
||||
Gibt CPU Taktfrequenz zurueck.
|
||||
|
||||
: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"
|
||||
) * 10
|
||||
|
||||
|
||||
class DioModule(Device):
|
||||
"""Stellt ein DIO / DI / DO Modul dar."""
|
||||
|
||||
|
||||
@@ -248,6 +248,12 @@ class RevPiModIO(object):
|
||||
self, device, simulator=self._simulator
|
||||
)
|
||||
self.core = dev_new
|
||||
elif pt == 104:
|
||||
# RevPi Compact
|
||||
dev_new = devicemodule.Compact(
|
||||
self, device, simulator=self._simulator
|
||||
)
|
||||
self.core = dev_new
|
||||
else:
|
||||
# Base immer als Fallback verwenden
|
||||
dev_new = devicemodule.Base(
|
||||
@@ -324,7 +330,8 @@ class RevPiModIO(object):
|
||||
self.syncoutputs()
|
||||
|
||||
# Für RS485 errors am core defaults laden sollte procimg NULL sein
|
||||
if not (self.core is None or self._monitoring or self._simulator):
|
||||
if isinstance(self.core, devicemodule.Core) and \
|
||||
not (self._monitoring or self._simulator):
|
||||
if self.core._slc_errorlimit1 is not None:
|
||||
io = self.io[
|
||||
self.core.offset + self.core._slc_errorlimit1.start
|
||||
|
||||
Reference in New Issue
Block a user