From 822a02419147a1a17ac915ee79983a998153747d Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh Date: Tue, 17 Sep 2024 15:09:31 +0000 Subject: [PATCH] added type changes to interface --- src/ophyd_async/core/_signal.py | 29 ++++++++++++--------- src/ophyd_async/epics/adcore/_core_logic.py | 5 ++-- tests/core/test_signal.py | 17 ++++++------ 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/ophyd_async/core/_signal.py b/src/ophyd_async/core/_signal.py index 127065a96..1ed839ea0 100644 --- a/src/ophyd_async/core/_signal.py +++ b/src/ophyd_async/core/_signal.py @@ -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 @@ -603,14 +603,14 @@ 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 ---------- @@ -618,9 +618,9 @@ async def set_and_wait_for_other_value( 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 @@ -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: @@ -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: @@ -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: @@ -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 ) diff --git a/src/ophyd_async/epics/adcore/_core_logic.py b/src/ophyd_async/epics/adcore/_core_logic.py index 21b07406f..b545ad27f 100644 --- a/src/ophyd_async/epics/adcore/_core_logic.py +++ b/src/ophyd_async/epics/adcore/_core_logic.py @@ -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 @@ -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( diff --git a/tests/core/test_signal.py b/tests/core/test_signal.py index d498e6753..acbbde6a2 100644 --- a/tests/core/test_signal.py +++ b/tests/core/test_signal.py @@ -178,7 +178,8 @@ 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 @@ -186,9 +187,9 @@ async def check_set_and_wait(): 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() @@ -196,14 +197,14 @@ async def test_set_and_wait_for_value_different_set_and_read(): 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