ophyd-async 0.13.6__py3-none-any.whl → 0.13.7__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/_signal.py +2 -1
- ophyd_async/epics/motor.py +18 -3
- ophyd_async/epics/pmac/_pmac_io.py +10 -13
- ophyd_async/epics/pmac/_pmac_trajectory.py +9 -10
- ophyd_async/epics/pmac/_utils.py +102 -59
- ophyd_async/tango/core/__init__.py +0 -2
- ophyd_async/tango/core/_base_device.py +4 -1
- ophyd_async/tango/demo/_counter.py +10 -3
- ophyd_async/tango/demo/_mover.py +4 -3
- {ophyd_async-0.13.6.dist-info → ophyd_async-0.13.7.dist-info}/METADATA +1 -1
- {ophyd_async-0.13.6.dist-info → ophyd_async-0.13.7.dist-info}/RECORD +15 -16
- ophyd_async/tango/core/_tango_readable.py +0 -15
- {ophyd_async-0.13.6.dist-info → ophyd_async-0.13.7.dist-info}/WHEEL +0 -0
- {ophyd_async-0.13.6.dist-info → ophyd_async-0.13.7.dist-info}/licenses/LICENSE +0 -0
- {ophyd_async-0.13.6.dist-info → ophyd_async-0.13.7.dist-info}/top_level.txt +0 -0
ophyd_async/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.13.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 13,
|
|
31
|
+
__version__ = version = '0.13.7'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 13, 7)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
ophyd_async/core/_signal.py
CHANGED
|
@@ -639,9 +639,10 @@ async def set_and_wait_for_other_value(
|
|
|
639
639
|
if wait_for_set_completion:
|
|
640
640
|
await status
|
|
641
641
|
except TimeoutError as exc:
|
|
642
|
+
matcher_name = getattr(matcher, "__name__", f"<{type(matcher).__name__}>")
|
|
642
643
|
raise TimeoutError(
|
|
643
644
|
f"{match_signal.name} value didn't match value from"
|
|
644
|
-
f" {
|
|
645
|
+
f" {matcher_name}() in {timeout}s"
|
|
645
646
|
) from exc
|
|
646
647
|
|
|
647
648
|
return status
|
ophyd_async/epics/motor.py
CHANGED
|
@@ -98,9 +98,12 @@ class Motor(
|
|
|
98
98
|
self.motor_done_move = epics_signal_r(int, prefix + ".DMOV")
|
|
99
99
|
self.low_limit_travel = epics_signal_rw(float, prefix + ".LLM")
|
|
100
100
|
self.high_limit_travel = epics_signal_rw(float, prefix + ".HLM")
|
|
101
|
+
self.dial_low_limit_travel = epics_signal_rw(float, prefix + ".DLLM")
|
|
102
|
+
self.dial_high_limit_travel = epics_signal_rw(float, prefix + ".DHLM")
|
|
101
103
|
self.offset_freeze_switch = epics_signal_rw(OffsetMode, prefix + ".FOFF")
|
|
102
104
|
self.high_limit_switch = epics_signal_r(int, prefix + ".HLS")
|
|
103
105
|
self.low_limit_switch = epics_signal_r(int, prefix + ".LLS")
|
|
106
|
+
self.output_link = epics_signal_r(str, prefix + ".OUT")
|
|
104
107
|
self.set_use_switch = epics_signal_rw(UseSetMode, prefix + ".SET")
|
|
105
108
|
|
|
106
109
|
# Note:cannot use epics_signal_x here, as the motor record specifies that
|
|
@@ -131,16 +134,26 @@ class Motor(
|
|
|
131
134
|
Will raise a MotorLimitsException if the given absolute positions will be
|
|
132
135
|
outside the motor soft limits.
|
|
133
136
|
"""
|
|
134
|
-
|
|
137
|
+
(
|
|
138
|
+
motor_lower_limit,
|
|
139
|
+
motor_upper_limit,
|
|
140
|
+
egu,
|
|
141
|
+
dial_lower_limit,
|
|
142
|
+
dial_upper_limit,
|
|
143
|
+
) = await asyncio.gather(
|
|
135
144
|
self.low_limit_travel.get_value(),
|
|
136
145
|
self.high_limit_travel.get_value(),
|
|
137
146
|
self.motor_egu.get_value(),
|
|
147
|
+
self.dial_low_limit_travel.get_value(),
|
|
148
|
+
self.dial_high_limit_travel.get_value(),
|
|
138
149
|
)
|
|
139
150
|
|
|
140
|
-
# EPICS motor record treats limits of 0, 0 as no limit
|
|
141
|
-
|
|
151
|
+
# EPICS motor record treats dial limits of 0, 0 as no limit
|
|
152
|
+
# Use DLLM and DHLM to check
|
|
153
|
+
if dial_lower_limit == 0 and dial_upper_limit == 0:
|
|
142
154
|
return
|
|
143
155
|
|
|
156
|
+
# Use real motor limit(i.e. HLM and LLM) to check if the move is permissible
|
|
144
157
|
if (
|
|
145
158
|
not motor_upper_limit >= abs_start_pos >= motor_lower_limit
|
|
146
159
|
or not motor_upper_limit >= abs_end_pos >= motor_lower_limit
|
|
@@ -150,6 +163,8 @@ class Motor(
|
|
|
150
163
|
f"{abs_start_pos}{egu} to "
|
|
151
164
|
f"{abs_end_pos}{egu} but motor limits are "
|
|
152
165
|
f"{motor_lower_limit}{egu} <= x <= {motor_upper_limit}{egu} "
|
|
166
|
+
f"dial limits are "
|
|
167
|
+
f"{dial_lower_limit}{egu} <= x <= {dial_upper_limit}"
|
|
153
168
|
)
|
|
154
169
|
|
|
155
170
|
@AsyncStatus.wrap
|
|
@@ -6,7 +6,8 @@ from ophyd_async.core import Array1D, Device, DeviceVector, StandardReadable
|
|
|
6
6
|
from ophyd_async.epics import motor
|
|
7
7
|
from ophyd_async.epics.core import epics_signal_r, epics_signal_rw, epics_signal_x
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
# Map the CS axis letters to their index (1 indexed)
|
|
10
|
+
CS_INDEX = {letter: index + 1 for index, letter in enumerate("ABCUVWXYZ")}
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class PmacTrajectoryIO(StandardReadable):
|
|
@@ -20,24 +21,20 @@ class PmacTrajectoryIO(StandardReadable):
|
|
|
20
21
|
# 1 indexed CS axes so we can index into them from the compound motor input link
|
|
21
22
|
self.positions = DeviceVector(
|
|
22
23
|
{
|
|
23
|
-
i
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
for i, letter in enumerate(CS_LETTERS)
|
|
24
|
+
i: epics_signal_rw(Array1D[np.float64], f"{prefix}{letter}:Positions")
|
|
25
|
+
for letter, i in CS_INDEX.items()
|
|
27
26
|
}
|
|
28
27
|
)
|
|
29
28
|
self.use_axis = DeviceVector(
|
|
30
29
|
{
|
|
31
|
-
i
|
|
32
|
-
for
|
|
30
|
+
i: epics_signal_rw(bool, f"{prefix}{letter}:UseAxis")
|
|
31
|
+
for letter, i in CS_INDEX.items()
|
|
33
32
|
}
|
|
34
33
|
)
|
|
35
34
|
self.velocities = DeviceVector(
|
|
36
35
|
{
|
|
37
|
-
i
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
for i, letter in enumerate(CS_LETTERS)
|
|
36
|
+
i: epics_signal_rw(Array1D[np.float64], f"{prefix}{letter}:Velocities")
|
|
37
|
+
for letter, i in CS_INDEX.items()
|
|
41
38
|
}
|
|
42
39
|
)
|
|
43
40
|
self.total_points = epics_signal_r(int, f"{prefix}TotalPoints_RBV")
|
|
@@ -76,8 +73,8 @@ class PmacCoordIO(Device):
|
|
|
76
73
|
self.cs_port = epics_signal_r(str, f"{prefix}Port")
|
|
77
74
|
self.cs_axis_setpoint = DeviceVector(
|
|
78
75
|
{
|
|
79
|
-
i
|
|
80
|
-
for i in
|
|
76
|
+
i: epics_signal_rw(float, f"{prefix}M{i}:DirectDemand")
|
|
77
|
+
for i in CS_INDEX.values()
|
|
81
78
|
}
|
|
82
79
|
)
|
|
83
80
|
super().__init__(name=name)
|
|
@@ -15,10 +15,10 @@ from ophyd_async.core import (
|
|
|
15
15
|
wait_for_value,
|
|
16
16
|
)
|
|
17
17
|
from ophyd_async.epics.motor import Motor
|
|
18
|
-
|
|
19
|
-
from
|
|
20
|
-
from
|
|
21
|
-
from
|
|
18
|
+
|
|
19
|
+
from ._pmac_io import CS_INDEX, PmacIO
|
|
20
|
+
from ._pmac_trajectory_generation import PVT, Trajectory
|
|
21
|
+
from ._utils import (
|
|
22
22
|
_PmacMotorInfo,
|
|
23
23
|
calculate_ramp_position_and_duration,
|
|
24
24
|
)
|
|
@@ -131,8 +131,7 @@ class PmacTrajectoryTriggerLogic(FlyerController):
|
|
|
131
131
|
slice, path_length, motor_info, ramp_up_time
|
|
132
132
|
)
|
|
133
133
|
use_axis = {
|
|
134
|
-
|
|
135
|
-
for axis in range(len(CS_LETTERS))
|
|
134
|
+
i: (i in motor_info.motor_cs_index.values()) for i in CS_INDEX.values()
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
coros = [
|
|
@@ -177,14 +176,14 @@ class PmacTrajectoryTriggerLogic(FlyerController):
|
|
|
177
176
|
self, trajectory: Trajectory, motor_info: _PmacMotorInfo
|
|
178
177
|
):
|
|
179
178
|
coros = []
|
|
180
|
-
for motor,
|
|
179
|
+
for motor, cs_index in motor_info.motor_cs_index.items():
|
|
181
180
|
coros.append(
|
|
182
|
-
self.pmac.trajectory.positions[
|
|
181
|
+
self.pmac.trajectory.positions[cs_index].set(
|
|
183
182
|
trajectory.positions[motor]
|
|
184
183
|
)
|
|
185
184
|
)
|
|
186
185
|
coros.append(
|
|
187
|
-
self.pmac.trajectory.velocities[
|
|
186
|
+
self.pmac.trajectory.velocities[cs_index].set(
|
|
188
187
|
trajectory.velocities[motor]
|
|
189
188
|
)
|
|
190
189
|
)
|
|
@@ -206,7 +205,7 @@ class PmacTrajectoryTriggerLogic(FlyerController):
|
|
|
206
205
|
for motor, position in ramp_up_position.items():
|
|
207
206
|
coros.append(
|
|
208
207
|
set_and_wait_for_value(
|
|
209
|
-
coord.cs_axis_setpoint[motor_info.motor_cs_index[motor]
|
|
208
|
+
coord.cs_axis_setpoint[motor_info.motor_cs_index[motor]],
|
|
210
209
|
position,
|
|
211
210
|
set_timeout=10,
|
|
212
211
|
wait_for_set_completion=False,
|
ophyd_async/epics/pmac/_utils.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import re
|
|
4
5
|
from collections.abc import Sequence
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
|
|
@@ -10,7 +11,7 @@ from scanspec.core import Slice
|
|
|
10
11
|
from ophyd_async.core import gather_dict
|
|
11
12
|
from ophyd_async.epics.motor import Motor
|
|
12
13
|
|
|
13
|
-
from ._pmac_io import
|
|
14
|
+
from ._pmac_io import CS_INDEX, PmacIO
|
|
14
15
|
|
|
15
16
|
# PMAC durations are in milliseconds
|
|
16
17
|
# We must convert from scanspec durations (seconds) to milliseconds
|
|
@@ -21,6 +22,11 @@ TICK_S = 0.000001
|
|
|
21
22
|
MIN_TURNAROUND = 0.002
|
|
22
23
|
MIN_INTERVAL = 0.002
|
|
23
24
|
|
|
25
|
+
# Regex to parse outlink strings of the form "@asyn(PMAC1CS2, 7)"
|
|
26
|
+
# returning PMAC1CS2 and 7
|
|
27
|
+
# https://regex101.com/r/Mu9XpO/1
|
|
28
|
+
OUTLINK_REGEX = re.compile(r"^\@asyn\(([^,]+),\s*(\d+)\)$")
|
|
29
|
+
|
|
24
30
|
|
|
25
31
|
@dataclass
|
|
26
32
|
class _PmacMotorInfo:
|
|
@@ -44,78 +50,115 @@ class _PmacMotorInfo:
|
|
|
44
50
|
dictionaries of motor's to their unique CS index and accelerate rate
|
|
45
51
|
|
|
46
52
|
"""
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
for
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
is_raw_motor = [motor in pmac.motor_assignment_index for motor in motors]
|
|
54
|
+
if all(is_raw_motor):
|
|
55
|
+
# Get the CS port, number and axis letter from the PVs for the raw motor
|
|
56
|
+
assignments = {
|
|
57
|
+
motor: pmac.assignment[pmac.motor_assignment_index[motor]]
|
|
58
|
+
for motor in motors
|
|
59
|
+
}
|
|
60
|
+
cs_ports, cs_numbers, cs_axis_letters = await asyncio.gather(
|
|
61
|
+
gather_dict(
|
|
62
|
+
{motor: assignments[motor].cs_port.get_value() for motor in motors}
|
|
63
|
+
),
|
|
64
|
+
gather_dict(
|
|
65
|
+
{
|
|
66
|
+
motor: assignments[motor].cs_number.get_value()
|
|
67
|
+
for motor in motors
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
gather_dict(
|
|
71
|
+
{
|
|
72
|
+
motor: assignments[motor].cs_axis_letter.get_value()
|
|
73
|
+
for motor in motors
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
)
|
|
77
|
+
# Translate axis letters to cs_index and check for duplicates
|
|
78
|
+
motor_cs_index: dict[Motor, int] = {}
|
|
79
|
+
for motor, cs_axis_letter in cs_axis_letters.items():
|
|
80
|
+
if not cs_axis_letter:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Motor {motor.name} does not have an axis assignment."
|
|
83
|
+
)
|
|
84
|
+
try:
|
|
85
|
+
# 1 indexed to match coord
|
|
86
|
+
index = CS_INDEX[cs_axis_letter]
|
|
87
|
+
except KeyError as err:
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"Motor {motor.name} assigned to '{cs_axis_letter}' "
|
|
90
|
+
f"but must be assigned to one of '{','.join(CS_INDEX)}'"
|
|
91
|
+
) from err
|
|
92
|
+
if index in motor_cs_index.values():
|
|
93
|
+
raise ValueError(
|
|
94
|
+
f"Motor {motor.name} assigned to '{cs_axis_letter}' "
|
|
95
|
+
"but another motor is already assigned to this axis."
|
|
96
|
+
)
|
|
97
|
+
motor_cs_index[motor] = index
|
|
98
|
+
elif not any(is_raw_motor):
|
|
99
|
+
# Get CS numbers from all the cs ports and output links for the CS motors
|
|
100
|
+
output_links, cs_lookup = await asyncio.gather(
|
|
101
|
+
gather_dict({motor: motor.output_link.get_value() for motor in motors}),
|
|
102
|
+
gather_dict(
|
|
103
|
+
{
|
|
104
|
+
cs_number: cs.cs_port.get_value()
|
|
105
|
+
for cs_number, cs in pmac.coord.items()
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
# Create a reverse lookup from cs_port to cs_number
|
|
110
|
+
cs_reverse_lookup = {
|
|
111
|
+
cs_port: cs_number for cs_number, cs_port in cs_lookup.items()
|
|
112
|
+
}
|
|
113
|
+
cs_ports: dict[Motor, str] = {}
|
|
114
|
+
cs_numbers: dict[Motor, int] = {}
|
|
115
|
+
motor_cs_index: dict[Motor, int] = {}
|
|
116
|
+
# Populate the cs_ports, cs_numbers and motor_cs_index dicts from outlinks
|
|
117
|
+
for motor, output_link in output_links.items():
|
|
118
|
+
match = OUTLINK_REGEX.match(output_link)
|
|
119
|
+
if not match:
|
|
120
|
+
raise ValueError(
|
|
121
|
+
f"Motor {motor.name} has invalid output link '{output_link}'"
|
|
122
|
+
)
|
|
123
|
+
cs_port, cs_index = match.groups()
|
|
124
|
+
cs_ports[motor] = cs_port
|
|
125
|
+
cs_numbers[motor] = cs_reverse_lookup[cs_port]
|
|
126
|
+
motor_cs_index[motor] = int(cs_index)
|
|
127
|
+
else:
|
|
128
|
+
raise ValueError("Unable to use raw motors and CS motors in the same scan")
|
|
70
129
|
|
|
71
130
|
# check if the values in cs_port and cs_number are the same
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if len(cs_ports) != 1:
|
|
131
|
+
cs_ports_set = set(cs_ports.values())
|
|
132
|
+
if len(cs_ports_set) != 1:
|
|
75
133
|
raise RuntimeError(
|
|
76
134
|
"Failed to fetch common CS port."
|
|
77
135
|
"Motors passed are assigned to multiple CS ports:"
|
|
78
|
-
f"{list(
|
|
136
|
+
f"{list(cs_ports_set)}"
|
|
79
137
|
)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
cs_numbers = set(cs_numbers.values())
|
|
84
|
-
if len(cs_numbers) != 1:
|
|
138
|
+
cs_numbers_set = set(cs_numbers.values())
|
|
139
|
+
if len(cs_numbers_set) != 1:
|
|
85
140
|
raise RuntimeError(
|
|
86
141
|
"Failed to fetch common CS number."
|
|
87
142
|
"Motors passed are assigned to multiple CS numbers:"
|
|
88
|
-
f"{list(
|
|
143
|
+
f"{list(cs_numbers_set)}"
|
|
89
144
|
)
|
|
90
145
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
motor_cs_index[motor] = CS_LETTERS.index(cs_axes[motor])
|
|
99
|
-
except ValueError as err:
|
|
100
|
-
raise ValueError(
|
|
101
|
-
"Failed to get motor CS index. "
|
|
102
|
-
f"Motor {motor.name} assigned to '{cs_axes[motor]}' "
|
|
103
|
-
f"but must be assignmed to '{CS_LETTERS}"
|
|
104
|
-
) from err
|
|
105
|
-
if len(set(motor_cs_index.values())) != len(motor_cs_index.items()):
|
|
106
|
-
raise RuntimeError(
|
|
107
|
-
"Failed to fetch distinct CS Axes."
|
|
108
|
-
"Motors passed are assigned to the same CS Axis"
|
|
109
|
-
f"{list(motor_cs_index)}"
|
|
110
|
-
)
|
|
111
|
-
|
|
146
|
+
# Get the velocities and acceleration rates for each motor
|
|
147
|
+
max_velocity, acceleration_time = await asyncio.gather(
|
|
148
|
+
gather_dict({motor: motor.max_velocity.get_value() for motor in motors}),
|
|
149
|
+
gather_dict(
|
|
150
|
+
{motor: motor.acceleration_time.get_value() for motor in motors}
|
|
151
|
+
),
|
|
152
|
+
)
|
|
112
153
|
motor_acceleration_rate = {
|
|
113
|
-
motor:
|
|
114
|
-
for motor in velocities
|
|
154
|
+
motor: max_velocity[motor] / acceleration_time[motor] for motor in motors
|
|
115
155
|
}
|
|
116
|
-
|
|
117
156
|
return _PmacMotorInfo(
|
|
118
|
-
cs_port,
|
|
157
|
+
cs_port=cs_ports_set.pop(),
|
|
158
|
+
cs_number=cs_numbers_set.pop(),
|
|
159
|
+
motor_cs_index=motor_cs_index,
|
|
160
|
+
motor_acceleration_rate=motor_acceleration_rate,
|
|
161
|
+
motor_max_velocity=max_velocity,
|
|
119
162
|
)
|
|
120
163
|
|
|
121
164
|
|
|
@@ -8,7 +8,6 @@ from ._signal import (
|
|
|
8
8
|
tango_signal_w,
|
|
9
9
|
tango_signal_x,
|
|
10
10
|
)
|
|
11
|
-
from ._tango_readable import TangoReadable
|
|
12
11
|
from ._tango_transport import (
|
|
13
12
|
AttributeProxy,
|
|
14
13
|
CommandProxy,
|
|
@@ -50,7 +49,6 @@ __all__ = [
|
|
|
50
49
|
"tango_signal_w",
|
|
51
50
|
"tango_signal_x",
|
|
52
51
|
"TangoDevice",
|
|
53
|
-
"TangoReadable",
|
|
54
52
|
"TangoPolling",
|
|
55
53
|
"TangoDeviceConnector",
|
|
56
54
|
"TangoLongStringTable",
|
|
@@ -29,7 +29,7 @@ class TangoDevice(Device):
|
|
|
29
29
|
|
|
30
30
|
def __init__(
|
|
31
31
|
self,
|
|
32
|
-
trl: str
|
|
32
|
+
trl: str = "",
|
|
33
33
|
support_events: bool = False,
|
|
34
34
|
name: str = "",
|
|
35
35
|
auto_fill_signals: bool = True,
|
|
@@ -80,6 +80,9 @@ class TangoDeviceConnector(DeviceConnector):
|
|
|
80
80
|
self._support_events = support_events
|
|
81
81
|
self._auto_fill_signals = auto_fill_signals
|
|
82
82
|
|
|
83
|
+
def set_trl(self, trl: str):
|
|
84
|
+
self.trl = trl
|
|
85
|
+
|
|
83
86
|
def create_children_from_annotations(self, device: Device):
|
|
84
87
|
if not hasattr(self, "filler"):
|
|
85
88
|
self.filler = DeviceFiller(
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
from typing import Annotated as A
|
|
2
2
|
|
|
3
|
-
from ophyd_async.core import
|
|
3
|
+
from ophyd_async.core import (
|
|
4
|
+
DEFAULT_TIMEOUT,
|
|
5
|
+
AsyncStatus,
|
|
6
|
+
SignalR,
|
|
7
|
+
SignalRW,
|
|
8
|
+
SignalX,
|
|
9
|
+
StandardReadable,
|
|
10
|
+
)
|
|
4
11
|
from ophyd_async.core import StandardReadableFormat as Format
|
|
5
|
-
from ophyd_async.tango.core import
|
|
12
|
+
from ophyd_async.tango.core import TangoDevice, TangoPolling
|
|
6
13
|
|
|
7
14
|
|
|
8
|
-
class TangoCounter(
|
|
15
|
+
class TangoCounter(TangoDevice, StandardReadable):
|
|
9
16
|
"""Tango counting device."""
|
|
10
17
|
|
|
11
18
|
# Enter the name and type of the signals you want to use
|
ophyd_async/tango/demo/_mover.py
CHANGED
|
@@ -11,16 +11,17 @@ from ophyd_async.core import (
|
|
|
11
11
|
SignalR,
|
|
12
12
|
SignalRW,
|
|
13
13
|
SignalX,
|
|
14
|
+
StandardReadable,
|
|
14
15
|
WatchableAsyncStatus,
|
|
15
16
|
WatcherUpdate,
|
|
16
17
|
observe_value,
|
|
17
18
|
wait_for_value,
|
|
18
19
|
)
|
|
19
20
|
from ophyd_async.core import StandardReadableFormat as Format
|
|
20
|
-
from ophyd_async.tango.core import DevStateEnum,
|
|
21
|
+
from ophyd_async.tango.core import DevStateEnum, TangoDevice, TangoPolling
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
class TangoMover(
|
|
24
|
+
class TangoMover(TangoDevice, StandardReadable, Movable, Stoppable):
|
|
24
25
|
"""Tango moving device."""
|
|
25
26
|
|
|
26
27
|
# Enter the name and type of the signals you want to use
|
|
@@ -32,7 +33,7 @@ class TangoMover(TangoReadable, Movable, Stoppable):
|
|
|
32
33
|
# If a tango name clashes with a bluesky verb, add a trailing underscore
|
|
33
34
|
stop_: SignalX
|
|
34
35
|
|
|
35
|
-
def __init__(self, trl: str
|
|
36
|
+
def __init__(self, trl: str = "", name=""):
|
|
36
37
|
super().__init__(trl, name=name)
|
|
37
38
|
self.add_readables([self.position], Format.HINTED_SIGNAL)
|
|
38
39
|
self.add_readables([self.velocity], Format.CONFIG_SIGNAL)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.7
|
|
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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
ophyd_async/__init__.py,sha256=dcAA3qsj1nNIMe5l-v2tlduZ_ypwBmyuHe45Lsq4k4w,206
|
|
2
2
|
ophyd_async/__main__.py,sha256=n_U4O9bgm97OuboUB_9eK7eFiwy8BZSgXJ0OzbE0DqU,481
|
|
3
3
|
ophyd_async/_docs_parser.py,sha256=gPYrigfSbYCF7QoSf2UvE-cpQu4snSssl7ZWN-kKDzI,352
|
|
4
|
-
ophyd_async/_version.py,sha256=
|
|
4
|
+
ophyd_async/_version.py,sha256=JHUU2H4LQG4g5yLVtdeoRqh4fKkn1TUpLvJEVN4qjr4,706
|
|
5
5
|
ophyd_async/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
ophyd_async/core/__init__.py,sha256=yGbkVju5otO8DmA3KyerYB0gLtcX5sdxlq3ajyGha4M,5531
|
|
7
7
|
ophyd_async/core/_derived_signal.py,sha256=TuZza_j3J1Bw4QSqBYB9Ta2FyQP5BycO3nSHVtJ890Q,13015
|
|
@@ -18,7 +18,7 @@ ophyd_async/core/_protocol.py,sha256=wQ_snxhTprHqEjQb1HgFwBljwolMY6A8C3xgV1PXwdU
|
|
|
18
18
|
ophyd_async/core/_providers.py,sha256=WBht3QCgvGc0stNcwH6z4Zr6hAz3e01-88NjsYI2w6I,9740
|
|
19
19
|
ophyd_async/core/_readable.py,sha256=iBo1YwA5bsAbzLbznvmSnzKDWUuGkLh850Br3BXsgeU,11707
|
|
20
20
|
ophyd_async/core/_settings.py,sha256=_ZccbXKP7j5rG6-bMKk7aaLr8hChdRDAPY_YSR71XXM,4213
|
|
21
|
-
ophyd_async/core/_signal.py,sha256=
|
|
21
|
+
ophyd_async/core/_signal.py,sha256=LVQ38-Txn6lIYFsIbRbZClOy9WXlLDc16FdaE1wVmII,28278
|
|
22
22
|
ophyd_async/core/_signal_backend.py,sha256=F3ma45cIIJ3D702zsVZIqn4Jv7u05YzMQBQND70QCbQ,6987
|
|
23
23
|
ophyd_async/core/_soft_signal_backend.py,sha256=NJUuyaCKtBZjggt8WKi7_lKQRHasToxviuQvl5xbhLU,6222
|
|
24
24
|
ophyd_async/core/_status.py,sha256=a2IDvv_GvUcFuhjQA5bQzWm9ngR6zGc9PR4XcZiaeqk,6557
|
|
@@ -26,7 +26,7 @@ ophyd_async/core/_table.py,sha256=ryJ7AwJBglQUzwP9_aSjR8cu8EKvYXfo1q1byhke3Uc,72
|
|
|
26
26
|
ophyd_async/core/_utils.py,sha256=gUewO4XPrBxsEWzObNumqAB2Q7Hwrd5F_Nc6B2XwQIM,12532
|
|
27
27
|
ophyd_async/core/_yaml_settings.py,sha256=Qojhku9l5kPSkTnEylCRWTe0gpw6S_XP5av5dPpqFgQ,2089
|
|
28
28
|
ophyd_async/epics/__init__.py,sha256=ou4yEaH9VZHz70e8oM614-arLMQvUfQyXhRJsnEpWn8,60
|
|
29
|
-
ophyd_async/epics/motor.py,sha256=
|
|
29
|
+
ophyd_async/epics/motor.py,sha256=RDcyKC_zFR5zLpAcf_yAbuY-1ImE3L3uBAoUXDEiz-s,10224
|
|
30
30
|
ophyd_async/epics/signal.py,sha256=0A-supp9ajr63O6aD7F9oG0-Q26YmRjk-ZGh57-jo1Y,239
|
|
31
31
|
ophyd_async/epics/adandor/__init__.py,sha256=dlitllrAdhvh16PAcVMUSSEytTDNMu6_HuYk8KD1EoY,343
|
|
32
32
|
ophyd_async/epics/adandor/_andor.py,sha256=TijGjNVxuH-P0X7UACPt9eLLQ449DwMyVhbn1kV7Le8,1245
|
|
@@ -83,10 +83,10 @@ ophyd_async/epics/demo/point_detector_channel.db,sha256=FZ9H6HjqplhcF2jgimv_dT1n
|
|
|
83
83
|
ophyd_async/epics/odin/__init__.py,sha256=7kRqVzwoD8PVtp7Nj9iQWlgbLeoWE_8oiq-B0kixwTE,93
|
|
84
84
|
ophyd_async/epics/odin/_odin_io.py,sha256=YDBrS15PnEKe5SHmz397Emh--lZSQEnbR3G7p8pbShY,6533
|
|
85
85
|
ophyd_async/epics/pmac/__init__.py,sha256=GqJTiJudqE9pu050ZNED09F9tKRfazn0wBsojsMH2gg,273
|
|
86
|
-
ophyd_async/epics/pmac/_pmac_io.py,sha256=
|
|
87
|
-
ophyd_async/epics/pmac/_pmac_trajectory.py,sha256=
|
|
86
|
+
ophyd_async/epics/pmac/_pmac_io.py,sha256=cbChieNrDWRzrr5Mdsqtm2Azp8sG0KHP9rGeJxmbYrA,4332
|
|
87
|
+
ophyd_async/epics/pmac/_pmac_trajectory.py,sha256=hzAcpLNmFoNceubsjk6mjsmg6-PgSjWUu1a8Exyvi6I,7729
|
|
88
88
|
ophyd_async/epics/pmac/_pmac_trajectory_generation.py,sha256=3IIxXa0r6-2uNnILKLGxp3xosOZx8MubKF-F_OM7uaw,27331
|
|
89
|
-
ophyd_async/epics/pmac/_utils.py,sha256=
|
|
89
|
+
ophyd_async/epics/pmac/_utils.py,sha256=MfuY6NicT7wkwVIWAZkWoCu1ZoSzy6jda1wLK9XAOLA,8614
|
|
90
90
|
ophyd_async/epics/testing/__init__.py,sha256=aTIv4D2DYrpnGco5RQF8QuLG1SfFkIlTyM2uYEKXltA,522
|
|
91
91
|
ophyd_async/epics/testing/_example_ioc.py,sha256=zb4ZEUzuB2MrSw5ETPLIiHhf-2BRU1Bdxco6Kh4iI1I,3880
|
|
92
92
|
ophyd_async/epics/testing/_utils.py,sha256=9gxpwaWX0HGtacu1LTupcw7viXN8G78RmuNciU_-cjs,1702
|
|
@@ -131,17 +131,16 @@ ophyd_async/sim/_pattern_generator.py,sha256=kuxvyX2gIxrywhQRhaO1g8YluBT7LBkE20I
|
|
|
131
131
|
ophyd_async/sim/_point_detector.py,sha256=wMG_ncvm99WMCPihlFyuMEf3UknAxCpB1hpk3uKiENE,3024
|
|
132
132
|
ophyd_async/sim/_stage.py,sha256=_SywbmSQwxf7JLx68qwo0RpiB3oIWlbTLmvRKxUoig0,1602
|
|
133
133
|
ophyd_async/tango/__init__.py,sha256=g9xzjlzPpUAP12YI-kYwfAoLSYPAQdL1S11R2c-cius,60
|
|
134
|
-
ophyd_async/tango/core/__init__.py,sha256=
|
|
135
|
-
ophyd_async/tango/core/_base_device.py,sha256=
|
|
134
|
+
ophyd_async/tango/core/__init__.py,sha256=dO2tG_y61zZFQRQh5L37Ps-IqNf-DGOT77Ov5Kobfhs,1349
|
|
135
|
+
ophyd_async/tango/core/_base_device.py,sha256=X5ncxaWKOfRhhqPyT8tmTBJGc3ldGthw1ZCe_j_M2Tg,5088
|
|
136
136
|
ophyd_async/tango/core/_converters.py,sha256=xI_RhMR8dY6IVORUZVVCL9LdYnEE6TA6BBPX_lTu06w,2183
|
|
137
137
|
ophyd_async/tango/core/_signal.py,sha256=8mIxRVEVjhDN33LDbbKZWGMUYn9Gl5ZMEIYw6GSBTUE,5569
|
|
138
|
-
ophyd_async/tango/core/_tango_readable.py,sha256=ctR6YcBGGatW6Jp2kvddA1hVZ2v1CidPsF9FmJK9BYg,406
|
|
139
138
|
ophyd_async/tango/core/_tango_transport.py,sha256=KxjhHqKADrOvzGi9tbOQXUWdsJ0NKGejWxHItxpUsjg,37401
|
|
140
139
|
ophyd_async/tango/core/_utils.py,sha256=pwT7V1DNWSyPOSzvDZ6OsDZTjaV-pAeDLDlmgtHVcNM,1673
|
|
141
140
|
ophyd_async/tango/demo/__init__.py,sha256=_j-UicTnckuIBp8PnieFMOMnLFGivnaKdmo9o0hYtzc,256
|
|
142
|
-
ophyd_async/tango/demo/_counter.py,sha256=
|
|
141
|
+
ophyd_async/tango/demo/_counter.py,sha256=m6zxOJLbHgCEBAapVc1UiOOqKj5lvrlxjA6mXWMRMjo,1200
|
|
143
142
|
ophyd_async/tango/demo/_detector.py,sha256=X5YWHAjukKZ7iYF1fBNle4CBDj1X5rvj0lnPMOcnRCU,1340
|
|
144
|
-
ophyd_async/tango/demo/_mover.py,sha256=
|
|
143
|
+
ophyd_async/tango/demo/_mover.py,sha256=FyG9g1TLaWoqjbLblqWK8inMuDcNVlioq0MIeD5npz4,2913
|
|
145
144
|
ophyd_async/tango/demo/_tango/__init__.py,sha256=FfONT7vM49nNo3a1Lv-LcMZO9EHv6bv91yY-RnxIib4,85
|
|
146
145
|
ophyd_async/tango/demo/_tango/_servers.py,sha256=putvERDyibibaTbhdWyqZB_axj2fURXqzDsZb9oSW14,2991
|
|
147
146
|
ophyd_async/tango/testing/__init__.py,sha256=l52SmX9XuxZUBuLpOYJzHfskkWVYhx3RkSbGL_wUu5Y,199
|
|
@@ -155,8 +154,8 @@ ophyd_async/testing/_one_of_everything.py,sha256=U9ui7B-iNHDM3H3hIWUuaCb8Gc2eLlU
|
|
|
155
154
|
ophyd_async/testing/_single_derived.py,sha256=5-HOTzgePcZ354NK_ssVpyIbJoJmKyjVQCxSwQXUC-4,2730
|
|
156
155
|
ophyd_async/testing/_utils.py,sha256=zClRo5ve8RGia7wQnby41W-Zprj-slOA5da1LfYnuhw,45
|
|
157
156
|
ophyd_async/testing/_wait_for_pending.py,sha256=YZAR48n-CW0GsPey3zFRzMJ4byDAr3HvMIoawjmTrHw,732
|
|
158
|
-
ophyd_async-0.13.
|
|
159
|
-
ophyd_async-0.13.
|
|
160
|
-
ophyd_async-0.13.
|
|
161
|
-
ophyd_async-0.13.
|
|
162
|
-
ophyd_async-0.13.
|
|
157
|
+
ophyd_async-0.13.7.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
|
|
158
|
+
ophyd_async-0.13.7.dist-info/METADATA,sha256=D28G3xy4fiF7xtLVoy10CqOiI7ZLDs2z1MO6DICwVdA,5703
|
|
159
|
+
ophyd_async-0.13.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
160
|
+
ophyd_async-0.13.7.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
|
|
161
|
+
ophyd_async-0.13.7.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from ophyd_async.core import StandardReadable
|
|
4
|
-
|
|
5
|
-
from ._base_device import TangoDevice
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class TangoReadable(TangoDevice, StandardReadable):
|
|
9
|
-
def __init__(
|
|
10
|
-
self,
|
|
11
|
-
trl: str | None = None,
|
|
12
|
-
name: str = "",
|
|
13
|
-
auto_fill_signals: bool = True,
|
|
14
|
-
) -> None:
|
|
15
|
-
TangoDevice.__init__(self, trl, name=name, auto_fill_signals=auto_fill_signals)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|