ophyd-async 0.8.0a5__py3-none-any.whl → 0.8.0a6__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 +1 -1
- ophyd_async/core/__init__.py +2 -0
- ophyd_async/core/_signal.py +90 -17
- ophyd_async/core/_table.py +9 -4
- ophyd_async/epics/adcore/_core_logic.py +3 -1
- ophyd_async/epics/eiger/_eiger_controller.py +6 -1
- 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/tango/__init__.py +0 -43
- ophyd_async/tango/{signal → core}/__init__.py +7 -2
- ophyd_async/tango/{base_devices → core}/_base_device.py +38 -64
- ophyd_async/tango/{signal → core}/_signal.py +13 -3
- ophyd_async/tango/{base_devices → core}/_tango_readable.py +3 -4
- ophyd_async/tango/demo/_counter.py +6 -7
- ophyd_async/tango/demo/_mover.py +8 -7
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.8.0a6.dist-info}/METADATA +47 -47
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.8.0a6.dist-info}/RECORD +25 -21
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.8.0a6.dist-info}/WHEEL +1 -1
- ophyd_async/tango/base_devices/__init__.py +0 -4
- /ophyd_async/tango/{signal → core}/_tango_transport.py +0 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.8.0a6.dist-info}/LICENSE +0 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.8.0a6.dist-info}/entry_points.txt +0 -0
- {ophyd_async-0.8.0a5.dist-info → ophyd_async-0.8.0a6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
record(waveform, "$(device)int8a") {
|
|
2
|
+
field(NELM, "3")
|
|
3
|
+
field(FTVL, "CHAR")
|
|
4
|
+
field(INP, {const:[-128, 127]})
|
|
5
|
+
field(PINI, "YES")
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
record(waveform, "$(device)uint16a") {
|
|
9
|
+
field(NELM, "3")
|
|
10
|
+
field(FTVL, "USHORT")
|
|
11
|
+
field(INP, {const:[0, 65535]})
|
|
12
|
+
field(PINI, "YES")
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
record(waveform, "$(device)uint32a") {
|
|
16
|
+
field(NELM, "3")
|
|
17
|
+
field(FTVL, "ULONG")
|
|
18
|
+
field(INP, {const:[0, 4294967295]})
|
|
19
|
+
field(PINI, "YES")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
record(waveform, "$(device)int64a") {
|
|
23
|
+
field(NELM, "3")
|
|
24
|
+
field(FTVL, "INT64")
|
|
25
|
+
# Can't do 64-bit int with JSON numbers in a const link...
|
|
26
|
+
field(INP, {const:[-2147483649, 2147483648]})
|
|
27
|
+
field(PINI, "YES")
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
record(waveform, "$(device)uint64a") {
|
|
31
|
+
field(NELM, "3")
|
|
32
|
+
field(FTVL, "UINT64")
|
|
33
|
+
field(INP, {const:[0, 4294967297]})
|
|
34
|
+
field(PINI, "YES")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
record(waveform, "$(device)table:labels") {
|
|
38
|
+
field(FTVL, "STRING")
|
|
39
|
+
field(NELM, "5")
|
|
40
|
+
field(INP, {const:["Bool", "Int", "Float", "Str", "Enum"]})
|
|
41
|
+
field(PINI, "YES")
|
|
42
|
+
info(Q:group, {
|
|
43
|
+
"$(device)table": {
|
|
44
|
+
"+id": "epics:nt/NTTable:1.0",
|
|
45
|
+
"labels": {
|
|
46
|
+
"+type": "plain",
|
|
47
|
+
"+channel": "VAL"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
record(waveform, "$(device)table:bool")
|
|
54
|
+
{
|
|
55
|
+
field(FTVL, "UCHAR")
|
|
56
|
+
field(NELM, "4096")
|
|
57
|
+
field(INP, {const:[false, false, true, true]})
|
|
58
|
+
field(PINI, "YES")
|
|
59
|
+
info(Q:group, {
|
|
60
|
+
"$(device)table": {
|
|
61
|
+
"value.bool": {
|
|
62
|
+
"+type": "plain",
|
|
63
|
+
"+channel": "VAL",
|
|
64
|
+
"+putorder": 1
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
record(waveform, "$(device)table:int")
|
|
71
|
+
{
|
|
72
|
+
field(FTVL, "LONG")
|
|
73
|
+
field(NELM, "4096")
|
|
74
|
+
field(INP, {const:[1, 8, -9, 32]})
|
|
75
|
+
field(PINI, "YES")
|
|
76
|
+
info(Q:group, {
|
|
77
|
+
"$(device)table": {
|
|
78
|
+
"value.int": {
|
|
79
|
+
"+type": "plain",
|
|
80
|
+
"+channel": "VAL",
|
|
81
|
+
"+putorder": 2
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
record(waveform, "$(device)table:float")
|
|
88
|
+
{
|
|
89
|
+
field(FTVL, "DOUBLE")
|
|
90
|
+
field(NELM, "4096")
|
|
91
|
+
field(INP, {const:[1.8, 8.2, -6, 32.9887]})
|
|
92
|
+
field(PINI, "YES")
|
|
93
|
+
info(Q:group, {
|
|
94
|
+
"$(device)table": {
|
|
95
|
+
"value.float": {
|
|
96
|
+
"+type": "plain",
|
|
97
|
+
"+channel": "VAL",
|
|
98
|
+
"+putorder": 3
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
record(waveform, "$(device)table:str")
|
|
105
|
+
{
|
|
106
|
+
field(FTVL, "STRING")
|
|
107
|
+
field(NELM, "4096")
|
|
108
|
+
field(INP, {const:["Hello", "World", "Foo", "Bar"]})
|
|
109
|
+
field(PINI, "YES")
|
|
110
|
+
info(Q:group, {
|
|
111
|
+
"$(device)table": {
|
|
112
|
+
"value.str": {
|
|
113
|
+
"+type": "plain",
|
|
114
|
+
"+channel": "VAL",
|
|
115
|
+
"+putorder": 4
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
record(waveform, "$(device)table:enum")
|
|
122
|
+
{
|
|
123
|
+
field(FTVL, "STRING")
|
|
124
|
+
field(NELM, "4096")
|
|
125
|
+
field(INP, {const:["Aaa", "Bbb", "Aaa", "Ccc"]})
|
|
126
|
+
field(PINI, "YES")
|
|
127
|
+
info(Q:group, {
|
|
128
|
+
"$(device)table": {
|
|
129
|
+
"value.enum": {
|
|
130
|
+
"+type": "plain",
|
|
131
|
+
"+channel": "VAL",
|
|
132
|
+
"+putorder": 5,
|
|
133
|
+
"+trigger": "*",
|
|
134
|
+
},
|
|
135
|
+
"": {"+type": "meta", "+channel": "VAL"}
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
record(longout, "$(device)ntndarray:ArraySize0_RBV") {
|
|
141
|
+
field(VAL, "3")
|
|
142
|
+
field(PINI, "YES")
|
|
143
|
+
info(Q:group, {
|
|
144
|
+
"$(device)ntndarray":{
|
|
145
|
+
"dimension[0].size":{+channel:"VAL", +type:"plain", +putorder:0}
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
record(longout, "$(device)ntndarray:ArraySize1_RBV") {
|
|
151
|
+
field(VAL, "2")
|
|
152
|
+
field(PINI, "YES")
|
|
153
|
+
info(Q:group, {
|
|
154
|
+
"$(device)ntndarray":{
|
|
155
|
+
"dimension[1].size":{+channel:"VAL", +type:"plain", +putorder:0}
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
record(waveform, "$(device)ntndarray:data")
|
|
161
|
+
{
|
|
162
|
+
field(FTVL, "INT64")
|
|
163
|
+
field(NELM, "6")
|
|
164
|
+
field(INP, {const:[0, 0, 0, 0, 0, 0]})
|
|
165
|
+
field(PINI, "YES")
|
|
166
|
+
info(Q:group, {
|
|
167
|
+
"$(device)ntndarray":{
|
|
168
|
+
+id:"epics:nt/NTNDArray:1.0",
|
|
169
|
+
"value":{
|
|
170
|
+
+type:"any",
|
|
171
|
+
+channel:"VAL",
|
|
172
|
+
+trigger:"*",
|
|
173
|
+
},
|
|
174
|
+
"": {+type:"meta", +channel:"SEVR"}
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
}
|
ophyd_async/tango/__init__.py
CHANGED
|
@@ -1,43 +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
|
-
ensure_proper_executor,
|
|
11
|
-
get_dtype_extended,
|
|
12
|
-
get_python_type,
|
|
13
|
-
get_tango_trl,
|
|
14
|
-
get_trl_descriptor,
|
|
15
|
-
infer_python_type,
|
|
16
|
-
infer_signal_type,
|
|
17
|
-
make_backend,
|
|
18
|
-
tango_signal_r,
|
|
19
|
-
tango_signal_rw,
|
|
20
|
-
tango_signal_w,
|
|
21
|
-
tango_signal_x,
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
__all__ = [
|
|
25
|
-
"TangoDevice",
|
|
26
|
-
"TangoReadable",
|
|
27
|
-
"tango_polling",
|
|
28
|
-
"TangoSignalBackend",
|
|
29
|
-
"get_python_type",
|
|
30
|
-
"get_dtype_extended",
|
|
31
|
-
"get_trl_descriptor",
|
|
32
|
-
"get_tango_trl",
|
|
33
|
-
"infer_python_type",
|
|
34
|
-
"infer_signal_type",
|
|
35
|
-
"make_backend",
|
|
36
|
-
"AttributeProxy",
|
|
37
|
-
"CommandProxy",
|
|
38
|
-
"ensure_proper_executor",
|
|
39
|
-
"tango_signal_r",
|
|
40
|
-
"tango_signal_rw",
|
|
41
|
-
"tango_signal_w",
|
|
42
|
-
"tango_signal_x",
|
|
43
|
-
]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from ._base_device import TangoDevice, TangoPolling
|
|
1
2
|
from ._signal import (
|
|
2
3
|
infer_python_type,
|
|
3
4
|
infer_signal_type,
|
|
@@ -7,6 +8,7 @@ from ._signal import (
|
|
|
7
8
|
tango_signal_w,
|
|
8
9
|
tango_signal_x,
|
|
9
10
|
)
|
|
11
|
+
from ._tango_readable import TangoReadable
|
|
10
12
|
from ._tango_transport import (
|
|
11
13
|
AttributeProxy,
|
|
12
14
|
CommandProxy,
|
|
@@ -18,7 +20,7 @@ from ._tango_transport import (
|
|
|
18
20
|
get_trl_descriptor,
|
|
19
21
|
)
|
|
20
22
|
|
|
21
|
-
__all__ =
|
|
23
|
+
__all__ = [
|
|
22
24
|
"AttributeProxy",
|
|
23
25
|
"CommandProxy",
|
|
24
26
|
"ensure_proper_executor",
|
|
@@ -34,4 +36,7 @@ __all__ = (
|
|
|
34
36
|
"tango_signal_rw",
|
|
35
37
|
"tango_signal_w",
|
|
36
38
|
"tango_signal_x",
|
|
37
|
-
|
|
39
|
+
"TangoDevice",
|
|
40
|
+
"TangoReadable",
|
|
41
|
+
"TangoPolling",
|
|
42
|
+
]
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
from ophyd_async.core
|
|
7
|
-
from ophyd_async.tango.signal import (
|
|
8
|
-
TangoSignalBackend,
|
|
9
|
-
infer_python_type,
|
|
10
|
-
infer_signal_type,
|
|
11
|
-
)
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, Generic, TypeVar
|
|
5
|
+
|
|
6
|
+
from ophyd_async.core import Device, DeviceConnector, DeviceFiller, LazyMock
|
|
12
7
|
from tango import DeviceProxy as DeviceProxy
|
|
13
8
|
from tango.asyncio import DeviceProxy as AsyncDeviceProxy
|
|
14
9
|
|
|
10
|
+
from ._signal import TangoSignalBackend, infer_python_type, infer_signal_type
|
|
11
|
+
|
|
15
12
|
T = TypeVar("T")
|
|
16
13
|
|
|
17
14
|
|
|
@@ -32,63 +29,45 @@ class TangoDevice(Device):
|
|
|
32
29
|
|
|
33
30
|
trl: str = ""
|
|
34
31
|
proxy: DeviceProxy | None = None
|
|
35
|
-
_polling: tuple[bool, float, float | None, float | None] = (False, 0.1, None, 0.1)
|
|
36
|
-
_signal_polling: dict[str, tuple[bool, float, float, float]] = {}
|
|
37
|
-
_poll_only_annotated_signals: bool = True
|
|
38
32
|
|
|
39
33
|
def __init__(
|
|
40
34
|
self,
|
|
41
35
|
trl: str | None = None,
|
|
42
36
|
device_proxy: DeviceProxy | None = None,
|
|
37
|
+
support_events: bool = False,
|
|
43
38
|
name: str = "",
|
|
44
39
|
) -> None:
|
|
45
40
|
connector = TangoDeviceConnector(
|
|
46
|
-
trl=trl,
|
|
47
|
-
device_proxy=device_proxy,
|
|
48
|
-
polling=self._polling,
|
|
49
|
-
signal_polling=self._signal_polling,
|
|
41
|
+
trl=trl, device_proxy=device_proxy, support_events=support_events
|
|
50
42
|
)
|
|
51
43
|
super().__init__(name=name, connector=connector)
|
|
52
44
|
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
| None = None
|
|
58
|
-
|
|
59
|
-
):
|
|
60
|
-
"""
|
|
61
|
-
Class decorator to configure polling for Tango devices.
|
|
62
|
-
|
|
63
|
-
This decorator allows for the configuration of both device-level and signal-level
|
|
64
|
-
polling for Tango devices. Polling is useful for device servers that do not support
|
|
65
|
-
event-driven updates.
|
|
66
|
-
|
|
67
|
-
Parameters
|
|
68
|
-
----------
|
|
69
|
-
polling : Optional[Union[Tuple[float, float, float],
|
|
70
|
-
Dict[str, Tuple[float, float, float]]]], optional
|
|
71
|
-
Device-level polling configuration as a tuple of three floats representing the
|
|
72
|
-
polling interval, polling timeout, and polling delay. Alternatively,
|
|
73
|
-
a dictionary can be provided to specify signal-level polling configurations
|
|
74
|
-
directly.
|
|
75
|
-
signal_polling : Optional[Dict[str, Tuple[float, float, float]]], optional
|
|
76
|
-
Signal-level polling configuration as a dictionary where keys are signal names
|
|
77
|
-
and values are tuples of three floats representing the polling interval, polling
|
|
78
|
-
timeout, and polling delay.
|
|
79
|
-
"""
|
|
80
|
-
if isinstance(polling, dict):
|
|
81
|
-
signal_polling = polling
|
|
82
|
-
polling = None
|
|
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
|
|
83
51
|
|
|
84
|
-
def decorator(cls):
|
|
85
|
-
if polling is not None:
|
|
86
|
-
cls._polling = (True, *polling)
|
|
87
|
-
if signal_polling is not None:
|
|
88
|
-
cls._signal_polling = {k: (True, *v) for k, v in signal_polling.items()}
|
|
89
|
-
return cls
|
|
90
52
|
|
|
91
|
-
|
|
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
|
|
92
71
|
|
|
93
72
|
|
|
94
73
|
class TangoDeviceConnector(DeviceConnector):
|
|
@@ -96,13 +75,11 @@ class TangoDeviceConnector(DeviceConnector):
|
|
|
96
75
|
self,
|
|
97
76
|
trl: str | None,
|
|
98
77
|
device_proxy: DeviceProxy | None,
|
|
99
|
-
|
|
100
|
-
signal_polling: dict[str, tuple[bool, float, float, float]],
|
|
78
|
+
support_events: bool,
|
|
101
79
|
) -> None:
|
|
102
80
|
self.trl = trl
|
|
103
81
|
self.proxy = device_proxy
|
|
104
|
-
self.
|
|
105
|
-
self._signal_polling = signal_polling
|
|
82
|
+
self._support_events = support_events
|
|
106
83
|
|
|
107
84
|
def create_children_from_annotations(self, device: Device):
|
|
108
85
|
if not hasattr(self, "filler"):
|
|
@@ -110,11 +87,14 @@ class TangoDeviceConnector(DeviceConnector):
|
|
|
110
87
|
device=device,
|
|
111
88
|
signal_backend_factory=TangoSignalBackend,
|
|
112
89
|
device_connector_factory=lambda: TangoDeviceConnector(
|
|
113
|
-
None, None,
|
|
90
|
+
None, None, self._support_events
|
|
114
91
|
),
|
|
115
92
|
)
|
|
116
93
|
list(self.filler.create_devices_from_annotations(filled=False))
|
|
117
|
-
|
|
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)
|
|
118
98
|
self.filler.check_created()
|
|
119
99
|
|
|
120
100
|
async def connect_mock(self, device: Device, mock: LazyMock):
|
|
@@ -145,12 +125,6 @@ class TangoDeviceConnector(DeviceConnector):
|
|
|
145
125
|
backend = self.filler.fill_child_signal(name, signal_type)
|
|
146
126
|
backend.datatype = await infer_python_type(full_trl, self.proxy)
|
|
147
127
|
backend.set_trl(full_trl)
|
|
148
|
-
if polling := self._signal_polling.get(name, ()):
|
|
149
|
-
backend.set_polling(*polling)
|
|
150
|
-
backend.allow_events(False)
|
|
151
|
-
elif self._polling[0]:
|
|
152
|
-
backend.set_polling(*self._polling)
|
|
153
|
-
backend.allow_events(False)
|
|
154
128
|
# Check that all the requested children have been filled
|
|
155
129
|
self.filler.check_filled(f"{self.trl}: {children}")
|
|
156
130
|
# Set the name of the device to name all children
|
|
@@ -16,7 +16,14 @@ from ophyd_async.core import (
|
|
|
16
16
|
SignalW,
|
|
17
17
|
SignalX,
|
|
18
18
|
)
|
|
19
|
-
from tango import
|
|
19
|
+
from tango import (
|
|
20
|
+
AttrDataFormat,
|
|
21
|
+
AttrWriteType,
|
|
22
|
+
CmdArgType,
|
|
23
|
+
DeviceProxy,
|
|
24
|
+
DevState,
|
|
25
|
+
NonSupportedFeature, # type: ignore
|
|
26
|
+
)
|
|
20
27
|
from tango.asyncio import DeviceProxy as AsyncDeviceProxy
|
|
21
28
|
|
|
22
29
|
from ._tango_transport import TangoSignalBackend, get_python_type
|
|
@@ -174,8 +181,11 @@ async def infer_signal_type(
|
|
|
174
181
|
else:
|
|
175
182
|
dev_proxy = proxy
|
|
176
183
|
|
|
177
|
-
|
|
178
|
-
|
|
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
|
|
179
189
|
|
|
180
190
|
if tr_name not in dev_proxy.get_attribute_list():
|
|
181
191
|
if tr_name not in dev_proxy.get_command_list():
|
|
@@ -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
|
"""
|
|
@@ -2,18 +2,17 @@ from typing import Annotated as A
|
|
|
2
2
|
|
|
3
3
|
from ophyd_async.core import DEFAULT_TIMEOUT, AsyncStatus, SignalR, SignalRW, SignalX
|
|
4
4
|
from ophyd_async.core import StandardReadableFormat as Format
|
|
5
|
-
from ophyd_async.tango import
|
|
5
|
+
from ophyd_async.tango.core import TangoPolling, TangoReadable
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
# Enable device level polling, useful for servers that do not support events
|
|
9
|
-
# Polling for individual signal can be enabled with a dict
|
|
10
|
-
@tango_polling({"counts": (1.0, 0.1, 0.1), "sample_time": (0.1, 0.1, 0.1)})
|
|
11
8
|
class TangoCounter(TangoReadable):
|
|
12
9
|
# Enter the name and type of the signals you want to use
|
|
13
|
-
# If
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
# If the server doesn't support events, the TangoPolling annotation gives
|
|
11
|
+
# the parameters for ophyd to poll instead
|
|
12
|
+
counts: A[SignalR[int], Format.HINTED_SIGNAL, TangoPolling(1.0, 0.1, 0.1)]
|
|
13
|
+
sample_time: A[SignalRW[float], Format.CONFIG_SIGNAL, TangoPolling(0.1, 0.1, 0.1)]
|
|
16
14
|
start: SignalX
|
|
15
|
+
# If a tango name clashes with a bluesky verb, add a trailing underscore
|
|
17
16
|
reset_: SignalX
|
|
18
17
|
|
|
19
18
|
@AsyncStatus.wrap
|
ophyd_async/tango/demo/_mover.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
from typing import Annotated as A
|
|
2
3
|
|
|
3
4
|
from bluesky.protocols import Movable, Stoppable
|
|
4
5
|
|
|
@@ -16,18 +17,18 @@ from ophyd_async.core import (
|
|
|
16
17
|
wait_for_value,
|
|
17
18
|
)
|
|
18
19
|
from ophyd_async.core import StandardReadableFormat as Format
|
|
19
|
-
from ophyd_async.tango import
|
|
20
|
+
from ophyd_async.tango.core import TangoPolling, TangoReadable
|
|
20
21
|
from tango import DevState
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
# Enable device level polling, useful for servers that do not support events
|
|
24
|
-
@tango_polling((0.1, 0.1, 0.1))
|
|
25
24
|
class TangoMover(TangoReadable, Movable, Stoppable):
|
|
26
25
|
# Enter the name and type of the signals you want to use
|
|
27
|
-
# If
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
# If the server doesn't support events, the TangoPolling annotation gives
|
|
27
|
+
# the parameters for ophyd to poll instead
|
|
28
|
+
position: A[SignalRW[float], TangoPolling(0.1, 0.1, 0.1)]
|
|
29
|
+
velocity: A[SignalRW[float], TangoPolling(0.1, 0.1, 0.1)]
|
|
30
|
+
state: A[SignalR[DevState], TangoPolling(0.1)]
|
|
31
|
+
# If a tango name clashes with a bluesky verb, add a trailing underscore
|
|
31
32
|
stop_: SignalX
|
|
32
33
|
|
|
33
34
|
def __init__(self, trl: str | None = "", name=""):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.0a6
|
|
4
4
|
Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
|
|
5
5
|
Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -40,62 +40,62 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
40
40
|
Requires-Python: >=3.10
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE
|
|
43
|
-
Requires-Dist: networkx
|
|
43
|
+
Requires-Dist: networkx>=2.0
|
|
44
44
|
Requires-Dist: numpy
|
|
45
45
|
Requires-Dist: packaging
|
|
46
46
|
Requires-Dist: pint
|
|
47
|
-
Requires-Dist: bluesky
|
|
48
|
-
Requires-Dist: event-model
|
|
49
|
-
Requires-Dist: p4p
|
|
47
|
+
Requires-Dist: bluesky>=1.13
|
|
48
|
+
Requires-Dist: event-model>=1.22.1
|
|
49
|
+
Requires-Dist: p4p>=4.2.0a3
|
|
50
50
|
Requires-Dist: pyyaml
|
|
51
51
|
Requires-Dist: colorlog
|
|
52
|
-
Requires-Dist: pydantic
|
|
52
|
+
Requires-Dist: pydantic>=2.0
|
|
53
53
|
Requires-Dist: pydantic-numpy
|
|
54
54
|
Provides-Extra: ca
|
|
55
|
-
Requires-Dist: aioca
|
|
56
|
-
Provides-Extra: dev
|
|
57
|
-
Requires-Dist: ophyd-async[pva] ; extra == 'dev'
|
|
58
|
-
Requires-Dist: ophyd-async[sim] ; extra == 'dev'
|
|
59
|
-
Requires-Dist: ophyd-async[ca] ; extra == 'dev'
|
|
60
|
-
Requires-Dist: ophyd-async[tango] ; extra == 'dev'
|
|
61
|
-
Requires-Dist: inflection ; extra == 'dev'
|
|
62
|
-
Requires-Dist: ipython ; extra == 'dev'
|
|
63
|
-
Requires-Dist: ipywidgets ; extra == 'dev'
|
|
64
|
-
Requires-Dist: matplotlib ; extra == 'dev'
|
|
65
|
-
Requires-Dist: myst-parser ; extra == 'dev'
|
|
66
|
-
Requires-Dist: numpydoc ; extra == 'dev'
|
|
67
|
-
Requires-Dist: ophyd ; extra == 'dev'
|
|
68
|
-
Requires-Dist: pickleshare ; extra == 'dev'
|
|
69
|
-
Requires-Dist: pipdeptree ; extra == 'dev'
|
|
70
|
-
Requires-Dist: pre-commit ; extra == 'dev'
|
|
71
|
-
Requires-Dist: pydata-sphinx-theme >=0.12 ; extra == 'dev'
|
|
72
|
-
Requires-Dist: pyepics >=3.4.2 ; extra == 'dev'
|
|
73
|
-
Requires-Dist: pyright ; extra == 'dev'
|
|
74
|
-
Requires-Dist: pyside6 ==6.7.0 ; extra == 'dev'
|
|
75
|
-
Requires-Dist: pytest ; extra == 'dev'
|
|
76
|
-
Requires-Dist: pytest-asyncio ; extra == 'dev'
|
|
77
|
-
Requires-Dist: pytest-cov ; extra == 'dev'
|
|
78
|
-
Requires-Dist: pytest-faulthandler ; extra == 'dev'
|
|
79
|
-
Requires-Dist: pytest-forked ; extra == 'dev'
|
|
80
|
-
Requires-Dist: pytest-rerunfailures ; extra == 'dev'
|
|
81
|
-
Requires-Dist: pytest-timeout ; extra == 'dev'
|
|
82
|
-
Requires-Dist: ruff ; extra == 'dev'
|
|
83
|
-
Requires-Dist: sphinx <7.4.0 ; extra == 'dev'
|
|
84
|
-
Requires-Dist: sphinx-autobuild ; extra == 'dev'
|
|
85
|
-
Requires-Dist: autodoc-pydantic ; extra == 'dev'
|
|
86
|
-
Requires-Dist: sphinxcontrib-mermaid ; extra == 'dev'
|
|
87
|
-
Requires-Dist: sphinx-copybutton ; extra == 'dev'
|
|
88
|
-
Requires-Dist: sphinx-design ; extra == 'dev'
|
|
89
|
-
Requires-Dist: super-state-machine ; extra == 'dev'
|
|
90
|
-
Requires-Dist: tox-direct ; extra == 'dev'
|
|
91
|
-
Requires-Dist: types-mock ; extra == 'dev'
|
|
92
|
-
Requires-Dist: types-pyyaml ; extra == 'dev'
|
|
55
|
+
Requires-Dist: aioca>=1.6; extra == "ca"
|
|
93
56
|
Provides-Extra: pva
|
|
94
|
-
Requires-Dist: p4p
|
|
57
|
+
Requires-Dist: p4p; extra == "pva"
|
|
95
58
|
Provides-Extra: sim
|
|
96
|
-
Requires-Dist: h5py
|
|
59
|
+
Requires-Dist: h5py; extra == "sim"
|
|
97
60
|
Provides-Extra: tango
|
|
98
|
-
Requires-Dist: pytango
|
|
61
|
+
Requires-Dist: pytango>=10.0.0; extra == "tango"
|
|
62
|
+
Provides-Extra: dev
|
|
63
|
+
Requires-Dist: ophyd_async[pva]; extra == "dev"
|
|
64
|
+
Requires-Dist: ophyd_async[sim]; extra == "dev"
|
|
65
|
+
Requires-Dist: ophyd_async[ca]; extra == "dev"
|
|
66
|
+
Requires-Dist: ophyd_async[tango]; extra == "dev"
|
|
67
|
+
Requires-Dist: inflection; extra == "dev"
|
|
68
|
+
Requires-Dist: ipython; extra == "dev"
|
|
69
|
+
Requires-Dist: ipywidgets; extra == "dev"
|
|
70
|
+
Requires-Dist: matplotlib; extra == "dev"
|
|
71
|
+
Requires-Dist: myst-parser; extra == "dev"
|
|
72
|
+
Requires-Dist: numpydoc; extra == "dev"
|
|
73
|
+
Requires-Dist: ophyd; extra == "dev"
|
|
74
|
+
Requires-Dist: pickleshare; extra == "dev"
|
|
75
|
+
Requires-Dist: pipdeptree; extra == "dev"
|
|
76
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
77
|
+
Requires-Dist: pydata-sphinx-theme>=0.12; extra == "dev"
|
|
78
|
+
Requires-Dist: pyepics>=3.4.2; extra == "dev"
|
|
79
|
+
Requires-Dist: pyright; extra == "dev"
|
|
80
|
+
Requires-Dist: pyside6==6.7.0; extra == "dev"
|
|
81
|
+
Requires-Dist: pytest; extra == "dev"
|
|
82
|
+
Requires-Dist: pytest-asyncio; extra == "dev"
|
|
83
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
84
|
+
Requires-Dist: pytest-faulthandler; extra == "dev"
|
|
85
|
+
Requires-Dist: pytest-forked; extra == "dev"
|
|
86
|
+
Requires-Dist: pytest-rerunfailures; extra == "dev"
|
|
87
|
+
Requires-Dist: pytest-timeout; extra == "dev"
|
|
88
|
+
Requires-Dist: ruff; extra == "dev"
|
|
89
|
+
Requires-Dist: sphinx<7.4.0; extra == "dev"
|
|
90
|
+
Requires-Dist: sphinx-autobuild; extra == "dev"
|
|
91
|
+
Requires-Dist: autodoc-pydantic; extra == "dev"
|
|
92
|
+
Requires-Dist: sphinxcontrib-mermaid; extra == "dev"
|
|
93
|
+
Requires-Dist: sphinx-copybutton; extra == "dev"
|
|
94
|
+
Requires-Dist: sphinx-design; extra == "dev"
|
|
95
|
+
Requires-Dist: super_state_machine; extra == "dev"
|
|
96
|
+
Requires-Dist: tox-direct; extra == "dev"
|
|
97
|
+
Requires-Dist: types-mock; extra == "dev"
|
|
98
|
+
Requires-Dist: types-pyyaml; extra == "dev"
|
|
99
99
|
|
|
100
100
|
[](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml)
|
|
101
101
|
[](https://codecov.io/gh/bluesky/ophyd-async)
|