mirror of
https://github.com/naruxde/revpimodio2.git
synced 2025-11-08 22:03:53 +01:00
Improved device search function and create run_net_plc shortcut
This commit is contained in:
@@ -15,7 +15,7 @@ fuehrt das Modul bei Datenaenderung aus.
|
|||||||
__all__ = [
|
__all__ = [
|
||||||
"IOEvent",
|
"IOEvent",
|
||||||
"RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected", "run_plc",
|
"RevPiModIO", "RevPiModIODriver", "RevPiModIOSelected", "run_plc",
|
||||||
"RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected",
|
"RevPiNetIO", "RevPiNetIODriver", "RevPiNetIOSelected", "run_net_plc",
|
||||||
"Cycletools", "EventCallback",
|
"Cycletools", "EventCallback",
|
||||||
"ProductType", "AIO", "COMPACT", "DI", "DO", "DIO", "FLAT", "MIO",
|
"ProductType", "AIO", "COMPACT", "DI", "DO", "DIO", "FLAT", "MIO",
|
||||||
]
|
]
|
||||||
@@ -29,5 +29,5 @@ from ._internal import *
|
|||||||
from .helper import Cycletools, EventCallback
|
from .helper import Cycletools, EventCallback
|
||||||
from .io import IOEvent
|
from .io import IOEvent
|
||||||
from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected, run_plc
|
from .modio import RevPiModIO, RevPiModIODriver, RevPiModIOSelected, run_plc
|
||||||
from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected
|
from .netio import RevPiNetIO, RevPiNetIODriver, RevPiNetIOSelected, run_net_plc
|
||||||
from .pictory import ProductType, AIO, COMPACT, DI, DO, DIO, FLAT, MIO
|
from .pictory import ProductType, AIO, COMPACT, DI, DO, DIO, FLAT, MIO
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ from .io import IOList
|
|||||||
from .io import StructIO
|
from .io import StructIO
|
||||||
from .pictory import DeviceType, ProductType
|
from .pictory import DeviceType, ProductType
|
||||||
|
|
||||||
DevSelect = namedtuple("DevSelect", ["type", "key", "values"])
|
DevSelect = namedtuple("DevSelect", ["type", "other_device_key", "values"])
|
||||||
"""Leave type, key empty for auto search name and position depending on type in values."""
|
"""Leave type, key empty for auto search name and position depending on type in values."""
|
||||||
|
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ class RevPiModIO(object):
|
|||||||
self.__cleanupfunc = None
|
self.__cleanupfunc = None
|
||||||
self._buffedwrite = False
|
self._buffedwrite = False
|
||||||
self._debug = 1
|
self._debug = 1
|
||||||
self._devselect = DevSelect("", "", ())
|
self._devselect = DevSelect(DeviceType.IGNORED, "", ())
|
||||||
self._exit = Event()
|
self._exit = Event()
|
||||||
self._exit_level = 0
|
self._exit_level = 0
|
||||||
self._imgwriter = None
|
self._imgwriter = None
|
||||||
@@ -212,19 +212,28 @@ class RevPiModIO(object):
|
|||||||
|
|
||||||
# Apply device filter
|
# Apply device filter
|
||||||
if self._devselect.values:
|
if self._devselect.values:
|
||||||
|
|
||||||
|
# Check for supported types in values
|
||||||
|
for dev in self._devselect.values:
|
||||||
|
if type(dev) not in (int, str):
|
||||||
|
raise ValueError(
|
||||||
|
"need device position as <class 'int'> or "
|
||||||
|
"device name as <class 'str'>"
|
||||||
|
)
|
||||||
|
|
||||||
lst_devices = []
|
lst_devices = []
|
||||||
for dev in jconfigrsc["Devices"]:
|
for dev in jconfigrsc["Devices"]:
|
||||||
if self._devselect.type and self._devselect.type != dev["type"]:
|
if self._devselect.type and self._devselect.type != dev["type"]:
|
||||||
continue
|
continue
|
||||||
if self._devselect.key:
|
if self._devselect.other_device_key:
|
||||||
if str(dev[self._devselect.key]) not in self._devselect.values:
|
key_value = str(dev[self._devselect.other_device_key])
|
||||||
|
if key_value not in self._devselect.values:
|
||||||
# The list is always filled with <class 'str'>
|
# The list is always filled with <class 'str'>
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
# Auto search depending of value item type
|
# Auto search depending of value item type
|
||||||
if dev["name"] not in self._devselect.values \
|
if not (dev["name"] in self._devselect.values
|
||||||
and not (dev["position"].isdigit()
|
or int(dev["position"]) in self._devselect.values):
|
||||||
and int(dev["position"]) in self._devselect.values):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
lst_devices.append(dev)
|
lst_devices.append(dev)
|
||||||
@@ -1326,7 +1335,7 @@ class RevPiModIOSelected(RevPiModIO):
|
|||||||
Klasse fuer die Verwaltung einzelner Devices aus piCtory.
|
Klasse fuer die Verwaltung einzelner Devices aus piCtory.
|
||||||
|
|
||||||
Diese Klasse uebernimmt nur angegebene Devices der piCtory Konfiguration
|
Diese Klasse uebernimmt nur angegebene Devices der piCtory Konfiguration
|
||||||
und laedt sie inkl. IOs. Sie uebernimmt die exklusive Verwaltung des
|
und bildet sie inkl. IOs ab. Sie uebernimmt die exklusive Verwaltung des
|
||||||
Adressbereichs im Prozessabbild an dem sich die angegebenen Devices
|
Adressbereichs im Prozessabbild an dem sich die angegebenen Devices
|
||||||
befinden und stellt sicher, dass die Daten synchron sind.
|
befinden und stellt sicher, dass die Daten synchron sind.
|
||||||
"""
|
"""
|
||||||
@@ -1355,22 +1364,11 @@ class RevPiModIOSelected(RevPiModIO):
|
|||||||
|
|
||||||
if type(deviceselection) is not DevSelect:
|
if type(deviceselection) is not DevSelect:
|
||||||
# Convert to tuple
|
# Convert to tuple
|
||||||
if type(deviceselection) in (int, str):
|
if type(deviceselection) not in (list, tuple):
|
||||||
deviceselection = (deviceselection,)
|
deviceselection = (deviceselection,)
|
||||||
|
|
||||||
# Check supported types
|
|
||||||
for dev in deviceselection:
|
|
||||||
if type(dev) not in (int, str):
|
|
||||||
raise ValueError(
|
|
||||||
"need device position as <class 'int'> or "
|
|
||||||
"device name as <class 'str'>"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Automatic search for name and position depends on type int / str
|
# Automatic search for name and position depends on type int / str
|
||||||
self._devselect = DevSelect(
|
self._devselect = DevSelect(DeviceType.IGNORED, "", deviceselection)
|
||||||
"VIRTUAL" if type(self) is RevPiModIODriver else "", "",
|
|
||||||
tuple(deviceselection),
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self._devselect = deviceselection
|
self._devselect = deviceselection
|
||||||
@@ -1378,23 +1376,25 @@ class RevPiModIOSelected(RevPiModIO):
|
|||||||
self._configure(self.get_jconfigrsc())
|
self._configure(self.get_jconfigrsc())
|
||||||
|
|
||||||
if len(self.device) == 0:
|
if len(self.device) == 0:
|
||||||
if type(self) == RevPiModIODriver:
|
if self._devselect.type:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find any given VIRTUAL devices in config"
|
"could not find ANY given {0} devices in config"
|
||||||
|
"".format(self._devselect.type)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find any given devices in config"
|
"could not find ANY given devices in config"
|
||||||
)
|
)
|
||||||
elif not self._devselect.key \
|
elif not self._devselect.other_device_key \
|
||||||
and len(self.device) != len(self._devselect.values):
|
and len(self.device) != len(self._devselect.values):
|
||||||
if type(self) == RevPiModIODriver:
|
if self._devselect.type:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find all given VIRTUAL devices in config"
|
"could not find ALL given {0} devices in config"
|
||||||
|
"".format(self._devselect.type)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find all given devices in config"
|
"could not find ALL given devices in config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1422,11 +1422,13 @@ class RevPiModIODriver(RevPiModIOSelected):
|
|||||||
|
|
||||||
:param virtdev: Virtuelles Device oder mehrere als <class 'list'>
|
:param virtdev: Virtuelles Device oder mehrere als <class 'list'>
|
||||||
:ref: :func:`RevPiModIO.__init__()`
|
:ref: :func:`RevPiModIO.__init__()`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Parent mit monitoring=False und simulator=True laden
|
# Parent mit monitoring=False und simulator=True laden
|
||||||
|
if type(virtdev) not in (list, tuple):
|
||||||
|
virtdev = (virtdev,)
|
||||||
|
dev_select = DevSelect(DeviceType.VIRTUAL, "", virtdev)
|
||||||
super().__init__(
|
super().__init__(
|
||||||
virtdev, autorefresh, False, syncoutputs, procimg, configrsc,
|
dev_select, autorefresh, False, syncoutputs, procimg, configrsc,
|
||||||
True, debug, replace_io_file, shared_procimg, direct_output
|
True, debug, replace_io_file, shared_procimg, direct_output
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ from threading import Event, Lock, Thread
|
|||||||
from .device import Device
|
from .device import Device
|
||||||
from .errors import DeviceNotFoundError
|
from .errors import DeviceNotFoundError
|
||||||
from .modio import DevSelect, RevPiModIO as _RevPiModIO
|
from .modio import DevSelect, RevPiModIO as _RevPiModIO
|
||||||
|
from .pictory import DeviceType
|
||||||
|
|
||||||
# Synchronisierungsbefehl
|
# Synchronisierungsbefehl
|
||||||
_syssync = b'\x01\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
|
_syssync = b'\x01\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17'
|
||||||
# Disconnectbefehl
|
# Disconnectbefehl
|
||||||
@@ -934,7 +936,7 @@ class RevPiNetIOSelected(RevPiNetIO):
|
|||||||
Klasse fuer die Verwaltung einzelner Devices aus piCtory.
|
Klasse fuer die Verwaltung einzelner Devices aus piCtory.
|
||||||
|
|
||||||
Diese Klasse uebernimmt nur angegebene Devices der piCtory Konfiguration
|
Diese Klasse uebernimmt nur angegebene Devices der piCtory Konfiguration
|
||||||
und bilded sie inkl. IOs ab. Sie uebernimmt die exklusive Verwaltung des
|
und bildet sie inkl. IOs ab. Sie uebernimmt die exklusive Verwaltung des
|
||||||
Adressbereichs im Prozessabbild an dem sich die angegebenen Devices
|
Adressbereichs im Prozessabbild an dem sich die angegebenen Devices
|
||||||
befinden und stellt sicher, dass die Daten synchron sind.
|
befinden und stellt sicher, dass die Daten synchron sind.
|
||||||
"""
|
"""
|
||||||
@@ -963,22 +965,11 @@ class RevPiNetIOSelected(RevPiNetIO):
|
|||||||
|
|
||||||
if type(deviceselection) is not DevSelect:
|
if type(deviceselection) is not DevSelect:
|
||||||
# Convert to tuple
|
# Convert to tuple
|
||||||
if type(deviceselection) in (int, str):
|
if type(deviceselection) not in (list, tuple):
|
||||||
deviceselection = (deviceselection,)
|
deviceselection = (deviceselection,)
|
||||||
|
|
||||||
# Check supported types
|
|
||||||
for dev in deviceselection:
|
|
||||||
if type(dev) not in (int, str):
|
|
||||||
raise ValueError(
|
|
||||||
"need device position as <class 'int'> or "
|
|
||||||
"device name as <class 'str'>"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Automatic search for name and position depends on type int / str
|
# Automatic search for name and position depends on type int / str
|
||||||
self._devselect = DevSelect(
|
self._devselect = DevSelect(DeviceType.IGNORED, "", deviceselection)
|
||||||
"VIRTUAL" if type(self) is RevPiNetIODriver else "", "",
|
|
||||||
tuple(deviceselection),
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self._devselect = deviceselection
|
self._devselect = deviceselection
|
||||||
@@ -986,23 +977,25 @@ class RevPiNetIOSelected(RevPiNetIO):
|
|||||||
self._configure(self.get_jconfigrsc())
|
self._configure(self.get_jconfigrsc())
|
||||||
|
|
||||||
if len(self.device) == 0:
|
if len(self.device) == 0:
|
||||||
if type(self) == RevPiNetIODriver:
|
if self._devselect.type:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find any given VIRTUAL devices in config"
|
"could not find ANY given {0} devices in config"
|
||||||
|
"".format(self._devselect.type)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find any given devices in config"
|
"could not find ANY given devices in config"
|
||||||
)
|
)
|
||||||
elif not self._devselect.key \
|
elif not self._devselect.other_device_key \
|
||||||
and len(self.device) != len(self._devselect.values):
|
and len(self.device) != len(self._devselect.values):
|
||||||
if type(self) == RevPiNetIODriver:
|
if self._devselect.type:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find all given VIRTUAL devices in config"
|
"could not find ALL given {0} devices in config"
|
||||||
|
"".format(self._devselect.type)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise DeviceNotFoundError(
|
raise DeviceNotFoundError(
|
||||||
"could not find all given devices in config"
|
"could not find ALL given devices in config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1033,7 +1026,44 @@ class RevPiNetIODriver(RevPiNetIOSelected):
|
|||||||
:ref: :func:`RevPiModIO.__init__()`
|
:ref: :func:`RevPiModIO.__init__()`
|
||||||
"""
|
"""
|
||||||
# Parent mit monitoring=False und simulator=True laden
|
# Parent mit monitoring=False und simulator=True laden
|
||||||
|
if type(virtdev) not in (list, tuple):
|
||||||
|
virtdev = (virtdev,)
|
||||||
|
dev_select = DevSelect(DeviceType.VIRTUAL, "", virtdev)
|
||||||
super().__init__(
|
super().__init__(
|
||||||
address, virtdev, autorefresh, False, syncoutputs, True, debug,
|
address, dev_select, autorefresh, False, syncoutputs, True, debug,
|
||||||
replace_io_file, shared_procimg, direct_output
|
replace_io_file, shared_procimg, direct_output
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def run_net_plc(
|
||||||
|
address, func, cycletime=50, replace_io_file=None, debug=True):
|
||||||
|
"""
|
||||||
|
Run Revoluton Pi as real plc with cycle loop and exclusive IO access.
|
||||||
|
|
||||||
|
This function is just a shortcut to run the module in cycle loop mode and
|
||||||
|
handle the program exit signal. You will access the .io, .core, .device
|
||||||
|
via the cycletools in your cycle function.
|
||||||
|
|
||||||
|
Shortcut for this source code:
|
||||||
|
rpi = RevPiModIO(autorefresh=True, replace_io_file=..., debug=...)
|
||||||
|
rpi.handlesignalend()
|
||||||
|
return rpi.cycleloop(func, cycletime)
|
||||||
|
|
||||||
|
:param address: IP-Adresse <class 'str'> / (IP, Port) <class 'tuple'>
|
||||||
|
:param func: Function to run every set milliseconds
|
||||||
|
:param cycletime: Cycle time in milliseconds
|
||||||
|
:param replace_io_file: Load replace IO configuration from file
|
||||||
|
:param debug: Print all warnings and detailed error messages
|
||||||
|
:param procimg: Use different process image
|
||||||
|
:param configrsc: Use different piCtory configuration
|
||||||
|
|
||||||
|
:return: None or the return value of the cycle function
|
||||||
|
"""
|
||||||
|
rpi = RevPiNetIO(
|
||||||
|
address=address,
|
||||||
|
autorefresh=True,
|
||||||
|
replace_io_file=replace_io_file,
|
||||||
|
debug=debug,
|
||||||
|
)
|
||||||
|
rpi.handlesignalend()
|
||||||
|
return rpi.cycleloop(func, cycletime)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class ProductType:
|
|||||||
|
|
||||||
class DeviceType:
|
class DeviceType:
|
||||||
"""Module key "type" in piCtory file."""
|
"""Module key "type" in piCtory file."""
|
||||||
|
IGNORED = ""
|
||||||
BASE = "BASE" # Core devices
|
BASE = "BASE" # Core devices
|
||||||
EDGE = "EDGE" # Gateways
|
EDGE = "EDGE" # Gateways
|
||||||
LEFT_RIGHT = "LEFT_RIGHT" # IOs
|
LEFT_RIGHT = "LEFT_RIGHT" # IOs
|
||||||
|
|||||||
Reference in New Issue
Block a user