From 396a67377f084916d7a461cb6dad235400498e12 Mon Sep 17 00:00:00 2001 From: alxj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Mon, 2 Nov 2026 16:46:43 +0000 Subject: [PATCH 01/10] Register child devices as top level devices --- src/blueapi/core/context.py | 46 ++++- tests/unit_tests/core/test_context.py | 191 +++++++++++++++++++-- tests/unit_tests/service/test_interface.py | 46 +++-- 3 files changed, 244 insertions(+), 39 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index f8a96b0d6..f28d411c1 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -9,7 +9,7 @@ from bluesky.protocols import HasName from bluesky.run_engine import RunEngine -from ophyd_async.core import NotConnectedError, PathProvider +from ophyd_async.core import NotConnectedError, PathProvider, walk_devices from pydantic import ( BaseModel, GetCoreSchemaHandler, @@ -335,11 +335,13 @@ def my_plan(a: int, b: str): def register_device(self, device: Device, name: str | None = None) -> None: """ - Register an device in the context. The device needs to be registered with a - name. If the device is Readable, Movable or Flyable it has a `name` - attribute which can be used. The attribute can be overridden with the - `name` parameter here. If the device conforms to a different protocol then - the parameter must be used to name it. + Register a device under `name`, or its own `.name` if not given - + devices without a usable `.name` must supply `name` explicitly. + + ophyd-async device children are also registered recursively under + their own ophyd-async names (e.g. "stage" also registers "stage-x", + "stage-y"), alongside existing dotted access (e.g. "stage.x"). Ophyd + v1 devices have no `children()` and are left untouched. Args: device (Device): The device to register @@ -359,6 +361,38 @@ def register_device(self, device: Device, name: str | None = None) -> None: raise KeyError(f"Must supply a name for this device: {device}") self.devices[name] = device + self._register_children(device) + + def _register_children(self, device: Device) -> None: + """ + Register `device`'s descendants under their ophyd-async names. No-op if + `device` isn't ophyd-async (e.g. ophyd v1, which has no `children()`). + """ + + if not isinstance(device, AsyncDevice): + return + + tree = walk_devices(device) + for path, child in tree.items(): + if not child.name: + continue + + # Some children deliberately share their parent's name, e.g. a + # motor's user_readback, so that readings are keyed by the parent + parent_path, _, _ = path.rpartition(".") + parent = tree[parent_path] if parent_path else device + if child.name == parent.name: + continue + + existing = self.devices.setdefault(child.name, child) + if existing is not child: + LOGGER.warning( + "Not registering %s as a top level device under the " + "name '%s': a different device is already registered " + "with that name", + child, + child.name, + ) def unregister_all_devices(self): """Unregister all devices from the context.""" diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 06c3391c7..62226e4b3 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -1,5 +1,6 @@ from __future__ import annotations +import logging from dataclasses import dataclass, field from inspect import Parameter from pathlib import Path @@ -31,6 +32,7 @@ from ophyd_async.epics.adaravis import AravisDetector from ophyd_async.epics.adcore import ADWriterFactory from ophyd_async.epics.motor import Motor +from ophyd_async.sim import SimMotor from pydantic import TypeAdapter, ValidationError from pydantic.json_schema import SkipJsonSchema from pytest import LogCaptureFixture @@ -68,6 +70,29 @@ "plan_m", "plan_n", } +EXPECTED_FAKE_DEVICE_MODULE_DEVICES = { + "fake_motor_x", + "fake_motor_x-velocity", + "fake_motor_x-acceleration_time", + "fake_motor_x-user_setpoint", + "fake_motor_y", + "fake_motor_y-velocity", + "fake_motor_y-acceleration_time", + "fake_motor_y-user_setpoint", + "fake_motor_bundle_a", + "fake_motor_bundle_a-velocity", + "fake_motor_bundle_a-acceleration_time", + "fake_motor_bundle_a-user_setpoint", + "fake_motor_bundle_b", + "fake_motor_bundle_b-velocity", + "fake_motor_bundle_b-acceleration_time", + "fake_motor_bundle_b-user_setpoint", + "device_a", + "device_a-motor", + "device_a-motor-velocity", + "device_a-motor-acceleration_time", + "device_a-motor-user_setpoint", +} # @@ -188,9 +213,28 @@ def demo_plan(foo: int, mov: Movable) -> MsgGenerator: devicey_context.register_plan(demo_plan) schema = devicey_context.plans["demo_plan"].model.model_json_schema() + + # Registering "sim" (a Motor) and "sim_det" (an AravisDetector) also + # registers all of their Movable-conforming child signals (PVs owned by + # ophyd-async, not blueapi), so the enum is more than just the two roots. + # Deriving it here, rather than hardcoding every PV name, keeps this test + # from breaking on unrelated upstream changes to those device classes. + expected_movables = sorted( + name + for name, device in devicey_context.devices.items() + if isinstance(device, Movable) + ) + assert "sim" in expected_movables + assert "sim-velocity" in expected_movables + assert len(expected_movables) > 2 + assert schema["properties"] == { "foo": {"title": "Foo", "type": "integer"}, - "mov": {"title": "Mov", "type": "bluesky.protocols.Movable", "enum": ["sim"]}, + "mov": { + "title": "Mov", + "type": "bluesky.protocols.Movable", + "enum": expected_movables, + }, } @@ -267,17 +311,134 @@ def test_override_device_name(empty_context: BlueskyContext, sim_motor: Motor): assert empty_context.devices["foo"] is sim_motor +class Stage(Device): + """A real (non-mock) nested ophyd-async device tree: a stage with two + motors as children, each of which has its own signals as children.""" + + def __init__(self, name: str = "") -> None: + self.x = SimMotor() + self.y = SimMotor() + super().__init__(name=name) + + +def test_register_device_registers_children_recursively( + empty_context: BlueskyContext, +): + stage = Stage(name="stage") + empty_context.register_device(stage) + + assert empty_context.devices.keys() == { + "stage", + "stage-x", + "stage-x-velocity", + "stage-x-acceleration_time", + "stage-x-user_setpoint", + "stage-y", + "stage-y-velocity", + "stage-y-acceleration_time", + "stage-y-user_setpoint", + } + assert empty_context.devices["stage-x"] is stage.x + assert empty_context.devices["stage-y"] is stage.y + + +def test_child_sharing_parent_name_is_not_registered_separately( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): + # SimMotor deliberately gives its readback signal the same ophyd-async + # name as the motor itself, so that readings are keyed by the device + # name. The motor, not the bare signal, should be found under "motor". + caplog.set_level(logging.WARNING) + motor = SimMotor(name="motor") + empty_context.register_device(motor) + + assert empty_context.devices["motor"] is motor + assert "motor-user_readback" not in empty_context.devices + assert not caplog.get_records("call") + + +def test_overridden_registration_name_does_not_rename_children( + empty_context: BlueskyContext, +): + # Children are registered under their own ophyd-async names, which are + # unaffected by the name their parent is registered under + motor = SimMotor(name="motor") + empty_context.register_device(motor, name="foo") + + assert empty_context.devices.keys() == { + "foo", + "motor-velocity", + "motor-acceleration_time", + "motor-user_setpoint", + } + assert empty_context.devices["foo"] is motor + assert empty_context.devices["motor-velocity"] is motor.velocity + + +def test_unrelated_name_collision_keeps_existing_device_and_warns( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): + # Pre-register something under the name that a motor's velocity signal + # would naturally take. + sentinel = SimMotor(name="sentinel") + empty_context.register_device(sentinel, name="motor-velocity") + + caplog.set_level(logging.WARNING) + motor = SimMotor(name="motor") + empty_context.register_device(motor) + + assert empty_context.devices["motor-velocity"] is sentinel + assert empty_context.devices["motor"] is motor + assert any( + "motor-velocity" in record.message for record in caplog.get_records("call") + ) + + +def test_register_device_is_idempotent(empty_context: BlueskyContext): + stage = Stage(name="stage") + empty_context.register_device(stage) + before = dict(empty_context.devices) + + empty_context.register_device(stage) + + assert empty_context.devices == before + + +def test_register_device_skips_unnamed_children(empty_context: BlueskyContext): + stage = Stage() # no name given, so stage and its children are unnamed + empty_context.register_device(stage, name="stage") + + assert empty_context.devices.keys() == {"stage"} + + +def test_dotted_and_dashed_lookup_return_same_device(empty_context: BlueskyContext): + stage = Stage(name="stage") + empty_context.register_device(stage) + + assert empty_context.find_device("stage.x") is empty_context.find_device("stage-x") + assert empty_context.find_device("stage-x") is stage.x + + +def test_child_device_usable_as_plan_argument(empty_context: BlueskyContext): + stage = Stage(name="stage") + empty_context.register_device(stage) + + def move_plan(mov: Movable) -> MsgGenerator: + yield from () + + empty_context.register_plan(move_plan) + model = empty_context.plans[move_plan.__name__].model + adapter = TypeAdapter(model) + + assert adapter.validate_python({"mov": "stage-x"}).mov is stage.x # type: ignore + assert adapter.validate_python({"mov": "stage.x"}).mov is stage.x # type: ignore + + def test_add_devices_from_module(empty_context: BlueskyContext): import tests.unit_tests.core.fake_device_module as device_module empty_context.with_device_manager(device_module.devices) # type: ignore - protocol uses Any to avoid dependency on dodal - assert { - "fake_motor_x", - "fake_motor_y", - "fake_motor_bundle_a", - "fake_motor_bundle_b", - "device_a", - } == empty_context.devices.keys() + assert EXPECTED_FAKE_DEVICE_MODULE_DEVICES == empty_context.devices.keys() def test_add_failing_devices_from_module( @@ -339,13 +500,7 @@ def test_add_devices_and_plans_from_modules_with_config( ] ) ) - assert { - "fake_motor_x", - "fake_motor_y", - "fake_motor_bundle_a", - "fake_motor_bundle_b", - "device_a", - } == empty_context.devices.keys() + assert EXPECTED_FAKE_DEVICE_MODULE_DEVICES == empty_context.devices.keys() assert EXPECTED_PLANS == empty_context.plans.keys() @@ -715,8 +870,7 @@ def test_empty_device_manager(empty_context: BlueskyContext): def test_single_device_manager(empty_context: BlueskyContext): - foo = Mock(spec=Device, name="foo") - foo.name = "foo" + foo = Device(name="foo") sdm = StaticDeviceManager(devices={"foo": foo}) empty_context.with_device_manager(sdm) @@ -780,8 +934,7 @@ def test_path_provider_passed_to_device_manager(empty_context: BlueskyContext): def test_device_manager_environment_source(empty_context: BlueskyContext): - foo = Mock(spec=Device, name="foo") - foo.name = "foo" + foo = Device(name="foo") stm = StaticDeviceManager(devices={"foo": foo}) dev_mod = Mock(spec=ModuleType) dev_mod.devices = stm diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index db4e68760..1d870d47c 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -157,28 +157,46 @@ def test_get_devices(context_mock: MagicMock): context.register_device(Motor("FOO:", name="my_axis")) context_mock.return_value = context - assert interface.get_devices() == [ - DeviceModel( - name="my_device", - protocols=[ - ProtocolInfo(name="Stoppable", types=[]), - ], - ), + devices = interface.get_devices() + + # Registering "my_axis" also registers its signals as top level devices + # (e.g. "my_axis-velocity"), so there is one DeviceModel per entry in the + # context rather than just the two explicitly registered above - each + # reported under its own registry key, in registration order. + assert [d.name for d in devices] == list(context.devices.keys()) + assert devices[0] == DeviceModel( + name="my_device", + protocols=[ + ProtocolInfo(name="Stoppable", types=[]), + ], + ) + assert devices[1] == DeviceModel( + name="my_axis", + protocols=[ + ProtocolInfo(name="Checkable", types=[]), + ProtocolInfo(name="Flyable", types=[]), + ProtocolInfo(name="Movable", types=[]), + ProtocolInfo(name="Readable", types=[]), + ProtocolInfo(name="Stageable", types=[]), + ProtocolInfo(name="Stoppable", types=[]), + ProtocolInfo(name="Subscribable", types=[]), + ProtocolInfo(name="Configurable", types=[]), + ProtocolInfo(name="Device", types=[]), + ], + ) + assert ( DeviceModel( - name="my_axis", + name="my_axis-velocity", protocols=[ - ProtocolInfo(name="Checkable", types=[]), - ProtocolInfo(name="Flyable", types=[]), ProtocolInfo(name="Movable", types=[]), ProtocolInfo(name="Readable", types=[]), ProtocolInfo(name="Stageable", types=[]), - ProtocolInfo(name="Stoppable", types=[]), ProtocolInfo(name="Subscribable", types=[]), - ProtocolInfo(name="Configurable", types=[]), ProtocolInfo(name="Device", types=[]), ], - ), - ] + ) + in devices + ) @patch("blueapi.service.interface.context") From 8ee7db79c3655af8b89659d93266c2d9204635b2 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:05:59 +0000 Subject: [PATCH 02/10] skipping signal --- src/blueapi/core/context.py | 29 ++- tests/system_tests/devices.json | 100 +++++++++ tests/system_tests/plans.json | 232 ++++++++++++++++----- tests/unit_tests/core/test_context.py | 109 +++------- tests/unit_tests/service/test_interface.py | 46 ++-- 5 files changed, 335 insertions(+), 181 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index f28d411c1..0f92604a9 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -9,7 +9,7 @@ from bluesky.protocols import HasName from bluesky.run_engine import RunEngine -from ophyd_async.core import NotConnectedError, PathProvider, walk_devices +from ophyd_async.core import NotConnectedError, PathProvider, Signal, walk_devices from pydantic import ( BaseModel, GetCoreSchemaHandler, @@ -338,10 +338,10 @@ def register_device(self, device: Device, name: str | None = None) -> None: Register a device under `name`, or its own `.name` if not given - devices without a usable `.name` must supply `name` explicitly. - ophyd-async device children are also registered recursively under - their own ophyd-async names (e.g. "stage" also registers "stage-x", - "stage-y"), alongside existing dotted access (e.g. "stage.x"). Ophyd - v1 devices have no `children()` and are left untouched. + ophyd-async child devices (but not signals) are also registered + recursively under their own ophyd-async names (e.g. "stage" also + registers "stage-x", "stage-y"), alongside existing dotted access (e.g. + "stage.x"). Ophyd v1 devices have no `children()` and are left untouched. Args: device (Device): The device to register @@ -365,23 +365,18 @@ def register_device(self, device: Device, name: str | None = None) -> None: def _register_children(self, device: Device) -> None: """ - Register `device`'s descendants under their ophyd-async names. No-op if - `device` isn't ophyd-async (e.g. ophyd v1, which has no `children()`). + Register `device`'s descendant devices (not signals) under their + ophyd-async names. No-op if `device` isn't ophyd-async (e.g. ophyd v1, + which has no `children()`). """ if not isinstance(device, AsyncDevice): return - tree = walk_devices(device) - for path, child in tree.items(): - if not child.name: - continue - - # Some children deliberately share their parent's name, e.g. a - # motor's user_readback, so that readings are keyed by the parent - parent_path, _, _ = path.rpartition(".") - parent = tree[parent_path] if parent_path else device - if child.name == parent.name: + for child in walk_devices(device).values(): + # Signals are attributes of their device rather than devices in + # their own right, and remain reachable via dotted access + if isinstance(child, Signal) or not child.name: continue existing = self.devices.setdefault(child.name, child) diff --git a/tests/system_tests/devices.json b/tests/system_tests/devices.json index ef75bf8ea..5dc553b40 100644 --- a/tests/system_tests/devices.json +++ b/tests/system_tests/devices.json @@ -53,6 +53,106 @@ "types": [] } ] + }, + { + "name": "det-driver", + "protocols": [ + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf", + "protocols": [ + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x", + "protocols": [ + { + "name": "Checkable", + "types": [] + }, + { + "name": "Flyable", + "types": [] + }, + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Stoppable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Configurable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta", + "protocols": [ + { + "name": "Checkable", + "types": [] + }, + { + "name": "Flyable", + "types": [] + }, + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Stoppable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Configurable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] } ] } diff --git a/tests/system_tests/plans.json b/tests/system_tests/plans.json index 6f84a9c38..1b19ad60c 100644 --- a/tests/system_tests/plans.json +++ b/tests/system_tests/plans.json @@ -12,14 +12,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -73,14 +77,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -95,7 +103,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -148,14 +159,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -170,7 +185,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -223,14 +241,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -245,7 +267,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -293,14 +318,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -315,7 +344,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -363,14 +395,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -385,7 +421,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -446,14 +485,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -468,7 +511,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -529,14 +575,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -551,7 +601,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -603,14 +656,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -625,7 +682,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -749,7 +809,10 @@ "properties": { "x_axis": { "description": "An identifier for what to move for x", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "X Axis", "type": "bluesky.protocols.Movable" }, @@ -771,7 +834,10 @@ }, "y_axis": { "description": "An identifier for what to move for y", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Y Axis", "type": "bluesky.protocols.Movable" }, @@ -848,7 +914,10 @@ "properties": { "axis": { "description": "An identifier for what to move", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Axis", "type": "bluesky.protocols.Movable" }, @@ -890,13 +959,19 @@ "properties": { "x_axis": { "description": "An identifier for what to move for x", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "X Axis", "type": "bluesky.protocols.Movable" }, "y_axis": { "description": "An identifier for what to move for y", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Y Axis", "type": "bluesky.protocols.Movable" }, @@ -1012,7 +1087,10 @@ "properties": { "axis": { "description": "An identifier for what to move", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Axis", "type": "bluesky.protocols.Movable" }, @@ -1135,7 +1213,10 @@ "properties": { "x_axis": { "description": "An identifier for what to move for x", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "X Axis", "type": "bluesky.protocols.Movable" }, @@ -1156,7 +1237,10 @@ }, "y_axis": { "description": "An identifier for what to move for y", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Y Axis", "type": "bluesky.protocols.Movable" }, @@ -1221,7 +1305,10 @@ "properties": { "axis": { "description": "An identifier for what to move", - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Axis", "type": "bluesky.protocols.Movable" }, @@ -1284,7 +1371,9 @@ "items": { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, @@ -1321,14 +1410,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1343,7 +1436,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -1396,14 +1492,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1418,7 +1518,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -1471,14 +1574,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1493,7 +1600,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -1541,14 +1651,18 @@ { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1563,7 +1677,10 @@ "minItems": 2, "prefixItems": [ { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "type": "bluesky.protocols.Movable" }, { @@ -1606,7 +1723,10 @@ "additionalProperties": false, "properties": { "movable": { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Movable", "type": "bluesky.protocols.Movable", "types": [ @@ -1641,7 +1761,10 @@ "additionalProperties": false, "properties": { "movable": { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Movable", "type": "bluesky.protocols.Movable", "types": [ @@ -1761,7 +1884,9 @@ "readable": { "enum": [ "det", - "stage" + "stage", + "stage-theta", + "stage-x" ], "title": "Readable", "type": "bluesky.protocols.Readable" @@ -1781,7 +1906,10 @@ "additionalProperties": false, "properties": { "stoppable": { - "enum": [], + "enum": [ + "stage-theta", + "stage-x" + ], "title": "Stoppable", "type": "bluesky.protocols.Stoppable" } diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 62226e4b3..181fa84f5 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -72,26 +72,11 @@ } EXPECTED_FAKE_DEVICE_MODULE_DEVICES = { "fake_motor_x", - "fake_motor_x-velocity", - "fake_motor_x-acceleration_time", - "fake_motor_x-user_setpoint", "fake_motor_y", - "fake_motor_y-velocity", - "fake_motor_y-acceleration_time", - "fake_motor_y-user_setpoint", "fake_motor_bundle_a", - "fake_motor_bundle_a-velocity", - "fake_motor_bundle_a-acceleration_time", - "fake_motor_bundle_a-user_setpoint", "fake_motor_bundle_b", - "fake_motor_bundle_b-velocity", - "fake_motor_bundle_b-acceleration_time", - "fake_motor_bundle_b-user_setpoint", "device_a", "device_a-motor", - "device_a-motor-velocity", - "device_a-motor-acceleration_time", - "device_a-motor-user_setpoint", } @@ -214,27 +199,9 @@ def demo_plan(foo: int, mov: Movable) -> MsgGenerator: devicey_context.register_plan(demo_plan) schema = devicey_context.plans["demo_plan"].model.model_json_schema() - # Registering "sim" (a Motor) and "sim_det" (an AravisDetector) also - # registers all of their Movable-conforming child signals (PVs owned by - # ophyd-async, not blueapi), so the enum is more than just the two roots. - # Deriving it here, rather than hardcoding every PV name, keeps this test - # from breaking on unrelated upstream changes to those device classes. - expected_movables = sorted( - name - for name, device in devicey_context.devices.items() - if isinstance(device, Movable) - ) - assert "sim" in expected_movables - assert "sim-velocity" in expected_movables - assert len(expected_movables) > 2 - assert schema["properties"] == { "foo": {"title": "Foo", "type": "integer"}, - "mov": { - "title": "Mov", - "type": "bluesky.protocols.Movable", - "enum": expected_movables, - }, + "mov": {"title": "Mov", "type": "bluesky.protocols.Movable", "enum": ["sim"]}, } @@ -312,49 +279,40 @@ def test_override_device_name(empty_context: BlueskyContext, sim_motor: Motor): class Stage(Device): - """A real (non-mock) nested ophyd-async device tree: a stage with two - motors as children, each of which has its own signals as children.""" - def __init__(self, name: str = "") -> None: self.x = SimMotor() self.y = SimMotor() super().__init__(name=name) +class Table(Device): + def __init__(self, name: str = "") -> None: + self.mount = Stage() + super().__init__(name=name) + + def test_register_device_registers_children_recursively( empty_context: BlueskyContext, ): - stage = Stage(name="stage") - empty_context.register_device(stage) + table = Table(name="table") + empty_context.register_device(table) assert empty_context.devices.keys() == { - "stage", - "stage-x", - "stage-x-velocity", - "stage-x-acceleration_time", - "stage-x-user_setpoint", - "stage-y", - "stage-y-velocity", - "stage-y-acceleration_time", - "stage-y-user_setpoint", + "table", + "table-mount", + "table-mount-x", + "table-mount-y", } - assert empty_context.devices["stage-x"] is stage.x - assert empty_context.devices["stage-y"] is stage.y + assert empty_context.devices["table-mount"] is table.mount + assert empty_context.devices["table-mount-x"] is table.mount.x + assert empty_context.devices["table-mount-y"] is table.mount.y -def test_child_sharing_parent_name_is_not_registered_separately( - empty_context: BlueskyContext, caplog: LogCaptureFixture -): - # SimMotor deliberately gives its readback signal the same ophyd-async - # name as the motor itself, so that readings are keyed by the device - # name. The motor, not the bare signal, should be found under "motor". - caplog.set_level(logging.WARNING) +def test_signals_are_not_registered(empty_context: BlueskyContext): motor = SimMotor(name="motor") empty_context.register_device(motor) - assert empty_context.devices["motor"] is motor - assert "motor-user_readback" not in empty_context.devices - assert not caplog.get_records("call") + assert empty_context.devices.keys() == {"motor"} def test_overridden_registration_name_does_not_rename_children( @@ -362,36 +320,27 @@ def test_overridden_registration_name_does_not_rename_children( ): # Children are registered under their own ophyd-async names, which are # unaffected by the name their parent is registered under - motor = SimMotor(name="motor") - empty_context.register_device(motor, name="foo") + stage = Stage(name="stage") + empty_context.register_device(stage, name="foo") - assert empty_context.devices.keys() == { - "foo", - "motor-velocity", - "motor-acceleration_time", - "motor-user_setpoint", - } - assert empty_context.devices["foo"] is motor - assert empty_context.devices["motor-velocity"] is motor.velocity + assert empty_context.devices.keys() == {"foo", "stage-x", "stage-y"} + assert empty_context.devices["foo"] is stage + assert empty_context.devices["stage-x"] is stage.x def test_unrelated_name_collision_keeps_existing_device_and_warns( empty_context: BlueskyContext, caplog: LogCaptureFixture ): - # Pre-register something under the name that a motor's velocity signal - # would naturally take. sentinel = SimMotor(name="sentinel") - empty_context.register_device(sentinel, name="motor-velocity") + empty_context.register_device(sentinel, name="stage-x") caplog.set_level(logging.WARNING) - motor = SimMotor(name="motor") - empty_context.register_device(motor) + stage = Stage(name="stage") + empty_context.register_device(stage) - assert empty_context.devices["motor-velocity"] is sentinel - assert empty_context.devices["motor"] is motor - assert any( - "motor-velocity" in record.message for record in caplog.get_records("call") - ) + assert empty_context.devices["stage-x"] is sentinel + assert empty_context.devices["stage-y"] is stage.y + assert any("stage-x" in record.message for record in caplog.get_records("call")) def test_register_device_is_idempotent(empty_context: BlueskyContext): diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index 1d870d47c..db4e68760 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -157,46 +157,28 @@ def test_get_devices(context_mock: MagicMock): context.register_device(Motor("FOO:", name="my_axis")) context_mock.return_value = context - devices = interface.get_devices() - - # Registering "my_axis" also registers its signals as top level devices - # (e.g. "my_axis-velocity"), so there is one DeviceModel per entry in the - # context rather than just the two explicitly registered above - each - # reported under its own registry key, in registration order. - assert [d.name for d in devices] == list(context.devices.keys()) - assert devices[0] == DeviceModel( - name="my_device", - protocols=[ - ProtocolInfo(name="Stoppable", types=[]), - ], - ) - assert devices[1] == DeviceModel( - name="my_axis", - protocols=[ - ProtocolInfo(name="Checkable", types=[]), - ProtocolInfo(name="Flyable", types=[]), - ProtocolInfo(name="Movable", types=[]), - ProtocolInfo(name="Readable", types=[]), - ProtocolInfo(name="Stageable", types=[]), - ProtocolInfo(name="Stoppable", types=[]), - ProtocolInfo(name="Subscribable", types=[]), - ProtocolInfo(name="Configurable", types=[]), - ProtocolInfo(name="Device", types=[]), - ], - ) - assert ( + assert interface.get_devices() == [ DeviceModel( - name="my_axis-velocity", + name="my_device", protocols=[ + ProtocolInfo(name="Stoppable", types=[]), + ], + ), + DeviceModel( + name="my_axis", + protocols=[ + ProtocolInfo(name="Checkable", types=[]), + ProtocolInfo(name="Flyable", types=[]), ProtocolInfo(name="Movable", types=[]), ProtocolInfo(name="Readable", types=[]), ProtocolInfo(name="Stageable", types=[]), + ProtocolInfo(name="Stoppable", types=[]), ProtocolInfo(name="Subscribable", types=[]), + ProtocolInfo(name="Configurable", types=[]), ProtocolInfo(name="Device", types=[]), ], - ) - in devices - ) + ), + ] @patch("blueapi.service.interface.context") From d92fe6a00556637ba2e2304928d2a1c86d152003 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Tue, 3 Nov 2026 10:53:19 +0000 Subject: [PATCH 03/10] Register signals again and tidy up name clash handling --- src/blueapi/core/context.py | 59 +- tests/system_tests/devices.json | 2523 +++++++++++ tests/system_tests/plans.json | 4396 +++++++++++++++++++- tests/unit_tests/core/test_context.py | 157 +- tests/unit_tests/service/test_interface.py | 36 +- 5 files changed, 7076 insertions(+), 95 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index 0f92604a9..c7c850986 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -9,7 +9,7 @@ from bluesky.protocols import HasName from bluesky.run_engine import RunEngine -from ophyd_async.core import NotConnectedError, PathProvider, Signal, walk_devices +from ophyd_async.core import NotConnectedError, PathProvider from pydantic import ( BaseModel, GetCoreSchemaHandler, @@ -335,13 +335,15 @@ def my_plan(a: int, b: str): def register_device(self, device: Device, name: str | None = None) -> None: """ - Register a device under `name`, or its own `.name` if not given - - devices without a usable `.name` must supply `name` explicitly. + Register an device in the context. The device needs to be registered with a + name. If the device is Readable, Movable or Flyable it has a `name` + attribute which can be used. The attribute can be overridden with the + `name` parameter here. If the device conforms to a different protocol then + the parameter must be used to name it. - ophyd-async child devices (but not signals) are also registered - recursively under their own ophyd-async names (e.g. "stage" also - registers "stage-x", "stage-y"), alongside existing dotted access (e.g. - "stage.x"). Ophyd v1 devices have no `children()` and are left untouched. + Children of ophyd-async devices, including signals, are also registered + under their own names, e.g. registering "stage" also registers "stage-x" + and "stage-x-velocity". Args: device (Device): The device to register @@ -360,34 +362,35 @@ def register_device(self, device: Device, name: str | None = None) -> None: else: raise KeyError(f"Must supply a name for this device: {device}") + existing = self.devices.get(name) + if existing is not None and existing is not device: + LOGGER.warning("Replacing existing device registered as '%s'", name) self.devices[name] = device self._register_children(device) - def _register_children(self, device: Device) -> None: - """ - Register `device`'s descendant devices (not signals) under their - ophyd-async names. No-op if `device` isn't ophyd-async (e.g. ophyd v1, - which has no `children()`). - """ + def _register_children( + self, device: Device, ancestor_names: frozenset[str] = frozenset() + ) -> None: + """Register the children of an ophyd-async device under their own names.""" if not isinstance(device, AsyncDevice): return - for child in walk_devices(device).values(): - # Signals are attributes of their device rather than devices in - # their own right, and remain reachable via dotted access - if isinstance(child, Signal) or not child.name: - continue - - existing = self.devices.setdefault(child.name, child) - if existing is not child: - LOGGER.warning( - "Not registering %s as a top level device under the " - "name '%s': a different device is already registered " - "with that name", - child, - child.name, - ) + ancestor_names = ancestor_names | {device.name} + for _, child in device.children(): + # Some children share an ancestor's name, e.g. a motor's user_readback + if child.name and child.name not in ancestor_names: + existing = self.devices.setdefault(child.name, child) + if existing is not child: + # Its children's names start with the clashing name, so skip + # them too + LOGGER.warning( + "Not registering %s or its children, name '%s' is in use", + child, + child.name, + ) + continue + self._register_children(child, ancestor_names) def unregister_all_devices(self): """Unregister all devices from the context.""" diff --git a/tests/system_tests/devices.json b/tests/system_tests/devices.json index 5dc553b40..e9077067b 100644 --- a/tests/system_tests/devices.json +++ b/tests/system_tests/devices.json @@ -153,6 +153,2529 @@ "types": [] } ] + }, + { + "name": "stage-x-motor_egu", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-motor_resolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-steps_per_revolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-units_per_revolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-encoder_resolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-velocity", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-offset", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-user_setpoint", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-max_velocity", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-acceleration_time", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-precision", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-deadband", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-motor_done_move", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-low_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-high_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-dial_low_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-dial_high_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-offset_freeze_switch", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-high_limit_switch", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-low_limit_switch", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-output_link", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-set_use_switch", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-x-motor_stop", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-motor_egu", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-motor_resolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-steps_per_revolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-units_per_revolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-encoder_resolution", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-velocity", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-offset", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-user_setpoint", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-max_velocity", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-acceleration_time", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-precision", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-deadband", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-motor_done_move", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-low_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-high_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-dial_low_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-dial_high_limit_travel", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-offset_freeze_switch", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-high_limit_switch", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-low_limit_switch", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-output_link", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-set_use_switch", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-motor_stop", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-port_name", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-unique_id", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-nd_attributes_file", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_size_x", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_size_y", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_size_z", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_size0", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_size1", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_size2", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-color_mode", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-data_type", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-array_counter", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-ad_core_version", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-driver_version", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-acquire_time", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-acquire_period", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-num_images", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-image_mode", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-detector_state", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-acquire", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-wait_for_plugins", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-manufacturer", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-model", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-serial_number", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-sdk_version", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-driver-firmware_version", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-port_name", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-unique_id", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-nd_attributes_file", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_size_x", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_size_y", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_size_z", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_size0", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_size1", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_size2", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-color_mode", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-data_type", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-array_counter", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-ad_core_version", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-driver_version", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-file_path", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-file_name", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-file_path_exists", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-file_template", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-full_file_name", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-file_number", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-auto_increment", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-file_write_mode", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-num_capture", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-num_captured", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-capture", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-create_directory", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-nd_array_port", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-enable_callbacks", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-nd_array_address", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-queue_size", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-position_mode", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-compression", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-num_extra_dims", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-swmr_mode", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-flush_now", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-xml_file_name", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-num_frames_chunks", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-chunk_size_auto", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "det-hdf-lazy_open", + "protocols": [ + { + "name": "Movable", + "types": [] + }, + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] } ] } diff --git a/tests/system_tests/plans.json b/tests/system_tests/plans.json index 1b19ad60c..7432b78f6 100644 --- a/tests/system_tests/plans.json +++ b/tests/system_tests/plans.json @@ -12,18 +12,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -77,18 +295,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -104,8 +540,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -159,18 +649,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -186,8 +894,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -241,18 +1003,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -268,8 +1248,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -318,18 +1352,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -345,8 +1597,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -395,18 +1701,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -422,8 +1946,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -485,18 +2063,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -512,8 +2308,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -575,18 +2425,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -602,8 +2670,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -656,18 +2778,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -683,8 +3023,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -810,8 +3204,62 @@ "x_axis": { "description": "An identifier for what to move for x", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "X Axis", "type": "bluesky.protocols.Movable" @@ -835,8 +3283,62 @@ "y_axis": { "description": "An identifier for what to move for y", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Y Axis", "type": "bluesky.protocols.Movable" @@ -915,8 +3417,62 @@ "axis": { "description": "An identifier for what to move", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Axis", "type": "bluesky.protocols.Movable" @@ -960,8 +3516,62 @@ "x_axis": { "description": "An identifier for what to move for x", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "X Axis", "type": "bluesky.protocols.Movable" @@ -969,8 +3579,62 @@ "y_axis": { "description": "An identifier for what to move for y", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Y Axis", "type": "bluesky.protocols.Movable" @@ -1088,8 +3752,62 @@ "axis": { "description": "An identifier for what to move", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Axis", "type": "bluesky.protocols.Movable" @@ -1214,8 +3932,62 @@ "x_axis": { "description": "An identifier for what to move for x", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "X Axis", "type": "bluesky.protocols.Movable" @@ -1238,8 +4010,62 @@ "y_axis": { "description": "An identifier for what to move for y", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Y Axis", "type": "bluesky.protocols.Movable" @@ -1306,8 +4132,62 @@ "axis": { "description": "An identifier for what to move", "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Axis", "type": "bluesky.protocols.Movable" @@ -1371,9 +4251,118 @@ "items": { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, @@ -1410,18 +4399,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1437,8 +4644,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -1492,18 +4753,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1519,8 +4998,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -1574,18 +5107,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1601,8 +5352,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -1651,18 +5456,236 @@ { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Readable" }, { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "ophyd_async.core._protocol.AsyncReadable" } @@ -1678,8 +5701,62 @@ "prefixItems": [ { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "type": "bluesky.protocols.Movable" }, @@ -1724,8 +5801,62 @@ "properties": { "movable": { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Movable", "type": "bluesky.protocols.Movable", @@ -1762,8 +5893,62 @@ "properties": { "movable": { "enum": [ + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-array_counter", + "det-driver-image_mode", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-wait_for_plugins", + "det-hdf-array_counter", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-xml_file_name", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_travel", + "stage-theta-motor_stop", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-set_use_switch", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-high_limit_travel", + "stage-x-low_limit_travel", + "stage-x-motor_stop", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-set_use_switch", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Movable", "type": "bluesky.protocols.Movable", @@ -1884,9 +6069,118 @@ "readable": { "enum": [ "det", + "det-driver-acquire", + "det-driver-acquire_period", + "det-driver-acquire_time", + "det-driver-ad_core_version", + "det-driver-array_counter", + "det-driver-array_size0", + "det-driver-array_size1", + "det-driver-array_size2", + "det-driver-array_size_x", + "det-driver-array_size_y", + "det-driver-array_size_z", + "det-driver-color_mode", + "det-driver-data_type", + "det-driver-detector_state", + "det-driver-driver_version", + "det-driver-firmware_version", + "det-driver-image_mode", + "det-driver-manufacturer", + "det-driver-model", + "det-driver-nd_attributes_file", + "det-driver-num_images", + "det-driver-port_name", + "det-driver-sdk_version", + "det-driver-serial_number", + "det-driver-unique_id", + "det-driver-wait_for_plugins", + "det-hdf-ad_core_version", + "det-hdf-array_counter", + "det-hdf-array_size0", + "det-hdf-array_size1", + "det-hdf-array_size2", + "det-hdf-array_size_x", + "det-hdf-array_size_y", + "det-hdf-array_size_z", + "det-hdf-auto_increment", + "det-hdf-capture", + "det-hdf-chunk_size_auto", + "det-hdf-color_mode", + "det-hdf-compression", + "det-hdf-create_directory", + "det-hdf-data_type", + "det-hdf-driver_version", + "det-hdf-enable_callbacks", + "det-hdf-file_name", + "det-hdf-file_number", + "det-hdf-file_path", + "det-hdf-file_path_exists", + "det-hdf-file_template", + "det-hdf-file_write_mode", + "det-hdf-flush_now", + "det-hdf-full_file_name", + "det-hdf-lazy_open", + "det-hdf-nd_array_address", + "det-hdf-nd_array_port", + "det-hdf-nd_attributes_file", + "det-hdf-num_capture", + "det-hdf-num_captured", + "det-hdf-num_extra_dims", + "det-hdf-num_frames_chunks", + "det-hdf-port_name", + "det-hdf-position_mode", + "det-hdf-queue_size", + "det-hdf-swmr_mode", + "det-hdf-unique_id", + "det-hdf-xml_file_name", "stage", "stage-theta", - "stage-x" + "stage-theta-acceleration_time", + "stage-theta-deadband", + "stage-theta-dial_high_limit_travel", + "stage-theta-dial_low_limit_travel", + "stage-theta-encoder_resolution", + "stage-theta-high_limit_switch", + "stage-theta-high_limit_travel", + "stage-theta-low_limit_switch", + "stage-theta-low_limit_travel", + "stage-theta-max_velocity", + "stage-theta-motor_done_move", + "stage-theta-motor_egu", + "stage-theta-motor_resolution", + "stage-theta-offset", + "stage-theta-offset_freeze_switch", + "stage-theta-output_link", + "stage-theta-precision", + "stage-theta-set_use_switch", + "stage-theta-steps_per_revolution", + "stage-theta-units_per_revolution", + "stage-theta-user_setpoint", + "stage-theta-velocity", + "stage-x", + "stage-x-acceleration_time", + "stage-x-deadband", + "stage-x-dial_high_limit_travel", + "stage-x-dial_low_limit_travel", + "stage-x-encoder_resolution", + "stage-x-high_limit_switch", + "stage-x-high_limit_travel", + "stage-x-low_limit_switch", + "stage-x-low_limit_travel", + "stage-x-max_velocity", + "stage-x-motor_done_move", + "stage-x-motor_egu", + "stage-x-motor_resolution", + "stage-x-offset", + "stage-x-offset_freeze_switch", + "stage-x-output_link", + "stage-x-precision", + "stage-x-set_use_switch", + "stage-x-steps_per_revolution", + "stage-x-units_per_revolution", + "stage-x-user_setpoint", + "stage-x-velocity" ], "title": "Readable", "type": "bluesky.protocols.Readable" diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 181fa84f5..8b07d7418 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -23,11 +23,13 @@ from dodal.common import PlanGenerator, inject from ophyd_async.core import ( Device, + DeviceVector, PathProvider, StandardDetector, StaticPathProvider, UUIDFilenameProvider, init_devices, + soft_signal_rw, ) from ophyd_async.epics.adaravis import AravisDetector from ophyd_async.epics.adcore import ADWriterFactory @@ -80,6 +82,15 @@ } +def assert_fake_device_module_registered(context: BlueskyContext) -> None: + # Which child signals exist depends on the upstream device classes + assert EXPECTED_FAKE_DEVICE_MODULE_DEVICES <= context.devices.keys() + assert all( + name.split("-")[0] in EXPECTED_FAKE_DEVICE_MODULE_DEVICES + for name in context.devices + ) + + # # Dummy plans # @@ -199,9 +210,20 @@ def demo_plan(foo: int, mov: Movable) -> MsgGenerator: devicey_context.register_plan(demo_plan) schema = devicey_context.plans["demo_plan"].model.model_json_schema() + # Which child signals exist depends on the upstream Motor class + expected_movables = sorted( + name + for name, device in devicey_context.devices.items() + if isinstance(device, Movable) + ) + assert {"sim", "sim-velocity"} <= set(expected_movables) assert schema["properties"] == { "foo": {"title": "Foo", "type": "integer"}, - "mov": {"title": "Mov", "type": "bluesky.protocols.Movable", "enum": ["sim"]}, + "mov": { + "title": "Mov", + "type": "bluesky.protocols.Movable", + "enum": expected_movables, + }, } @@ -278,10 +300,17 @@ def test_override_device_name(empty_context: BlueskyContext, sim_motor: Motor): assert empty_context.devices["foo"] is sim_motor +class Axis(Device): + def __init__(self, name: str = "") -> None: + self.position = soft_signal_rw(float) + self.velocity = soft_signal_rw(float) + super().__init__(name=name) + + class Stage(Device): def __init__(self, name: str = "") -> None: - self.x = SimMotor() - self.y = SimMotor() + self.x = Axis() + self.y = Axis() super().__init__(name=name) @@ -301,29 +330,87 @@ def test_register_device_registers_children_recursively( "table", "table-mount", "table-mount-x", + "table-mount-x-position", + "table-mount-x-velocity", "table-mount-y", + "table-mount-y-position", + "table-mount-y-velocity", } assert empty_context.devices["table-mount"] is table.mount assert empty_context.devices["table-mount-x"] is table.mount.x - assert empty_context.devices["table-mount-y"] is table.mount.y + assert empty_context.devices["table-mount-x-velocity"] is table.mount.x.velocity + + +class Detector(Device): + def __init__(self, name: str = "") -> None: + self.lens_mode = soft_signal_rw(str) + super().__init__(name=name) -def test_signals_are_not_registered(empty_context: BlueskyContext): +def test_signals_are_registered(empty_context: BlueskyContext): + detector = Detector(name="detector") + empty_context.register_device(detector) + + assert empty_context.devices["detector-lens_mode"] is detector.lens_mode + + +def test_child_sharing_parent_name_is_not_registered_separately( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): + # SimMotor's readback signal has the same name as the motor + caplog.set_level(logging.WARNING) motor = SimMotor(name="motor") empty_context.register_device(motor) - assert empty_context.devices.keys() == {"motor"} + assert empty_context.devices["motor"] is motor + assert motor.user_readback not in empty_context.devices.values() + assert not caplog.get_records("call") + + +def test_descendant_sharing_ancestor_name_is_not_registered_separately( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): + caplog.set_level(logging.WARNING) + stage = Stage(name="stage") + stage.x.position.set_name("stage") + empty_context.register_device(stage) + + assert empty_context.devices["stage"] is stage + assert stage.x.position not in empty_context.devices.values() + assert not caplog.get_records("call") + + +class AxisBank(Device): + def __init__(self, name: str = "") -> None: + self.axes = DeviceVector({1: Axis(), 2: Axis()}) + super().__init__(name=name) + + +def test_device_vector_children_are_registered(empty_context: BlueskyContext): + bank = AxisBank(name="bank") + empty_context.register_device(bank) + + assert empty_context.devices["bank-axes"] is bank.axes + assert empty_context.devices["bank-axes-1"] is bank.axes[1] + assert empty_context.devices["bank-axes-2-velocity"] is bank.axes[2].velocity def test_overridden_registration_name_does_not_rename_children( empty_context: BlueskyContext, ): - # Children are registered under their own ophyd-async names, which are - # unaffected by the name their parent is registered under + # Children keep their own names when the parent is registered as "foo" stage = Stage(name="stage") empty_context.register_device(stage, name="foo") - assert empty_context.devices.keys() == {"foo", "stage-x", "stage-y"} + assert empty_context.devices.keys() == { + "foo", + "stage-x", + "stage-x-position", + "stage-x-velocity", + "stage-y", + "stage-y-position", + "stage-y-velocity", + } assert empty_context.devices["foo"] is stage assert empty_context.devices["stage-x"] is stage.x @@ -339,22 +426,61 @@ def test_unrelated_name_collision_keeps_existing_device_and_warns( empty_context.register_device(stage) assert empty_context.devices["stage-x"] is sentinel + assert "stage-x-position" not in empty_context.devices assert empty_context.devices["stage-y"] is stage.y assert any("stage-x" in record.message for record in caplog.get_records("call")) -def test_register_device_is_idempotent(empty_context: BlueskyContext): +def test_top_level_device_replacing_existing_device_warns( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): + stage = Stage(name="stage") + empty_context.register_device(stage) + + caplog.set_level(logging.WARNING) + replacement = SimMotor(name="stage-x") + empty_context.register_device(replacement) + + assert empty_context.devices["stage-x"] is replacement + assert any("stage-x" in record.message for record in caplog.get_records("call")) + + +class EqualToEverything(SimMotor): + def __eq__(self, other: object) -> bool: + return True + + __hash__ = SimMotor.__hash__ + + +def test_replacement_warning_uses_identity( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): + empty_context.register_device(EqualToEverything(name="motor")) + + caplog.set_level(logging.WARNING) + replacement = EqualToEverything(name="motor") + empty_context.register_device(replacement) + + assert empty_context.devices["motor"] is replacement + assert any("motor" in record.message for record in caplog.get_records("call")) + + +def test_register_device_is_idempotent( + empty_context: BlueskyContext, caplog: LogCaptureFixture +): stage = Stage(name="stage") empty_context.register_device(stage) before = dict(empty_context.devices) + caplog.set_level(logging.WARNING) empty_context.register_device(stage) assert empty_context.devices == before + assert not caplog.get_records("call") def test_register_device_skips_unnamed_children(empty_context: BlueskyContext): - stage = Stage() # no name given, so stage and its children are unnamed + stage = Stage() # unnamed, so its children are too empty_context.register_device(stage, name="stage") assert empty_context.devices.keys() == {"stage"} @@ -379,15 +505,16 @@ def move_plan(mov: Movable) -> MsgGenerator: model = empty_context.plans[move_plan.__name__].model adapter = TypeAdapter(model) - assert adapter.validate_python({"mov": "stage-x"}).mov is stage.x # type: ignore - assert adapter.validate_python({"mov": "stage.x"}).mov is stage.x # type: ignore + position = stage.x.position + assert adapter.validate_python({"mov": "stage-x-position"}).mov is position # type: ignore + assert adapter.validate_python({"mov": "stage.x.position"}).mov is position # type: ignore def test_add_devices_from_module(empty_context: BlueskyContext): import tests.unit_tests.core.fake_device_module as device_module empty_context.with_device_manager(device_module.devices) # type: ignore - protocol uses Any to avoid dependency on dodal - assert EXPECTED_FAKE_DEVICE_MODULE_DEVICES == empty_context.devices.keys() + assert_fake_device_module_registered(empty_context) def test_add_failing_devices_from_module( @@ -449,7 +576,7 @@ def test_add_devices_and_plans_from_modules_with_config( ] ) ) - assert EXPECTED_FAKE_DEVICE_MODULE_DEVICES == empty_context.devices.keys() + assert_fake_device_module_registered(empty_context) assert EXPECTED_PLANS == empty_context.plans.keys() diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index db4e68760..633f6dd78 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -11,6 +11,7 @@ from bluesky.utils import MsgGenerator from bluesky_stomp.messaging import StompClient from fastapi import status +from ophyd_async.core import Device, soft_signal_rw from ophyd_async.epics.motor import Motor from pydantic import HttpUrl, SecretStr from pytest_httpx import HTTPXMock @@ -157,7 +158,10 @@ def test_get_devices(context_mock: MagicMock): context.register_device(Motor("FOO:", name="my_axis")) context_mock.return_value = context - assert interface.get_devices() == [ + # Which child signals exist depends on the upstream Motor class + devices = interface.get_devices() + assert [d.name for d in devices] == list(context.devices) + assert devices[:2] == [ DeviceModel( name="my_device", protocols=[ @@ -181,6 +185,36 @@ def test_get_devices(context_mock: MagicMock): ] +class Detector(Device): + def __init__(self, name: str = "") -> None: + self.lens_mode = soft_signal_rw(str) + super().__init__(name=name) + + +@patch("blueapi.service.interface.context") +def test_get_devices_includes_child_signals(context_mock: MagicMock): + context = BlueskyContext() + context.register_device(Detector(name="detector")) + context_mock.return_value = context + + assert interface.get_devices() == [ + DeviceModel( + name="detector", + protocols=[ProtocolInfo(name="Device", types=[])], + ), + DeviceModel( + name="detector-lens_mode", + protocols=[ + ProtocolInfo(name="Movable", types=[]), + ProtocolInfo(name="Readable", types=[]), + ProtocolInfo(name="Stageable", types=[]), + ProtocolInfo(name="Subscribable", types=[]), + ProtocolInfo(name="Device", types=[]), + ], + ), + ] + + @patch("blueapi.service.interface.context") def test_get_device(context_mock: MagicMock): context = BlueskyContext() From b2ff53113aa611d1a5554e3e5c316718a0567009 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Tue, 3 Nov 2026 11:24:28 +0000 Subject: [PATCH 04/10] Register signals and name clashing children by attribute --- src/blueapi/core/context.py | 15 ++++-- src/blueapi/service/interface.py | 12 +++-- src/blueapi/service/model.py | 5 +- tests/system_tests/devices.json | 42 ++++++++++++++++ tests/system_tests/plans.json | 56 ++++++++++++++++++++++ tests/unit_tests/core/test_context.py | 8 ++-- tests/unit_tests/service/test_interface.py | 13 +++++ 7 files changed, 137 insertions(+), 14 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index c7c850986..80ebacd83 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -377,17 +377,22 @@ def _register_children( return ancestor_names = ancestor_names | {device.name} - for _, child in device.children(): - # Some children share an ancestor's name, e.g. a motor's user_readback - if child.name and child.name not in ancestor_names: - existing = self.devices.setdefault(child.name, child) + for attr_name, child in device.children(): + if child.name: + # Some children share an ancestor's name, e.g. a motor's + # user_readback, so name these after their attribute instead + if child.name in ancestor_names: + name = f"{device.name}-{attr_name}" + else: + name = child.name + existing = self.devices.setdefault(name, child) if existing is not child: # Its children's names start with the clashing name, so skip # them too LOGGER.warning( "Not registering %s or its children, name '%s' is in use", child, - child.name, + name, ) continue self._register_children(child, ancestor_names) diff --git a/src/blueapi/service/interface.py b/src/blueapi/service/interface.py index 7df474557..4e64b9cde 100644 --- a/src/blueapi/service/interface.py +++ b/src/blueapi/service/interface.py @@ -191,15 +191,21 @@ def get_plan(name: str) -> PlanModel: def get_devices() -> list[DeviceModel]: """Get all available devices in the BlueskyContext""" - return [DeviceModel.from_device(device) for device in context().devices.values()] + # Use the registered name, as some children are registered under a name + # other than their own, e.g. a motor's user_readback + return [ + DeviceModel.from_device(device, name) + for name, device in context().devices.items() + ] def get_device(name: str) -> DeviceModel: """Retrieve device by name from the BlueskyContext""" - if not (device := context().find_device(name)): + ctx = context() + if not (device := ctx.find_device(name)): raise KeyError(name) - return DeviceModel.from_device(device) + return DeviceModel.from_device(device, name if name in ctx.devices else None) def submit_task( diff --git a/src/blueapi/service/model.py b/src/blueapi/service/model.py index 1b690d5c0..ac5c26688 100644 --- a/src/blueapi/service/model.py +++ b/src/blueapi/service/model.py @@ -36,8 +36,9 @@ class DeviceModel(BlueapiBaseModel): ) @classmethod - def from_device(cls, device: Device) -> "DeviceModel": - name = device.name if isinstance(device, HasName) else _UNKNOWN_NAME + def from_device(cls, device: Device, name: str | None = None) -> "DeviceModel": + if name is None: + name = device.name if isinstance(device, HasName) else _UNKNOWN_NAME return cls(name=name, protocols=list(_protocol_info(device))) diff --git a/tests/system_tests/devices.json b/tests/system_tests/devices.json index e9077067b..7636cb05f 100644 --- a/tests/system_tests/devices.json +++ b/tests/system_tests/devices.json @@ -2676,6 +2676,48 @@ "types": [] } ] + }, + { + "name": "stage-x-user_readback", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] + }, + { + "name": "stage-theta-user_readback", + "protocols": [ + { + "name": "Readable", + "types": [] + }, + { + "name": "Stageable", + "types": [] + }, + { + "name": "Subscribable", + "types": [] + }, + { + "name": "Device", + "types": [] + } + ] } ] } diff --git a/tests/system_tests/plans.json b/tests/system_tests/plans.json index 7432b78f6..ddce7f2d6 100644 --- a/tests/system_tests/plans.json +++ b/tests/system_tests/plans.json @@ -99,6 +99,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -122,6 +123,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -217,6 +219,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -240,6 +243,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -382,6 +386,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -405,6 +410,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -500,6 +506,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -523,6 +530,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -736,6 +744,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -759,6 +768,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -854,6 +864,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -877,6 +888,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1090,6 +1102,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1113,6 +1126,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1208,6 +1222,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1231,6 +1246,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1439,6 +1455,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1462,6 +1479,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1557,6 +1575,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1580,6 +1599,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1788,6 +1808,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1811,6 +1832,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1906,6 +1928,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1929,6 +1952,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2150,6 +2174,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2173,6 +2198,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2268,6 +2294,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2291,6 +2318,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2512,6 +2540,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2535,6 +2564,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2630,6 +2660,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2653,6 +2684,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2865,6 +2897,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2888,6 +2921,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2983,6 +3017,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -3006,6 +3041,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4338,6 +4374,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4361,6 +4398,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4486,6 +4524,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4509,6 +4548,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4604,6 +4644,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4627,6 +4668,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4840,6 +4882,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4863,6 +4906,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4958,6 +5002,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4981,6 +5026,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5194,6 +5240,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5217,6 +5264,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5312,6 +5360,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5335,6 +5384,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5543,6 +5593,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5566,6 +5617,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5661,6 +5713,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5684,6 +5737,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -6156,6 +6210,7 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", + "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -6179,6 +6234,7 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", + "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 8b07d7418..bade52f2a 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -354,7 +354,7 @@ def test_signals_are_registered(empty_context: BlueskyContext): assert empty_context.devices["detector-lens_mode"] is detector.lens_mode -def test_child_sharing_parent_name_is_not_registered_separately( +def test_child_sharing_parent_name_is_registered_by_attribute( empty_context: BlueskyContext, caplog: LogCaptureFixture ): # SimMotor's readback signal has the same name as the motor @@ -363,11 +363,11 @@ def test_child_sharing_parent_name_is_not_registered_separately( empty_context.register_device(motor) assert empty_context.devices["motor"] is motor - assert motor.user_readback not in empty_context.devices.values() + assert empty_context.devices["motor-user_readback"] is motor.user_readback assert not caplog.get_records("call") -def test_descendant_sharing_ancestor_name_is_not_registered_separately( +def test_descendant_sharing_ancestor_name_is_registered_by_attribute( empty_context: BlueskyContext, caplog: LogCaptureFixture ): caplog.set_level(logging.WARNING) @@ -376,7 +376,7 @@ def test_descendant_sharing_ancestor_name_is_not_registered_separately( empty_context.register_device(stage) assert empty_context.devices["stage"] is stage - assert stage.x.position not in empty_context.devices.values() + assert empty_context.devices["stage-x-position"] is stage.x.position assert not caplog.get_records("call") diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index 633f6dd78..ee592c6cf 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -13,6 +13,7 @@ from fastapi import status from ophyd_async.core import Device, soft_signal_rw from ophyd_async.epics.motor import Motor +from ophyd_async.sim import SimMotor from pydantic import HttpUrl, SecretStr from pytest_httpx import HTTPXMock from stomp.connect import StompConnection11 as Connection @@ -215,6 +216,18 @@ def test_get_devices_includes_child_signals(context_mock: MagicMock): ] +@patch("blueapi.service.interface.context") +def test_get_devices_reports_registered_names(context_mock: MagicMock): + context = BlueskyContext() + context.register_device(SimMotor(name="motor")) + context_mock.return_value = context + + names = [device.name for device in interface.get_devices()] + assert "motor-user_readback" in names + assert names.count("motor") == 1 + assert interface.get_device("motor-user_readback").name == "motor-user_readback" + + @patch("blueapi.service.interface.context") def test_get_device(context_mock: MagicMock): context = BlueskyContext() From ad1e6e781aac69fae710a462961aa66fdb1d66c8 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Thu, 5 Nov 2026 07:28:14 +0000 Subject: [PATCH 05/10] removing unnecessary test --- tests/unit_tests/core/test_context.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index bade52f2a..040f158ed 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -347,13 +347,6 @@ def __init__(self, name: str = "") -> None: super().__init__(name=name) -def test_signals_are_registered(empty_context: BlueskyContext): - detector = Detector(name="detector") - empty_context.register_device(detector) - - assert empty_context.devices["detector-lens_mode"] is detector.lens_mode - - def test_child_sharing_parent_name_is_registered_by_attribute( empty_context: BlueskyContext, caplog: LogCaptureFixture ): From 8fd379d9bca4d24d63429728894289240edf5286 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Thu, 5 Nov 2026 07:31:03 +0000 Subject: [PATCH 06/10] Swapping from adapter.validate_python to model_validate --- tests/unit_tests/core/test_context.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 040f158ed..2aa88130c 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -496,11 +496,10 @@ def move_plan(mov: Movable) -> MsgGenerator: empty_context.register_plan(move_plan) model = empty_context.plans[move_plan.__name__].model - adapter = TypeAdapter(model) position = stage.x.position - assert adapter.validate_python({"mov": "stage-x-position"}).mov is position # type: ignore - assert adapter.validate_python({"mov": "stage.x.position"}).mov is position # type: ignore + assert model.model_validate({"mov": "stage-x-position"}).mov is position # type: ignore + assert model.model_validate({"mov": "stage.x.position"}).mov is position # type: ignore def test_add_devices_from_module(empty_context: BlueskyContext): From ec750de925c9928db02099431c78c435d34bf3fe Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:18:00 +0000 Subject: [PATCH 07/10] Check registered devices instead of ancestor names for child clashes- on feedback from Peter Drop the identity replacement test as other tests already cover it --- src/blueapi/core/context.py | 14 ++++-------- tests/unit_tests/core/test_context.py | 33 +++++++++++---------------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index 80ebacd83..b6d16eb0c 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -368,23 +368,19 @@ def register_device(self, device: Device, name: str | None = None) -> None: self.devices[name] = device self._register_children(device) - def _register_children( - self, device: Device, ancestor_names: frozenset[str] = frozenset() - ) -> None: + def _register_children(self, device: Device) -> None: """Register the children of an ophyd-async device under their own names.""" if not isinstance(device, AsyncDevice): return - ancestor_names = ancestor_names | {device.name} for attr_name, child in device.children(): if child.name: - # Some children share an ancestor's name, e.g. a motor's + name = child.name + # Some children share a name already in use, e.g. a motor's # user_readback, so name these after their attribute instead - if child.name in ancestor_names: + if self.devices.get(name, child) is not child: name = f"{device.name}-{attr_name}" - else: - name = child.name existing = self.devices.setdefault(name, child) if existing is not child: # Its children's names start with the clashing name, so skip @@ -395,7 +391,7 @@ def _register_children( name, ) continue - self._register_children(child, ancestor_names) + self._register_children(child) def unregister_all_devices(self): """Unregister all devices from the context.""" diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 2aa88130c..97da76031 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -408,6 +408,19 @@ def test_overridden_registration_name_does_not_rename_children( assert empty_context.devices["stage-x"] is stage.x +def test_overridden_registration_name_frees_parent_name_for_child( + empty_context: BlueskyContext, +): + # "motor" isn't in use when the motor is registered as "foo", so its + # readback keeps its own name + motor = SimMotor(name="motor") + empty_context.register_device(motor, name="foo") + + assert empty_context.devices["foo"] is motor + assert empty_context.devices["motor"] is motor.user_readback + assert "motor-user_readback" not in empty_context.devices + + def test_unrelated_name_collision_keeps_existing_device_and_warns( empty_context: BlueskyContext, caplog: LogCaptureFixture ): @@ -438,26 +451,6 @@ def test_top_level_device_replacing_existing_device_warns( assert any("stage-x" in record.message for record in caplog.get_records("call")) -class EqualToEverything(SimMotor): - def __eq__(self, other: object) -> bool: - return True - - __hash__ = SimMotor.__hash__ - - -def test_replacement_warning_uses_identity( - empty_context: BlueskyContext, caplog: LogCaptureFixture -): - empty_context.register_device(EqualToEverything(name="motor")) - - caplog.set_level(logging.WARNING) - replacement = EqualToEverything(name="motor") - empty_context.register_device(replacement) - - assert empty_context.devices["motor"] is replacement - assert any("motor" in record.message for record in caplog.get_records("call")) - - def test_register_device_is_idempotent( empty_context: BlueskyContext, caplog: LogCaptureFixture ): From 73932ec2139df8fb50a45fdf6d67cda0ce4e26c0 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Thu, 5 Nov 2026 12:48:10 +0000 Subject: [PATCH 08/10] Keep the first device registered under a name and warn once on clashes --- src/blueapi/core/context.py | 53 ++++++++++---------- tests/system_tests/devices.json | 42 ---------------- tests/system_tests/plans.json | 56 ---------------------- tests/unit_tests/core/test_context.py | 47 +++++++++--------- tests/unit_tests/service/test_interface.py | 7 +-- 5 files changed, 55 insertions(+), 150 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index b6d16eb0c..277d1fad2 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -132,6 +132,7 @@ class BlueskyContext: plan_functions: dict[str, PlanGenerator] = field(default_factory=dict) _reference_cache: dict[type, type] = field(default_factory=dict) + _warned_name_clash: bool = field(default=False, init=False, repr=False) def __post_init__(self, configuration: ApplicationConfig | None): if not configuration: @@ -343,7 +344,8 @@ def register_device(self, device: Device, name: str | None = None) -> None: Children of ophyd-async devices, including signals, are also registered under their own names, e.g. registering "stage" also registers "stage-x" - and "stage-x-velocity". + and "stage-x-velocity". If a name is already in use, the existing device + is kept and the new one and its children are not registered. Args: device (Device): The device to register @@ -362,11 +364,8 @@ def register_device(self, device: Device, name: str | None = None) -> None: else: raise KeyError(f"Must supply a name for this device: {device}") - existing = self.devices.get(name) - if existing is not None and existing is not device: - LOGGER.warning("Replacing existing device registered as '%s'", name) - self.devices[name] = device - self._register_children(device) + if self._add_device(name, device): + self._register_children(device) def _register_children(self, device: Device) -> None: """Register the children of an ophyd-async device under their own names.""" @@ -374,24 +373,30 @@ def _register_children(self, device: Device) -> None: if not isinstance(device, AsyncDevice): return - for attr_name, child in device.children(): - if child.name: - name = child.name - # Some children share a name already in use, e.g. a motor's - # user_readback, so name these after their attribute instead - if self.devices.get(name, child) is not child: - name = f"{device.name}-{attr_name}" - existing = self.devices.setdefault(name, child) - if existing is not child: - # Its children's names start with the clashing name, so skip - # them too - LOGGER.warning( - "Not registering %s or its children, name '%s' is in use", - child, - name, - ) - continue - self._register_children(child) + for _, child in device.children(): + if not child.name or self._add_device(child.name, child): + self._register_children(child) + + def _add_device(self, name: str, device: Device) -> bool: + """Add a device unless a different one is already registered as name.""" + + existing = self.devices.setdefault(name, device) + if existing is not device: + # Its children's names start with the clashing name, so skip them too. + # Expected for e.g. a motor's user_readback, which has the motor's name + if not self._warned_name_clash: + LOGGER.warning( + "Some devices were not registered as their names are in use, " + "e.g. motor readbacks. Enable debug logging to see which" + ) + self._warned_name_clash = True + LOGGER.debug( + "Not registering %s or its children, name '%s' is in use", + device, + name, + ) + return False + return True def unregister_all_devices(self): """Unregister all devices from the context.""" diff --git a/tests/system_tests/devices.json b/tests/system_tests/devices.json index 7636cb05f..e9077067b 100644 --- a/tests/system_tests/devices.json +++ b/tests/system_tests/devices.json @@ -2676,48 +2676,6 @@ "types": [] } ] - }, - { - "name": "stage-x-user_readback", - "protocols": [ - { - "name": "Readable", - "types": [] - }, - { - "name": "Stageable", - "types": [] - }, - { - "name": "Subscribable", - "types": [] - }, - { - "name": "Device", - "types": [] - } - ] - }, - { - "name": "stage-theta-user_readback", - "protocols": [ - { - "name": "Readable", - "types": [] - }, - { - "name": "Stageable", - "types": [] - }, - { - "name": "Subscribable", - "types": [] - }, - { - "name": "Device", - "types": [] - } - ] } ] } diff --git a/tests/system_tests/plans.json b/tests/system_tests/plans.json index ddce7f2d6..7432b78f6 100644 --- a/tests/system_tests/plans.json +++ b/tests/system_tests/plans.json @@ -99,7 +99,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -123,7 +122,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -219,7 +217,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -243,7 +240,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -386,7 +382,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -410,7 +405,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -506,7 +500,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -530,7 +523,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -744,7 +736,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -768,7 +759,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -864,7 +854,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -888,7 +877,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1102,7 +1090,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1126,7 +1113,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1222,7 +1208,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1246,7 +1231,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1455,7 +1439,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1479,7 +1462,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1575,7 +1557,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1599,7 +1580,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1808,7 +1788,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1832,7 +1811,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -1928,7 +1906,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -1952,7 +1929,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2174,7 +2150,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2198,7 +2173,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2294,7 +2268,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2318,7 +2291,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2540,7 +2512,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2564,7 +2535,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2660,7 +2630,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2684,7 +2653,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -2897,7 +2865,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -2921,7 +2888,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -3017,7 +2983,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -3041,7 +3006,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4374,7 +4338,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4398,7 +4361,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4524,7 +4486,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4548,7 +4509,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4644,7 +4604,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4668,7 +4627,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -4882,7 +4840,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -4906,7 +4863,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5002,7 +4958,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5026,7 +4981,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5240,7 +5194,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5264,7 +5217,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5360,7 +5312,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5384,7 +5335,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5593,7 +5543,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5617,7 +5566,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -5713,7 +5661,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -5737,7 +5684,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], @@ -6210,7 +6156,6 @@ "stage-theta-set_use_switch", "stage-theta-steps_per_revolution", "stage-theta-units_per_revolution", - "stage-theta-user_readback", "stage-theta-user_setpoint", "stage-theta-velocity", "stage-x", @@ -6234,7 +6179,6 @@ "stage-x-set_use_switch", "stage-x-steps_per_revolution", "stage-x-units_per_revolution", - "stage-x-user_readback", "stage-x-user_setpoint", "stage-x-velocity" ], diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index 97da76031..cb8d52c4e 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -347,30 +347,26 @@ def __init__(self, name: str = "") -> None: super().__init__(name=name) -def test_child_sharing_parent_name_is_registered_by_attribute( +def test_child_sharing_parent_name_is_skipped_and_warned_once( empty_context: BlueskyContext, caplog: LogCaptureFixture ): # SimMotor's readback signal has the same name as the motor - caplog.set_level(logging.WARNING) + caplog.set_level(logging.DEBUG) motor = SimMotor(name="motor") empty_context.register_device(motor) + empty_context.register_device(SimMotor(name="other")) assert empty_context.devices["motor"] is motor - assert empty_context.devices["motor-user_readback"] is motor.user_readback - assert not caplog.get_records("call") - - -def test_descendant_sharing_ancestor_name_is_registered_by_attribute( - empty_context: BlueskyContext, caplog: LogCaptureFixture -): - caplog.set_level(logging.WARNING) - stage = Stage(name="stage") - stage.x.position.set_name("stage") - empty_context.register_device(stage) - - assert empty_context.devices["stage"] is stage - assert empty_context.devices["stage-x-position"] is stage.x.position - assert not caplog.get_records("call") + assert motor.user_readback not in empty_context.devices.values() + assert empty_context.find_device("motor.user_readback") is motor.user_readback + records = caplog.get_records("call") + assert [record.levelno for record in records] == [ + logging.WARNING, + logging.DEBUG, + logging.DEBUG, + ] + assert "'motor'" in records[1].message + assert "'other'" in records[2].message class AxisBank(Device): @@ -408,7 +404,7 @@ def test_overridden_registration_name_does_not_rename_children( assert empty_context.devices["stage-x"] is stage.x -def test_overridden_registration_name_frees_parent_name_for_child( +def test_oerridden_registration_name_frees_parent_name_for_child( empty_context: BlueskyContext, ): # "motor" isn't in use when the motor is registered as "foo", so its @@ -421,13 +417,13 @@ def test_overridden_registration_name_frees_parent_name_for_child( assert "motor-user_readback" not in empty_context.devices -def test_unrelated_name_collision_keeps_existing_device_and_warns( +def test_unrelated_name_collision_keeps_existing_device_and_logs( empty_context: BlueskyContext, caplog: LogCaptureFixture ): sentinel = SimMotor(name="sentinel") empty_context.register_device(sentinel, name="stage-x") - caplog.set_level(logging.WARNING) + caplog.set_level(logging.DEBUG) stage = Stage(name="stage") empty_context.register_device(stage) @@ -437,17 +433,18 @@ def test_unrelated_name_collision_keeps_existing_device_and_warns( assert any("stage-x" in record.message for record in caplog.get_records("call")) -def test_top_level_device_replacing_existing_device_warns( +def test_top_level_name_collision_keeps_existing_device_and_logs( empty_context: BlueskyContext, caplog: LogCaptureFixture ): stage = Stage(name="stage") empty_context.register_device(stage) - caplog.set_level(logging.WARNING) - replacement = SimMotor(name="stage-x") - empty_context.register_device(replacement) + caplog.set_level(logging.DEBUG) + motor = SimMotor(name="stage-x") + empty_context.register_device(motor) - assert empty_context.devices["stage-x"] is replacement + assert empty_context.devices["stage-x"] is stage.x + assert motor.velocity not in empty_context.devices.values() assert any("stage-x" in record.message for record in caplog.get_records("call")) diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index ee592c6cf..d61605381 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -218,14 +218,15 @@ def test_get_devices_includes_child_signals(context_mock: MagicMock): @patch("blueapi.service.interface.context") def test_get_devices_reports_registered_names(context_mock: MagicMock): + # The motor is registered as "foo", but its readback is named "motor" context = BlueskyContext() - context.register_device(SimMotor(name="motor")) + context.register_device(SimMotor(name="motor"), name="foo") context_mock.return_value = context names = [device.name for device in interface.get_devices()] - assert "motor-user_readback" in names + assert names.count("foo") == 1 assert names.count("motor") == 1 - assert interface.get_device("motor-user_readback").name == "motor-user_readback" + assert interface.get_device("foo").name == "foo" @patch("blueapi.service.interface.context") From 1118625bb03206bdaa97f1de91418f0a58b210d0 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Thu, 5 Nov 2026 12:52:36 +0000 Subject: [PATCH 09/10] Tidy comments and remove redundant tests --- src/blueapi/service/interface.py | 4 +-- tests/unit_tests/core/test_context.py | 17 +----------- tests/unit_tests/service/test_interface.py | 31 ---------------------- 3 files changed, 3 insertions(+), 49 deletions(-) diff --git a/src/blueapi/service/interface.py b/src/blueapi/service/interface.py index 4e64b9cde..6277a45ef 100644 --- a/src/blueapi/service/interface.py +++ b/src/blueapi/service/interface.py @@ -191,8 +191,8 @@ def get_plan(name: str) -> PlanModel: def get_devices() -> list[DeviceModel]: """Get all available devices in the BlueskyContext""" - # Use the registered name, as some children are registered under a name - # other than their own, e.g. a motor's user_readback + # Use the registered name, as a device registered with an override name would + # otherwise show its own name, which a child may also be registered as return [ DeviceModel.from_device(device, name) for name, device in context().devices.items() diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index cb8d52c4e..aacb483c0 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -341,12 +341,6 @@ def test_register_device_registers_children_recursively( assert empty_context.devices["table-mount-x-velocity"] is table.mount.x.velocity -class Detector(Device): - def __init__(self, name: str = "") -> None: - self.lens_mode = soft_signal_rw(str) - super().__init__(name=name) - - def test_child_sharing_parent_name_is_skipped_and_warned_once( empty_context: BlueskyContext, caplog: LogCaptureFixture ): @@ -404,7 +398,7 @@ def test_overridden_registration_name_does_not_rename_children( assert empty_context.devices["stage-x"] is stage.x -def test_oerridden_registration_name_frees_parent_name_for_child( +def test_overridden_registration_name_frees_parent_name_for_child( empty_context: BlueskyContext, ): # "motor" isn't in use when the motor is registered as "foo", so its @@ -414,7 +408,6 @@ def test_oerridden_registration_name_frees_parent_name_for_child( assert empty_context.devices["foo"] is motor assert empty_context.devices["motor"] is motor.user_readback - assert "motor-user_readback" not in empty_context.devices def test_unrelated_name_collision_keeps_existing_device_and_logs( @@ -469,14 +462,6 @@ def test_register_device_skips_unnamed_children(empty_context: BlueskyContext): assert empty_context.devices.keys() == {"stage"} -def test_dotted_and_dashed_lookup_return_same_device(empty_context: BlueskyContext): - stage = Stage(name="stage") - empty_context.register_device(stage) - - assert empty_context.find_device("stage.x") is empty_context.find_device("stage-x") - assert empty_context.find_device("stage-x") is stage.x - - def test_child_device_usable_as_plan_argument(empty_context: BlueskyContext): stage = Stage(name="stage") empty_context.register_device(stage) diff --git a/tests/unit_tests/service/test_interface.py b/tests/unit_tests/service/test_interface.py index d61605381..fc9afb7b9 100644 --- a/tests/unit_tests/service/test_interface.py +++ b/tests/unit_tests/service/test_interface.py @@ -11,7 +11,6 @@ from bluesky.utils import MsgGenerator from bluesky_stomp.messaging import StompClient from fastapi import status -from ophyd_async.core import Device, soft_signal_rw from ophyd_async.epics.motor import Motor from ophyd_async.sim import SimMotor from pydantic import HttpUrl, SecretStr @@ -186,36 +185,6 @@ def test_get_devices(context_mock: MagicMock): ] -class Detector(Device): - def __init__(self, name: str = "") -> None: - self.lens_mode = soft_signal_rw(str) - super().__init__(name=name) - - -@patch("blueapi.service.interface.context") -def test_get_devices_includes_child_signals(context_mock: MagicMock): - context = BlueskyContext() - context.register_device(Detector(name="detector")) - context_mock.return_value = context - - assert interface.get_devices() == [ - DeviceModel( - name="detector", - protocols=[ProtocolInfo(name="Device", types=[])], - ), - DeviceModel( - name="detector-lens_mode", - protocols=[ - ProtocolInfo(name="Movable", types=[]), - ProtocolInfo(name="Readable", types=[]), - ProtocolInfo(name="Stageable", types=[]), - ProtocolInfo(name="Subscribable", types=[]), - ProtocolInfo(name="Device", types=[]), - ], - ), - ] - - @patch("blueapi.service.interface.context") def test_get_devices_reports_registered_names(context_mock: MagicMock): # The motor is registered as "foo", but its readback is named "motor" From 8c587344b7fc453c82f5501857c279643e571bd6 Mon Sep 17 00:00:00 2001 From: Alexj9837 <52531949+Alexj9837@users.noreply.github.com> Date: Thu, 5 Nov 2026 16:30:41 +0000 Subject: [PATCH 10/10] Clarify clash comments and merge override name tests --- src/blueapi/core/context.py | 4 ++-- src/blueapi/service/interface.py | 5 +++-- tests/unit_tests/core/test_context.py | 25 +++---------------------- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/blueapi/core/context.py b/src/blueapi/core/context.py index 277d1fad2..8c92a0952 100644 --- a/src/blueapi/core/context.py +++ b/src/blueapi/core/context.py @@ -382,8 +382,8 @@ def _add_device(self, name: str, device: Device) -> bool: existing = self.devices.setdefault(name, device) if existing is not device: - # Its children's names start with the clashing name, so skip them too. - # Expected for e.g. a motor's user_readback, which has the motor's name + # Expected for e.g. a motor's user_readback, which has the motor's name. + # The caller skips its children too, as their names start with this one if not self._warned_name_clash: LOGGER.warning( "Some devices were not registered as their names are in use, " diff --git a/src/blueapi/service/interface.py b/src/blueapi/service/interface.py index 6277a45ef..0c1aca5f1 100644 --- a/src/blueapi/service/interface.py +++ b/src/blueapi/service/interface.py @@ -191,8 +191,9 @@ def get_plan(name: str) -> PlanModel: def get_devices() -> list[DeviceModel]: """Get all available devices in the BlueskyContext""" - # Use the registered name, as a device registered with an override name would - # otherwise show its own name, which a child may also be registered as + # Report each device under its registered name. A device registered under an + # override name would otherwise show its own name, which one of its children + # may be registered as, e.g. a motor's user_readback return [ DeviceModel.from_device(device, name) for name, device in context().devices.items() diff --git a/tests/unit_tests/core/test_context.py b/tests/unit_tests/core/test_context.py index aacb483c0..6fd53dd05 100644 --- a/tests/unit_tests/core/test_context.py +++ b/tests/unit_tests/core/test_context.py @@ -381,33 +381,14 @@ def test_device_vector_children_are_registered(empty_context: BlueskyContext): def test_overridden_registration_name_does_not_rename_children( empty_context: BlueskyContext, ): - # Children keep their own names when the parent is registered as "foo" - stage = Stage(name="stage") - empty_context.register_device(stage, name="foo") - - assert empty_context.devices.keys() == { - "foo", - "stage-x", - "stage-x-position", - "stage-x-velocity", - "stage-y", - "stage-y-position", - "stage-y-velocity", - } - assert empty_context.devices["foo"] is stage - assert empty_context.devices["stage-x"] is stage.x - - -def test_overridden_registration_name_frees_parent_name_for_child( - empty_context: BlueskyContext, -): - # "motor" isn't in use when the motor is registered as "foo", so its - # readback keeps its own name + # Children keep their own names when the parent is registered as "foo", so + # the motor's readback is registered as "motor", which is not in use motor = SimMotor(name="motor") empty_context.register_device(motor, name="foo") assert empty_context.devices["foo"] is motor assert empty_context.devices["motor"] is motor.user_readback + assert empty_context.devices["motor-velocity"] is motor.velocity def test_unrelated_name_collision_keeps_existing_device_and_logs(