mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 13:53:53 +01:00
direct_output zu RevPiModIO hinzugefügt
Outputs werden direkt in Processimage geschrieben Der Puffer wird nur durch gängige Techniken aktualisiert TODO: Umsetzung für procimg=file fehlt
This commit is contained in:
@@ -164,7 +164,7 @@ Static Methods</h3>
|
||||
<a NAME="RevPiModIO.__init__" ID="RevPiModIO.__init__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiModIO (Constructor)</h3>
|
||||
<b>RevPiModIO</b>(<i>autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None</i>)
|
||||
<b>RevPiModIO</b>(<i>autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
|
||||
<p>
|
||||
Instantiiert die Grundfunktionen.
|
||||
</p><dl>
|
||||
@@ -192,6 +192,9 @@ Gibt bei allen Fehlern komplette Meldungen aus
|
||||
</dd><dt><i>replace_io_file</i></dt>
|
||||
<dd>
|
||||
Replace IO Konfiguration aus Datei laden
|
||||
</dd><dt><i>direct_output</i></dt>
|
||||
<dd>
|
||||
Write outputs immediately to process image (slow)
|
||||
</dd>
|
||||
</dl><a NAME="RevPiModIO.__del__" ID="RevPiModIO.__del__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
@@ -632,7 +635,7 @@ Static Methods</h3>
|
||||
<a NAME="RevPiModIODriver.__init__" ID="RevPiModIODriver.__init__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiModIODriver (Constructor)</h3>
|
||||
<b>RevPiModIODriver</b>(<i>virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None</i>)
|
||||
<b>RevPiModIODriver</b>(<i>virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None, direct_output=False</i>)
|
||||
<p>
|
||||
Instantiiert die Grundfunktionen.
|
||||
</p><p>
|
||||
@@ -692,7 +695,7 @@ Static Methods</h3>
|
||||
<a NAME="RevPiModIOSelected.__init__" ID="RevPiModIOSelected.__init__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiModIOSelected (Constructor)</h3>
|
||||
<b>RevPiModIOSelected</b>(<i>deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None</i>)
|
||||
<b>RevPiModIOSelected</b>(<i>deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
|
||||
<p>
|
||||
Instantiiert nur fuer angegebene Devices die Grundfunktionen.
|
||||
</p><p>
|
||||
|
||||
@@ -175,9 +175,9 @@ revpimodio2.modio.RevPiModIO.setdefaultvalues?4(device=None)
|
||||
revpimodio2.modio.RevPiModIO.simulator?7
|
||||
revpimodio2.modio.RevPiModIO.syncoutputs?4(device=None)
|
||||
revpimodio2.modio.RevPiModIO.writeprocimg?4(device=None)
|
||||
revpimodio2.modio.RevPiModIO?1(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None)
|
||||
revpimodio2.modio.RevPiModIODriver?1(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None)
|
||||
revpimodio2.modio.RevPiModIOSelected?1(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None)
|
||||
revpimodio2.modio.RevPiModIO?1(autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False)
|
||||
revpimodio2.modio.RevPiModIODriver?1(virtdev, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, debug=False, replace_io_file=None, direct_output=False)
|
||||
revpimodio2.modio.RevPiModIOSelected?1(deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, procimg=None, configrsc=None, simulator=False, debug=False, replace_io_file=None, direct_output=False)
|
||||
revpimodio2.netio.NetFH._connect?5()
|
||||
revpimodio2.netio.NetFH._direct_send?5(send_bytes, recv_count)
|
||||
revpimodio2.netio.NetFH.clear_dirtybytes?4(position=None)
|
||||
|
||||
@@ -481,7 +481,7 @@ class ProcimgWriter(Thread):
|
||||
fh.seek(0)
|
||||
bytesbuff = bytearray(fh.read(self._modio._length))
|
||||
|
||||
if self._modio._monitoring:
|
||||
if self._modio._monitoring or self._modio._direct_output:
|
||||
# Inputs und Outputs in Puffer
|
||||
for dev in self._modio._lst_refresh:
|
||||
with dev._filelock:
|
||||
|
||||
@@ -8,7 +8,7 @@ import struct
|
||||
import warnings
|
||||
from re import match as rematch
|
||||
from threading import Event
|
||||
from revpimodio2 import RISING, FALLING, BOTH, INP, OUT, MEM, consttostr
|
||||
from revpimodio2 import RISING, FALLING, BOTH, INP, MEM, consttostr
|
||||
from .netio import RevPiNetIO
|
||||
try:
|
||||
# Funktioniert nur auf Unix
|
||||
@@ -259,7 +259,8 @@ class IOBase(object):
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = "_bitaddress", "_bitlength", "_byteorder", "_defaultvalue", \
|
||||
__slots__ = "__bit_ioctl_off", "__bit_ioctl_on", \
|
||||
"_bitaddress", "_bitlength", "_byteorder", "_defaultvalue", \
|
||||
"_iotype", "_length", "_name", "_parentdevice", \
|
||||
"_signed", "_slc_address", "bmk", "export"
|
||||
|
||||
@@ -285,6 +286,8 @@ class IOBase(object):
|
||||
self._bitlength = int(valuelist[2])
|
||||
self._length = 1 if self._bitaddress == 0 else int(self._bitlength / 8)
|
||||
|
||||
self.__bit_ioctl_off = None
|
||||
self.__bit_ioctl_on = None
|
||||
self._byteorder = byteorder
|
||||
self._iotype = iotype
|
||||
self._name = valuelist[0]
|
||||
@@ -345,6 +348,12 @@ class IOBase(object):
|
||||
except Exception:
|
||||
self._defaultvalue = False
|
||||
|
||||
# Ioctl für Bitsetzung setzen
|
||||
self.__bit_ioctl_off = \
|
||||
self._get_address().to_bytes(2, "little") \
|
||||
+ self._bitaddress.to_bytes(1, "little")
|
||||
self.__bit_ioctl_on = self.__bit_ioctl_off + b'\x01'
|
||||
|
||||
def __bool__(self):
|
||||
"""<class 'bool'>-Wert der Klasse.
|
||||
@return <class 'bool'> Nur False wenn False oder 0 sonst True"""
|
||||
@@ -506,10 +515,60 @@ class IOBase(object):
|
||||
def set_value(self, value):
|
||||
"""Setzt den Wert des IOs.
|
||||
@param value IO-Wert als <class bytes'> oder <class 'bool'>"""
|
||||
if self._iotype == OUT:
|
||||
if self._bitaddress >= 0:
|
||||
# Versuchen egal welchen Typ in Bool zu konvertieren
|
||||
value = bool(value)
|
||||
if self._iotype == INP:
|
||||
if self._parentdevice._modio._simulator:
|
||||
raise RuntimeError(
|
||||
"can not write to output '{0}' in simulator mode"
|
||||
"".format(self._name)
|
||||
)
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"can not write to input '{0}'".format(self._name)
|
||||
)
|
||||
if self._iotype == MEM:
|
||||
raise RuntimeError(
|
||||
"can not write to memory '{0}'".format(self._name)
|
||||
)
|
||||
|
||||
if self._bitaddress >= 0:
|
||||
# Versuchen egal welchen Typ in Bool zu konvertieren
|
||||
value = bool(value)
|
||||
|
||||
if self._parentdevice._modio._direct_output:
|
||||
# Direktes Schreiben der Outputs
|
||||
# TODO: Abfragen minimieren für Schreiben der Outputs
|
||||
|
||||
if isinstance(self._parentdevice._modio, RevPiNetIO):
|
||||
# IOCTL über Netzwerk
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
self._parentdevice._modio._myfh.ioctl(
|
||||
19216,
|
||||
self.__bit_ioctl_on if value
|
||||
else self.__bit_ioctl_off
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror(
|
||||
"net_ioctl", e)
|
||||
else:
|
||||
# IOCTL auf dem RevPi
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
# Set value durchführen (Funktion K+16)
|
||||
ioctl(
|
||||
self._parentdevice._modio._myfh,
|
||||
19216,
|
||||
self.__bit_ioctl_on if value
|
||||
else self.__bit_ioctl_off
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("ioset", e)
|
||||
|
||||
else:
|
||||
# Gepuffertes Schreiben der Outputs
|
||||
|
||||
# Für Bitoperationen sperren
|
||||
self._parentdevice._filelock.acquire()
|
||||
|
||||
# ganzes Byte laden
|
||||
byte_buff = self._parentdevice._ba_devdata[self._slc_address]
|
||||
@@ -530,39 +589,37 @@ class IOBase(object):
|
||||
self._parentdevice._ba_devdata[self._slc_address] = \
|
||||
int_byte.to_bytes(int_len, byteorder=self._byteorder)
|
||||
|
||||
else:
|
||||
if type(value) == bytes:
|
||||
if self._length == len(value):
|
||||
self._parentdevice._ba_devdata[self._slc_address] = \
|
||||
value
|
||||
else:
|
||||
raise ValueError(
|
||||
"'{0}' requires a <class 'bytes'> object of "
|
||||
"length {1}, but {2} was given".format(
|
||||
self._name, self._length, len(value)
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise TypeError(
|
||||
"'{0}' requires a <class 'bytes'> object, not {1}"
|
||||
"".format(self._name, type(value))
|
||||
self._parentdevice._filelock.release()
|
||||
|
||||
else:
|
||||
if type(value) != bytes:
|
||||
raise TypeError(
|
||||
"'{0}' requires a <class 'bytes'> object, not {1}".format(
|
||||
self._name, type(value)
|
||||
)
|
||||
|
||||
elif self._iotype == INP:
|
||||
if self._parentdevice._modio._simulator:
|
||||
raise RuntimeError(
|
||||
"can not write to output '{0}' in simulator mode"
|
||||
"".format(self._name)
|
||||
)
|
||||
|
||||
if self._length != len(value):
|
||||
raise ValueError(
|
||||
"'{0}' requires a <class 'bytes'> object of "
|
||||
"length {1}, but {2} was given".format(
|
||||
self._name, self._length, len(value)
|
||||
)
|
||||
)
|
||||
|
||||
if self._parentdevice._modio._direct_output:
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
self._parentdevice._modio._myfh.seek(
|
||||
self._get_address()
|
||||
)
|
||||
self._parentdevice._modio._myfh.write(value)
|
||||
if self._parentdevice._modio._buffedwrite:
|
||||
self._parentdevice._modio._myfh.flush()
|
||||
except IOError as e:
|
||||
self._parentdevice._modio._gotioerror("ioset", e)
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"can not write to input '{0}'".format(self._name)
|
||||
)
|
||||
|
||||
elif self._iotype == MEM:
|
||||
raise RuntimeError(
|
||||
"can not write to memory '{0}'".format(self._name)
|
||||
)
|
||||
self._parentdevice._ba_devdata[self._slc_address] = value
|
||||
|
||||
def unreg_event(self, func=None, edge=None):
|
||||
"""Entfernt ein Event aus der Eventueberwachung.
|
||||
|
||||
@@ -30,17 +30,17 @@ class RevPiModIO(object):
|
||||
"""
|
||||
|
||||
__slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", \
|
||||
"_configrsc", "_exit", "_imgwriter", "_ioerror", "_length", \
|
||||
"_looprunning", "_lst_devselect", "_lst_refresh", "_maxioerrors", \
|
||||
"_myfh", "_myfh_lck", "_monitoring", "_procimg", "_simulator", \
|
||||
"_syncoutputs", "_th_mainloop", "_waitexit", \
|
||||
"_configrsc", "_direct_output", "_exit", "_imgwriter", "_ioerror", \
|
||||
"_length", "_looprunning", "_lst_devselect", "_lst_refresh", \
|
||||
"_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \
|
||||
"_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \
|
||||
"core", "app", "device", "exitsignal", "io", "summary", "_debug", \
|
||||
"_lck_replace_io", "_replace_io_file"
|
||||
|
||||
def __init__(
|
||||
self, autorefresh=False, monitoring=False, syncoutputs=True,
|
||||
procimg=None, configrsc=None, simulator=False, debug=False,
|
||||
replace_io_file=None):
|
||||
replace_io_file=None, direct_output=False):
|
||||
"""Instantiiert die Grundfunktionen.
|
||||
|
||||
@param autorefresh Wenn True, alle Devices zu autorefresh hinzufuegen
|
||||
@@ -51,12 +51,14 @@ class RevPiModIO(object):
|
||||
@param simulator Laedt das Modul als Simulator und vertauscht IOs
|
||||
@param debug Gibt bei allen Fehlern komplette Meldungen aus
|
||||
@param replace_io_file Replace IO Konfiguration aus Datei laden
|
||||
@param direct_output Write outputs immediately to process image (slow)
|
||||
|
||||
"""
|
||||
# Parameterprüfung
|
||||
acheck(
|
||||
bool, autorefresh=autorefresh, monitoring=monitoring,
|
||||
syncoutputs=syncoutputs, simulator=simulator, debug=debug
|
||||
syncoutputs=syncoutputs, simulator=simulator, debug=debug,
|
||||
direct_output=direct_output
|
||||
)
|
||||
acheck(
|
||||
str, procimg_noneok=procimg, configrsc_noneok=configrsc,
|
||||
@@ -65,6 +67,7 @@ class RevPiModIO(object):
|
||||
|
||||
self._autorefresh = autorefresh
|
||||
self._configrsc = configrsc
|
||||
self._direct_output = direct_output
|
||||
self._monitoring = monitoring
|
||||
self._procimg = "/dev/piControl0" if procimg is None else procimg
|
||||
self._simulator = simulator
|
||||
@@ -103,6 +106,13 @@ class RevPiModIO(object):
|
||||
# Event für Benutzeraktionen
|
||||
self.exitsignal = Event()
|
||||
|
||||
if self._direct_output and not \
|
||||
(self._procimg == "/dev/piControl0" or
|
||||
isinstance(self, RevPiNetIO)):
|
||||
raise RuntimeError(
|
||||
"use direct_output with piControl0 or RevPiNetIO only"
|
||||
)
|
||||
|
||||
# Nur Konfigurieren, wenn nicht vererbt
|
||||
if type(self) == RevPiModIO:
|
||||
self._configure(self.get_jconfigrsc())
|
||||
@@ -368,9 +378,7 @@ class RevPiModIO(object):
|
||||
except Exception as e:
|
||||
raise RuntimeError(
|
||||
"replace_io_file: can not replace '{0}' with '{1}' "
|
||||
"| RevPiModIO message: {2}".format(
|
||||
parentio, io, e
|
||||
)
|
||||
"| RevPiModIO message: {2}".format(parentio, io, e)
|
||||
)
|
||||
|
||||
def _create_myfh(self):
|
||||
@@ -854,7 +862,7 @@ class RevPiModIO(object):
|
||||
# FileHandler sperren
|
||||
dev._filelock.acquire()
|
||||
|
||||
if self._monitoring:
|
||||
if self._monitoring or self._direct_output:
|
||||
# Alles vom Bus einlesen
|
||||
dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
|
||||
else:
|
||||
@@ -942,6 +950,10 @@ class RevPiModIO(object):
|
||||
@return True, wenn Arbeiten an allen Devices erfolgreich waren
|
||||
|
||||
"""
|
||||
if self._direct_output:
|
||||
# TODO: Wie soll das bei direct_output umgesetzt werden?
|
||||
return True
|
||||
|
||||
if self._monitoring:
|
||||
raise RuntimeError(
|
||||
"can not write process image, while system is in monitoring "
|
||||
@@ -1018,7 +1030,8 @@ class RevPiModIOSelected(RevPiModIO):
|
||||
def __init__(
|
||||
self, deviceselection, autorefresh=False, monitoring=False,
|
||||
syncoutputs=True, procimg=None, configrsc=None,
|
||||
simulator=False, debug=False, replace_io_file=None):
|
||||
simulator=False, debug=False, replace_io_file=None,
|
||||
direct_output=False):
|
||||
"""Instantiiert nur fuer angegebene Devices die Grundfunktionen.
|
||||
|
||||
Der Parameter deviceselection kann eine einzelne
|
||||
@@ -1031,7 +1044,7 @@ class RevPiModIOSelected(RevPiModIO):
|
||||
"""
|
||||
super().__init__(
|
||||
autorefresh, monitoring, syncoutputs, procimg, configrsc,
|
||||
simulator, debug, replace_io_file
|
||||
simulator, debug, replace_io_file, direct_output
|
||||
)
|
||||
|
||||
# Device liste erstellen
|
||||
@@ -1086,7 +1099,7 @@ class RevPiModIODriver(RevPiModIOSelected):
|
||||
def __init__(
|
||||
self, virtdev, autorefresh=False, monitoring=False,
|
||||
syncoutputs=True, procimg=None, configrsc=None, debug=False,
|
||||
replace_io_file=None):
|
||||
replace_io_file=None, direct_output=False):
|
||||
"""Instantiiert die Grundfunktionen.
|
||||
|
||||
Parameter 'monitoring' und 'simulator' stehen hier nicht zur
|
||||
@@ -1099,7 +1112,7 @@ class RevPiModIODriver(RevPiModIOSelected):
|
||||
# Parent mit monitoring=False und simulator=True laden
|
||||
super().__init__(
|
||||
virtdev, autorefresh, False, syncoutputs, procimg, configrsc,
|
||||
True, debug, replace_io_file
|
||||
True, debug, replace_io_file, direct_output
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user