Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Signal/SignalBackend args #562

Closed
evalott100 opened this issue Sep 9, 2024 · 0 comments · Fixed by #594
Closed

Change Signal/SignalBackend args #562

evalott100 opened this issue Sep 9, 2024 · 0 comments · Fixed by #594

Comments

@evalott100
Copy link
Contributor

evalott100 commented Sep 9, 2024

We should alter the kwargs of Signal/SignalBackend such that

  • Signal takes an optional datatype in __init__ and do some validation on it
  • EpicsSignalBackend takes datatype in __init__
  • SignalBackend.connect now takes datatype instead
  • On both Signal and SignalBackend __init__ and connect arg to kwarg inference is prevented
# Signal
    def __init__(
        self,
        *,
        backend: Optional[SignalBackend[T]] = None,
        datatype: Optional[SignalDataType] = None,
        timeout: Optional[float] = DEFAULT_TIMEOUT,
        name: str = "",
    ) -> None:
        #: If set, then the datatype of the value is guaranteed to be this type
        self.datatype = datatype
        ....

    async def connect(
        self,
        *,
        mock=False,
        timeout=DEFAULT_TIMEOUT,
        force_reconnect: bool = False,
        backend: Optional[SignalBackend[T]] = None,
    ):
        ....

# Signal backend

@abstractmethod
async def connect(
    self,
    *,
    datatype: Optional[type] = None,
    timeout: float = DEFAULT_TIMEOUT
):
    ....

Part of this change will be getting rid of conversion in mock signal backend.

Originally posted by @coretl in #310 (comment)

@coretl coretl closed this as completed in a30d8cd Oct 30, 2024
ZohebShaikh pushed a commit that referenced this issue Nov 14, 2024
Rewrite the type support, and use a plugin `Connector` architecture to support reconnection for PVI and Tango.

Fixes #472, fixes #562, fixes #535, fixes #505, fixes #373, fixes #601

Required for #551

Structure now read from `.value` rather than `.pvi`. Supported in FastCS. Requires at least PandABlocks-ioc 0.10.0
```python
from enum import Enum
class MyEnum(str, Enum):
    ONE = "one"
    TWO = "two"
from ophyd_async.core import StrictEnum
class MyEnum(StrictEnum):
    ONE = "one"
    TWO = "two"
```
```python
from ophyd_async.core import SubsetEnum
MySubsetEnum = SubsetEnum["one", "two"]
class MySubsetEnum(SubsetEnum):
    ONE = "one"
    TWO = "two"
```
```python
import numpy as np
x = epics_signal_rw(np.int32, "PV")
x = epics_signal_rw(int, "PV")
```
```python
import numpy as np
import numpy.typing as npt
x = epics_signal_rw(npt.NDArray[np.int32], "PV")
from ophyd_async.core import Array1D
x = epics_signal_rw(Array1D[np.int32], "PV")
```
```python
import numpy as np
import numpy.typing as npt
x = epics_signal_rw(npt.NDArray[np.str_], "PV")
from collections.abc import Sequence
x = epics_signal_rw(Sequence[str], "PV")
```
```python
fake_set_signal = SignalRW(MockSignalBackend(float))
fake_set_signal = soft_signal_rw(float)
await fake_set_signal.connect(mock=True)
```
```python
get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY, timeout=ANY)
get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY)
```
```python
class MyDevice(Device):
    def __init__(self, name: str = ""):
        self.signal, self.backend_put = soft_signal_r_and_setter(int)
class MyDevice(Device):
    def __init__(self, name: str = ""):
        self.signal, self.backend_put = soft_signal_r_and_setter(int)
        super().__init__(name=name)
```
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
```python
class SourceDevice(Device):
    def __init__(self, name: str = ""):
        self.signal = soft_signal_rw(int)
        super().__init__(name=name)

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)
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)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant