Skip to content

Commit

Permalink
added type changes to interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ZohebShaikh committed Sep 17, 2024
1 parent caadaca commit 822a024
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 22 deletions.
29 changes: 17 additions & 12 deletions src/ophyd_async/core/_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ async def observe_signals_values(
*signals: SignalR[T],
timeout: float | None = None,
done_status: Status | None = None,
) -> AsyncGenerator[T, None]:
) -> AsyncGenerator[Tuple[SignalR[T], T], None]:
"""Subscribe to the value of a signal so it can be iterated from.
Parameters
Expand Down Expand Up @@ -603,24 +603,24 @@ async def set_and_wait_for_other_value(
set_signal: SignalW[T],
set_value: T,
match_signal: SignalR[S],
match_value: S,
match_value: S | Callable[[S], bool],
timeout: float = DEFAULT_TIMEOUT,
set_timeout: Optional[float] = None,
) -> AsyncStatus:
):
"""Set a signal and monitor another signal until it has the specified value.
This function sets a set_signal to a specified set_value and waits for
a read_signal to have the read_value.
a match_signal to have the match_value.
Parameters
----------
signal:
The signal to set
set_value:
The value to set it to
read_signal:
match_signal:
The signal to monitor
read_value:
match_value:
The value to wait for
timeout:
How long to wait for the signal to have the value
Expand All @@ -639,7 +639,7 @@ async def set_and_wait_for_other_value(
# Get the initial value from the monitor to make sure we've created it
current_value = await anext(values_gen)

status = set_signal.set(set_value, timeout=set_timeout)
set_signal.set(set_value, timeout=set_timeout)

# If the value was the same as before no need to wait for it to change
if current_value != match_value:
Expand All @@ -656,15 +656,14 @@ async def _wait_for_value():
f"{match_signal.name} didn't match {match_value} in {timeout}s"
) from e

return status


async def set_and_wait_for_value(
signal: SignalRW[T],
value: T,
match_value: T | Callable[[T], bool] | None = None,
timeout: float = DEFAULT_TIMEOUT,
status_timeout: Optional[float] = None,
) -> AsyncStatus:
):
"""Set a signal and monitor it until it has that value.
Useful for busy record, or other Signals with pattern:
Expand All @@ -678,6 +677,9 @@ async def set_and_wait_for_value(
The signal to set
value:
The value to set it to
match_value:
The expected value of the signal after the operation.
Used to verify that the set operation was successful.
timeout:
How long to wait for the signal to have the value
status_timeout:
Expand All @@ -689,6 +691,9 @@ async def set_and_wait_for_value(
set_and_wait_for_value(device.acquire, 1)
"""
return await set_and_wait_for_other_value(
signal, value, signal, value, timeout, status_timeout
if match_value is None:
match_value = value

await set_and_wait_for_other_value(
signal, value, signal, match_value, timeout, status_timeout
)
5 changes: 3 additions & 2 deletions src/ophyd_async/epics/adcore/_core_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
DetectorControl,
set_and_wait_for_value,
)
from ophyd_async.core._signal import wait_for_value
from ophyd_async.epics.adcore._utils import convert_ad_dtype_to_np

from ._core_io import ADBaseIO, DetectorState
Expand Down Expand Up @@ -92,12 +93,12 @@ async def start_acquiring_driver_and_ensure_status(
subsequent raising (if applicable) due to detector state.
"""

status = await set_and_wait_for_value(driver.acquire, True, timeout=timeout)
await set_and_wait_for_value(driver.acquire, True, timeout=timeout)

async def complete_acquisition() -> None:
"""NOTE: possible race condition here between the callback from
set_and_wait_for_value and the detector state updating."""
await status
await wait_for_value(driver.acquire, True, timeout=None)
state = await driver.detector_state.get_value()
if state not in good_states:
raise ValueError(
Expand Down
17 changes: 9 additions & 8 deletions tests/core/test_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,32 +178,33 @@ async def wait_and_set_proceeds():
set_mock_put_proceeds(signal, True)

async def check_set_and_wait():
await (await set_and_wait_for_value(signal, 1, timeout=0.1))
await set_and_wait_for_value(signal, 1, timeout=0.1)
await wait_for_value(signal, 1, timeout=0.1)

await asyncio.gather(wait_and_set_proceeds(), check_set_and_wait())
assert await signal.get_value() == 1


async def test_set_and_wait_for_value_different_set_and_read():
set_signal = epics_signal_rw(int, "pva://set", name="set-signal")
read_signal = epics_signal_r(str, "pva://read", name="read-signal")
match_signal = epics_signal_r(str, "pva://read", name="read-signal")
await set_signal.connect(mock=True)
await read_signal.connect(mock=True)
await match_signal.connect(mock=True)

do_read_set = Event()

callback_on_mock_put(set_signal, lambda *args, **kwargs: do_read_set.set())

async def wait_and_set_read():
await do_read_set.wait()
set_mock_value(read_signal, "test")
set_mock_value(match_signal, "test")

async def check_set_and_wait():
await (
await set_and_wait_for_other_value(
set_signal, 1, read_signal, "test", timeout=100
)
await set_and_wait_for_other_value(
set_signal, 1, match_signal, "test", timeout=100
)
await wait_for_value(set_signal, 1, timeout=100)
await wait_for_value(match_signal, "test", timeout=100)

await asyncio.gather(wait_and_set_read(), check_set_and_wait())
assert await set_signal.get_value() == 1
Expand Down

0 comments on commit 822a024

Please sign in to comment.