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__ = [
|
__all__ = [
|
||||||
"RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected",
|
"RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected",
|
||||||
"RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected",
|
"RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected",
|
||||||
"Cycletools",
|
"Cycletools", "EventCallback"
|
||||||
]
|
]
|
||||||
__author__ = "Sven Sager <akira@revpimodio.org>"
|
__author__ = "Sven Sager <akira@revpimodio.org>"
|
||||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||||
__license__ = "LGPLv3"
|
__license__ = "LGPLv3"
|
||||||
__name__ = "revpimodio2"
|
__name__ = "revpimodio2"
|
||||||
__version__ = "2.4.5"
|
__version__ = "2.4.5c"
|
||||||
|
|
||||||
# Global package values
|
# Global package values
|
||||||
OFF = 0
|
OFF = 0
|
||||||
@@ -94,6 +94,6 @@ def consttostr(value) -> str:
|
|||||||
|
|
||||||
|
|
||||||
# Benötigte Klassen importieren
|
# Benötigte Klassen importieren
|
||||||
from .helper import Cycletools
|
from .helper import Cycletools, EventCallback
|
||||||
from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected
|
from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected
|
||||||
from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected
|
from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected
|
||||||
|
|||||||
@@ -647,12 +647,8 @@ class Core(Base):
|
|||||||
|
|
||||||
:return: 0=aus, 1=gruen, 2=rot
|
:return: 0=aus, 1=gruen, 2=rot
|
||||||
"""
|
"""
|
||||||
int_led = int.from_bytes(
|
# 0b00000011 = 3
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
return self._ba_devdata[self._slc_led.start] & 3
|
||||||
)
|
|
||||||
led = int_led & 1
|
|
||||||
led += int_led & 2
|
|
||||||
return led
|
|
||||||
|
|
||||||
def _get_leda2(self) -> int:
|
def _get_leda2(self) -> int:
|
||||||
"""
|
"""
|
||||||
@@ -660,37 +656,8 @@ class Core(Base):
|
|||||||
|
|
||||||
:return: 0=aus, 1=gruen, 2=rot
|
:return: 0=aus, 1=gruen, 2=rot
|
||||||
"""
|
"""
|
||||||
int_led = int.from_bytes(
|
# 0b00001100 = 12
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
return (self._ba_devdata[self._slc_led.start] & 12) >> 2
|
||||||
) >> 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")
|
|
||||||
|
|
||||||
def _set_leda1(self, value: int) -> None:
|
def _set_leda1(self, value: int) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -699,7 +666,13 @@ class Core(Base):
|
|||||||
:param value: 0=aus, 1=gruen, 2=rot
|
:param value: 0=aus, 1=gruen, 2=rot
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 3:
|
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:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
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
|
:param value: 0=aus, 1=gruen, 2=rot
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 3:
|
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:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
raise ValueError("led status must be between 0 and 3")
|
||||||
|
|
||||||
@@ -960,12 +940,8 @@ class Connect(Core):
|
|||||||
|
|
||||||
:return: 0=aus, 1=gruen, 2=rot
|
:return: 0=aus, 1=gruen, 2=rot
|
||||||
"""
|
"""
|
||||||
int_led = int.from_bytes(
|
# 0b00110000 = 48
|
||||||
self._ba_devdata[self._slc_led], byteorder="little"
|
return (self._ba_devdata[self._slc_led.start] & 48) >> 4
|
||||||
) >> 4
|
|
||||||
led = int_led & 1
|
|
||||||
led += int_led & 2
|
|
||||||
return led
|
|
||||||
|
|
||||||
def _get_wdtoggle(self) -> bool:
|
def _get_wdtoggle(self) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -982,7 +958,14 @@ class Connect(Core):
|
|||||||
:param: value 0=aus, 1=gruen, 2=rot
|
:param: value 0=aus, 1=gruen, 2=rot
|
||||||
"""
|
"""
|
||||||
if 0 <= value <= 3:
|
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:
|
else:
|
||||||
raise ValueError("led status must be between 0 and 3")
|
raise ValueError("led status must be between 0 and 3")
|
||||||
|
|
||||||
@@ -1023,6 +1006,145 @@ class Connect(Core):
|
|||||||
wdautotoggle = property(_get_wdtoggle, _set_wdtoggle)
|
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):
|
class DioModule(Device):
|
||||||
"""Stellt ein DIO / DI / DO Modul dar."""
|
"""Stellt ein DIO / DI / DO Modul dar."""
|
||||||
|
|
||||||
|
|||||||
@@ -339,9 +339,9 @@ class ProcimgWriter(Thread):
|
|||||||
|
|
||||||
if io_event._bitshift:
|
if io_event._bitshift:
|
||||||
boolcp = dev._ba_datacp[io_event._slc_address.start] \
|
boolcp = dev._ba_datacp[io_event._slc_address.start] \
|
||||||
& io_event._bitshift
|
& io_event._bitshift
|
||||||
boolor = dev._ba_devdata[io_event._slc_address.start] \
|
boolor = dev._ba_devdata[io_event._slc_address.start] \
|
||||||
& io_event._bitshift
|
& io_event._bitshift
|
||||||
|
|
||||||
if boolor == boolcp:
|
if boolor == boolcp:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -248,6 +248,12 @@ class RevPiModIO(object):
|
|||||||
self, device, simulator=self._simulator
|
self, device, simulator=self._simulator
|
||||||
)
|
)
|
||||||
self.core = dev_new
|
self.core = dev_new
|
||||||
|
elif pt == 104:
|
||||||
|
# RevPi Compact
|
||||||
|
dev_new = devicemodule.Compact(
|
||||||
|
self, device, simulator=self._simulator
|
||||||
|
)
|
||||||
|
self.core = dev_new
|
||||||
else:
|
else:
|
||||||
# Base immer als Fallback verwenden
|
# Base immer als Fallback verwenden
|
||||||
dev_new = devicemodule.Base(
|
dev_new = devicemodule.Base(
|
||||||
@@ -324,7 +330,8 @@ class RevPiModIO(object):
|
|||||||
self.syncoutputs()
|
self.syncoutputs()
|
||||||
|
|
||||||
# Für RS485 errors am core defaults laden sollte procimg NULL sein
|
# 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:
|
if self.core._slc_errorlimit1 is not None:
|
||||||
io = self.io[
|
io = self.io[
|
||||||
self.core.offset + self.core._slc_errorlimit1.start
|
self.core.offset + self.core._slc_errorlimit1.start
|
||||||
|
|||||||
@@ -714,8 +714,8 @@ class NetFH(Thread):
|
|||||||
|
|
||||||
# Datenblöcke mit Group Seperator in Puffer ablegen
|
# Datenblöcke mit Group Seperator in Puffer ablegen
|
||||||
self.__by_buff += self.__position.to_bytes(length=2, byteorder="little") + \
|
self.__by_buff += self.__position.to_bytes(length=2, byteorder="little") + \
|
||||||
len(bytebuff).to_bytes(length=2, byteorder="little") + \
|
len(bytebuff).to_bytes(length=2, byteorder="little") + \
|
||||||
bytebuff
|
bytebuff
|
||||||
|
|
||||||
# TODO: Bufferlänge und dann flushen?
|
# TODO: Bufferlänge und dann flushen?
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user