ophyd-async 0.7.0__py3-none-any.whl → 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ophyd_async/_version.py +2 -2
- ophyd_async/core/__init__.py +34 -9
- ophyd_async/core/_detector.py +5 -10
- ophyd_async/core/_device.py +170 -68
- ophyd_async/core/_device_filler.py +269 -0
- ophyd_async/core/_device_save_loader.py +6 -7
- ophyd_async/core/_mock_signal_backend.py +35 -40
- ophyd_async/core/_mock_signal_utils.py +25 -16
- ophyd_async/core/_protocol.py +28 -8
- ophyd_async/core/_readable.py +133 -134
- ophyd_async/core/_signal.py +219 -163
- ophyd_async/core/_signal_backend.py +131 -64
- ophyd_async/core/_soft_signal_backend.py +131 -194
- ophyd_async/core/_status.py +22 -6
- ophyd_async/core/_table.py +102 -100
- ophyd_async/core/_utils.py +143 -32
- ophyd_async/epics/adaravis/_aravis_controller.py +2 -2
- ophyd_async/epics/adaravis/_aravis_io.py +8 -6
- ophyd_async/epics/adcore/_core_io.py +5 -7
- ophyd_async/epics/adcore/_core_logic.py +3 -1
- ophyd_async/epics/adcore/_hdf_writer.py +2 -2
- ophyd_async/epics/adcore/_single_trigger.py +6 -10
- ophyd_async/epics/adcore/_utils.py +15 -10
- ophyd_async/epics/adkinetix/__init__.py +2 -1
- ophyd_async/epics/adkinetix/_kinetix_controller.py +6 -3
- ophyd_async/epics/adkinetix/_kinetix_io.py +4 -5
- ophyd_async/epics/adpilatus/_pilatus_controller.py +2 -2
- ophyd_async/epics/adpilatus/_pilatus_io.py +3 -4
- ophyd_async/epics/adsimdetector/_sim_controller.py +2 -2
- ophyd_async/epics/advimba/__init__.py +4 -1
- ophyd_async/epics/advimba/_vimba_controller.py +6 -3
- ophyd_async/epics/advimba/_vimba_io.py +8 -9
- ophyd_async/epics/core/__init__.py +26 -0
- ophyd_async/epics/core/_aioca.py +323 -0
- ophyd_async/epics/core/_epics_connector.py +53 -0
- ophyd_async/epics/core/_epics_device.py +13 -0
- ophyd_async/epics/core/_p4p.py +383 -0
- ophyd_async/epics/core/_pvi_connector.py +91 -0
- ophyd_async/epics/core/_signal.py +171 -0
- ophyd_async/epics/core/_util.py +61 -0
- ophyd_async/epics/demo/_mover.py +4 -5
- ophyd_async/epics/demo/_sensor.py +14 -13
- ophyd_async/epics/eiger/_eiger.py +1 -2
- ophyd_async/epics/eiger/_eiger_controller.py +7 -2
- ophyd_async/epics/eiger/_eiger_io.py +3 -5
- ophyd_async/epics/eiger/_odin_io.py +5 -5
- ophyd_async/epics/motor.py +4 -5
- ophyd_async/epics/signal.py +11 -0
- ophyd_async/epics/testing/__init__.py +24 -0
- ophyd_async/epics/testing/_example_ioc.py +105 -0
- ophyd_async/epics/testing/_utils.py +78 -0
- ophyd_async/epics/testing/test_records.db +152 -0
- ophyd_async/epics/testing/test_records_pva.db +177 -0
- ophyd_async/fastcs/core.py +9 -0
- ophyd_async/fastcs/panda/__init__.py +4 -4
- ophyd_async/fastcs/panda/_block.py +18 -13
- ophyd_async/fastcs/panda/_control.py +3 -5
- ophyd_async/fastcs/panda/_hdf_panda.py +5 -19
- ophyd_async/fastcs/panda/_table.py +30 -52
- ophyd_async/fastcs/panda/_trigger.py +8 -8
- ophyd_async/fastcs/panda/_writer.py +2 -5
- ophyd_async/plan_stubs/_ensure_connected.py +20 -13
- ophyd_async/plan_stubs/_fly.py +2 -2
- ophyd_async/plan_stubs/_nd_attributes.py +5 -4
- ophyd_async/py.typed +0 -0
- ophyd_async/sim/demo/_pattern_detector/_pattern_detector_controller.py +1 -2
- ophyd_async/sim/demo/_sim_motor.py +3 -4
- ophyd_async/tango/__init__.py +0 -45
- ophyd_async/tango/{signal → core}/__init__.py +9 -6
- ophyd_async/tango/core/_base_device.py +132 -0
- ophyd_async/tango/{signal → core}/_signal.py +42 -53
- ophyd_async/tango/{base_devices → core}/_tango_readable.py +3 -4
- ophyd_async/tango/{signal → core}/_tango_transport.py +38 -40
- ophyd_async/tango/demo/_counter.py +12 -23
- ophyd_async/tango/demo/_mover.py +13 -13
- {ophyd_async-0.7.0.dist-info → ophyd_async-0.8.0.dist-info}/METADATA +52 -55
- ophyd_async-0.8.0.dist-info/RECORD +116 -0
- {ophyd_async-0.7.0.dist-info → ophyd_async-0.8.0.dist-info}/WHEEL +1 -1
- ophyd_async/epics/pvi/__init__.py +0 -3
- ophyd_async/epics/pvi/_pvi.py +0 -338
- ophyd_async/epics/signal/__init__.py +0 -21
- ophyd_async/epics/signal/_aioca.py +0 -378
- ophyd_async/epics/signal/_common.py +0 -57
- ophyd_async/epics/signal/_epics_transport.py +0 -34
- ophyd_async/epics/signal/_p4p.py +0 -518
- ophyd_async/epics/signal/_signal.py +0 -114
- ophyd_async/tango/base_devices/__init__.py +0 -4
- ophyd_async/tango/base_devices/_base_device.py +0 -225
- ophyd_async-0.7.0.dist-info/RECORD +0 -108
- {ophyd_async-0.7.0.dist-info → ophyd_async-0.8.0.dist-info}/LICENSE +0 -0
- {ophyd_async-0.7.0.dist-info → ophyd_async-0.8.0.dist-info}/entry_points.txt +0 -0
- {ophyd_async-0.7.0.dist-info → ophyd_async-0.8.0.dist-info}/top_level.txt +0 -0
|
@@ -6,8 +6,6 @@ from bluesky.protocols import Movable, Stoppable
|
|
|
6
6
|
|
|
7
7
|
from ophyd_async.core import (
|
|
8
8
|
AsyncStatus,
|
|
9
|
-
ConfigSignal,
|
|
10
|
-
HintedSignal,
|
|
11
9
|
StandardReadable,
|
|
12
10
|
WatchableAsyncStatus,
|
|
13
11
|
WatcherUpdate,
|
|
@@ -15,6 +13,7 @@ from ophyd_async.core import (
|
|
|
15
13
|
soft_signal_r_and_setter,
|
|
16
14
|
soft_signal_rw,
|
|
17
15
|
)
|
|
16
|
+
from ophyd_async.core import StandardReadableFormat as Format
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
class SimMotor(StandardReadable, Movable, Stoppable):
|
|
@@ -28,11 +27,11 @@ class SimMotor(StandardReadable, Movable, Stoppable):
|
|
|
28
27
|
- instant: bool: whether to move instantly, or with a delay
|
|
29
28
|
"""
|
|
30
29
|
# Define some signals
|
|
31
|
-
with self.add_children_as_readables(
|
|
30
|
+
with self.add_children_as_readables(Format.HINTED_SIGNAL):
|
|
32
31
|
self.user_readback, self._user_readback_set = soft_signal_r_and_setter(
|
|
33
32
|
float, 0
|
|
34
33
|
)
|
|
35
|
-
with self.add_children_as_readables(
|
|
34
|
+
with self.add_children_as_readables(Format.CONFIG_SIGNAL):
|
|
36
35
|
self.velocity = soft_signal_rw(float, 0 if instant else 1.0)
|
|
37
36
|
self.units = soft_signal_rw(str, "mm")
|
|
38
37
|
self.user_setpoint = soft_signal_rw(float, 0)
|
ophyd_async/tango/__init__.py
CHANGED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
from .base_devices import (
|
|
2
|
-
TangoDevice,
|
|
3
|
-
TangoReadable,
|
|
4
|
-
tango_polling,
|
|
5
|
-
)
|
|
6
|
-
from .signal import (
|
|
7
|
-
AttributeProxy,
|
|
8
|
-
CommandProxy,
|
|
9
|
-
TangoSignalBackend,
|
|
10
|
-
__tango_signal_auto,
|
|
11
|
-
ensure_proper_executor,
|
|
12
|
-
get_dtype_extended,
|
|
13
|
-
get_python_type,
|
|
14
|
-
get_tango_trl,
|
|
15
|
-
get_trl_descriptor,
|
|
16
|
-
infer_python_type,
|
|
17
|
-
infer_signal_character,
|
|
18
|
-
make_backend,
|
|
19
|
-
tango_signal_r,
|
|
20
|
-
tango_signal_rw,
|
|
21
|
-
tango_signal_w,
|
|
22
|
-
tango_signal_x,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
__all__ = [
|
|
26
|
-
"TangoDevice",
|
|
27
|
-
"TangoReadable",
|
|
28
|
-
"tango_polling",
|
|
29
|
-
"TangoSignalBackend",
|
|
30
|
-
"get_python_type",
|
|
31
|
-
"get_dtype_extended",
|
|
32
|
-
"get_trl_descriptor",
|
|
33
|
-
"get_tango_trl",
|
|
34
|
-
"infer_python_type",
|
|
35
|
-
"infer_signal_character",
|
|
36
|
-
"make_backend",
|
|
37
|
-
"AttributeProxy",
|
|
38
|
-
"CommandProxy",
|
|
39
|
-
"ensure_proper_executor",
|
|
40
|
-
"__tango_signal_auto",
|
|
41
|
-
"tango_signal_r",
|
|
42
|
-
"tango_signal_rw",
|
|
43
|
-
"tango_signal_w",
|
|
44
|
-
"tango_signal_x",
|
|
45
|
-
]
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
from ._base_device import TangoDevice, TangoPolling
|
|
1
2
|
from ._signal import (
|
|
2
|
-
__tango_signal_auto,
|
|
3
3
|
infer_python_type,
|
|
4
|
-
|
|
4
|
+
infer_signal_type,
|
|
5
5
|
make_backend,
|
|
6
6
|
tango_signal_r,
|
|
7
7
|
tango_signal_rw,
|
|
8
8
|
tango_signal_w,
|
|
9
9
|
tango_signal_x,
|
|
10
10
|
)
|
|
11
|
+
from ._tango_readable import TangoReadable
|
|
11
12
|
from ._tango_transport import (
|
|
12
13
|
AttributeProxy,
|
|
13
14
|
CommandProxy,
|
|
@@ -19,7 +20,7 @@ from ._tango_transport import (
|
|
|
19
20
|
get_trl_descriptor,
|
|
20
21
|
)
|
|
21
22
|
|
|
22
|
-
__all__ =
|
|
23
|
+
__all__ = [
|
|
23
24
|
"AttributeProxy",
|
|
24
25
|
"CommandProxy",
|
|
25
26
|
"ensure_proper_executor",
|
|
@@ -29,11 +30,13 @@ __all__ = (
|
|
|
29
30
|
"get_trl_descriptor",
|
|
30
31
|
"get_tango_trl",
|
|
31
32
|
"infer_python_type",
|
|
32
|
-
"
|
|
33
|
+
"infer_signal_type",
|
|
33
34
|
"make_backend",
|
|
34
35
|
"tango_signal_r",
|
|
35
36
|
"tango_signal_rw",
|
|
36
37
|
"tango_signal_w",
|
|
37
38
|
"tango_signal_x",
|
|
38
|
-
"
|
|
39
|
-
|
|
39
|
+
"TangoDevice",
|
|
40
|
+
"TangoReadable",
|
|
41
|
+
"TangoPolling",
|
|
42
|
+
]
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Generic, TypeVar
|
|
5
|
+
|
|
6
|
+
from ophyd_async.core import Device, DeviceConnector, DeviceFiller, LazyMock
|
|
7
|
+
from tango import DeviceProxy as DeviceProxy
|
|
8
|
+
from tango.asyncio import DeviceProxy as AsyncDeviceProxy
|
|
9
|
+
|
|
10
|
+
from ._signal import TangoSignalBackend, infer_python_type, infer_signal_type
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TangoDevice(Device):
|
|
16
|
+
"""
|
|
17
|
+
General class for TangoDevices. Extends Device to provide attributes for Tango
|
|
18
|
+
devices.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
trl: str
|
|
23
|
+
Tango resource locator, typically of the device server.
|
|
24
|
+
device_proxy: Optional[Union[AsyncDeviceProxy, SyncDeviceProxy]]
|
|
25
|
+
Asynchronous or synchronous DeviceProxy object for the device. If not provided,
|
|
26
|
+
an asynchronous DeviceProxy object will be created using the trl and awaited
|
|
27
|
+
when the device is connected.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
trl: str = ""
|
|
31
|
+
proxy: DeviceProxy | None = None
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
trl: str | None = None,
|
|
36
|
+
device_proxy: DeviceProxy | None = None,
|
|
37
|
+
support_events: bool = False,
|
|
38
|
+
name: str = "",
|
|
39
|
+
) -> None:
|
|
40
|
+
connector = TangoDeviceConnector(
|
|
41
|
+
trl=trl, device_proxy=device_proxy, support_events=support_events
|
|
42
|
+
)
|
|
43
|
+
super().__init__(name=name, connector=connector)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class TangoPolling(Generic[T]):
|
|
48
|
+
ophyd_polling_period: float = 0.1
|
|
49
|
+
abs_change: T | None = None
|
|
50
|
+
rel_change: T | None = None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def fill_backend_with_polling(
|
|
54
|
+
support_events: bool, backend: TangoSignalBackend, annotations: list[Any]
|
|
55
|
+
):
|
|
56
|
+
unhandled = []
|
|
57
|
+
while annotations:
|
|
58
|
+
annotation = annotations.pop(0)
|
|
59
|
+
backend.allow_events(support_events)
|
|
60
|
+
if isinstance(annotation, TangoPolling):
|
|
61
|
+
backend.set_polling(
|
|
62
|
+
not support_events,
|
|
63
|
+
annotation.ophyd_polling_period,
|
|
64
|
+
annotation.abs_change,
|
|
65
|
+
annotation.rel_change,
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
unhandled.append(annotation)
|
|
69
|
+
annotations.extend(unhandled)
|
|
70
|
+
# These leftover annotations will now be handled by the iterator
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class TangoDeviceConnector(DeviceConnector):
|
|
74
|
+
def __init__(
|
|
75
|
+
self,
|
|
76
|
+
trl: str | None,
|
|
77
|
+
device_proxy: DeviceProxy | None,
|
|
78
|
+
support_events: bool,
|
|
79
|
+
) -> None:
|
|
80
|
+
self.trl = trl
|
|
81
|
+
self.proxy = device_proxy
|
|
82
|
+
self._support_events = support_events
|
|
83
|
+
|
|
84
|
+
def create_children_from_annotations(self, device: Device):
|
|
85
|
+
if not hasattr(self, "filler"):
|
|
86
|
+
self.filler = DeviceFiller(
|
|
87
|
+
device=device,
|
|
88
|
+
signal_backend_factory=TangoSignalBackend,
|
|
89
|
+
device_connector_factory=lambda: TangoDeviceConnector(
|
|
90
|
+
None, None, self._support_events
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
list(self.filler.create_devices_from_annotations(filled=False))
|
|
94
|
+
for backend, annotations in self.filler.create_signals_from_annotations(
|
|
95
|
+
filled=False
|
|
96
|
+
):
|
|
97
|
+
fill_backend_with_polling(self._support_events, backend, annotations)
|
|
98
|
+
self.filler.check_created()
|
|
99
|
+
|
|
100
|
+
async def connect_mock(self, device: Device, mock: LazyMock):
|
|
101
|
+
# Make 2 entries for each DeviceVector
|
|
102
|
+
self.filler.create_device_vector_entries_to_mock(2)
|
|
103
|
+
# Set the name of the device to name all children
|
|
104
|
+
device.set_name(device.name)
|
|
105
|
+
return await super().connect_mock(device, mock)
|
|
106
|
+
|
|
107
|
+
async def connect_real(self, device: Device, timeout: float, force_reconnect: bool):
|
|
108
|
+
if self.trl and self.proxy is None:
|
|
109
|
+
self.proxy = await AsyncDeviceProxy(self.trl)
|
|
110
|
+
elif self.proxy and not self.trl:
|
|
111
|
+
self.trl = self.proxy.name()
|
|
112
|
+
else:
|
|
113
|
+
raise TypeError("Neither proxy nor trl supplied")
|
|
114
|
+
|
|
115
|
+
children = sorted(
|
|
116
|
+
set()
|
|
117
|
+
.union(self.proxy.get_attribute_list())
|
|
118
|
+
.union(self.proxy.get_command_list())
|
|
119
|
+
)
|
|
120
|
+
for name in children:
|
|
121
|
+
# TODO: strip attribute name
|
|
122
|
+
full_trl = f"{self.trl}/{name}"
|
|
123
|
+
signal_type = await infer_signal_type(full_trl, self.proxy)
|
|
124
|
+
if signal_type:
|
|
125
|
+
backend = self.filler.fill_child_signal(name, signal_type)
|
|
126
|
+
backend.datatype = await infer_python_type(full_trl, self.proxy)
|
|
127
|
+
backend.set_trl(full_trl)
|
|
128
|
+
# Check that all the requested children have been filled
|
|
129
|
+
self.filler.check_filled(f"{self.trl}: {children}")
|
|
130
|
+
# Set the name of the device to name all children
|
|
131
|
+
device.set_name(device.name)
|
|
132
|
+
return await super().connect_real(device, timeout, force_reconnect)
|
|
@@ -2,21 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
from enum import Enum, IntEnum
|
|
6
7
|
|
|
7
8
|
import numpy.typing as npt
|
|
8
9
|
|
|
9
|
-
from ophyd_async.core import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
from ophyd_async.core import (
|
|
11
|
+
DEFAULT_TIMEOUT,
|
|
12
|
+
Signal,
|
|
13
|
+
SignalDatatypeT,
|
|
14
|
+
SignalR,
|
|
15
|
+
SignalRW,
|
|
16
|
+
SignalW,
|
|
17
|
+
SignalX,
|
|
18
|
+
)
|
|
19
|
+
from tango import (
|
|
20
|
+
AttrDataFormat,
|
|
21
|
+
AttrWriteType,
|
|
22
|
+
CmdArgType,
|
|
23
|
+
DeviceProxy,
|
|
24
|
+
DevState,
|
|
25
|
+
NonSupportedFeature, # type: ignore
|
|
13
26
|
)
|
|
14
|
-
from tango import AttrDataFormat, AttrWriteType, CmdArgType, DeviceProxy, DevState
|
|
15
27
|
from tango.asyncio import DeviceProxy as AsyncDeviceProxy
|
|
16
28
|
|
|
29
|
+
from ._tango_transport import TangoSignalBackend, get_python_type
|
|
30
|
+
|
|
17
31
|
|
|
18
32
|
def make_backend(
|
|
19
|
-
datatype: type[
|
|
33
|
+
datatype: type[SignalDatatypeT] | None,
|
|
20
34
|
read_trl: str = "",
|
|
21
35
|
write_trl: str = "",
|
|
22
36
|
device_proxy: DeviceProxy | None = None,
|
|
@@ -25,13 +39,13 @@ def make_backend(
|
|
|
25
39
|
|
|
26
40
|
|
|
27
41
|
def tango_signal_rw(
|
|
28
|
-
datatype: type[
|
|
42
|
+
datatype: type[SignalDatatypeT],
|
|
29
43
|
read_trl: str,
|
|
30
44
|
write_trl: str = "",
|
|
31
45
|
device_proxy: DeviceProxy | None = None,
|
|
32
46
|
timeout: float = DEFAULT_TIMEOUT,
|
|
33
47
|
name: str = "",
|
|
34
|
-
) -> SignalRW[
|
|
48
|
+
) -> SignalRW[SignalDatatypeT]:
|
|
35
49
|
"""Create a `SignalRW` backed by 1 or 2 Tango Attribute/Command
|
|
36
50
|
|
|
37
51
|
Parameters
|
|
@@ -54,12 +68,12 @@ def tango_signal_rw(
|
|
|
54
68
|
|
|
55
69
|
|
|
56
70
|
def tango_signal_r(
|
|
57
|
-
datatype: type[
|
|
71
|
+
datatype: type[SignalDatatypeT],
|
|
58
72
|
read_trl: str,
|
|
59
73
|
device_proxy: DeviceProxy | None = None,
|
|
60
74
|
timeout: float = DEFAULT_TIMEOUT,
|
|
61
75
|
name: str = "",
|
|
62
|
-
) -> SignalR[
|
|
76
|
+
) -> SignalR[SignalDatatypeT]:
|
|
63
77
|
"""Create a `SignalR` backed by 1 Tango Attribute/Command
|
|
64
78
|
|
|
65
79
|
Parameters
|
|
@@ -80,12 +94,12 @@ def tango_signal_r(
|
|
|
80
94
|
|
|
81
95
|
|
|
82
96
|
def tango_signal_w(
|
|
83
|
-
datatype: type[
|
|
97
|
+
datatype: type[SignalDatatypeT],
|
|
84
98
|
write_trl: str,
|
|
85
99
|
device_proxy: DeviceProxy | None = None,
|
|
86
100
|
timeout: float = DEFAULT_TIMEOUT,
|
|
87
101
|
name: str = "",
|
|
88
|
-
) -> SignalW[
|
|
102
|
+
) -> SignalW[SignalDatatypeT]:
|
|
89
103
|
"""Create a `SignalW` backed by 1 Tango Attribute/Command
|
|
90
104
|
|
|
91
105
|
Parameters
|
|
@@ -128,39 +142,10 @@ def tango_signal_x(
|
|
|
128
142
|
return SignalX(backend, timeout=timeout, name=name)
|
|
129
143
|
|
|
130
144
|
|
|
131
|
-
async def __tango_signal_auto(
|
|
132
|
-
datatype: type[T] | None = None,
|
|
133
|
-
*,
|
|
134
|
-
trl: str,
|
|
135
|
-
device_proxy: DeviceProxy | None,
|
|
136
|
-
timeout: float = DEFAULT_TIMEOUT,
|
|
137
|
-
name: str = "",
|
|
138
|
-
) -> SignalW | SignalX | SignalR | SignalRW | None:
|
|
139
|
-
try:
|
|
140
|
-
signal_character = await infer_signal_character(trl, device_proxy)
|
|
141
|
-
except RuntimeError as e:
|
|
142
|
-
if "Commands with different in and out dtypes" in str(e):
|
|
143
|
-
return None
|
|
144
|
-
else:
|
|
145
|
-
raise e
|
|
146
|
-
|
|
147
|
-
if datatype is None:
|
|
148
|
-
datatype = await infer_python_type(trl, device_proxy)
|
|
149
|
-
|
|
150
|
-
backend = make_backend(datatype, trl, trl, device_proxy)
|
|
151
|
-
if signal_character == "RW":
|
|
152
|
-
return SignalRW(backend=backend, timeout=timeout, name=name)
|
|
153
|
-
if signal_character == "R":
|
|
154
|
-
return SignalR(backend=backend, timeout=timeout, name=name)
|
|
155
|
-
if signal_character == "W":
|
|
156
|
-
return SignalW(backend=backend, timeout=timeout, name=name)
|
|
157
|
-
if signal_character == "X":
|
|
158
|
-
return SignalX(backend=backend, timeout=timeout, name=name)
|
|
159
|
-
|
|
160
|
-
|
|
161
145
|
async def infer_python_type(
|
|
162
146
|
trl: str = "", proxy: DeviceProxy | None = None
|
|
163
147
|
) -> object | npt.NDArray | type[DevState] | IntEnum:
|
|
148
|
+
# TODO: work out if this is still needed
|
|
164
149
|
device_trl, tr_name = trl.rsplit("/", 1)
|
|
165
150
|
if proxy is None:
|
|
166
151
|
dev_proxy = await AsyncDeviceProxy(device_trl)
|
|
@@ -187,15 +172,20 @@ async def infer_python_type(
|
|
|
187
172
|
return npt.NDArray[py_type] if isarray else py_type
|
|
188
173
|
|
|
189
174
|
|
|
190
|
-
async def
|
|
175
|
+
async def infer_signal_type(
|
|
176
|
+
trl, proxy: DeviceProxy | None = None
|
|
177
|
+
) -> type[Signal] | None:
|
|
191
178
|
device_trl, tr_name = trl.rsplit("/", 1)
|
|
192
179
|
if proxy is None:
|
|
193
180
|
dev_proxy = await AsyncDeviceProxy(device_trl)
|
|
194
181
|
else:
|
|
195
182
|
dev_proxy = proxy
|
|
196
183
|
|
|
197
|
-
|
|
198
|
-
|
|
184
|
+
try:
|
|
185
|
+
if tr_name in dev_proxy.get_pipe_list():
|
|
186
|
+
raise NotImplementedError("Pipes are not supported")
|
|
187
|
+
except NonSupportedFeature: # type: ignore
|
|
188
|
+
pass
|
|
199
189
|
|
|
200
190
|
if tr_name not in dev_proxy.get_attribute_list():
|
|
201
191
|
if tr_name not in dev_proxy.get_command_list():
|
|
@@ -204,20 +194,19 @@ async def infer_signal_character(trl, proxy: DeviceProxy | None = None) -> str:
|
|
|
204
194
|
if tr_name in dev_proxy.get_attribute_list():
|
|
205
195
|
config = await dev_proxy.get_attribute_config(tr_name)
|
|
206
196
|
if config.writable in [AttrWriteType.READ_WRITE, AttrWriteType.READ_WITH_WRITE]:
|
|
207
|
-
return
|
|
197
|
+
return SignalRW
|
|
208
198
|
elif config.writable == AttrWriteType.READ:
|
|
209
|
-
return
|
|
199
|
+
return SignalR
|
|
210
200
|
else:
|
|
211
|
-
return
|
|
201
|
+
return SignalW
|
|
212
202
|
|
|
213
203
|
if tr_name in dev_proxy.get_command_list():
|
|
214
204
|
config = await dev_proxy.get_command_config(tr_name)
|
|
215
205
|
if config.in_type == CmdArgType.DevVoid:
|
|
216
|
-
return
|
|
206
|
+
return SignalX
|
|
217
207
|
elif config.in_type != config.out_type:
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
)
|
|
208
|
+
logging.debug("Commands with different in and out dtypes are not supported")
|
|
209
|
+
return None
|
|
221
210
|
else:
|
|
222
|
-
return
|
|
211
|
+
return SignalRW
|
|
223
212
|
raise RuntimeError(f"Unable to infer signal character for {trl}")
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from ophyd_async.core import
|
|
4
|
-
StandardReadable,
|
|
5
|
-
)
|
|
6
|
-
from ophyd_async.tango.base_devices._base_device import TangoDevice
|
|
3
|
+
from ophyd_async.core import StandardReadable
|
|
7
4
|
from tango import DeviceProxy
|
|
8
5
|
|
|
6
|
+
from ._base_device import TangoDevice
|
|
7
|
+
|
|
9
8
|
|
|
10
9
|
class TangoReadable(TangoDevice, StandardReadable):
|
|
11
10
|
"""
|