Skip to content

Releases: bluesky/ophyd-async

v0.8.0

26 Nov 12:27
e75d1cd
Compare
Choose a tag to compare

Breaking changes

pvi structure changes

Structure now read from .value rather than .pvi and includes DeviceVector support. Supported in FastCS. Requires at least PandABlocks-ioc 0.11.4

set_and_wait_for_value changes

Some keyword argument changes to observe_value and set_and_wait_for_value. There is a new argument to set_and_wait_for_value, it now has a wait_for_set_completion argument with default of True. This is a change in behaviour to before where it would not wait for the set to complete before returning the Status, however it is the desired behaviour in the majority of cases. If using with areaDetector then supply wait_for_set_completion=False as per the docs

Epics signal module moves

ophyd_async.epics.signal moves to ophyd_async.epics.core with a backwards compat module that emits deprecation warning.

# old
from ophyd_async.epics.signal import epics_signal_rw
# new
from ophyd_async.epics.core import epics_signal_rw

StandardReadable wrappers change to StandardReadableFormat

StandardReadable wrappers change to enum members of StandardReadableFormat (normally imported as Format)

# old
from ophyd_async.core import ConfigSignal, HintedSignal
class MyDevice(StandardReadable):
    def __init__(self):
        self.add_readables([sig1], ConfigSignal)
        self.add_readables([sig2], HintedSignal)
        self.add_readables([sig3], HintedSignal.uncached)
# new
from ophyd_async.core import StandardReadableFormat as Format
class MyDevice(StandardReadable):
    def __init__(self):
        self.add_readables([sig1], Format.CONFIG_SIGNAL)
        self.add_readables([sig2], Format.HINTED_SIGNAL)
        self.add_readables([sig3], Format.HINTED_UNCACHED_SIGNAL

Declarative Devices are now available

# old
from ophyd_async.core import ConfigSignal, HintedSignal
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw

class Sensor(StandardReadable):
    def __init__(self, prefix: str, name="") -> None:
        with self.add_children_as_readables(HintedSignal):
            self.value = epics_signal_r(float, prefix + "Value")
        with self.add_children_as_readables(ConfigSignal):
            self.mode = epics_signal_rw(EnergyMode, prefix + "Mode")
        super().__init__(name=name)
# new
from typing import Annotated as A
from ophyd_async.core import StandardReadableFormat as Format
from ophyd_async.epics.core import EpicsDevice, PvSuffix, epics_signal_r, epics_signal_rw

class Sensor(StandardReadable, EpicsDevice):
    value: A[SignalR[float], PvSuffix("Value"), Format.HINTED_SIGNAL]
    mode: A[SignalRW[EnergyMode], PvSuffix("Mode"), Format.CONFIG_SIGNAL]

StrictEnum is now requried for all strictly checked Enums

# old
from enum import Enum
class MyEnum(str, Enum):
    ONE = "one"
    TWO = "two"
# new
from ophyd_async.core import StrictEnum
class MyEnum(StrictEnum):
    ONE = "one"
    TWO = "two"

SubsetEnum is now an Enum subclass:

from ophyd_async.core import SubsetEnum
# old
MySubsetEnum = SubsetEnum["one", "two"]
# new
class MySubsetEnum(SubsetEnum):
    ONE = "one"
    TWO = "two"

Use python primitives for scalar types instead of numpy types

# old
import numpy as np
x = epics_signal_rw(np.int32, "PV")
# new
x = epics_signal_rw(int, "PV")

Use Array1D for 1D arrays instead of npt.NDArray

import numpy as np
# old
import numpy.typing as npt
x = epics_signal_rw(npt.NDArray[np.int32], "PV")
# new
from ophyd_async.core import Array1D
x = epics_signal_rw(Array1D[np.int32], "PV")

Use Sequence[str] for arrays of strings instead of npt.NDArray[np.str_]

import numpy as np
# old
import numpy.typing as npt
x = epics_signal_rw(npt.NDArray[np.str_], "PV")
# new
from collections.abc import Sequence
x = epics_signal_rw(Sequence[str], "PV")

MockSignalBackend requires a real backend

# old
fake_set_signal = SignalRW(MockSignalBackend(float))
# new
fake_set_signal = soft_signal_rw(float)
await fake_set_signal.connect(mock=True)

get_mock_put is no longer passed timeout as it is handled in Signal

# old
get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY, timeout=ANY)
# new
get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY)

super().__init__ required for Device subclasses

# old
class MyDevice(Device):
    def __init__(self, name: str = ""):
        self.signal, self.backend_put = soft_signal_r_and_setter(int)
# new
class MyDevice(Device):
    def __init__(self, name: str = ""):
        self.signal, self.backend_put = soft_signal_r_and_setter(int)
        super().__init__(name=name)

Arbitrary BaseModels not supported, pending use cases for them

The Table type has been suitable for everything we have seen so far, if you need an arbitrary BaseModel subclass then please make an issue

Child Devices set parent on attach, and can't be public children of more than one parent

class SourceDevice(Device):
    def __init__(self, name: str = ""):
        self.signal = soft_signal_rw(int)
        super().__init__(name=name)

# old
class ReferenceDevice(Device):
    def __init__(self, signal: SignalRW[int], name: str = ""):
        self.signal = signal
        super().__init__(name=name)

    def set(self, value) -> AsyncStatus:
        return self.signal.set(value + 1)
# new
from ophyd_async.core import Reference

class ReferenceDevice(Device):
    def __init__(self, signal: SignalRW[int], name: str = ""):
        self._signal_ref = Reference(signal)
        super().__init__(name=name)

    def set(self, value) -> AsyncStatus:
        return self._signal_ref().set(value + 1)

What's Changed

  • Add test for context race condition by @DominicOram in #600
  • New signal typing by @coretl in #594
  • Update copier template to 2.4.0 by @coretl in #628
  • Logo by @coretl in #629
  • Allow CA/PVA mismatching enums to be bools by @coretl in #632
  • Allow shared parent mock to be passed to Device.connect by @jsouter in #599
  • Report Device name in error when using AsyncStatus.wrap by @jsouter in #607
  • Temporary fix for PyPI publishing by @coretl in #634
  • Windows: fix unit tests & enable CI by @Tom-Willemsen in #633
  • Declarative EPICS and StandardReadable Devices by @coretl in #598
  • Update to copier 2.5.0 by @coretl in #637
  • Speed up device creation and connection in mock mode by @coretl in #641
  • Set parent of children of DeviceVector passed at init by @coretl in #644
  • Fix some small issues discovered in testing by @coretl in #646
  • Yield in each loop of observe_value by @coretl in #648
  • Add introspection of the errors that make up NotConnected by @coretl in #649
  • Rename hdf5_type to data_type in DatasetTable by @jwlodek in #651
  • Fix wrong function call name for str waveform that causes issue when … by @DiamondJoseph in #653
  • wait_for_value_interface_change by @ZohebShaikh in #652
  • Fix type hints and error messages in tests caused by pydantic update by @coretl in #665
  • FIX: Handle NonSupportedFeature exception for pipes by @burkeds in #660
  • Change tango decorators to Annotations by @coretl in #658
  • Restructure epics/test_signals.py by @jsouter in #630
  • Add the python package and the config and make the contracts kept by @stan-dot in #669
  • Add missing space in log message by @jwlodek in #676

Full Changelog: v0.7.0...v0.8.0

v0.8.0a6

25 Nov 09:47
1d444f4
Compare
Choose a tag to compare
v0.8.0a6 Pre-release
Pre-release

What's Changed

  • wait_for_value_interface_change by @ZohebShaikh in #652
  • Fix type hints and error messages in tests caused by pydantic update by @coretl in #665
  • FIX: Handle NonSupportedFeature exception for pipes by @burkeds in #660
  • Change tango decorators to Annotations by @coretl in #658
  • Restructure epics/test_signals.py by @jsouter in #630

Changes

set_and_wait_for_value changes

Some keyword argument changes to observe_value and set_and_wait_for_value. There is a new argument to set_and_wait_for_value, it now has a wait_for_set_completion argument with default of True. This is a change in behaviour to before where it would not wait for the set to complete before returning the Status, however it is the desired behaviour in the majority of cases. If using with areaDetector then supply wait_for_set_completion=False as per the docs

Full Changelog: v0.8.0a5...v0.8.0a6

v0.8.0a5

18 Nov 20:26
9ea28ad
Compare
Choose a tag to compare
v0.8.0a5 Pre-release
Pre-release

What's Changed

  • Set parent of children of DeviceVector passed at init by @coretl in #644
  • Fix some small issues discovered in testing by @coretl in #646
  • Yield in each loop of observe_value by @coretl in #648
  • Add introspection of the errors that make up NotConnected by @coretl in #649
  • Rename hdf5_type to data_type in DatasetTable by @jwlodek in #651
  • Fix wrong function call name for str waveform that causes issue when … by @DiamondJoseph in #653

Full Changelog: v0.8.0a4...v0.8.0a5

v0.8.0a4

11 Nov 21:47
3d9f508
Compare
Choose a tag to compare
v0.8.0a4 Pre-release
Pre-release

What's Changed

  • Update to copier 2.5.0 by @coretl in #637
  • Speed up device creation and connection in mock mode by @coretl in #641

Full Changelog: v0.8.0a3...v0.8.0a4

v0.8.0a3

04 Nov 11:10
32afe3d
Compare
Choose a tag to compare
v0.8.0a3 Pre-release
Pre-release

What's Changed

Changes

pvi structure changes

Structure read from .value now includes DeviceVector support. Requires at least PandABlocks-ioc 0.11.2

Epics signal module moves

ophyd_async.epics.signal moves to ophyd_async.epics.core with a backwards compat module that emits deprecation warning.

# old
from ophyd_async.epics.signal import epics_signal_rw
# new
from ophyd_async.epics.core import epics_signal_rw

StandardReadable wrappers change to StandardReadableFormat

StandardReadable wrappers change to enum members of StandardReadableFormat (normally imported as Format)

# old
from ophyd_async.core import ConfigSignal, HintedSignal
class MyDevice(StandardReadable):
    def __init__(self):
        self.add_readables([sig1], ConfigSignal)
        self.add_readables([sig2], HintedSignal)
        self.add_readables([sig3], HintedSignal.uncached)
# new
from ophyd_async.core import StandardReadableFormat as Format
class MyDevice(StandardReadable):
    def __init__(self):
        self.add_readables([sig1], Format.CONFIG_SIGNAL)
        self.add_readables([sig2], Format.HINTED_SIGNAL)
        self.add_readables([sig3], Format.HINTED_UNCACHED_SIGNAL

Declarative Devices are now available

# old
from ophyd_async.core import ConfigSignal, HintedSignal
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw

class Sensor(StandardReadable):
    def __init__(self, prefix: str, name="") -> None:
        with self.add_children_as_readables(HintedSignal):
            self.value = epics_signal_r(float, prefix + "Value")
        with self.add_children_as_readables(ConfigSignal):
            self.mode = epics_signal_rw(EnergyMode, prefix + "Mode")
        super().__init__(name=name)
# new
from typing import Annotated as A
from ophyd_async.core import StandardReadableFormat as Format
from ophyd_async.epics.core import EpicsDevice, PvSuffix, epics_signal_r, epics_signal_rw

class Sensor(StandardReadable, EpicsDevice):
    value: A[SignalR[float], PvSuffix("Value"), Format.HINTED_SIGNAL]
    mode: A[SignalRW[EnergyMode], PvSuffix("Mode"), Format.CONFIG_SIGNAL]

Full Changelog: v0.8.0a2...v0.8.0a3

v0.8.0a2

01 Nov 11:30
2234e3f
Compare
Choose a tag to compare
v0.8.0a2 Pre-release
Pre-release

What's Changed

  • Allow CA/PVA mismatching enums to be bools by @coretl in #632
  • Allow shared parent mock to be passed to Device.connect by @jsouter in #599
  • Report Device name in error when using AsyncStatus.wrap by @jsouter in #607
  • Temporary fix for PyPI publishing by @coretl in #634

Full Changelog: v0.8.0a1...v0.8.0a2

v0.8.0a1

30 Oct 14:08
7d6070b
Compare
Choose a tag to compare
v0.8.0a1 Pre-release
Pre-release

What's Changed

Breaking changes

pvi structure changes

Structure now read from .value rather than .pvi. Supported in FastCS. Requires at least PandABlocks-ioc 0.10.0

StrictEnum is now requried for all strictly checked Enums

# old
from enum import Enum
class MyEnum(str, Enum):
    ONE = "one"
    TWO = "two"
# new
from ophyd_async.core import StrictEnum
class MyEnum(StrictEnum):
    ONE = "one"
    TWO = "two"

SubsetEnum is now an Enum subclass:

from ophyd_async.core import SubsetEnum
# old
MySubsetEnum = SubsetEnum["one", "two"]
# new
class MySubsetEnum(SubsetEnum):
    ONE = "one"
    TWO = "two"

Use python primitives for scalar types instead of numpy types

# old
import numpy as np
x = epics_signal_rw(np.int32, "PV")
# new
x = epics_signal_rw(int, "PV")

Use Array1D for 1D arrays instead of npt.NDArray

import numpy as np
# old
import numpy.typing as npt
x = epics_signal_rw(npt.NDArray[np.int32], "PV")
# new
from ophyd_async.core import Array1D
x = epics_signal_rw(Array1D[np.int32], "PV")

Use Sequence[str] for arrays of strings instead of npt.NDArray[np.str_]

import numpy as np
# old
import numpy.typing as npt
x = epics_signal_rw(npt.NDArray[np.str_], "PV")
# new
from collections.abc import Sequence
x = epics_signal_rw(Sequence[str], "PV")

MockSignalBackend requires a real backend

# old
fake_set_signal = SignalRW(MockSignalBackend(float))
# new
fake_set_signal = soft_signal_rw(float)
await fake_set_signal.connect(mock=True)

get_mock_put is no longer passed timeout as it is handled in Signal

# old
get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY, timeout=ANY)
# new
get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY)

super().__init__ required for Device subclasses

# old
class MyDevice(Device):
    def __init__(self, name: str = ""):
        self.signal, self.backend_put = soft_signal_r_and_setter(int)
# new
class MyDevice(Device):
    def __init__(self, name: str = ""):
        self.signal, self.backend_put = soft_signal_r_and_setter(int)
        super().__init__(name=name)

Arbitrary BaseModels not supported, pending use cases for them

The Table type has been suitable for everything we have seen so far, if you need an arbitrary BaseModel subclass then please make an issue

Child Devices set parent on attach, and can't be public children of more than one parent

class SourceDevice(Device):
    def __init__(self, name: str = ""):
        self.signal = soft_signal_rw(int)
        super().__init__(name=name)

# old
class ReferenceDevice(Device):
    def __init__(self, signal: SignalRW[int], name: str = ""):
        self.signal = signal
        super().__init__(name=name)

    def set(self, value) -> AsyncStatus:
        return self.signal.set(value + 1)
# new
from ophyd_async.core import Reference

class ReferenceDevice(Device):
    def __init__(self, signal: SignalRW[int], name: str = ""):
        self._signal_ref = Reference(signal)
        super().__init__(name=name)

    def set(self, value) -> AsyncStatus:
        return self._signal_ref().set(value + 1)

Full Changelog: v0.7.0...v0.8.0a1

v0.7.0

24 Oct 09:35
3e74761
Compare
Choose a tag to compare

What's Changed

  • fixed typos by @ZohebShaikh in #589
  • Make table subclass enums be sequence enum rather than numpy string by @evalott100 in #579
  • Reset completed iterations counter to 0 once target iterations are reached and detector is disarmed by @jwlodek in #590
  • Simplify ad standard det tests by @jwlodek in #592
  • Remove config sigs kwarg from flyer since use case for them was unclear. by @jwlodek in #593
  • added number_of_frames instead of iterations by @ZohebShaikh in #581
  • Rename core classes by @abbiemery in #577
  • Tango support by @burkeds in #437
  • add Capture mode signal to Panda DataBlock by @jsouter in #604
  • with DeviceCollector doesn't work in plans, so error rather than hang by @coretl in #612

New Contributors

Full Changelog: v0.6.0...v0.7.0

v0.7.0a1

09 Oct 12:58
1559aa0
Compare
Choose a tag to compare
v0.7.0a1 Pre-release
Pre-release

What's Changed

New Contributors

Full Changelog: v0.6.0...v0.7.0a1

v0.6.0

19 Sep 13:48
35c07fe
Compare
Choose a tag to compare

What's Changed

  • Print warning if DATASETS table is empty on PandA writer open by @jwlodek in #558
  • 539 put mock should be async by @DominicOram in #559
  • Update signature of init for simdetector to match other detector classes by @jwlodek in #563
  • Extend sleep time to avoid race condition by @coretl in #566
  • Introduce PvaAbstractions and use them in SeqTable by @evalott100 in #522
  • Use asyncio TimeoutError in wait_for_value by @DominicOram in #573
  • Interface change of StandardDetector and Standard Controller by @ZohebShaikh in #568
  • Added a fixtures that checks if tasks are still running in tests by @evalott100 in #538
  • Update to copier template 2.3.0 by @coretl in #580
  • Fix typo by @jwlodek in #588
  • Use name provider instead of hdf name when calling path provider in ADHDFWriter by @jwlodek in #587
  • Add asyncio_default_fixture_loop_scope variable to pytest.ini to avoid deprecation warning by @jwlodek in #584
  • Include chunk shape as a parameter in stream resource for HDF dataset by @jwlodek in #544

Full Changelog: 0.5.2...v0.6.0