Skip to content

Commit

Permalink
signalRW locate now returns proper Location
Browse files Browse the repository at this point in the history
  • Loading branch information
olliesilvester committed Sep 20, 2023
1 parent 128b294 commit d4412a1
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 29 deletions.
38 changes: 36 additions & 2 deletions src/ophyd_async/core/_device/_signal/signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from bluesky.protocols import (
Descriptor,
Locatable,
Location,
Movable,
Readable,
Reading,
Expand Down Expand Up @@ -200,17 +201,50 @@ async def unstage(self) -> None:
class SignalW(Signal[T], Movable):
"""Signal that can be set"""

_cache: Optional[_SignalCache] = None

def _backend_or_cache(
self, cached: Optional[bool]
) -> Union[_SignalCache, SignalBackend]:
# If cached is None then calculate it based on whether we already have a cache
if cached is None:
cached = self._cache is not None
if cached:
assert self._cache, f"{self.source} not being monitored"
return self._cache
else:
return self._backend

def _get_cache(self) -> _SignalCache:
if not self._cache:
self._cache = _SignalCache(self._backend, self)
return self._cache

def _del_cache(self, needed: bool):
if self._cache and not needed:
self._cache.close()
self._cache = None

def set(self, value: T, wait=True, timeout=None) -> AsyncStatus:
"""Set the value and return a status saying when it's done"""
coro = self._backend.put(value, wait=wait, timeout=timeout or self._timeout)
return AsyncStatus(coro)

@_add_timeout
async def get_setpoint(self, cached: Optional[bool] = None) -> T:
"""The current value"""
return await self._backend_or_cache(cached).get_value()


class SignalRW(SignalR[T], SignalW[T], Locatable):
"""Signal that can be both read and set"""

async def locate(self):
return await self.get_value()
async def locate(self) -> Location:
location: Location = {
"setpoint": await self.get_setpoint(),
"readback": await self.get_value(),
}
return location


class SignalX(Signal):
Expand Down
52 changes: 27 additions & 25 deletions src/ophyd_async/core/_device/device_save_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,27 @@
def get_signal_RWs_from_device(
device: Device, path_prefix: str = "", signalRWs: Dict[str, SignalRW] = {}
) -> Dict[str, SignalRW]:
"""Get all the signalRW's from a device and store with their dotted attribute paths.
Used by the save_device and load_device methods.
"""
Get all the SignalRWs from a device and store them with their dotted attribute
paths. Used by the save and load methods.
Parameters
----------
device: Device
Ophyd device to retrieve read write signals from
device : Device
Ophyd device to retrieve read-write signals from.
path_prefix: Str
For internal use, leave blank when calling method.
path_prefix : str
For internal use, leave blank when calling the method.
SignalRWs: Dict
A dictionary matching the string attribute path of a SignalRW with the
signal itself. Leave blank when calling method.
SignalRWs : dict
A dictionary matching the string attribute path of a SignalRW with the
signal itself. Leave blank when calling the method.
Returns:
SignalRWs: Dict
A dictionary matching the string attribute path of a SignalRW with the
signal itself.
Returns
-------
SignalRWs : dict
A dictionary matching the string attribute path of a SignalRW with the
signal itself.
"""

for attr_name, attr in device.children():
Expand All @@ -48,31 +50,31 @@ def get_signal_RWs_from_device(
def save_device(device: Device, savename: str, ignore: List[str] = []):
"""
Plan to save the setup of a device by getting a list of its signals and their
readback values
readback values.
Store the output to savename.yaml
Store the output to `savename.yaml`.
Parameters
----------
device : Savable
Ophyd device which implements the sort_signal_by_phase method.
savename: String
name of yaml file
Ophyd device which implements the `sort_signal_by_phase` method.
ignore: List[String]
List of attributes path strings to not include in the save file
savename : str
Name of the YAML file.
ignore : list of str
List of attribute path strings to not include in the save file.
Yields
------
msg : Msg
'locate', *signals
`locate`, `*signals`
See Also
--------
:func:`ophyd_async.core.load_device_plan`
:func:`ophyd_async.core.load_device`
:func:`sort_signal_by_phase`
"""

signalRWs: Dict[str, SignalRW] = get_signal_RWs_from_device(device, "")
Expand All @@ -90,6 +92,7 @@ def save_device(device: Device, savename: str, ignore: List[str] = []):
for phase in phase_dicts:
signals_to_locate.extend(phase.values())
signal_values = yield Msg("locate", *signals_to_locate)
signal_values = [value["setpoint"] for value in signal_values]

# The table PVs are dictionaries of np arrays. Need to convert these to
# lists for easy saving
Expand All @@ -109,9 +112,8 @@ def save_device(device: Device, savename: str, ignore: List[str] = []):
for phase in phase_dicts:
signal_name_values: Dict[str, Any] = {}
for signal_name in phase.keys():
if signal_name in ignore:
continue
signal_name_values[signal_name] = signal_values[signal_value_index]
if signal_name not in ignore:
signal_name_values[signal_name] = signal_values[signal_value_index]
signal_value_index += 1

phase_outputs.append(signal_name_values)
Expand Down
3 changes: 1 addition & 2 deletions tests/core/_device/test_device_save_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async def test_save_device_no_phase(device, device_with_phases, tmp_path):

# Test enum PVs
await device.parent_sig3.set(EnumTest.VAL1)
RE(save_device(device, path.join(tmp_path, "test_file")))
RE(save_device(device, path.join(tmp_path, "test_file"), ignore=["parent_sig1"]))

with open(path.join(tmp_path, "test_file.yaml"), "r") as file:
yaml_content = yaml.safe_load(file)
Expand All @@ -92,7 +92,6 @@ async def test_save_device_no_phase(device, device_with_phases, tmp_path):
"VAL1": [1, 1, 1, 1, 1],
"VAL2": [1, 1, 1, 1, 1],
},
"parent_sig1": "",
"parent_sig3": "val1",
}

Expand Down

0 comments on commit d4412a1

Please sign in to comment.