From af15bd36cd71bb8f04674ea1ce2d289520167ff5 Mon Sep 17 00:00:00 2001 From: Sven Sager Date: Mon, 3 May 2021 09:56:12 +0200 Subject: [PATCH] Internal change RevPi*IOSelected search method Internal device search is more flexible to expand the search functions of RevPi*IOSelected in the future. There are no changes in usage. --- revpimodio2/modio.py | 102 ++++++++++++++++++++++------------------- revpimodio2/netio.py | 45 ++++++++++-------- revpimodio2/pictory.py | 10 +++- 3 files changed, 91 insertions(+), 66 deletions(-) diff --git a/revpimodio2/modio.py b/revpimodio2/modio.py index c3a9d54..050834c 100644 --- a/revpimodio2/modio.py +++ b/revpimodio2/modio.py @@ -1,6 +1,11 @@ # -*- coding: utf-8 -*- """RevPiModIO Hauptklasse fuer piControl0 Zugriff.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2020 Sven Sager" +__license__ = "LGPLv3" + import warnings +from collections import namedtuple from configparser import ConfigParser from json import load as jload from multiprocessing import cpu_count @@ -13,12 +18,10 @@ from threading import Event, Lock, Thread from timeit import default_timer from revpimodio2 import BOTH, DeviceNotFoundError, FALLING, RISING, acheck +from .pictory import DeviceType, ProductType -__author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" - -from .pictory import ProductType +DevSelect = namedtuple("DevSelect", ["type", "key", "values"]) +"""Leave type, key empty for auto search name and position depending on type in values.""" class RevPiModIO(object): @@ -35,7 +38,7 @@ class RevPiModIO(object): __slots__ = "__cleanupfunc", "_autorefresh", "_buffedwrite", "_exit_level", \ "_configrsc", "_shared_procimg", "_exit", "_imgwriter", "_ioerror", \ - "_length", "_looprunning", "_lst_devselect", "_lst_refresh", \ + "_length", "_looprunning", "_devselect", "_lst_refresh", \ "_maxioerrors", "_myfh", "_myfh_lck", "_monitoring", "_procimg", \ "_simulator", "_syncoutputs", "_th_mainloop", "_waitexit", \ "core", "app", "device", "exitsignal", "io", "summary", "_debug", \ @@ -90,13 +93,13 @@ class RevPiModIO(object): self.__cleanupfunc = None self._buffedwrite = False self._debug = 1 + self._devselect = DevSelect("", "", ()) self._exit = Event() self._exit_level = 0 self._imgwriter = None self._ioerror = 0 self._length = 0 self._looprunning = False - self._lst_devselect = [] self._lst_refresh = [] self._maxioerrors = 0 self._myfh = None @@ -196,27 +199,24 @@ class RevPiModIO(object): # App Klasse instantiieren self.app = appmodule.App(jconfigrsc["App"]) - # Devicefilter anwenden - if len(self._lst_devselect) > 0: - lst_found = [] - - if type(self) == RevPiModIODriver \ - or type(self) == RevPiNetIODriver: - _searchtype = "VIRTUAL" - else: - _searchtype = None - - # Angegebene Devices suchen + # Apply device filter + if self._devselect.values: + lst_devices = [] for dev in jconfigrsc["Devices"]: - if _searchtype is None or dev["type"] == _searchtype: - if dev["name"] in self._lst_devselect: - lst_found.append(dev) - elif dev["position"].isdigit() \ - and int(dev["position"]) in self._lst_devselect: - lst_found.append(dev) + if self._devselect.type and self._devselect.type != dev["type"]: + continue + if self._devselect.key: + if str(dev[self._devselect.key]) not in self._devselect.values: + # The list is always filled with + continue + else: + # Auto search depending of value item type + if dev["name"] not in self._devselect.values \ + and not (dev["position"].isdigit() + and int(dev["position"]) in self._devselect.values): + continue - # Devices Filter übernehmen - lst_devices = lst_found + lst_devices.append(dev) else: # Devices aus JSON übernehmen lst_devices = jconfigrsc["Devices"] @@ -235,7 +235,7 @@ class RevPiModIO(object): while device["position"] in self.device: device["position"] += 1 - if device["type"] == "BASE": + if device["type"] == DeviceType.BASE: # Basedevices pt = int(device["productType"]) if pt == ProductType.REVPI_CORE: @@ -267,7 +267,7 @@ class RevPiModIO(object): dev_new = devicemodule.Base( self, device, simulator=self._simulator ) - elif device["type"] == "LEFT_RIGHT": + elif device["type"] == DeviceType.LEFT_RIGHT: # IOs pt = int(device["productType"]) if pt == ProductType.DIO or pt == ProductType.DI or pt == ProductType.DO: @@ -280,17 +280,17 @@ class RevPiModIO(object): dev_new = devicemodule.Device( self, device, simulator=self._simulator ) - elif device["type"] == "VIRTUAL": + elif device["type"] == DeviceType.VIRTUAL: # Virtuals dev_new = devicemodule.Virtual( self, device, simulator=self._simulator ) - elif device["type"] == "EDGE": + elif device["type"] == DeviceType.EDGE: # Gateways dev_new = devicemodule.Gateway( self, device, simulator=self._simulator ) - elif device["type"] == "RIGHT": + elif device["type"] == DeviceType.RIGHT: # Connectdevice dev_new = None else: @@ -434,7 +434,7 @@ class RevPiModIO(object): self.io[parentio].replace_io(name=io, **dict_replace) except Exception as e: # NOTE: Bei Selected/Driver kann nicht geprüft werden - if len(self._lst_devselect) == 0: + if len(self._devselect.values) == 0: raise RuntimeError( "replace_io_file: can not replace '{0}' with '{1}' " "| RevPiModIO message: {2}".format(parentio, io, e) @@ -1312,19 +1312,27 @@ class RevPiModIOSelected(RevPiModIO): simulator, debug, replace_io_file, shared_procimg, direct_output ) - # Device liste erstellen - if type(deviceselection) == list: - for dev in deviceselection: - self._lst_devselect.append(dev) - else: - self._lst_devselect.append(deviceselection) + if type(deviceselection) is not DevSelect: + # Convert to tuple + if type(deviceselection) in (int, str): + deviceselection = (deviceselection,) - for vdev in self._lst_devselect: - if type(vdev) != int and type(vdev) != str: - raise ValueError( - "need device position as or device name as " - "" - ) + # Check supported types + for dev in deviceselection: + if type(dev) not in (int, str): + raise ValueError( + "need device position as or " + "device name as " + ) + + # Automatic search for name and position depends on type int / str + self._devselect = DevSelect( + "VIRTUAL" if type(self) is RevPiModIODriver else "", "", + tuple(deviceselection), + ) + + else: + self._devselect = deviceselection self._configure(self.get_jconfigrsc()) self._configure_replace_io(self._get_cpreplaceio()) @@ -1338,7 +1346,8 @@ class RevPiModIOSelected(RevPiModIO): raise DeviceNotFoundError( "could not find any given devices in config" ) - elif len(self.device) != len(self._lst_devselect): + elif not self._devselect.key \ + and len(self.device) != len(self._devselect.values): if type(self) == RevPiModIODriver: raise DeviceNotFoundError( "could not find all given VIRTUAL devices in config" @@ -1424,5 +1433,4 @@ from . import helper as helpermodule from . import summary as summarymodule from .io import IOList from .io import StructIO - -from .netio import RevPiNetIODriver, RevPiNetIO +from .netio import RevPiNetIO diff --git a/revpimodio2/netio.py b/revpimodio2/netio.py index 60e9dfd..d088463 100644 --- a/revpimodio2/netio.py +++ b/revpimodio2/netio.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- """RevPiModIO Hauptklasse fuer Netzwerkzugriff.""" +__author__ = "Sven Sager" +__copyright__ = "Copyright (C) 2020 Sven Sager" +__license__ = "LGPLv3" + import socket import warnings from configparser import ConfigParser @@ -10,11 +14,7 @@ from threading import Event, Lock, Thread from revpimodio2 import DeviceNotFoundError from .device import Device -from .modio import RevPiModIO as _RevPiModIO - -__author__ = "Sven Sager" -__copyright__ = "Copyright (C) 2020 Sven Sager" -__license__ = "LGPLv3" +from .modio import DevSelect, RevPiModIO as _RevPiModIO # Synchronisierungsbefehl _syssync = b'\x01\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17' @@ -959,19 +959,27 @@ class RevPiNetIOSelected(RevPiNetIO): replace_io_file, shared_procimg, direct_output ) - # Device liste erstellen - if type(deviceselection) == list: - for dev in deviceselection: - self._lst_devselect.append(dev) - else: - self._lst_devselect.append(deviceselection) + if type(deviceselection) is not DevSelect: + # Convert to tuple + if type(deviceselection) in (int, str): + deviceselection = (deviceselection,) - for vdev in self._lst_devselect: - if type(vdev) != int and type(vdev) != str: - raise TypeError( - "need device position as or device name as " - "" - ) + # Check supported types + for dev in deviceselection: + if type(dev) not in (int, str): + raise ValueError( + "need device position as or " + "device name as " + ) + + # Automatic search for name and position depends on type int / str + self._devselect = DevSelect( + "VIRTUAL" if type(self) is RevPiNetIODriver else "", "", + tuple(deviceselection), + ) + + else: + self._devselect = deviceselection self._configure(self.get_jconfigrsc()) self._configure_replace_io(self._get_cpreplaceio()) @@ -985,7 +993,8 @@ class RevPiNetIOSelected(RevPiNetIO): raise DeviceNotFoundError( "could not find any given devices in config" ) - elif len(self.device) != len(self._lst_devselect): + elif not self._devselect.key \ + and len(self.device) != len(self._devselect.values): if type(self) == RevPiNetIODriver: raise DeviceNotFoundError( "could not find all given VIRTUAL devices in config" diff --git a/revpimodio2/pictory.py b/revpimodio2/pictory.py index 466d0a9..03dfcdb 100644 --- a/revpimodio2/pictory.py +++ b/revpimodio2/pictory.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- """Pictory aliases for IO values.""" - __author__ = "Théo Rozier" __copyright__ = "Copyright (C) 2020 Sven Sager" __license__ = "LGPLv3" @@ -46,6 +45,15 @@ class ProductType: REVPI_FLAT = 135 +class DeviceType: + """Module key "type" in piCtory file.""" + BASE = "BASE" # Core devices + EDGE = "EDGE" # Gateways + LEFT_RIGHT = "LEFT_RIGHT" # IOs + RIGHT = "RIGHT" # Connect device + VIRTUAL = "VIRTUAL" # All virtual devices + + class AIO: """Memory value mappings for RevPi AIO 1.0 (RevPiAIO_20170301_1_0.rap).""" OUT_RANGE_OFF = 0 # Off