dls-dodal 1.57.0__py3-none-any.whl → 1.58.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dls-dodal
3
- Version: 1.57.0
3
+ Version: 1.58.0
4
4
  Summary: Ophyd devices and other utils that could be used across DLS beamlines
5
5
  Author-email: Dominic Oram <dominic.oram@diamond.ac.uk>, Joseph Ware <joseph.ware@diamond.ac.uk>, Oliver Silvester <Oliver.Silvester@diamond.ac.uk>, Noemi Frisina <noemi.frisina@diamond.ac.uk>
6
6
  License: Apache License
@@ -1,7 +1,7 @@
1
- dls_dodal-1.57.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
1
+ dls_dodal-1.58.0.dist-info/licenses/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
2
2
  dodal/__init__.py,sha256=Ksms_WJF8LTkbm38gEpm1jBpGqcQ8NGvmb2ZJlOE1j8,198
3
3
  dodal/__main__.py,sha256=kP2S2RPitnOWpNGokjZ1Yq-1umOtp5sNOZk2B3tBPLM,111
4
- dodal/_version.py,sha256=UMWpFq_XEVs_RQua2c3vn_WoxKKPZqViS9Btwn1PIkY,706
4
+ dodal/_version.py,sha256=0S_WOya-t7UDFMpZKDOCqr088G6Obb9i_ReErRJRu3o,706
5
5
  dodal/cli.py,sha256=yi8dXOp0hqzlg4ZZXCRGU-LpDa_ydaropDjyREWbZ5Y,4152
6
6
  dodal/log.py,sha256=Rt5O3hFZfMnJvQueZvgagQuXnPqHrFxhponOvVkpfrk,9871
7
7
  dodal/utils.py,sha256=abGitd4FLpLnmckF7lUqOKYUL88r5Ex_NGSVgO4gOf4,19305
@@ -19,8 +19,8 @@ dodal/beamlines/b16.py,sha256=rK00hEj8KLGNkLZr9omAuoMz_DyLN9rK4eUQssETR9E,1703
19
19
  dodal/beamlines/b18.py,sha256=ryxrGtcCdwoFgZ8ljWYgr1g9gKvoA7nxkARVxl1IE78,1189
20
20
  dodal/beamlines/b21.py,sha256=mN21vnOBmnwzG695HuV7P5DkuTtU8joflJI-evOpgwc,3333
21
21
  dodal/beamlines/i02_1.py,sha256=d2IyqFMgeaSEyZYm7GMSjTKr7_02SakyC_oARx-XwnY,1204
22
- dodal/beamlines/i03.py,sha256=4ZDmWoqHBz1fu0sgMOinQsxBDnH70oeGs78XIrgVMEs,16132
23
- dodal/beamlines/i04.py,sha256=MhKVuMdbw58YSYbLKaRmkoUHjOykqS10jEWp35d8H3Y,13228
22
+ dodal/beamlines/i03.py,sha256=wYeOyVn7UKhj7NhoGSeiFzK3TduL6YHMIHg37tVmE18,16170
23
+ dodal/beamlines/i04.py,sha256=mRzHnKSKHVmJzs6fwpfBi0QSiry72ixYqa-bs96-0gU,13717
24
24
  dodal/beamlines/i05.py,sha256=v4QKd8-neh4Og205oovm6NDRnAU6Oktu1WrxalXsI40,656
25
25
  dodal/beamlines/i05_1.py,sha256=R6JFFg8Bj-Izw355mx3mOd4IDvJb5ipB4p7_S0I_4Z0,670
26
26
  dodal/beamlines/i09.py,sha256=OrqOcVanJU4F7erRZZDkjLwV8VnLlUzz3LUduaCBgUc,1629
@@ -32,7 +32,7 @@ dodal/beamlines/i13_1.py,sha256=VYVqMN8-njy7YSI08gskRccT-K2paRC9edAx0ah-Cwo,1602
32
32
  dodal/beamlines/i17.py,sha256=Nickt8CKQ9JcQ1D_ulNICUT4jjLF1Aib7D9jblSnzA4,987
33
33
  dodal/beamlines/i18.py,sha256=FuU8G-q1piu6BRou-Shj3BQEbNtsF7CUsSIqqkvCKZc,3615
34
34
  dodal/beamlines/i19_1.py,sha256=tg3eALJTn9p686VFV7GjfUvChGS1mrh8-98uzjdLj_g,2934
35
- dodal/beamlines/i19_2.py,sha256=xSMS2Vhk_6V5WYyefVo1SWXbC4UUyaqru7JVK8VTg00,2554
35
+ dodal/beamlines/i19_2.py,sha256=qotmAulSL2zTLaoxG1Mf6UabeJV-X4iekL0cotTtTww,2929
36
36
  dodal/beamlines/i19_optics.py,sha256=8hdlDAAMgFrhcXrp5xCPZtLUlrDUEC9VwKnnuUAMbbU,1150
37
37
  dodal/beamlines/i20_1.py,sha256=Zsr1lsH7ySbOgK7RhMVMWzNWZAV-fuYW0iAjSEJZicY,2625
38
38
  dodal/beamlines/i22.py,sha256=009Tk5cYyHfmm1DfIwR562WzomXRvyv_5chiBbPgQUs,8100
@@ -58,13 +58,14 @@ dodal/common/watcher_utils.py,sha256=jWtXjr2a2NAcTy8A9OnvtB_hWh3GuuLvWxVWHouSvOs
58
58
  dodal/common/beamlines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  dodal/common/beamlines/beamline_parameters.py,sha256=nYTy5TDYegvon6iNCxf7Uez3hbdu9GCoLUmJhRO1qhE,2665
60
60
  dodal/common/beamlines/beamline_utils.py,sha256=UnDJlRs7p8srjv-peX05jHZBb8J2d2lPSyG9118x560,5286
61
+ dodal/common/beamlines/commissioning_mode.py,sha256=KL24Ia4IOkSxi7M4CKRRQQW0T3HUDpj7K3Y5_DtALRA,1314
61
62
  dodal/common/beamlines/device_helpers.py,sha256=8sasAIFRDwo6ElHqLrXnpj_v7xcEg-29Zhey_e4r9u8,84
62
63
  dodal/devices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
64
  dodal/devices/aperture.py,sha256=S7AoIoQg_kFxaQk7HUMijbm1kYkOEi2csbdj76kp1ys,427
64
65
  dodal/devices/aperturescatterguard.py,sha256=FH2oru3DU-I6BwOJOVEgHdFplLKIIknxtEBUBAXZ_WA,13946
65
66
  dodal/devices/apple2_undulator.py,sha256=KbAX1GstP01XOm-QpXlyWCJewfxXKKawnoqbsfsksyY,26265
66
67
  dodal/devices/backlight.py,sha256=y40kR6N3qSFVLRaGU8CjJJpwv_hq2QALf_85fLQqras,1415
67
- dodal/devices/baton.py,sha256=BnakfZxx3cIIX6Kxj8-abxn8Z9LaQODhcPbStbD0as4,485
68
+ dodal/devices/baton.py,sha256=315I_0V73_DYYVT0PBs0luVy4CMqdPo0kLvHBi12MIU,606
68
69
  dodal/devices/bimorph_mirror.py,sha256=OGe6aCczG0gVco4OvIRLJVxn2kw5F2QG1e06uqhFLTw,4609
69
70
  dodal/devices/collimation_table.py,sha256=64HunSPJH-L2gZdfIj_RYdOlOuwRFEfMHfLHzu4BAKI,1681
70
71
  dodal/devices/common_dcm.py,sha256=8QSRE6Z10RQjfL3g4JZhyHRNI_aCKxWlzKSsDgiJHhE,3049
@@ -97,10 +98,10 @@ dodal/devices/synchrotron.py,sha256=OHBrTrm4K39XE8BrE9b_Jn_ZfMRyDp9CHCwvmiV-KOc,
97
98
  dodal/devices/tetramm.py,sha256=qBu2ClXRM4RFO-y4C2pXVKsp5sX4VpOelbVHOAkkUHQ,8936
98
99
  dodal/devices/thawer.py,sha256=HexahKZ1rUxF9jBMeULruqYt6I7fsl6OgXkvcxPQY3M,1963
99
100
  dodal/devices/turbo_slit.py,sha256=xhcnhfbdcTYSYozogw6Li4fF4ofoPsc350rEyrRdaNE,1460
100
- dodal/devices/undulator.py,sha256=3IRn1iOF1PLOuIzaMpsNLVYx-rGvAnr-PG7C3YupW-w,5266
101
+ dodal/devices/undulator.py,sha256=SsgYvIEQUNs_zZiUPAzlw0yJPaSExdmBFltlq5ypbc8,5530
101
102
  dodal/devices/watsonmarlow323_pump.py,sha256=xNwjoxW3NJIDkeDWHfb0A8Yj95_KKRXMD9AghvX-WLk,1337
102
103
  dodal/devices/webcam.py,sha256=UAx2KF0mKi6I-mJJUb5z56MHY-Wd89-tqyPcFbouQFg,2491
103
- dodal/devices/xbpm_feedback.py,sha256=Uv_jML9gkMT5OcpUrckzxDmsBmktEwV1lga6USxeRyY,1065
104
+ dodal/devices/xbpm_feedback.py,sha256=HKLY3k52FPe2G-EAg8ir2LSdeUuGvhRD73ibDZ4mjH8,1418
104
105
  dodal/devices/aithre_lasershaping/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
106
  dodal/devices/aithre_lasershaping/goniometer.py,sha256=-2ewYMcdzB1DqP9sMpr4L1i4KeTCrGAJfngAt9-eFWw,1005
106
107
  dodal/devices/aithre_lasershaping/laser_robot.py,sha256=vy-I1ASYflFYIUYePhT2l3l7g2iekrIFzLxA0GLmKY8,717
@@ -182,6 +183,7 @@ dodal/devices/i13_1/merlin_controller.py,sha256=myfmByOEXyMrlJZfsjOxDHeGQVwZGfsR
182
183
  dodal/devices/i18/KBMirror.py,sha256=W4R3TeulSjosUqAFIIznyWzje_Y2AoEf9f8N-NkisYM,710
183
184
  dodal/devices/i18/diode.py,sha256=nk5kvn4LsbhczRpCwHOO0_jJTYOz7MP9qm_uvBWuv7c,1468
184
185
  dodal/devices/i19/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
186
+ dodal/devices/i19/backlight.py,sha256=c3F8RTessUJmJHlCWATSj-W25qlkAttb-c95eS28lKs,662
185
187
  dodal/devices/i19/beamstop.py,sha256=JkcvkEmcC3eY3GHrvYNGqv2yDwrfgdpWKVZJWSadWW8,715
186
188
  dodal/devices/i19/blueapi_device.py,sha256=Tsl4vsREz7FM2d-kKJK-9tGrYbyKq4SLxnMlEKIM-g8,3966
187
189
  dodal/devices/i19/diffractometer.py,sha256=QCEi0Gko6Ja9_ec2vfdazwMspknvX63jcz8hQ2XW1xo,1182
@@ -253,8 +255,8 @@ dodal/testing/__init__.py,sha256=AUYZKAvVOs7ZvxO1dVhL0pDTleRO34FQlO5MNe_cwgU,96
253
255
  dodal/testing/setup.py,sha256=8cQnrzE5MQD4Etf0eqMarmtr-opsUOMQww-k1V7DzIQ,2442
254
256
  dodal/testing/electron_analyser/__init__.py,sha256=-lc1opD2dCv0x678-J-ApOhHtvEvcslfOQ7E613U8-Y,118
255
257
  dodal/testing/electron_analyser/device_factory.py,sha256=tkMY6fW3iI02DTD1XXHi4lH6sjo8RHHZBGDHSuTdmNU,2243
256
- dls_dodal-1.57.0.dist-info/METADATA,sha256=8uZwtRMSABZLLYumDM2RDWn4zaE5IJ6N5H5zMk5Vz1w,16928
257
- dls_dodal-1.57.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
258
- dls_dodal-1.57.0.dist-info/entry_points.txt,sha256=bycw_EKUzup_rxfCetOwcauXV4kLln_OPpPT8jEnr-I,94
259
- dls_dodal-1.57.0.dist-info/top_level.txt,sha256=xIozdmZk_wmMV4wugpq9-6eZs0vgADNUKz3j2UAwlhc,6
260
- dls_dodal-1.57.0.dist-info/RECORD,,
258
+ dls_dodal-1.58.0.dist-info/METADATA,sha256=FL_laMKISMqDK1hq8tvlBEF1M-r4XhFjVYBfT8yya5E,16928
259
+ dls_dodal-1.58.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
260
+ dls_dodal-1.58.0.dist-info/entry_points.txt,sha256=bycw_EKUzup_rxfCetOwcauXV4kLln_OPpPT8jEnr-I,94
261
+ dls_dodal-1.58.0.dist-info/top_level.txt,sha256=xIozdmZk_wmMV4wugpq9-6eZs0vgADNUKz3j2UAwlhc,6
262
+ dls_dodal-1.58.0.dist-info/RECORD,,
dodal/_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 = '1.57.0'
32
- __version_tuple__ = version_tuple = (1, 57, 0)
31
+ __version__ = version = '1.58.0'
32
+ __version_tuple__ = version_tuple = (1, 58, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
dodal/beamlines/i03.py CHANGED
@@ -261,6 +261,7 @@ def undulator(daq_configuration_path: str | None = None) -> Undulator:
261
261
  f"{BeamlinePrefix(BL).insertion_prefix}-MO-SERVC-01:",
262
262
  # evaluate here not as parameter default to enable post-import mocking
263
263
  id_gap_lookup_table_path=f"{daq_configuration_path or DAQ_CONFIGURATION_PATH}/lookup/BeamLine_Undulator_toGap.txt",
264
+ baton=baton(),
264
265
  )
265
266
 
266
267
 
@@ -333,7 +334,7 @@ def xbpm_feedback() -> XBPMFeedback:
333
334
  """Get the i03 XBPM feeback device, instantiate it if it hasn't already been.
334
335
  If this is called when already instantiated in i03, it will return the existing object.
335
336
  """
336
- return XBPMFeedback(f"{PREFIX.beamline_prefix}-EA-FDBK-01:")
337
+ return XBPMFeedback(f"{PREFIX.beamline_prefix}-EA-FDBK-01:", baton=baton())
337
338
 
338
339
 
339
340
  @device_factory()
dodal/beamlines/i04.py CHANGED
@@ -1,3 +1,5 @@
1
+ from ophyd_async.core import Reference
2
+
1
3
  from dodal.common.beamlines.beamline_parameters import get_beamline_parameters
2
4
  from dodal.common.beamlines.beamline_utils import (
3
5
  device_factory,
@@ -30,6 +32,7 @@ from dodal.devices.oav.oav_to_redis_forwarder import OAVToRedisForwarder
30
32
  from dodal.devices.oav.pin_image_recognition import PinTipDetection
31
33
  from dodal.devices.robot import BartRobot
32
34
  from dodal.devices.s4_slit_gaps import S4SlitGaps
35
+ from dodal.devices.scintillator import Scintillator
33
36
  from dodal.devices.smargon import Smargon
34
37
  from dodal.devices.synchrotron import Synchrotron
35
38
  from dodal.devices.thawer import Thawer
@@ -357,3 +360,15 @@ def pin_tip_detection() -> PinTipDetection:
357
360
  If this is called when already instantiated in i04, it will return the existing object.
358
361
  """
359
362
  return PinTipDetection(f"{PREFIX.beamline_prefix}-DI-OAV-01:")
363
+
364
+
365
+ @device_factory()
366
+ def scintillator() -> Scintillator:
367
+ """Get the i04 scintillator device, instantiate it if it hasn't already been.
368
+ If this is called when already instantiated in i04, it will return the existing object.
369
+ """
370
+ return Scintillator(
371
+ f"{PREFIX.beamline_prefix}-MO-SCIN-01:",
372
+ Reference(aperture_scatterguard()),
373
+ get_beamline_parameters(),
374
+ )
dodal/beamlines/i19_2.py CHANGED
@@ -4,6 +4,7 @@ from dodal.common.beamlines.beamline_utils import (
4
4
  from dodal.common.beamlines.beamline_utils import (
5
5
  set_beamline as set_utils_beamline,
6
6
  )
7
+ from dodal.devices.i19.backlight import BacklightPosition
7
8
  from dodal.devices.i19.beamstop import BeamStop
8
9
  from dodal.devices.i19.blueapi_device import HutchState
9
10
  from dodal.devices.i19.diffractometer import FourCircleDiffractometer
@@ -75,3 +76,11 @@ def synchrotron() -> Synchrotron:
75
76
  If this is called when already instantiated in i19-2, it will return the existing object.
76
77
  """
77
78
  return Synchrotron()
79
+
80
+
81
+ @device_factory()
82
+ def backlight() -> BacklightPosition:
83
+ """Get the i19-2 backlight device, instantiate it if it hasn't already been.
84
+ If this is called when already instantiated in i19-2, it will return the existing object.
85
+ """
86
+ return BacklightPosition(prefix=f"{PREFIX.beamline_prefix}-EA-IOC-12:")
@@ -0,0 +1,33 @@
1
+ """Functions relating to commissioning mode.
2
+
3
+ Commissioning Mode can be enabled for a production beamline when there is no
4
+ beam. The intent is that when it is enabled, bluesky plans may be run without beam
5
+ and plans and devices will as far as is possible behave normally.
6
+ """
7
+
8
+ import bluesky.plan_stubs as bps
9
+ from bluesky.utils import MsgGenerator
10
+ from ophyd_async.core import SignalR
11
+
12
+ _commissioning_signal: SignalR | None = None
13
+
14
+
15
+ def read_commissioning_mode() -> MsgGenerator[bool]:
16
+ """Utility method for reading the commissioning mode state from the context
17
+ of a bluesky plan, where a baton may or may not be present, or
18
+ commissioning mode is provided by some other mechanism."""
19
+ if _commissioning_signal:
20
+ return (yield from bps.rd(_commissioning_signal))
21
+ else:
22
+ return False
23
+
24
+
25
+ def set_commissioning_signal(signal: SignalR[bool] | None):
26
+ """Commissioning mode is enabled by a PV which when set enables commissioning mode.
27
+ This allows beamline staff to ensure that commissioning mode is disabled prior
28
+ to production use, via their own 'good morning' startup scripts.
29
+ Args:
30
+ signal: The signal which will be read in order to determine whether
31
+ commissioning mode is enabled."""
32
+ global _commissioning_signal
33
+ _commissioning_signal = signal
dodal/devices/baton.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from typing import Annotated as A
2
2
 
3
3
  from ophyd_async.core import (
4
+ SignalR,
4
5
  SignalRW,
5
6
  StandardReadable,
6
7
  )
@@ -15,3 +16,6 @@ class Baton(StandardReadable, EpicsDevice):
15
16
  current_user: A[
16
17
  SignalRW[str], PvSuffix("CURRENT_USER"), Format.HINTED_UNCACHED_SIGNAL
17
18
  ]
19
+ commissioning: A[
20
+ SignalR[bool], PvSuffix("COMMISSIONING"), Format.HINTED_UNCACHED_SIGNAL
21
+ ]
@@ -0,0 +1,17 @@
1
+ from bluesky.protocols import Movable
2
+ from ophyd_async.core import AsyncStatus, StandardReadable
3
+ from ophyd_async.epics.core import epics_signal_rw
4
+
5
+ from dodal.common.enums import InOutUpper
6
+
7
+
8
+ class BacklightPosition(StandardReadable, Movable[InOutUpper]):
9
+ """Device moves backlight to the IN or OUT position since controls side manages switching the light on/off"""
10
+
11
+ def __init__(self, prefix: str, name: str = "") -> None:
12
+ self.position = epics_signal_rw(InOutUpper, f"{prefix}AD1:choiceButton")
13
+ super().__init__(name)
14
+
15
+ @AsyncStatus.wrap
16
+ async def set(self, value: InOutUpper):
17
+ await self.position.set(value, wait=True)
@@ -5,6 +5,7 @@ from bluesky.protocols import Movable
5
5
  from numpy import ndarray
6
6
  from ophyd_async.core import (
7
7
  AsyncStatus,
8
+ Reference,
8
9
  StandardReadable,
9
10
  StandardReadableFormat,
10
11
  soft_signal_r_and_setter,
@@ -15,6 +16,7 @@ from ophyd_async.epics.motor import Motor
15
16
  from dodal.common.enums import EnabledDisabledUpper
16
17
  from dodal.log import LOGGER
17
18
 
19
+ from .baton import Baton
18
20
  from .util.lookup_tables import energy_distance_table
19
21
 
20
22
 
@@ -22,11 +24,6 @@ class AccessError(Exception):
22
24
  pass
23
25
 
24
26
 
25
- # Enable to allow testing when the beamline is down, do not change in production!
26
- TEST_MODE = False
27
- # will be made more generic in https://github.com/DiamondLightSource/dodal/issues/754
28
-
29
-
30
27
  # The acceptable difference, in mm, between the undulator gap and the DCM
31
28
  # energy, when the latter is converted to mm using lookup tables
32
29
  UNDULATOR_DISCREPANCY_THRESHOLD_MM = 2e-3
@@ -54,6 +51,7 @@ class Undulator(StandardReadable, Movable[float]):
54
51
  name: str = "",
55
52
  poles: int | None = None,
56
53
  length: float | None = None,
54
+ baton: Baton | None = None,
57
55
  ) -> None:
58
56
  """Constructor
59
57
 
@@ -64,6 +62,7 @@ class Undulator(StandardReadable, Movable[float]):
64
62
  name (str, optional): Name for device. Defaults to "".
65
63
  """
66
64
 
65
+ self.baton_ref = Reference(baton) if baton else None
67
66
  self.id_gap_lookup_table_path = id_gap_lookup_table_path
68
67
  with self.add_children_as_readables():
69
68
  self.gap_motor = Motor(prefix + "BLGAPMTR")
@@ -105,7 +104,8 @@ class Undulator(StandardReadable, Movable[float]):
105
104
 
106
105
  async def raise_if_not_enabled(self):
107
106
  access_level = await self.gap_access.get_value()
108
- if access_level is EnabledDisabledUpper.DISABLED and not TEST_MODE:
107
+ commissioning_mode = await self._is_commissioning_mode_enabled()
108
+ if access_level is EnabledDisabledUpper.DISABLED and not commissioning_mode:
109
109
  raise AccessError("Undulator gap access is disabled. Contact Control Room")
110
110
 
111
111
  async def _set_undulator_gap(self, energy_kev: float) -> None:
@@ -124,21 +124,25 @@ class Undulator(StandardReadable, Movable[float]):
124
124
  f"Undulator gap mismatch. {difference:.3f}mm is outside tolerance.\
125
125
  Moving gap to nominal value, {target_gap:.3f}mm"
126
126
  )
127
- if not TEST_MODE:
127
+ commissioning_mode = await self._is_commissioning_mode_enabled()
128
+ if not commissioning_mode:
128
129
  # Only move if the gap is sufficiently different to the value from the
129
- # DCM lookup table AND we're not in TEST_MODE
130
+ # DCM lookup table AND we're not in commissioning mode
130
131
  await self.gap_motor.set(
131
132
  target_gap,
132
133
  timeout=STATUS_TIMEOUT_S,
133
134
  )
134
135
  else:
135
- LOGGER.debug("In test mode, not moving ID gap")
136
+ LOGGER.warning("In test mode, not moving ID gap")
136
137
  else:
137
138
  LOGGER.debug(
138
139
  "Gap is already in the correct place for the new energy value "
139
140
  f"{energy_kev}, no need to ask it to move"
140
141
  )
141
142
 
143
+ async def _is_commissioning_mode_enabled(self):
144
+ return self.baton_ref and await self.baton_ref().commissioning.get_value()
145
+
142
146
  async def _get_gap_to_match_energy(self, energy_kev: float) -> float:
143
147
  """
144
148
  get a 2d np.array from lookup table that
@@ -1,8 +1,10 @@
1
1
  from bluesky.protocols import Triggerable
2
- from ophyd_async.core import AsyncStatus, Device, StrictEnum, observe_value
2
+ from ophyd_async.core import AsyncStatus, Device, Reference, StrictEnum, observe_value
3
3
  from ophyd_async.epics.core import epics_signal_r, epics_signal_rw
4
4
 
5
5
  from dodal.common.device_utils import periodic_reminder
6
+ from dodal.devices.baton import Baton
7
+ from dodal.log import LOGGER
6
8
 
7
9
 
8
10
  class Pause(StrictEnum):
@@ -14,15 +16,19 @@ class XBPMFeedback(Device, Triggerable):
14
16
  """The XBPM feedback device is an IOC that moves the DCM, HFM and VFM to automatically
15
17
  hold the beam into place, as measured by the XBPM sensor."""
16
18
 
17
- def __init__(self, prefix: str, name: str = "") -> None:
19
+ def __init__(self, prefix: str, name: str = "", baton: Baton | None = None) -> None:
18
20
  self.pos_ok = epics_signal_r(float, prefix + "XBPM2POSITION_OK")
19
21
  self.pos_stable = epics_signal_r(float, prefix + "XBPM2_STABLE")
20
22
  self.pause_feedback = epics_signal_rw(Pause, prefix + "FB_PAUSE")
23
+ self.baton_ref = Reference(baton) if baton else None
21
24
  super().__init__(name=name)
22
25
 
23
26
  @AsyncStatus.wrap
24
27
  async def trigger(self):
25
- async with periodic_reminder("Waiting for XBPM"):
26
- async for value in observe_value(self.pos_stable):
27
- if value:
28
- return
28
+ if self.baton_ref and await self.baton_ref().commissioning.get_value():
29
+ LOGGER.warning("Commissioning mode enabled, ignoring feedback")
30
+ else:
31
+ async with periodic_reminder("Waiting for XBPM"):
32
+ async for value in observe_value(self.pos_stable):
33
+ if value:
34
+ return