Skip to content

Commit 4d606fa

Browse files
authored
Merge pull request #282 from python-accelerator-middle-layer/fix-device-access-list
Fix device access list
2 parents 7e30323 + 24c632f commit 4d606fa

4 files changed

Lines changed: 34 additions & 32 deletions

File tree

pyaml/control/abstract_impl.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,21 @@ def _iter_devices_and_ranges(devs: DeviceAccess | DeviceAccessList):
9595
- DeviceAccessList: yields N items based on get_devices() and get_range() flattening
9696
"""
9797
# Single device
98-
if hasattr(devs, "get") and hasattr(devs, "get_range") and not hasattr(devs, "get_devices"):
98+
if isinstance(devs, DeviceAccess):
9999
r = devs.get_range()
100100
if r is None:
101101
r = [None, None]
102102
return [(devs, [r[0], r[1]])]
103103

104-
# Device list (expects get_devices() + get_range() flat list)
105-
devices = devs.get_devices()
106-
flat = np.asarray(devs.get_range(), dtype=object).ravel()
107-
if (flat.size % 2) != 0:
104+
# get_range() return a flat list
105+
flat = devs.get_range()
106+
if (len(flat) % 2) != 0:
108107
raise ValueError(f"dev_range must have an even length, got {flat.size}")
109108

109+
# Reshape
110110
pairs = []
111-
for i, d in enumerate(devices):
112-
pairs.append((d, [flat[2 * i], flat[2 * i + 1]]))
111+
for i in range(devs.len()):
112+
pairs.append((devs.get_device_at(i), [flat[2 * i], flat[2 * i + 1]]))
113113
return pairs
114114

115115

@@ -196,7 +196,7 @@ def unit(self) -> str:
196196
return self._devs.unit()
197197

198198
def nb_device(self) -> int:
199-
return self._devs.__len__()
199+
return self._devs.len()
200200

201201

202202
# ------------------------------------------------------------------------------

pyaml/control/deviceaccesslist.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,27 @@
44
import numpy.typing as npt
55

66
from .deviceaccess import DeviceAccess
7-
from .readback_value import Value
87

98

10-
class DeviceAccessList(list[DeviceAccess], metaclass=ABCMeta):
9+
class DeviceAccessList(metaclass=ABCMeta):
1110
"""
12-
Abstract class providing access to a list of control system float variable
11+
Abstract class providing access to a list of control system variales.
12+
Internal structure depends on the backend and might not be trivially iterable.
1313
"""
1414

1515
@abstractmethod
1616
def add_devices(self, devices: DeviceAccess | list[DeviceAccess]):
17-
"""Add a DeviceAccess to this list"""
17+
"""Add a DeviceAccess (or a list) to this list"""
1818
pass
1919

2020
@abstractmethod
21-
def get_devices(self) -> DeviceAccess | list[DeviceAccess]:
22-
"""Get the DeviceAccess list"""
21+
def get_device_at(self, index: int) -> DeviceAccess:
22+
"""Returns the device at the given index"""
23+
pass
24+
25+
@abstractmethod
26+
def len(self) -> int:
27+
"""Get the DeviceAccessList length"""
2328
pass
2429

2530
@abstractmethod
@@ -56,7 +61,7 @@ def get_range(self) -> list[float]:
5661
Returns
5762
-------
5863
list[float]
59-
List containing [min, max] values
64+
List containing [min0, max0, min1, max1, ...] values
6065
"""
6166
pass
6267

tests/dummy_cs/tango-pyaml/tango/pyaml/controlsystem.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,5 @@ def name(self) -> str:
8585
def get_aggregator(self) -> str | None:
8686
return MultiAttribute()
8787

88-
def vector_aggregator(self) -> str | None:
89-
return self._cfg.vector_aggregator
90-
9188
def __repr__(self):
9289
return repr(self._cfg).replace("ConfigModel", self.__class__.__name__)

tests/dummy_cs/tango-pyaml/tango/pyaml/multi_attribute.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
class MultiAttribute(DeviceAccessList):
1414
def __init__(self):
15-
super().__init__()
15+
self._items = []
1616

1717
def add_devices(self, devices: DeviceAccess | list[DeviceAccess]):
1818
if isinstance(devices, list):
@@ -23,54 +23,54 @@ def add_devices(self, devices: DeviceAccess | list[DeviceAccess]):
2323
(tango.pyaml.attribute) but got
2424
({device.__class__.__name__})"""
2525
)
26-
super().extend(devices)
26+
self._items.extend(devices)
2727
else:
2828
if not isinstance(devices, Attribute):
2929
raise pyaml.PyAMLException(
3030
f"""Device must be an instance of Attribute
3131
(tango.pyaml.attribute) but got
3232
({devices.__class__.__name__})"""
3333
)
34-
super().append(devices)
34+
self._items.append(devices)
3535

36-
def get_devices(self) -> DeviceAccess | list[DeviceAccess]:
37-
if len(self) == 1:
38-
return self[0]
39-
else:
40-
return self
36+
def len(self) -> int:
37+
return len(self._items)
38+
39+
def get_device_at(self, index: int) -> DeviceAccess:
40+
return self._items[index]
4141

4242
def set(self, value: npt.NDArray[np.float64]):
4343
print(f"MultiAttribute.set({len(value)} values)")
4444
global LAST_NB_WRITTEN
4545
LAST_NB_WRITTEN += len(value)
46-
for idx, a in enumerate(self):
46+
for idx, a in enumerate(self._items):
4747
a.set(value[idx])
4848

4949
def set_and_wait(self, value: npt.NDArray[np.float64]):
5050
pass
5151

5252
def get(self) -> npt.NDArray[np.float64]:
53-
print(f"MultiAttribute.get({len(self)} values)")
54-
return np.array([a.get() for a in self])
53+
print(f"MultiAttribute.get({len(self._items)} values)")
54+
return np.array([a.get() for a in self._items])
5555

5656
def readback(self) -> np.array:
5757
return np.array([])
5858

5959
def unit(self) -> list[str]:
60-
return [a.unit() for a in self]
60+
return [a.unit() for a in self._items]
6161

6262
def get_last_nb_written(self) -> int:
6363
return self.__last_nb_written
6464

6565
def get_range(self) -> list[float]:
6666
attr_range: list[float] = []
67-
for device in self:
67+
for device in self._items:
6868
attr_range.extend(device.get_range())
6969
return attr_range
7070

7171
def check_device_availability(self) -> bool:
7272
available = False
73-
for device in self:
73+
for device in self._items:
7474
available = device.check_device_availability()
7575
if not available:
7676
break

0 commit comments

Comments
 (0)