From afdc64e296c08487d26745daef18d679297d34a4 Mon Sep 17 00:00:00 2001 From: appel_c Date: Thu, 26 Feb 2026 16:12:40 +0100 Subject: [PATCH] fix(rio): fix rio cached readings --- csaxs_bec/devices/omny/galil/galil_rio.py | 40 ++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/csaxs_bec/devices/omny/galil/galil_rio.py b/csaxs_bec/devices/omny/galil/galil_rio.py index dc599d7..dd0313e 100644 --- a/csaxs_bec/devices/omny/galil/galil_rio.py +++ b/csaxs_bec/devices/omny/galil/galil_rio.py @@ -13,6 +13,7 @@ which can be easily supported by changing the _NUM_DIGITAL_OUTPUT_CHANNELS varia from __future__ import annotations +import time from typing import TYPE_CHECKING, Literal from bec_lib.logger import bec_logger @@ -78,12 +79,38 @@ class GalilRIOAnalogSignalRO(GalilSignalBase): """ _NUM_ANALOG_CHANNELS = 8 + READBACK_TIMEOUT = 0.1 # time to wait in between two readback attemps in seconds, otherwise return cached value - def __init__(self, signal_name: str, channel: int, parent: GalilRIO, **kwargs): + def __init__( + self, + signal_name: str, + channel: int, + parent: GalilRIO, + readback_timeout: float = None, + **kwargs, + ): super().__init__(signal_name=signal_name, parent=parent, **kwargs) self._channel = channel self._metadata["connected"] = False + self._readback_timeout = ( + readback_timeout if readback_timeout is not None else self.READBACK_TIMEOUT + ) self._metadata["write_access"] = False + self._last_readback = 0.0 + + def get(self): + current_time = time.monotonic() + if current_time - self._last_readback > self._readback_timeout: + old_value = self._readback + self._last_readback = current_time # _socket_get may rely on this value to be set. + self._readback = self._socket_get() + self._run_subs( + sub_type=self.SUB_VALUE, + old_value=old_value, + value=self._readback, + timestamp=current_time, + ) + return self._readback def _socket_set(self, val): """Read-only signal, so set method raises an error.""" @@ -136,6 +163,8 @@ class GalilRIOAnalogSignalRO(GalilSignalBase): # Run subscriptions after all readbacks have been updated # on all channels except the one that triggered the update + # TODO for now skip running subscribers, this should be re-implemented + # once we properly handle subscriptions from bec running "read" for walk in self.parent.walk_signals(): if walk.item.attr_name in updates: new_val, old_val = updates[walk.item.attr_name] @@ -185,7 +214,7 @@ def _create_analog_channels(num_channels: int) -> dict[str, tuple]: an_channels[f"ch{i}"] = ( GalilRIOAnalogSignalRO, f"ch{i}", - {"kind": Kind.normal, "notify_bec": True, "channel": i, "doc": f"Analog channel {i}."}, + {"kind": Kind.normal, "channel": i, "doc": f"Analog channel {i}."}, ) return an_channels @@ -202,12 +231,7 @@ def _create_digital_output_channels(num_channels: int) -> dict[str, tuple]: di_out_channels[f"ch{i}"] = ( GalilRIODigitalOutSignal, f"ch{i}", - { - "kind": Kind.config, - "notify_bec": True, - "channel": i, - "doc": f"Digital output channel {i}.", - }, + {"kind": Kind.config, "channel": i, "doc": f"Digital output channel {i}."}, ) return di_out_channels