Skip to content

Commit b539ac0

Browse files
tpoliawrtuck99
andauthored
Add DeviceManager as alternative to make_all_devices (#1549)
* Proof of concept device manager * Use fixtures parameter instead of **kwargs * Expand dependencies * Pre-optional handling * 'Working' optional dependencies * Docs, comments and warnings * Check for positional only arguments * Handle connections and support new loader in cli * Convert adsim to new loading * Add auto_connect to device manager * Remove references to connecting from device manager * DeviceResult wrappers * Demo adsim * build_and_connect method * Multiple manager CLI * FIXTUEES * Use device decorator for timeouts * Type build_and_connect and rely on fixtures for path provider * mostly reformatting * Make fixture generators lazy * Apologise for build_order method * Return function from fixture decorator * Add timeout parameter to build_and_connect * Remove dead comment * Use set in expand_dependencies to prevent repetition * Check for duplicate factory names * Add Ophyd v1 support * Connect Ophyd v1 devices * Move device_manager to new module Instead of burying it amongst the beamlines. * Remove test code from device_manager module * Remove debugging and commented code * Merge connectionspec and connectionparameters * Add or_raise method to DeviceBuildResult * Add docstrings * Use or_raise to handle build errors * Only set device name if required * Add TODOs to remove v1 support * Make v1 device timeout configurable * Default to waiting for v1 device connection * Add repr to v1 device factory * Split DeviceBuildResult devices and connection specs Makes access to the devices easier and makes it easier to build parameters * Remove device_type property from factories * Include fixture overrides in built devices * Fix duplication in factory repr * Add initial device_manager tests * Revert adsim changes for now * Enough tests to get full coverage Maybe enough tests to cover basic use * Create DeviceManager in fixture * Add test for docstrings * Reformat tests * Linting et al * Support single device manager name in CLI * Ignore mock type warnings * Appease pre-commit lints * Add tests for device manager use in CLI * Make 'devices' default name for device manager in CLI * Clean up TODO comments * Set return_value when creating mocks * Fix typing in v1_init decorator * Use ParamSpec when passing through __call__ * Handle or ignore var args * Update tests * Rename ignore skip test * Simplify LazyFixture __getitem__ * Used UserDict as base class for LazyFixtures * Make pyright happy * Remove need for type ignore --------- Co-authored-by: Robert Tuck <[email protected]>
1 parent f50aaaa commit b539ac0

File tree

4 files changed

+1422
-13
lines changed

4 files changed

+1422
-13
lines changed

src/dodal/cli.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import importlib
12
import os
23
from collections.abc import Mapping
34
from pathlib import Path
@@ -9,6 +10,7 @@
910

1011
from dodal.beamlines import all_beamline_names, module_name_for_beamline
1112
from dodal.common.beamlines.beamline_utils import set_path_provider
13+
from dodal.device_manager import DeviceManager
1214
from dodal.utils import AnyDevice, filter_ophyd_devices, make_all_devices
1315

1416
from . import __version__
@@ -43,15 +45,15 @@ def main(ctx: click.Context) -> None:
4345
"attempt any I/O. Useful as a a dry-run.",
4446
default=False,
4547
)
46-
def connect(beamline: str, all: bool, sim_backend: bool) -> None:
48+
@click.option("-n", "--name", "device_manager", default="devices")
49+
def connect(beamline: str, all: bool, sim_backend: bool, device_manager: str) -> None:
4750
"""Initialises a beamline module, connects to all devices, reports
4851
any connection issues."""
4952

5053
os.environ["BEAMLINE"] = beamline
5154

5255
# We need to make a fake path provider for any detectors that need one,
5356
# it is not used in dodal connect
54-
_spoof_path_provider()
5557

5658
module_name = module_name_for_beamline(beamline)
5759
full_module_path = f"dodal.beamlines.{module_name}"
@@ -62,16 +64,28 @@ def connect(beamline: str, all: bool, sim_backend: bool) -> None:
6264

6365
print(f"Attempting connection to {beamline} (using {full_module_path})")
6466

65-
# Force all devices to be lazy (don't connect to PVs on instantiation) and do
66-
# connection as an extra step, because the alternatives is handling the fact
67-
# that only some devices may be lazy.
68-
devices, instance_exceptions = make_all_devices(
69-
full_module_path,
70-
include_skipped=all,
71-
fake_with_ophyd_sim=sim_backend,
72-
wait_for_connection=False,
73-
)
74-
devices, connect_exceptions = _connect_devices(run_engine, devices, sim_backend)
67+
mod = importlib.import_module(full_module_path)
68+
69+
# Don't connect devices as they're built and do connection as an extra step,
70+
# because the alternatives is handling the fact that only some devices may
71+
# be lazy.
72+
73+
if (manager := getattr(mod, device_manager, None)) and isinstance(
74+
manager, DeviceManager
75+
):
76+
devices, instance_exceptions, connect_exceptions = manager.build_and_connect(
77+
mock=sim_backend,
78+
)
79+
else:
80+
print(f"No device manager named '{device_manager}' found in {mod}")
81+
_spoof_path_provider()
82+
devices, instance_exceptions = make_all_devices(
83+
full_module_path,
84+
include_skipped=all,
85+
fake_with_ophyd_sim=sim_backend,
86+
wait_for_connection=False,
87+
)
88+
devices, connect_exceptions = _connect_devices(run_engine, devices, sim_backend)
7589

7690
# Inform user of successful connections
7791
_report_successful_devices(devices, sim_backend)

0 commit comments

Comments
 (0)