mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
direct_output in RevPiNetIO übernommen
Eindeutige erkennung des procimg (file or character) Simulationsfunktionen für IOCTL gegen einfache Datei bei procimg Parameter IOCTLs werden nun einfacher verarbeitet / umgelenkt
This commit is contained in:
@@ -116,6 +116,9 @@ Methods</h3>
|
||||
<td><a style="color:#0000FF" href="#RevPiModIO._set_maxioerrors">_set_maxioerrors</a></td>
|
||||
<td>Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.</td>
|
||||
</tr><tr>
|
||||
<td><a style="color:#0000FF" href="#RevPiModIO._simulate_ioctl">_simulate_ioctl</a></td>
|
||||
<td>Simuliert IOCTL Funktionen auf procimg Datei.</td>
|
||||
</tr><tr>
|
||||
<td><a style="color:#0000FF" href="#RevPiModIO.autorefresh_all">autorefresh_all</a></td>
|
||||
<td>Setzt alle Devices in autorefresh Funktion.</td>
|
||||
</tr><tr>
|
||||
@@ -365,6 +368,20 @@ Setzt Anzahl der maximal erlaubten Fehler bei Prozessabbildzugriff.
|
||||
<dd>
|
||||
Anzahl erlaubte Fehler
|
||||
</dd>
|
||||
</dl><a NAME="RevPiModIO._simulate_ioctl" ID="RevPiModIO._simulate_ioctl"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiModIO._simulate_ioctl</h3>
|
||||
<b>_simulate_ioctl</b>(<i>request, arg=b''</i>)
|
||||
<p>
|
||||
Simuliert IOCTL Funktionen auf procimg Datei.
|
||||
</p><dl>
|
||||
<dt><i>request</i></dt>
|
||||
<dd>
|
||||
IO Request
|
||||
</dd><dt><i>arg:</i></dt>
|
||||
<dd>
|
||||
Request argument
|
||||
</dd>
|
||||
</dl><a NAME="RevPiModIO.autorefresh_all" ID="RevPiModIO.autorefresh_all"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiModIO.autorefresh_all</h3>
|
||||
|
||||
@@ -423,7 +423,7 @@ Static Methods</h3>
|
||||
<a NAME="RevPiNetIO.__init__" ID="RevPiNetIO.__init__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiNetIO (Constructor)</h3>
|
||||
<b>RevPiNetIO</b>(<i>address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None</i>)
|
||||
<b>RevPiNetIO</b>(<i>address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
|
||||
<p>
|
||||
Instantiiert die Grundfunktionen.
|
||||
</p><dl>
|
||||
@@ -448,6 +448,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="RevPiNetIO._create_myfh" ID="RevPiNetIO._create_myfh"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
@@ -539,7 +542,7 @@ Static Methods</h3>
|
||||
<a NAME="RevPiNetIODriver.__init__" ID="RevPiNetIODriver.__init__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiNetIODriver (Constructor)</h3>
|
||||
<b>RevPiNetIODriver</b>(<i>address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None</i>)
|
||||
<b>RevPiNetIODriver</b>(<i>address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None, direct_output=False</i>)
|
||||
<p>
|
||||
Instantiiert die Grundfunktionen.
|
||||
</p><p>
|
||||
@@ -602,7 +605,7 @@ Static Methods</h3>
|
||||
<a NAME="RevPiNetIOSelected.__init__" ID="RevPiNetIOSelected.__init__"></a>
|
||||
<h3 style="background-color:#FFFFFF;color:#FF0000">
|
||||
RevPiNetIOSelected (Constructor)</h3>
|
||||
<b>RevPiNetIOSelected</b>(<i>address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None</i>)
|
||||
<b>RevPiNetIOSelected</b>(<i>address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False</i>)
|
||||
<p>
|
||||
Instantiiert nur fuer angegebene Devices die Grundfunktionen.
|
||||
</p><p>
|
||||
|
||||
@@ -154,6 +154,7 @@ revpimodio2.modio.RevPiModIO._get_simulator?5()
|
||||
revpimodio2.modio.RevPiModIO._gotioerror?5(action, e=None)
|
||||
revpimodio2.modio.RevPiModIO._set_cycletime?5(milliseconds)
|
||||
revpimodio2.modio.RevPiModIO._set_maxioerrors?5(value)
|
||||
revpimodio2.modio.RevPiModIO._simulate_ioctl?5(request, arg=b'')
|
||||
revpimodio2.modio.RevPiModIO.autorefresh_all?4()
|
||||
revpimodio2.modio.RevPiModIO.cleanup?4()
|
||||
revpimodio2.modio.RevPiModIO.configrsc?7
|
||||
@@ -204,9 +205,9 @@ revpimodio2.netio.RevPiNetIO.disconnect?4()
|
||||
revpimodio2.netio.RevPiNetIO.get_jconfigrsc?4()
|
||||
revpimodio2.netio.RevPiNetIO.net_cleardefaultvalues?4(device=None)
|
||||
revpimodio2.netio.RevPiNetIO.net_setdefaultvalues?4(device=None)
|
||||
revpimodio2.netio.RevPiNetIO?1(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None)
|
||||
revpimodio2.netio.RevPiNetIODriver?1(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None)
|
||||
revpimodio2.netio.RevPiNetIOSelected?1(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None)
|
||||
revpimodio2.netio.RevPiNetIO?1(address, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False)
|
||||
revpimodio2.netio.RevPiNetIODriver?1(address, virtdev, autorefresh=False, monitoring=False, syncoutputs=True, debug=False, replace_io_file=None, direct_output=False)
|
||||
revpimodio2.netio.RevPiNetIOSelected?1(address, deviceselection, autorefresh=False, monitoring=False, syncoutputs=True, simulator=False, debug=False, replace_io_file=None, direct_output=False)
|
||||
revpimodio2.netio._sysdeldirty?8
|
||||
revpimodio2.netio._sysexit?8
|
||||
revpimodio2.netio._sysflush?8
|
||||
|
||||
@@ -5,11 +5,9 @@ __copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||
__license__ = "LGPLv3"
|
||||
|
||||
import struct
|
||||
import warnings
|
||||
from re import match as rematch
|
||||
from threading import Event
|
||||
from revpimodio2 import RISING, FALLING, BOTH, INP, MEM, consttostr
|
||||
from .netio import RevPiNetIO
|
||||
try:
|
||||
# Funktioniert nur auf Unix
|
||||
from fcntl import ioctl
|
||||
@@ -536,21 +534,8 @@ class IOBase(object):
|
||||
|
||||
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:
|
||||
if self._parentdevice._modio._run_on_pi:
|
||||
# IOCTL auf dem RevPi
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
@@ -564,6 +549,31 @@ class IOBase(object):
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("ioset", e)
|
||||
|
||||
elif hasattr(self._parentdevice._modio._myfh, "ioctl"):
|
||||
# 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_ioset", e)
|
||||
|
||||
else:
|
||||
# IOCTL in Datei simulieren
|
||||
try:
|
||||
# Set value durchführen (Funktion K+16)
|
||||
self._parentdevice._modio._simulate_ioctl(
|
||||
19216,
|
||||
self.__bit_ioctl_on if value
|
||||
else self.__bit_ioctl_off
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("file_ioset", e)
|
||||
|
||||
else:
|
||||
# Gepuffertes Schreiben der Outputs
|
||||
|
||||
@@ -901,24 +911,7 @@ class IntIOCounter(IntIO):
|
||||
"can not reset counter, while system is in simulator mode"
|
||||
)
|
||||
|
||||
if isinstance(self._parentdevice._modio, RevPiNetIO):
|
||||
# IOCTL über Netzwerk
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
self._parentdevice._modio._myfh.ioctl(
|
||||
19220, self.__ioctl_arg
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("net_ioctl", e)
|
||||
|
||||
elif self._parentdevice._modio._procimg != "/dev/piControl0":
|
||||
# NOTE: Soll hier eine 0 in den Input geschrieben werden?
|
||||
warnings.warn(
|
||||
"this will work on a revolution pi only",
|
||||
RuntimeWarning
|
||||
)
|
||||
|
||||
else:
|
||||
if self._parentdevice._modio._run_on_pi:
|
||||
# IOCTL auf dem RevPi
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
@@ -928,7 +921,27 @@ class IntIOCounter(IntIO):
|
||||
19220, self.__ioctl_arg
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("ioctl", e)
|
||||
self._parentdevice._modio._gotioerror("iorst", e)
|
||||
|
||||
elif hasattr(self._parentdevice._modio._myfh, "ioctl"):
|
||||
# IOCTL über Netzwerk
|
||||
with self._parentdevice._modio._myfh_lck:
|
||||
try:
|
||||
self._parentdevice._modio._myfh.ioctl(
|
||||
19220, self.__ioctl_arg
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("net_iorst", e)
|
||||
|
||||
else:
|
||||
# IOCTL in Datei simulieren
|
||||
try:
|
||||
# Set value durchführen (Funktion K+20)
|
||||
self._parentdevice._modio._simulate_ioctl(
|
||||
19220, self.__ioctl_arg
|
||||
)
|
||||
except Exception as e:
|
||||
self._parentdevice._modio._gotioerror("file_iorst", e)
|
||||
|
||||
|
||||
class IntIOReplaceable(IntIO):
|
||||
|
||||
@@ -9,9 +9,11 @@ from configparser import ConfigParser
|
||||
from json import load as jload
|
||||
from multiprocessing import cpu_count
|
||||
from os import access, F_OK, R_OK
|
||||
from os import stat as osstat
|
||||
from queue import Empty
|
||||
from revpimodio2 import acheck
|
||||
from signal import signal, SIG_DFL, SIGINT, SIGTERM
|
||||
from stat import S_ISCHR
|
||||
from threading import Thread, Event, Lock
|
||||
from timeit import default_timer
|
||||
|
||||
@@ -35,7 +37,7 @@ class RevPiModIO(object):
|
||||
"_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \
|
||||
"_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \
|
||||
"core", "app", "device", "exitsignal", "io", "summary", "_debug", \
|
||||
"_lck_replace_io", "_replace_io_file"
|
||||
"_lck_replace_io", "_replace_io_file", "_run_on_pi"
|
||||
|
||||
def __init__(
|
||||
self, autorefresh=False, monitoring=False, syncoutputs=True,
|
||||
@@ -106,12 +108,10 @@ 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"
|
||||
)
|
||||
try:
|
||||
self._run_on_pi = S_ISCHR(osstat(self._procimg).st_mode)
|
||||
except Exception:
|
||||
self._run_on_pi = False
|
||||
|
||||
# Nur Konfigurieren, wenn nicht vererbt
|
||||
if type(self) == RevPiModIO:
|
||||
@@ -471,6 +471,57 @@ class RevPiModIO(object):
|
||||
else:
|
||||
raise ValueError("value must be 0 or a positive integer")
|
||||
|
||||
def _simulate_ioctl(self, request, arg=b''):
|
||||
"""Simuliert IOCTL Funktionen auf procimg Datei.
|
||||
@param request IO Request
|
||||
@param arg: Request argument"""
|
||||
if request == 19216:
|
||||
# Einzelnes Bit setzen
|
||||
byte_address = int.from_bytes(arg[:2], byteorder="little")
|
||||
bit_address = arg[2]
|
||||
new_value = bool(0 if len(arg) <= 3 else arg[3])
|
||||
|
||||
# Simulatonsmodus schreibt direkt in Datei
|
||||
with self._myfh_lck:
|
||||
self._myfh.seek(byte_address)
|
||||
int_byte = int.from_bytes(
|
||||
self._myfh.read(1), byteorder="little"
|
||||
)
|
||||
int_bit = 1 << bit_address
|
||||
|
||||
if not bool(int_byte & int_bit) == new_value:
|
||||
if new_value:
|
||||
int_byte += int_bit
|
||||
else:
|
||||
int_byte -= int_bit
|
||||
|
||||
self._myfh.seek(byte_address)
|
||||
self._myfh.write(int_byte.to_bytes(1, byteorder="little"))
|
||||
if self._buffedwrite:
|
||||
self._myfh.flush()
|
||||
|
||||
elif request == 19220:
|
||||
# FIXME: Implement
|
||||
# Counterwert auf 0 setzen
|
||||
dev_position = arg[0]
|
||||
bit_field = int.from_bytes(arg[2:], byteorder="little")
|
||||
io_byte = -1
|
||||
|
||||
for i in range(16):
|
||||
if bool(bit_field & 1 << i):
|
||||
io_byte = self.device[dev_position].offset \
|
||||
+ int(self.device[dev_position]._lst_counter[i])
|
||||
break
|
||||
|
||||
if io_byte == -1:
|
||||
raise RuntimeError("count not reset counter io in file")
|
||||
|
||||
with self._myfh_lck:
|
||||
self._myfh.seek(io_byte)
|
||||
self._myfh.write(b'\x00\x00\x00\x00')
|
||||
if self._buffedwrite:
|
||||
self._myfh.flush()
|
||||
|
||||
def autorefresh_all(self):
|
||||
"""Setzt alle Devices in autorefresh Funktion."""
|
||||
for dev in self.device:
|
||||
@@ -951,7 +1002,6 @@ class RevPiModIO(object):
|
||||
|
||||
"""
|
||||
if self._direct_output:
|
||||
# TODO: Wie soll das bei direct_output umgesetzt werden?
|
||||
return True
|
||||
|
||||
if self._monitoring:
|
||||
|
||||
@@ -490,7 +490,7 @@ class RevPiNetIO(_RevPiModIO):
|
||||
def __init__(
|
||||
self, address, autorefresh=False, monitoring=False,
|
||||
syncoutputs=True, simulator=False, debug=False,
|
||||
replace_io_file=None):
|
||||
replace_io_file=None, direct_output=False):
|
||||
"""Instantiiert die Grundfunktionen.
|
||||
|
||||
@param address: IP-Adresse <class 'str'> / (IP, Port) <class 'tuple'>
|
||||
@@ -500,6 +500,7 @@ class RevPiNetIO(_RevPiModIO):
|
||||
@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)
|
||||
|
||||
"""
|
||||
check_ip = compile(
|
||||
@@ -549,7 +550,8 @@ class RevPiNetIO(_RevPiModIO):
|
||||
None,
|
||||
simulator,
|
||||
debug,
|
||||
replace_io_file
|
||||
replace_io_file,
|
||||
direct_output
|
||||
)
|
||||
|
||||
# Netzwerkfilehandler anlegen
|
||||
@@ -661,7 +663,7 @@ class RevPiNetIOSelected(RevPiNetIO):
|
||||
def __init__(
|
||||
self, address, deviceselection, autorefresh=False,
|
||||
monitoring=False, syncoutputs=True, simulator=False, debug=False,
|
||||
replace_io_file=None):
|
||||
replace_io_file=None, direct_output=False):
|
||||
"""Instantiiert nur fuer angegebene Devices die Grundfunktionen.
|
||||
|
||||
Der Parameter deviceselection kann eine einzelne
|
||||
@@ -675,7 +677,7 @@ class RevPiNetIOSelected(RevPiNetIO):
|
||||
"""
|
||||
super().__init__(
|
||||
address, autorefresh, monitoring, syncoutputs, simulator, debug,
|
||||
replace_io_file
|
||||
replace_io_file, direct_output
|
||||
)
|
||||
|
||||
# Device liste erstellen
|
||||
@@ -729,7 +731,8 @@ class RevPiNetIODriver(RevPiNetIOSelected):
|
||||
|
||||
def __init__(
|
||||
self, address, virtdev, autorefresh=False, monitoring=False,
|
||||
syncoutputs=True, debug=False, replace_io_file=None):
|
||||
syncoutputs=True, debug=False, replace_io_file=None,
|
||||
direct_output=False):
|
||||
"""Instantiiert die Grundfunktionen.
|
||||
|
||||
Parameter 'monitoring' und 'simulator' stehen hier nicht zur
|
||||
@@ -743,5 +746,5 @@ class RevPiNetIODriver(RevPiNetIOSelected):
|
||||
# Parent mit monitoring=False und simulator=True laden
|
||||
super().__init__(
|
||||
address, virtdev, autorefresh, False, syncoutputs, True, debug,
|
||||
replace_io_file
|
||||
replace_io_file, direct_output
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user