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 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.6'
32
- __version_tuple__ = version_tuple = (0, 13, 6)
31
+ __version__ = version = '0.13.7'
32
+ __version_tuple__ = version_tuple = (0, 13, 7)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -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" {matcher.__name__}() in {timeout}s"
645
+ f" {matcher_name}() in {timeout}s"
645
646
  ) from exc
646
647
 
647
648
  return status
@@ -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
- motor_lower_limit, motor_upper_limit, egu = await asyncio.gather(
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
- if motor_lower_limit == 0 and motor_upper_limit == 0:
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
- CS_LETTERS = "ABCUVWXYZ"
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 + 1: epics_signal_rw(
24
- Array1D[np.float64], f"{prefix}{letter}:Positions"
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 + 1: epics_signal_rw(bool, f"{prefix}{letter}:UseAxis")
32
- for i, letter in enumerate(CS_LETTERS)
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 + 1: epics_signal_rw(
38
- Array1D[np.float64], f"{prefix}{letter}:Velocities"
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 + 1: epics_signal_rw(float, f"{prefix}M{i + 1}:DirectDemand")
80
- for i in range(len(CS_LETTERS))
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
- from ophyd_async.epics.pmac import PmacIO
19
- from ophyd_async.epics.pmac._pmac_io import CS_LETTERS
20
- from ophyd_async.epics.pmac._pmac_trajectory_generation import PVT, Trajectory
21
- from ophyd_async.epics.pmac._utils import (
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
- axis + 1: (axis in motor_info.motor_cs_index.values())
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, number in motor_info.motor_cs_index.items():
179
+ for motor, cs_index in motor_info.motor_cs_index.items():
181
180
  coros.append(
182
- self.pmac.trajectory.positions[number + 1].set(
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[number + 1].set(
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] + 1],
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,
@@ -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 CS_LETTERS, PmacIO
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
- assignments = {
48
- motor: pmac.assignment[pmac.motor_assignment_index[motor]]
49
- for motor in motors
50
- }
51
-
52
- cs_ports, cs_numbers, cs_axes, velocities, accls = await asyncio.gather(
53
- gather_dict(
54
- {motor: assignments[motor].cs_port.get_value() for motor in motors}
55
- ),
56
- gather_dict(
57
- {motor: assignments[motor].cs_number.get_value() for motor in motors}
58
- ),
59
- gather_dict(
60
- {
61
- motor: assignments[motor].cs_axis_letter.get_value()
62
- for motor in motors
63
- }
64
- ),
65
- gather_dict({motor: motor.max_velocity.get_value() for motor in motors}),
66
- gather_dict(
67
- {motor: motor.acceleration_time.get_value() for motor in motors}
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
- cs_ports = set(cs_ports.values())
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(cs_ports)}"
136
+ f"{list(cs_ports_set)}"
79
137
  )
80
-
81
- cs_port = cs_ports.pop()
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(cs_numbers)}"
143
+ f"{list(cs_numbers_set)}"
89
144
  )
90
145
 
91
- cs_number = cs_numbers.pop()
92
-
93
- motor_cs_index = {}
94
- for motor in cs_axes:
95
- try:
96
- if not cs_axes[motor]:
97
- raise ValueError
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: float(velocities[motor]) / float(accls[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, cs_number, motor_cs_index, motor_acceleration_rate, velocities
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 | None,
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 DEFAULT_TIMEOUT, AsyncStatus, SignalR, SignalRW, SignalX
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 TangoPolling, TangoReadable
12
+ from ophyd_async.tango.core import TangoDevice, TangoPolling
6
13
 
7
14
 
8
- class TangoCounter(TangoReadable):
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
@@ -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, TangoPolling, TangoReadable
21
+ from ophyd_async.tango.core import DevStateEnum, TangoDevice, TangoPolling
21
22
 
22
23
 
23
- class TangoMover(TangoReadable, Movable, Stoppable):
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 | None = "", name=""):
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.6
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=opPR5vtgMqtAtI-1B5Bg_MEreSc0tb9JwaQhHrD7xNE,706
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=085vcyjhEyZECi4Svjq6DUM5kxrzZh8s5DoHR2LALOc,28195
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=nS6Vx4-6vYso3b_QtpE8p8dlys5jRr2LK7prZCkZMc8,9558
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=E7tdaq9FAM6BeGQG1L8ALEYpXOlyqTXl_NLLSWzmCdk,4345
87
- ophyd_async/epics/pmac/_pmac_trajectory.py,sha256=7wTaetNNy9uj7C_skcs0VH5BthuY4Ec5zn-m4ROxd8k,7866
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=n4vh9n7hmaWe9g02FtguF2oDsYuVvsTgmK7fYEyGuIE,6092
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=OOVdHu07cssK90F-caG0CY7qKpPYy0MSV421YNAI-_8,1413
135
- ophyd_async/tango/core/_base_device.py,sha256=e9oqSL-fDOj8r9nUUFZkbibhRGbI6HYtlnZjK5B_2fE,5033
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=2J4SCHnBWLF0O5mFWlJdO4tmnElvlx5sRrk4op_AC9U,1139
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=i-Tq5nDmYi4RcC4O6mOJoVeMEIIxuqyS_2AfjTpAcnk,2884
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.6.dist-info/licenses/LICENSE,sha256=pU5shZcsvWgz701EbT7yjFZ8rMvZcWgRH54CRt8ld_c,1517
159
- ophyd_async-0.13.6.dist-info/METADATA,sha256=o3yNVUgIIR1UiWECtmQX9WZLuZAu4et3sru1DKoOsDM,5703
160
- ophyd_async-0.13.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
161
- ophyd_async-0.13.6.dist-info/top_level.txt,sha256=-hjorMsv5Rmjo3qrgqhjpal1N6kW5vMxZO3lD4iEaXs,12
162
- ophyd_async-0.13.6.dist-info/RECORD,,
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)