photoreflectance/prsctrl/utility/device_select.py
JohannesDittloff 7f7561e4d9 rename prsctrl
2025-05-08 13:07:22 +02:00

73 lines
3.1 KiB
Python

def select_device_interactive(type_devices_dict: dict[str, list[str]], prompt="Select an instrument: ") -> tuple[str, str]:
"""
Select a device interactively from the command line
Parameters
----------
type_devices_dict
A dictionary of device types and their corresponding device names
-------
The type and name of the selected device.
These can be passed to the connect_device method of the led_control_device or voltage_measurement_device libraries
"""
res = type_devices_dict
flat_res = [ (t, v) for t, l in res.items() for v in l ]
for i, (t,v) in enumerate(flat_res):
print(f"{i+1:02}: {t} - {v}")
while len(flat_res) > 0:
try:
instr = int(input(prompt)) - 1
if instr < 0 or instr >= len(flat_res):
raise ValueError
return flat_res[instr]
except ValueError:
print(f"Enter a number between 1 and {len(flat_res)}")
continue
raise Exception("No devices found")
from .config_file import ConfigFile
import logging
def connect_device_from_config_or_interactive(config_file: ConfigFile, device_typename: str, device_typename_prompt: str, module, config_key_template="last_dev_<device>_<type/name>", log: logging.Logger=logging.getLogger(__name__), n_interactive_tries=2):
"""
Connect a device from the type and name stored in a config file, and if that fails prompt the user on the command line
:param config_file: ConfigFile object
:param device_typename: device type name to use in the config file key
:param device_typename_prompt: device type name to use in interactive prompt
:param module: python module supporting .connect_device(type, name) and .enumerate_devices()
:param config_key_template: template for the config key string
:param log: Logger
:param n_interactive_tries: how often to try the interactive selection
:return: device
"""
# get the last connected from the config file
key_type = config_key_template.replace("<device>", device_typename).replace("<type/name>", "type")
key_name = config_key_template.replace("<device>", device_typename).replace("<type/name>", "name")
last_shutter_type = config_file.get_or(key_type, None)
last_shutter_name = config_file.get_or(key_name, None)
dev = None
# try to connect
if last_shutter_name and last_shutter_type:
try:
dev = module.connect_device(last_shutter_type, last_shutter_name)
except:
log.error(f"Failed to connect to last used device {last_shutter_type}::{last_shutter_name}")
while dev is None and n_interactive_tries > 0:
devs = module.list_devices()
print("-" * 50)
dev_type, dev_name = select_device_interactive(devs, f"Select {device_typename_prompt}: ")
try:
dev = module.connect_device(dev_type, dev_name)
config_file.set(key_type, dev_type)
config_file.set(key_name, dev_name)
except:
log.error(f"Failed to connect to device {dev_type}::{dev_name}")
n_interactive_tries -= 1
if dev is None:
raise Exception("Failed to connect a device")
return dev