Parameter shared_procimg can be set per device

The shared_procimg Parameter is still a global parameter, but can now be set
per device as well with .shared_procimg(...) of all devices.
This commit is contained in:
2020-12-16 18:46:45 +01:00
parent 6beb05577e
commit dc731afafd
6 changed files with 41 additions and 26 deletions

View File

@@ -125,10 +125,11 @@ class Device(object):
""" """
__slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \ __slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \
"_dict_events", "_filelock", "_length", "_modio", "_name", "_offset", \ "_dict_events", "_filelock", "_length", "_modio", "_name", \
"_position", "_producttype", "_selfupdate", "_slc_devoff", \ "_offset", "_position", "_producttype", "_selfupdate", \
"_slc_inp", "_slc_inpoff", "_slc_mem", "_slc_memoff", \ "_slc_devoff", "_slc_inp", "_slc_inpoff", "_slc_mem", \
"_slc_out", "_slc_outoff", "bmk", "catalognr", "comment", "extend", \ "_slc_memoff", "_slc_out", "_slc_outoff", "_shared_procimg", \
"bmk", "catalognr", "comment", "extend", \
"guid", "id", "inpvariant", "outvariant", "type" "guid", "id", "inpvariant", "outvariant", "type"
def __init__(self, parentmodio, dict_device, simulator=False): def __init__(self, parentmodio, dict_device, simulator=False):
@@ -146,6 +147,7 @@ class Device(object):
self._length = 0 self._length = 0
self.__my_io_list = [] self.__my_io_list = []
self._selfupdate = False self._selfupdate = False
self._shared_procimg = parentmodio._shared_procimg
# Wertzuweisung aus dict_device # Wertzuweisung aus dict_device
self._name = dict_device.get("name") self._name = dict_device.get("name")
@@ -500,6 +502,17 @@ class Device(object):
""" """
self._modio.setdefaultvalues(self) self._modio.setdefaultvalues(self)
def shared_procimg(self, activate: bool) -> None:
"""
Activate sharing of process image just for this device.
WARNING: All outputs will set immediately in process image on value
change. That is also inside the cycle loop!
:param activate: Set True to activate process image sharing
"""
self._shared_procimg = True if activate else False
def syncoutputs(self) -> bool: def syncoutputs(self) -> bool:
""" """
Lesen aller Outputs im Prozessabbild fuer dieses Device. Lesen aller Outputs im Prozessabbild fuer dieses Device.

View File

@@ -464,6 +464,7 @@ class ProcimgWriter(Thread):
tup_fireth[0].func, tup_fireth[1], tup_fireth[2] tup_fireth[0].func, tup_fireth[1], tup_fireth[2]
) )
th.start() th.start()
self._eventqth.task_done()
except queue.Empty: except queue.Empty:
pass pass
@@ -533,20 +534,18 @@ class ProcimgWriter(Thread):
fh.seek(0) fh.seek(0)
fh.readinto(bytesbuff) fh.readinto(bytesbuff)
if self._modio._monitoring or self._modio._direct_output: for dev in self._modio._lst_refresh:
# Inputs und Outputs in Puffer with dev._filelock:
for dev in self._modio._lst_refresh: if self._modio._monitoring or dev._shared_procimg:
with dev._filelock: # Inputs und Outputs in Puffer
dev._ba_devdata[:] = bytesbuff[dev._slc_devoff] dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
if self.__eventwork \ if self.__eventwork \
and len(dev._dict_events) > 0 \ and len(dev._dict_events) > 0 \
and dev._ba_datacp != dev._ba_devdata: and dev._ba_datacp != dev._ba_devdata:
self.__check_change(dev) self.__check_change(dev)
else: else:
# Inputs in Puffer, Outputs in Prozessabbild # Inputs in Puffer, Outputs in Prozessabbild
for dev in self._modio._lst_refresh:
with dev._filelock:
dev._ba_devdata[dev._slc_inp] = \ dev._ba_devdata[dev._slc_inp] = \
bytesbuff[dev._slc_inpoff] bytesbuff[dev._slc_inpoff]
if self.__eventwork \ if self.__eventwork \
@@ -557,8 +556,8 @@ class ProcimgWriter(Thread):
fh.seek(dev._slc_outoff.start) fh.seek(dev._slc_outoff.start)
fh.write(dev._ba_devdata[dev._slc_out]) fh.write(dev._ba_devdata[dev._slc_out])
if self._modio._buffedwrite: if self._modio._buffedwrite:
fh.flush() fh.flush()
except IOError as e: except IOError as e:
self._modio._gotioerror("autorefresh", e, mrk_warn) self._modio._gotioerror("autorefresh", e, mrk_warn)

View File

@@ -614,7 +614,7 @@ class IOBase(object):
# Versuchen egal welchen Typ in Bool zu konvertieren # Versuchen egal welchen Typ in Bool zu konvertieren
value = bool(value) value = bool(value)
if self._parentdevice._modio._direct_output: if self._parentdevice._shared_procimg:
# Direktes Schreiben der Outputs # Direktes Schreiben der Outputs
if self._parentdevice._modio._run_on_pi: if self._parentdevice._modio._run_on_pi:
@@ -694,7 +694,7 @@ class IOBase(object):
) )
) )
if self._parentdevice._modio._direct_output: if self._parentdevice._shared_procimg:
with self._parentdevice._modio._myfh_lck: with self._parentdevice._modio._myfh_lck:
try: try:
self._parentdevice._modio._myfh.seek( self._parentdevice._modio._myfh.seek(

View File

@@ -32,7 +32,7 @@ class RevPiModIO(object):
""" """
__slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", "_exit_level", \ __slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", "_exit_level", \
"_configrsc", "_direct_output", "_exit", "_imgwriter", "_ioerror", \ "_configrsc", "_shared_procimg", "_exit", "_imgwriter", "_ioerror", \
"_length", "_looprunning", "_lst_devselect", "_lst_refresh", \ "_length", "_looprunning", "_lst_devselect", "_lst_refresh", \
"_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \ "_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \
"_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \ "_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \
@@ -76,10 +76,10 @@ class RevPiModIO(object):
self._autorefresh = autorefresh self._autorefresh = autorefresh
self._configrsc = configrsc self._configrsc = configrsc
self._direct_output = shared_procimg or direct_output
self._monitoring = monitoring self._monitoring = monitoring
self._procimg = "/dev/piControl0" if procimg is None else procimg self._procimg = "/dev/piControl0" if procimg is None else procimg
self._simulator = simulator self._simulator = simulator
self._shared_procimg = shared_procimg or direct_output
self._syncoutputs = syncoutputs self._syncoutputs = syncoutputs
# TODO: bei simulator und procimg prüfen ob datei existiert / anlegen? # TODO: bei simulator und procimg prüfen ob datei existiert / anlegen?
@@ -1036,6 +1036,7 @@ class RevPiModIO(object):
# Direct callen da Prüfung in io.IOBase.reg_event ist # Direct callen da Prüfung in io.IOBase.reg_event ist
tup_fire[0].func(tup_fire[1], tup_fire[2]) tup_fire[0].func(tup_fire[1], tup_fire[2])
self._imgwriter._eventq.task_done()
# Laufzeitprüfung # Laufzeitprüfung
if runtime != -1 and \ if runtime != -1 and \
@@ -1107,7 +1108,7 @@ class RevPiModIO(object):
# FileHandler sperren # FileHandler sperren
dev._filelock.acquire() dev._filelock.acquire()
if self._monitoring or self._direct_output: if self._monitoring or dev._shared_procimg:
# Alles vom Bus einlesen # Alles vom Bus einlesen
dev._ba_devdata[:] = bytesbuff[dev._slc_devoff] dev._ba_devdata[:] = bytesbuff[dev._slc_devoff]
else: else:
@@ -1194,9 +1195,6 @@ class RevPiModIO(object):
:param device: nur auf einzelnes Device anwenden :param device: nur auf einzelnes Device anwenden
:return: True, wenn Arbeiten an allen Devices erfolgreich waren :return: True, wenn Arbeiten an allen Devices erfolgreich waren
""" """
if self._direct_output:
return True
if self._monitoring: if self._monitoring:
raise RuntimeError( raise RuntimeError(
"can not write process image, while system is in monitoring " "can not write process image, while system is in monitoring "
@@ -1219,7 +1217,9 @@ class RevPiModIO(object):
global_ex = None global_ex = None
workokay = True workokay = True
for dev in mylist: for dev in mylist:
if not dev._selfupdate: if dev._shared_procimg:
continue
elif not dev._selfupdate:
dev._filelock.acquire() dev._filelock.acquire()
# Outpus auf Bus schreiben # Outpus auf Bus schreiben

View File

@@ -337,6 +337,9 @@ class NetFH(Thread):
if self.__sockend.is_set(): if self.__sockend.is_set():
raise ValueError("flush of closed file") raise ValueError("flush of closed file")
if self.__int_buff == 0:
return
try: try:
# b CM ii ii 00000000 b = 16 # b CM ii ii 00000000 b = 16
buff = self._direct_sr(pack( buff = self._direct_sr(pack(
@@ -659,7 +662,7 @@ class NetFH(Thread):
with self.__socklock: with self.__socklock:
self.__int_buff += 1 self.__int_buff += 1
# Datenblöcke mit Group Seperator in Puffer ablegen # Datenblock mit Position und Länge 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
@@ -707,7 +710,7 @@ class RevPiNetIO(_RevPiModIO):
:param direct_output: Deprecated, use shared_procimg :param direct_output: Deprecated, use shared_procimg
""" """
check_ip = compile( check_ip = compile(
r"^(?P<ipn>(25[0-5]|(2[0-4]|[01]?\d|)\d))(\.(?P=ipn)){3}$" r"^(25[0-5]|(2[0-4]|[01]?\d|)\d)(\.(25[0-5]|(2[0-4]|[01]?\d|)\d)){3}$"
) )
# Adresse verarbeiten # Adresse verarbeiten

View File

@@ -17,7 +17,7 @@ setup(
license="LGPLv3", license="LGPLv3",
name="revpimodio2", name="revpimodio2",
version="2.5.3f", version="2.5.3g",
packages=["revpimodio2"], packages=["revpimodio2"],
python_requires="~=3.2", python_requires="~=3.2",