Source code for ophyd_async.core._signal_backend

from abc import abstractmethod
from typing import (
    TYPE_CHECKING,
    Any,
    ClassVar,
    Generic,
    Literal,
)

from bluesky.protocols import Reading
from event_model import DataKey

from ._utils import DEFAULT_TIMEOUT, ReadingValueCallback, T


[docs] class SignalBackend(Generic[T]): """A read/write/monitor backend for a Signals""" #: Datatype of the signal value datatype: type[T] | None = None
[docs] @classmethod @abstractmethod def datatype_allowed(cls, dtype: Any) -> bool: """Check if a given datatype is acceptable for this signal backend."""
#: Like ca://PV_PREFIX:SIGNAL
[docs] @abstractmethod def source(self, name: str) -> str: """Return source of signal. Signals may pass a name to the backend, which can be used or discarded."""
[docs] @abstractmethod async def connect(self, timeout: float = DEFAULT_TIMEOUT): """Connect to underlying hardware"""
[docs] @abstractmethod async def put(self, value: T | None, wait=True, timeout=None): """Put a value to the PV, if wait then wait for completion for up to timeout"""
[docs] @abstractmethod async def get_datakey(self, source: str) -> DataKey: """Metadata like source, dtype, shape, precision, units"""
[docs] @abstractmethod async def get_reading(self) -> Reading: """The current value, timestamp and severity"""
[docs] @abstractmethod async def get_value(self) -> T: """The current value"""
[docs] @abstractmethod async def get_setpoint(self) -> T: """The point that a signal was requested to move to."""
[docs] @abstractmethod def set_callback(self, callback: ReadingValueCallback[T] | None) -> None: """Observe changes to the current value, timestamp and severity"""
class _RuntimeSubsetEnumMeta(type): def __str__(cls): if hasattr(cls, "choices"): return f"SubsetEnum{list(cls.choices)}" # type: ignore return "SubsetEnum" def __getitem__(cls, _choices): if isinstance(_choices, str): _choices = (_choices,) else: if not isinstance(_choices, tuple) or not all( isinstance(c, str) for c in _choices ): raise TypeError( "Choices must be a str or a tuple of str, " f"not {type(_choices)}." ) if len(set(_choices)) != len(_choices): raise TypeError("Duplicate elements in runtime enum choices.") class _RuntimeSubsetEnum(cls): choices = _choices return _RuntimeSubsetEnum class RuntimeSubsetEnum(metaclass=_RuntimeSubsetEnumMeta): choices: ClassVar[tuple[str, ...]] def __init__(self): raise RuntimeError("SubsetEnum cannot be instantiated") if TYPE_CHECKING: SubsetEnum = Literal else: SubsetEnum = RuntimeSubsetEnum