From dc731afafdf727ca98be382eb61c51094001ee36 Mon Sep 17 00:00:00 2001 From: Sven Sager Date: Wed, 16 Dec 2020 18:46:45 +0100 Subject: [PATCH] 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. --- revpimodio2/device.py | 21 +++++++++++++++++---- revpimodio2/helper.py | 19 +++++++++---------- revpimodio2/io.py | 4 ++-- revpimodio2/modio.py | 14 +++++++------- revpimodio2/netio.py | 7 +++++-- setup.py | 2 +- 6 files changed, 41 insertions(+), 26 deletions(-) diff --git a/revpimodio2/device.py b/revpimodio2/device.py index 3608889..bc4898a 100644 --- a/revpimodio2/device.py +++ b/revpimodio2/device.py @@ -125,10 +125,11 @@ class Device(object): """ __slots__ = "__my_io_list", "_ba_devdata", "_ba_datacp", \ - "_dict_events", "_filelock", "_length", "_modio", "_name", "_offset", \ - "_position", "_producttype", "_selfupdate", "_slc_devoff", \ - "_slc_inp", "_slc_inpoff", "_slc_mem", "_slc_memoff", \ - "_slc_out", "_slc_outoff", "bmk", "catalognr", "comment", "extend", \ + "_dict_events", "_filelock", "_length", "_modio", "_name", \ + "_offset", "_position", "_producttype", "_selfupdate", \ + "_slc_devoff", "_slc_inp", "_slc_inpoff", "_slc_mem", \ + "_slc_memoff", "_slc_out", "_slc_outoff", "_shared_procimg", \ + "bmk", "catalognr", "comment", "extend", \ "guid", "id", "inpvariant", "outvariant", "type" def __init__(self, parentmodio, dict_device, simulator=False): @@ -146,6 +147,7 @@ class Device(object): self._length = 0 self.__my_io_list = [] self._selfupdate = False + self._shared_procimg = parentmodio._shared_procimg # Wertzuweisung aus dict_device self._name = dict_device.get("name") @@ -500,6 +502,17 @@ class Device(object): """ 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: """ Lesen aller Outputs im Prozessabbild fuer dieses Device. diff --git a/revpimodio2/helper.py b/revpimodio2/helper.py index b256ff3..3a49896 100644 --- a/revpimodio2/helper.py +++ b/revpimodio2/helper.py @@ -464,6 +464,7 @@ class ProcimgWriter(Thread): tup_fireth[0].func, tup_fireth[1], tup_fireth[2] ) th.start() + self._eventqth.task_done() except queue.Empty: pass @@ -533,20 +534,18 @@ class ProcimgWriter(Thread): fh.seek(0) fh.readinto(bytesbuff) - if self._modio._monitoring or self._modio._direct_output: - # Inputs und Outputs in Puffer - for dev in self._modio._lst_refresh: - with dev._filelock: + for dev in self._modio._lst_refresh: + with dev._filelock: + if self._modio._monitoring or dev._shared_procimg: + # Inputs und Outputs in Puffer dev._ba_devdata[:] = bytesbuff[dev._slc_devoff] if self.__eventwork \ and len(dev._dict_events) > 0 \ and dev._ba_datacp != dev._ba_devdata: self.__check_change(dev) - else: - # Inputs in Puffer, Outputs in Prozessabbild - for dev in self._modio._lst_refresh: - with dev._filelock: + else: + # Inputs in Puffer, Outputs in Prozessabbild dev._ba_devdata[dev._slc_inp] = \ bytesbuff[dev._slc_inpoff] if self.__eventwork \ @@ -557,8 +556,8 @@ class ProcimgWriter(Thread): fh.seek(dev._slc_outoff.start) fh.write(dev._ba_devdata[dev._slc_out]) - if self._modio._buffedwrite: - fh.flush() + if self._modio._buffedwrite: + fh.flush() except IOError as e: self._modio._gotioerror("autorefresh", e, mrk_warn) diff --git a/revpimodio2/io.py b/revpimodio2/io.py index ec63c5c..4d03407 100644 --- a/revpimodio2/io.py +++ b/revpimodio2/io.py @@ -614,7 +614,7 @@ class IOBase(object): # Versuchen egal welchen Typ in Bool zu konvertieren value = bool(value) - if self._parentdevice._modio._direct_output: + if self._parentdevice._shared_procimg: # Direktes Schreiben der Outputs 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: try: self._parentdevice._modio._myfh.seek( diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index 31f93ba..b11c675 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -32,7 +32,7 @@ class RevPiModIO(object): """ __slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", "_exit_level", \ - "_configrsc", "_direct_output", "_exit", "_imgwriter", "_ioerror", \ + "_configrsc", "_shared_procimg", "_exit", "_imgwriter", "_ioerror", \ "_length", "_looprunning", "_lst_devselect", "_lst_refresh", \ "_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \ "_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \ @@ -76,10 +76,10 @@ class RevPiModIO(object): self._autorefresh = autorefresh self._configrsc = configrsc - self._direct_output = shared_procimg or direct_output self._monitoring = monitoring self._procimg = "/dev/piControl0" if procimg is None else procimg self._simulator = simulator + self._shared_procimg = shared_procimg or direct_output self._syncoutputs = syncoutputs # 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 tup_fire[0].func(tup_fire[1], tup_fire[2]) + self._imgwriter._eventq.task_done() # Laufzeitprüfung if runtime != -1 and \ @@ -1107,7 +1108,7 @@ class RevPiModIO(object): # FileHandler sperren dev._filelock.acquire() - if self._monitoring or self._direct_output: + if self._monitoring or dev._shared_procimg: # Alles vom Bus einlesen dev._ba_devdata[:] = bytesbuff[dev._slc_devoff] else: @@ -1194,9 +1195,6 @@ class RevPiModIO(object): :param device: nur auf einzelnes Device anwenden :return: True, wenn Arbeiten an allen Devices erfolgreich waren """ - if self._direct_output: - return True - if self._monitoring: raise RuntimeError( "can not write process image, while system is in monitoring " @@ -1219,7 +1217,9 @@ class RevPiModIO(object): global_ex = None workokay = True for dev in mylist: - if not dev._selfupdate: + if dev._shared_procimg: + continue + elif not dev._selfupdate: dev._filelock.acquire() # Outpus auf Bus schreiben diff --git a/revpimodio2/netio.py b/revpimodio2/netio.py index 4189ec5..8b8c913 100644 --- a/revpimodio2/netio.py +++ b/revpimodio2/netio.py @@ -337,6 +337,9 @@ class NetFH(Thread): if self.__sockend.is_set(): raise ValueError("flush of closed file") + if self.__int_buff == 0: + return + try: # b CM ii ii 00000000 b = 16 buff = self._direct_sr(pack( @@ -659,7 +662,7 @@ class NetFH(Thread): with self.__socklock: 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") + \ len(bytebuff).to_bytes(length=2, byteorder="little") + \ bytebuff @@ -707,7 +710,7 @@ class RevPiNetIO(_RevPiModIO): :param direct_output: Deprecated, use shared_procimg """ check_ip = compile( - r"^(?P(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 diff --git a/setup.py b/setup.py index 1b7c037..899d939 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ setup( license="LGPLv3", name="revpimodio2", - version="2.5.3f", + version="2.5.3g", packages=["revpimodio2"], python_requires="~=3.2",