Skip to content

Commit

Permalink
Added AsyncReadable, AsyncConfigurable and AsyncPausable
Browse files Browse the repository at this point in the history
Also replaced imports of bluesky.protocols for each with their new async counterparts.
  • Loading branch information
Oliver Copping committed Apr 16, 2024
1 parent e54c91c commit d519495
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 8 deletions.
7 changes: 3 additions & 4 deletions src/ophyd_async/core/detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@

from bluesky.protocols import (
Collectable,
Configurable,
Descriptor,
Flyable,
Preparable,
Readable,
Reading,
Stageable,
StreamAsset,
Triggerable,
WritesStreamAssets,
)
from ophyd_async.protocols import AsyncReadable, AsyncConfigurable

from .async_status import AsyncStatus
from .device import Device
Expand Down Expand Up @@ -143,8 +142,8 @@ async def close(self) -> None:
class StandardDetector(
Device,
Stageable,
Configurable,
Readable,
AsyncConfigurable,
AsyncReadable,
Triggerable,
Preparable,
Flyable,
Expand Down
4 changes: 2 additions & 2 deletions src/ophyd_async/core/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
Locatable,
Location,
Movable,
Readable,
Reading,
Stageable,
Subscribable,
)
from ophyd_async.protocols import AsyncReadable

from .async_status import AsyncStatus
from .device import Device
Expand Down Expand Up @@ -133,7 +133,7 @@ def set_staged(self, staged: bool):
return self._staged or bool(self._listeners)


class SignalR(Signal[T], Readable, Stageable, Subscribable):
class SignalR(Signal[T], AsyncReadable, Stageable, Subscribable):
"""Signal that can be read from and monitored"""

_cache: Optional[_SignalCache] = None
Expand Down
5 changes: 3 additions & 2 deletions src/ophyd_async/core/standard_readable.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from typing import Dict, Sequence, Tuple

from bluesky.protocols import Configurable, Descriptor, Readable, Reading, Stageable
from bluesky.protocols import Descriptor, Reading, Stageable
from ophyd_async.protocols import AsyncConfigurable, AsyncReadable

from .async_status import AsyncStatus
from .device import Device
from .signal import SignalR
from .utils import merge_gathered_dicts


class StandardReadable(Device, Readable, Configurable, Stageable):
class StandardReadable(Device, AsyncReadable, AsyncConfigurable, Stageable):
"""Device that owns its children and provides useful default behavior.
- When its name is set it renames child Devices
Expand Down
3 changes: 3 additions & 0 deletions src/ophyd_async/protocols/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .protocols import AsyncReadable, AsyncConfigurable, AsyncPausable

__all__ = ["AsyncReadable", "AsyncConfigurable", "AsyncPausable"]
72 changes: 72 additions & 0 deletions src/ophyd_async/protocols/protocols.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from abc import abstractmethod
from typing import Any, Coroutine, Dict, Protocol, runtime_checkable
from bluesky.protocols import HasName, Reading, Descriptor


@runtime_checkable
class AsyncReadable(HasName, Protocol):
@abstractmethod
async def read(self) -> Coroutine[Any, Any, Dict[str, Reading]]:
"""Return an OrderedDict mapping string field name(s) to dictionaries
of values and timestamps and optional per-point metadata.
Example return value:
.. code-block:: python
OrderedDict(('channel1',
{'value': 5, 'timestamp': 1472493713.271991}),
('channel2',
{'value': 16, 'timestamp': 1472493713.539238}))
"""
...

@abstractmethod
async def describe(self) -> Coroutine[Any, Any, Dict[str, Descriptor]]:
"""Return an OrderedDict with exactly the same keys as the ``read``
method, here mapped to per-scan metadata about each field.
Example return value:
.. code-block:: python
OrderedDict(('channel1',
{'source': 'XF23-ID:SOME_PV_NAME',
'dtype': 'number',
'shape': []}),
('channel2',
{'source': 'XF23-ID:SOME_PV_NAME',
'dtype': 'number',
'shape': []}))
"""
...


@runtime_checkable
class AsyncConfigurable(Protocol):
@abstractmethod
async def read_configuration(self) -> Coroutine[Any, Any, Dict[str, Reading]]:
"""Same API as ``read`` but for slow-changing fields related to configuration.
e.g., exposure time. These will typically be read only once per run.
"""
...

@abstractmethod
async def describe_configuration(self) -> Coroutine[Any, Any, Dict[str, Descriptor]]:
"""Same API as ``describe``, but corresponding to the keys in
``read_configuration``.
"""
...


@runtime_checkable
class AsyncPausable(Protocol):
@abstractmethod
async def pause(self) -> None:
"""Perform device-specific work when the RunEngine pauses."""
...

@abstractmethod
async def resume(self) -> None:
"""Perform device-specific work when the RunEngine resumes after a pause."""
...

0 comments on commit d519495

Please sign in to comment.