pyobs-core 2.0.0.dev3__py3-none-any.whl → 2.0.0.dev5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyobs/comm/comm.py +14 -18
- pyobs/comm/local/localcomm.py +1 -1
- pyobs/comm/proxy.py +14 -2
- pyobs/comm/xmpp/xmppcomm.py +5 -5
- pyobs/interfaces/IBinning.py +15 -10
- pyobs/interfaces/IConfig.py +7 -6
- pyobs/interfaces/ICooling.py +10 -7
- pyobs/interfaces/IExposure.py +10 -7
- pyobs/interfaces/IExposureTime.py +8 -5
- pyobs/interfaces/IFilters.py +14 -9
- pyobs/interfaces/IFocuser.py +9 -6
- pyobs/interfaces/IGain.py +9 -6
- pyobs/interfaces/IImageFormat.py +14 -9
- pyobs/interfaces/IImageType.py +8 -5
- pyobs/interfaces/IMode.py +14 -9
- pyobs/interfaces/IModule.py +8 -5
- pyobs/interfaces/IMotion.py +15 -11
- pyobs/interfaces/IMultiFiber.py +17 -13
- pyobs/interfaces/IOffsetsAltAz.py +9 -6
- pyobs/interfaces/IOffsetsRaDec.py +9 -6
- pyobs/interfaces/IPointingAltAz.py +9 -6
- pyobs/interfaces/IPointingHGS.py +9 -6
- pyobs/interfaces/IPointingHelioprojective.py +9 -6
- pyobs/interfaces/IPointingRaDec.py +9 -6
- pyobs/interfaces/IReady.py +8 -5
- pyobs/interfaces/IRotation.py +8 -5
- pyobs/interfaces/IRunning.py +8 -5
- pyobs/interfaces/ITemperatures.py +13 -11
- pyobs/interfaces/IVideo.py +7 -4
- pyobs/interfaces/IWindow.py +20 -12
- pyobs/interfaces/__init__.py +62 -26
- pyobs/interfaces/interface.py +3 -0
- pyobs/mixins/motionstatus.py +3 -3
- pyobs/modules/camera/basecamera.py +19 -9
- pyobs/modules/camera/basevideo.py +2 -2
- pyobs/modules/camera/dummycamera.py +52 -20
- pyobs/modules/camera/dummyvideo.py +3 -3
- pyobs/modules/flatfield/flatfield.py +16 -6
- pyobs/modules/module.py +6 -8
- pyobs/modules/pointing/autoguiding.py +2 -2
- pyobs/modules/roof/baseroof.py +2 -2
- pyobs/modules/telescope/dummytelescope.py +27 -16
- pyobs/modules/utils/dummymode.py +5 -5
- {pyobs_core-2.0.0.dev3.dist-info → pyobs_core-2.0.0.dev5.dist-info}/METADATA +1 -1
- {pyobs_core-2.0.0.dev3.dist-info → pyobs_core-2.0.0.dev5.dist-info}/RECORD +48 -48
- {pyobs_core-2.0.0.dev3.dist-info → pyobs_core-2.0.0.dev5.dist-info}/WHEEL +0 -0
- {pyobs_core-2.0.0.dev3.dist-info → pyobs_core-2.0.0.dev5.dist-info}/entry_points.txt +0 -0
- {pyobs_core-2.0.0.dev3.dist-info → pyobs_core-2.0.0.dev5.dist-info}/licenses/LICENSE +0 -0
pyobs/comm/comm.py
CHANGED
|
@@ -4,7 +4,6 @@ import asyncio
|
|
|
4
4
|
import functools
|
|
5
5
|
import inspect
|
|
6
6
|
import logging
|
|
7
|
-
import sys
|
|
8
7
|
from collections.abc import Callable, Coroutine
|
|
9
8
|
from typing import TYPE_CHECKING, Any, overload
|
|
10
9
|
|
|
@@ -132,12 +131,20 @@ class Comm:
|
|
|
132
131
|
except IndexError:
|
|
133
132
|
return None
|
|
134
133
|
|
|
134
|
+
# collect capabilities (fixed at proxy construction time)
|
|
135
|
+
capabilities: dict[type[Interface], Any] = {}
|
|
136
|
+
for interface in interfaces:
|
|
137
|
+
if interface.capabilities is not None:
|
|
138
|
+
cap = await self._get_capabilities(client, interface)
|
|
139
|
+
if cap is not None:
|
|
140
|
+
capabilities[interface] = cap
|
|
141
|
+
|
|
135
142
|
# create new proxy
|
|
136
|
-
proxy = Proxy(self, client, interfaces)
|
|
143
|
+
proxy = Proxy(self, client, interfaces, capabilities)
|
|
137
144
|
|
|
138
145
|
# subscribe to state
|
|
139
146
|
for interface in interfaces:
|
|
140
|
-
if
|
|
147
|
+
if interface.state is not None:
|
|
141
148
|
await self.subscribe_state(client, interface, functools.partial(proxy.update_state, interface))
|
|
142
149
|
|
|
143
150
|
self._proxies[client] = proxy
|
|
@@ -438,40 +445,29 @@ class Comm:
|
|
|
438
445
|
) -> None:
|
|
439
446
|
pass
|
|
440
447
|
|
|
441
|
-
|
|
442
|
-
def _interface_from_state(state_cls: type) -> type:
|
|
443
|
-
outer_name = state_cls.__qualname__.rsplit(".", 1)[0]
|
|
444
|
-
return getattr(sys.modules[state_cls.__module__], outer_name)
|
|
445
|
-
|
|
446
|
-
async def set_state(self, state: Any) -> None:
|
|
448
|
+
async def set_state(self, interface: type[Interface], state: Any) -> None:
|
|
447
449
|
"""Publish state for this module.
|
|
448
450
|
|
|
449
451
|
Args:
|
|
450
452
|
interface: Interface type for the state.
|
|
451
453
|
state: State object to publish.
|
|
452
454
|
"""
|
|
453
|
-
interface = Comm._interface_from_state(type(state))
|
|
454
455
|
await self._set_state(interface, state)
|
|
455
456
|
|
|
456
457
|
async def _set_state(self, interface: type[Interface], state: Any) -> None:
|
|
457
458
|
pass
|
|
458
459
|
|
|
459
|
-
|
|
460
|
-
def _interface_from_capabilities(caps_cls: type) -> type:
|
|
461
|
-
outer_name = caps_cls.__qualname__.rsplit(".", 1)[0]
|
|
462
|
-
return getattr(sys.modules[caps_cls.__module__], outer_name)
|
|
463
|
-
|
|
464
|
-
async def set_capabilities(self, capabilities: Any) -> None:
|
|
460
|
+
async def set_capabilities(self, interface: type[Interface], capabilities: Any) -> None:
|
|
465
461
|
"""Publish capabilities for this module.
|
|
466
462
|
|
|
467
|
-
Called by Module.open() for each interface that defines a
|
|
463
|
+
Called by Module.open() for each interface that defines a capabilities
|
|
468
464
|
dataclass. Not intended to be called directly by module authors after
|
|
469
465
|
that point — capabilities are fixed for the module lifetime.
|
|
470
466
|
|
|
471
467
|
Args:
|
|
468
|
+
interface: Interface type the capabilities belong to.
|
|
472
469
|
capabilities: Capabilities dataclass instance.
|
|
473
470
|
"""
|
|
474
|
-
interface = Comm._interface_from_capabilities(type(capabilities))
|
|
475
471
|
await self._set_capabilities(interface, capabilities)
|
|
476
472
|
|
|
477
473
|
async def _set_capabilities(self, interface: type[Interface], capabilities: Any) -> None:
|
pyobs/comm/local/localcomm.py
CHANGED
|
@@ -120,7 +120,7 @@ class LocalComm(Comm):
|
|
|
120
120
|
|
|
121
121
|
async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
122
122
|
"""Fetch capabilities from a remote module."""
|
|
123
|
-
if
|
|
123
|
+
if interface.capabilities is None:
|
|
124
124
|
return None
|
|
125
125
|
try:
|
|
126
126
|
remote = self._network.get_client(module)
|
pyobs/comm/proxy.py
CHANGED
|
@@ -21,13 +21,20 @@ class Proxy:
|
|
|
21
21
|
|
|
22
22
|
__module__ = "pyobs.comm"
|
|
23
23
|
|
|
24
|
-
def __init__(
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
comm: Comm,
|
|
27
|
+
client: str,
|
|
28
|
+
interfaces: list[type[Interface]],
|
|
29
|
+
capabilities: dict[type[Interface], Any] | None = None,
|
|
30
|
+
):
|
|
25
31
|
"""Creates a new proxy.
|
|
26
32
|
|
|
27
33
|
Args:
|
|
28
34
|
comm: Comm object to use for connection.
|
|
29
35
|
client: Name of client to connect to.
|
|
30
36
|
interfaces: List of interfaces supported by client.
|
|
37
|
+
capabilities: Pre-populated capabilities dict, keyed by interface type.
|
|
31
38
|
"""
|
|
32
39
|
|
|
33
40
|
# set client and interfaces
|
|
@@ -53,8 +60,9 @@ class Proxy:
|
|
|
53
60
|
# create methods
|
|
54
61
|
self._methods = self._create_methods()
|
|
55
62
|
|
|
56
|
-
# store state
|
|
63
|
+
# store state and capabilities
|
|
57
64
|
self._state: dict[type[Interface], Any] = {}
|
|
65
|
+
self._capabilities: dict[type[Interface], Any] = capabilities if capabilities is not None else {}
|
|
58
66
|
|
|
59
67
|
@property
|
|
60
68
|
def name(self) -> str:
|
|
@@ -170,6 +178,10 @@ class Proxy:
|
|
|
170
178
|
"""Latest known state for the given interface, or None if nothing has arrived yet."""
|
|
171
179
|
return self._state.get(interface)
|
|
172
180
|
|
|
181
|
+
def capabilities(self, interface: type[Interface]) -> Any | None:
|
|
182
|
+
"""Capabilities for the given interface, populated once at Proxy construction."""
|
|
183
|
+
return self._capabilities.get(interface)
|
|
184
|
+
|
|
173
185
|
async def wait_for_state(
|
|
174
186
|
self,
|
|
175
187
|
interface: type[Interface],
|
pyobs/comm/xmpp/xmppcomm.py
CHANGED
|
@@ -658,7 +658,7 @@ class XmppComm(Comm):
|
|
|
658
658
|
item_xml = items_xml.find(f"{{{pubsub_ns}}}item")
|
|
659
659
|
payload = list(item_xml)[0] if item_xml is not None and len(item_xml) > 0 else None
|
|
660
660
|
if payload is not None:
|
|
661
|
-
state_obj = _xml_to_dataclass(payload, interface.
|
|
661
|
+
state_obj = _xml_to_dataclass(payload, interface.state)
|
|
662
662
|
for callback in callbacks:
|
|
663
663
|
callback(state_obj)
|
|
664
664
|
else:
|
|
@@ -786,7 +786,7 @@ class XmppComm(Comm):
|
|
|
786
786
|
item_xml = items_xml.find(f"{{{pubsub_ns}}}item") if items_xml is not None else None
|
|
787
787
|
payload = list(item_xml)[0] if item_xml is not None and len(item_xml) > 0 else None
|
|
788
788
|
if payload is not None:
|
|
789
|
-
callback(_xml_to_dataclass(payload, interface.
|
|
789
|
+
callback(_xml_to_dataclass(payload, interface.state))
|
|
790
790
|
except (slixmpp.exceptions.IqError, slixmpp.exceptions.IqTimeout):
|
|
791
791
|
pass
|
|
792
792
|
|
|
@@ -828,7 +828,7 @@ class XmppComm(Comm):
|
|
|
828
828
|
|
|
829
829
|
async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
830
830
|
"""Fetch and deserialize capabilities for a remote module's interface."""
|
|
831
|
-
if
|
|
831
|
+
if interface.capabilities is None:
|
|
832
832
|
return None
|
|
833
833
|
# Use full JID (with resource) if we know it — bare JID may not route correctly
|
|
834
834
|
full_jid = next(
|
|
@@ -848,7 +848,7 @@ class XmppComm(Comm):
|
|
|
848
848
|
for elem in child:
|
|
849
849
|
tag = elem.tag.split("}")[-1]
|
|
850
850
|
if tag == "capabilities" and f"{{{ns}}}" in elem.tag:
|
|
851
|
-
return _xml_to_dataclass(elem, interface.
|
|
851
|
+
return _xml_to_dataclass(elem, interface.capabilities)
|
|
852
852
|
return None
|
|
853
853
|
|
|
854
854
|
async def _set_presence(self, state: ModuleState, error_string: str = "") -> None:
|
|
@@ -902,7 +902,7 @@ class XmppComm(Comm):
|
|
|
902
902
|
payload = list(item_xml)[0] if item_xml is not None and len(item_xml) > 0 else None
|
|
903
903
|
if payload is not None and node in self._state_node_handlers:
|
|
904
904
|
_, callbacks = self._state_node_handlers[node]
|
|
905
|
-
state_obj = _xml_to_dataclass(payload, interface.
|
|
905
|
+
state_obj = _xml_to_dataclass(payload, interface.state)
|
|
906
906
|
for cb in callbacks:
|
|
907
907
|
cb(state_obj)
|
|
908
908
|
except (slixmpp.exceptions.IqError, slixmpp.exceptions.IqTimeout):
|
pyobs/interfaces/IBinning.py
CHANGED
|
@@ -8,20 +8,25 @@ from ..utils.time import Time
|
|
|
8
8
|
from .interface import Interface
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class BinningState:
|
|
13
|
+
x: int
|
|
14
|
+
y: int
|
|
15
|
+
time: Time = field(default_factory=Time.now)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class BinningCapabilities:
|
|
20
|
+
binnings: list[BinningState] = field(default_factory=list)
|
|
21
|
+
|
|
22
|
+
|
|
11
23
|
class IBinning(Interface, metaclass=ABCMeta):
|
|
12
24
|
"""The camera supports binning, to be used together with :class:`~pyobs.interfaces.ICamera`."""
|
|
13
25
|
|
|
14
26
|
__module__ = "pyobs.interfaces"
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
x: int
|
|
19
|
-
y: int
|
|
20
|
-
time: Time = field(default_factory=Time.now)
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class Capabilities:
|
|
24
|
-
binnings: list[IBinning.State] = field(default_factory=list)
|
|
28
|
+
state = BinningState
|
|
29
|
+
capabilities = BinningCapabilities
|
|
25
30
|
|
|
26
31
|
@abstractmethod
|
|
27
32
|
async def set_binning(self, x: int, y: int, **kwargs: Any) -> None:
|
|
@@ -37,4 +42,4 @@ class IBinning(Interface, metaclass=ABCMeta):
|
|
|
37
42
|
...
|
|
38
43
|
|
|
39
44
|
|
|
40
|
-
__all__ = ["IBinning"]
|
|
45
|
+
__all__ = ["IBinning", "BinningState", "BinningCapabilities"]
|
pyobs/interfaces/IConfig.py
CHANGED
|
@@ -7,16 +7,17 @@ from typing import Any
|
|
|
7
7
|
from .interface import Interface
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
@dataclass
|
|
11
|
+
class ConfigCapabilities:
|
|
12
|
+
caps: dict[str, tuple[bool, bool, bool]] = field(default_factory=dict)
|
|
13
|
+
|
|
14
|
+
|
|
10
15
|
class IConfig(Interface, metaclass=ABCMeta):
|
|
11
16
|
"""The module allows access to some of its configuration options."""
|
|
12
17
|
|
|
13
18
|
__module__ = "pyobs.interfaces"
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
class Capabilities:
|
|
17
|
-
readable: list[str] = field(default_factory=list)
|
|
18
|
-
writable: list[str] = field(default_factory=list)
|
|
19
|
-
options: dict[str, list[str]] = field(default_factory=dict)
|
|
20
|
+
capabilities = ConfigCapabilities
|
|
20
21
|
|
|
21
22
|
@abstractmethod
|
|
22
23
|
async def get_config_value(self, name: str, **kwargs: Any) -> Any:
|
|
@@ -47,4 +48,4 @@ class IConfig(Interface, metaclass=ABCMeta):
|
|
|
47
48
|
...
|
|
48
49
|
|
|
49
50
|
|
|
50
|
-
__all__ = ["IConfig"]
|
|
51
|
+
__all__ = ["IConfig", "ConfigCapabilities"]
|
pyobs/interfaces/ICooling.py
CHANGED
|
@@ -9,17 +9,20 @@ from ..utils.time import Time
|
|
|
9
9
|
from .ITemperatures import ITemperatures
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
@dataclass
|
|
13
|
+
class CoolingState:
|
|
14
|
+
setpoint: Annotated[float, Unit.CELSIUS] | None
|
|
15
|
+
power: Annotated[int, Unit.PERCENT] | None
|
|
16
|
+
enabled: bool
|
|
17
|
+
time: Time = field(default_factory=Time.now)
|
|
18
|
+
|
|
19
|
+
|
|
12
20
|
class ICooling(ITemperatures, metaclass=ABCMeta):
|
|
13
21
|
"""The module can control the cooling of a device."""
|
|
14
22
|
|
|
15
23
|
__module__ = "pyobs.interfaces"
|
|
16
24
|
|
|
17
|
-
|
|
18
|
-
class State:
|
|
19
|
-
setpoint: Annotated[float, Unit.CELSIUS] | None
|
|
20
|
-
power: Annotated[int, Unit.PERCENT] | None
|
|
21
|
-
enabled: bool
|
|
22
|
-
time: Time = field(default_factory=Time.now)
|
|
25
|
+
state = CoolingState
|
|
23
26
|
|
|
24
27
|
@abstractmethod
|
|
25
28
|
async def set_cooling(self, enabled: bool, setpoint: Annotated[float, Unit.CELSIUS], **kwargs: Any) -> None:
|
|
@@ -35,4 +38,4 @@ class ICooling(ITemperatures, metaclass=ABCMeta):
|
|
|
35
38
|
...
|
|
36
39
|
|
|
37
40
|
|
|
38
|
-
__all__ = ["ICooling"]
|
|
41
|
+
__all__ = ["ICooling", "CoolingState"]
|
pyobs/interfaces/IExposure.py
CHANGED
|
@@ -10,17 +10,20 @@ from ..utils.time import Time
|
|
|
10
10
|
from .interface import Interface
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
@dataclass
|
|
14
|
+
class ExposureState:
|
|
15
|
+
status: ExposureStatus
|
|
16
|
+
progress: Annotated[float, Unit.PERCENT]
|
|
17
|
+
exposure_time_left: Annotated[float, Unit.SECONDS] = 0.0
|
|
18
|
+
time: Time = field(default_factory=Time.now)
|
|
19
|
+
|
|
20
|
+
|
|
13
21
|
class IExposure(Interface, metaclass=ABCMeta):
|
|
14
22
|
"""The module controls a camera."""
|
|
15
23
|
|
|
16
24
|
__module__ = "pyobs.interfaces"
|
|
17
25
|
|
|
18
|
-
|
|
19
|
-
class State:
|
|
20
|
-
status: ExposureStatus
|
|
21
|
-
progress: Annotated[float, Unit.PERCENT]
|
|
22
|
-
exposure_time_left: Annotated[float, Unit.SECONDS] = 0.0
|
|
23
|
-
time: Time = field(default_factory=Time.now)
|
|
26
|
+
state = ExposureState
|
|
24
27
|
|
|
25
28
|
|
|
26
|
-
__all__ = ["IExposure"]
|
|
29
|
+
__all__ = ["IExposure", "ExposureState"]
|
|
@@ -9,15 +9,18 @@ from ..utils.time import Time
|
|
|
9
9
|
from .interface import Interface
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
@dataclass
|
|
13
|
+
class ExposureTimeState:
|
|
14
|
+
exposure_time: Annotated[float, Unit.SECONDS]
|
|
15
|
+
time: Time = field(default_factory=Time.now)
|
|
16
|
+
|
|
17
|
+
|
|
12
18
|
class IExposureTime(Interface, metaclass=ABCMeta):
|
|
13
19
|
"""The camera supports exposure times, to be used together with :class:`~pyobs.interfaces.ICamera`."""
|
|
14
20
|
|
|
15
21
|
__module__ = "pyobs.interfaces"
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
class State:
|
|
19
|
-
exposure_time: Annotated[float, Unit.SECONDS]
|
|
20
|
-
time: Time = field(default_factory=Time.now)
|
|
23
|
+
state = ExposureTimeState
|
|
21
24
|
|
|
22
25
|
@abstractmethod
|
|
23
26
|
async def set_exposure_time(self, exposure_time: Annotated[float, Unit.SECONDS], **kwargs: Any) -> None:
|
|
@@ -32,4 +35,4 @@ class IExposureTime(Interface, metaclass=ABCMeta):
|
|
|
32
35
|
...
|
|
33
36
|
|
|
34
37
|
|
|
35
|
-
__all__ = ["IExposureTime"]
|
|
38
|
+
__all__ = ["IExposureTime", "ExposureTimeState"]
|
pyobs/interfaces/IFilters.py
CHANGED
|
@@ -8,19 +8,24 @@ from ..utils.time import Time
|
|
|
8
8
|
from .IMotion import IMotion
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class FilterState:
|
|
13
|
+
filter: str
|
|
14
|
+
time: Time = field(default_factory=Time.now)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class FiltersCapabilities:
|
|
19
|
+
filters: list[str] = field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
|
|
11
22
|
class IFilters(IMotion, metaclass=ABCMeta):
|
|
12
23
|
"""The module can change filters in a device."""
|
|
13
24
|
|
|
14
25
|
__module__ = "pyobs.interfaces"
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
filter: str
|
|
19
|
-
time: Time = field(default_factory=Time.now)
|
|
20
|
-
|
|
21
|
-
@dataclass
|
|
22
|
-
class Capabilities:
|
|
23
|
-
filters: list[str] = field(default_factory=list)
|
|
27
|
+
state = FilterState
|
|
28
|
+
capabilities = FiltersCapabilities
|
|
24
29
|
|
|
25
30
|
@abstractmethod
|
|
26
31
|
async def set_filter(self, filter_name: str, **kwargs: Any) -> None:
|
|
@@ -36,4 +41,4 @@ class IFilters(IMotion, metaclass=ABCMeta):
|
|
|
36
41
|
...
|
|
37
42
|
|
|
38
43
|
|
|
39
|
-
__all__ = ["IFilters"]
|
|
44
|
+
__all__ = ["IFilters", "FilterState", "FiltersCapabilities"]
|
pyobs/interfaces/IFocuser.py
CHANGED
|
@@ -8,16 +8,19 @@ from ..utils.time import Time
|
|
|
8
8
|
from .IMotion import IMotion
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class FocuserState:
|
|
13
|
+
focus: float
|
|
14
|
+
focus_offset: float
|
|
15
|
+
time: Time = field(default_factory=Time.now)
|
|
16
|
+
|
|
17
|
+
|
|
11
18
|
class IFocuser(IMotion, metaclass=ABCMeta):
|
|
12
19
|
"""The module is a focusing device."""
|
|
13
20
|
|
|
14
21
|
__module__ = "pyobs.interfaces"
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
class State:
|
|
18
|
-
focus: float
|
|
19
|
-
focus_offset: float
|
|
20
|
-
time: Time = field(default_factory=Time.now)
|
|
23
|
+
state = FocuserState
|
|
21
24
|
|
|
22
25
|
@abstractmethod
|
|
23
26
|
async def set_focus(self, focus: float, **kwargs: Any) -> None:
|
|
@@ -46,4 +49,4 @@ class IFocuser(IMotion, metaclass=ABCMeta):
|
|
|
46
49
|
...
|
|
47
50
|
|
|
48
51
|
|
|
49
|
-
__all__ = ["IFocuser"]
|
|
52
|
+
__all__ = ["IFocuser", "FocuserState"]
|
pyobs/interfaces/IGain.py
CHANGED
|
@@ -8,16 +8,19 @@ from ..utils.time import Time
|
|
|
8
8
|
from .interface import Interface
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class GainState:
|
|
13
|
+
gain: float
|
|
14
|
+
offset: float
|
|
15
|
+
time: Time = field(default_factory=Time.now)
|
|
16
|
+
|
|
17
|
+
|
|
11
18
|
class IGain(Interface, metaclass=ABCMeta):
|
|
12
19
|
"""The camera supports setting of gain, to be used together with :class:`~pyobs.interfaces.ICamera`."""
|
|
13
20
|
|
|
14
21
|
__module__ = "pyobs.interfaces"
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
class State:
|
|
18
|
-
gain: float
|
|
19
|
-
offset: float
|
|
20
|
-
time: Time = field(default_factory=Time.now)
|
|
23
|
+
state = GainState
|
|
21
24
|
|
|
22
25
|
@abstractmethod
|
|
23
26
|
async def set_gain(self, gain: float, **kwargs: Any) -> None:
|
|
@@ -44,4 +47,4 @@ class IGain(Interface, metaclass=ABCMeta):
|
|
|
44
47
|
...
|
|
45
48
|
|
|
46
49
|
|
|
47
|
-
__all__ = ["IGain"]
|
|
50
|
+
__all__ = ["IGain", "GainState"]
|
pyobs/interfaces/IImageFormat.py
CHANGED
|
@@ -10,19 +10,24 @@ from ..utils.time import Time
|
|
|
10
10
|
from .interface import Interface
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
@dataclass
|
|
14
|
+
class ImageFormatState:
|
|
15
|
+
image_format: ImageFormat
|
|
16
|
+
time: Time = field(default_factory=Time.now)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class ImageFormatCapabilities:
|
|
21
|
+
image_formats: list[str] = field(default_factory=list)
|
|
22
|
+
|
|
23
|
+
|
|
13
24
|
class IImageFormat(Interface, metaclass=ABCMeta):
|
|
14
25
|
"""The module supports different image formats (e.g. INT16, FLOAT32), mainly used by cameras."""
|
|
15
26
|
|
|
16
27
|
__module__ = "pyobs.interfaces"
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
image_format: ImageFormat
|
|
21
|
-
time: Time = field(default_factory=Time.now)
|
|
22
|
-
|
|
23
|
-
@dataclass
|
|
24
|
-
class Capabilities:
|
|
25
|
-
image_formats: list[str] = field(default_factory=list)
|
|
29
|
+
state = ImageFormatState
|
|
30
|
+
capabilities = ImageFormatCapabilities
|
|
26
31
|
|
|
27
32
|
@abstractmethod
|
|
28
33
|
async def set_image_format(self, fmt: ImageFormat, **kwargs: Any) -> None:
|
|
@@ -37,4 +42,4 @@ class IImageFormat(Interface, metaclass=ABCMeta):
|
|
|
37
42
|
...
|
|
38
43
|
|
|
39
44
|
|
|
40
|
-
__all__ = ["IImageFormat"]
|
|
45
|
+
__all__ = ["IImageFormat", "ImageFormatState", "ImageFormatCapabilities"]
|
pyobs/interfaces/IImageType.py
CHANGED
|
@@ -10,15 +10,18 @@ from ..utils.time import Time
|
|
|
10
10
|
from .interface import Interface
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
@dataclass
|
|
14
|
+
class ImageTypeState:
|
|
15
|
+
image_type: ImageType
|
|
16
|
+
time: Time = field(default_factory=Time.now)
|
|
17
|
+
|
|
18
|
+
|
|
13
19
|
class IImageType(Interface, metaclass=ABCMeta):
|
|
14
20
|
"""The module supports different image types (e.g. object, bias, dark, etc), mainly used by cameras."""
|
|
15
21
|
|
|
16
22
|
__module__ = "pyobs.interfaces"
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
class State:
|
|
20
|
-
image_type: ImageType
|
|
21
|
-
time: Time = field(default_factory=Time.now)
|
|
24
|
+
state = ImageTypeState
|
|
22
25
|
|
|
23
26
|
@abstractmethod
|
|
24
27
|
async def set_image_type(self, image_type: ImageType, **kwargs: Any) -> None:
|
|
@@ -30,4 +33,4 @@ class IImageType(Interface, metaclass=ABCMeta):
|
|
|
30
33
|
...
|
|
31
34
|
|
|
32
35
|
|
|
33
|
-
__all__ = ["IImageType"]
|
|
36
|
+
__all__ = ["IImageType", "ImageTypeState"]
|
pyobs/interfaces/IMode.py
CHANGED
|
@@ -8,19 +8,24 @@ from ..utils.time import Time
|
|
|
8
8
|
from .interface import Interface
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class ModeState:
|
|
13
|
+
modes: dict[str, str] = field(default_factory=dict) # group -> current mode
|
|
14
|
+
time: Time = field(default_factory=Time.now)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ModeCapabilities:
|
|
19
|
+
modes: dict[str, list[str]] = field(default_factory=dict) # group -> list of modes
|
|
20
|
+
|
|
21
|
+
|
|
11
22
|
class IMode(Interface, metaclass=ABCMeta):
|
|
12
23
|
"""The module can change modes in a device."""
|
|
13
24
|
|
|
14
25
|
__module__ = "pyobs.interfaces"
|
|
15
26
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
modes: dict[str, list[str]] = field(default_factory=dict) # group -> list of modes
|
|
19
|
-
|
|
20
|
-
@dataclass
|
|
21
|
-
class State:
|
|
22
|
-
modes: dict[str, str] = field(default_factory=dict) # group -> current mode
|
|
23
|
-
time: Time = field(default_factory=Time.now)
|
|
27
|
+
state = ModeState
|
|
28
|
+
capabilities = ModeCapabilities
|
|
24
29
|
|
|
25
30
|
@abstractmethod
|
|
26
31
|
async def set_mode(self, mode: str, group: int = 0, **kwargs: Any) -> None:
|
|
@@ -37,4 +42,4 @@ class IMode(Interface, metaclass=ABCMeta):
|
|
|
37
42
|
...
|
|
38
43
|
|
|
39
44
|
|
|
40
|
-
__all__ = ["IMode"]
|
|
45
|
+
__all__ = ["IMode", "ModeState", "ModeCapabilities"]
|
pyobs/interfaces/IModule.py
CHANGED
|
@@ -7,15 +7,18 @@ from typing import Any
|
|
|
7
7
|
from .interface import Interface
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
@dataclass
|
|
11
|
+
class ModuleCapabilities:
|
|
12
|
+
label: str = ""
|
|
13
|
+
version: str = ""
|
|
14
|
+
|
|
15
|
+
|
|
10
16
|
class IModule(Interface, metaclass=ABCMeta):
|
|
11
17
|
"""The module is actually a module. Implemented by all modules."""
|
|
12
18
|
|
|
13
19
|
__module__ = "pyobs.interfaces"
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
class Capabilities:
|
|
17
|
-
version: str = ""
|
|
18
|
-
label: str = ""
|
|
21
|
+
capabilities = ModuleCapabilities
|
|
19
22
|
|
|
20
23
|
@abstractmethod
|
|
21
24
|
async def reset_error(self, **kwargs: Any) -> bool:
|
|
@@ -23,4 +26,4 @@ class IModule(Interface, metaclass=ABCMeta):
|
|
|
23
26
|
...
|
|
24
27
|
|
|
25
28
|
|
|
26
|
-
__all__ = ["IModule"]
|
|
29
|
+
__all__ = ["IModule", "ModuleCapabilities"]
|
pyobs/interfaces/IMotion.py
CHANGED
|
@@ -10,21 +10,25 @@ from ..utils.time import Time
|
|
|
10
10
|
from .IReady import IReady
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
@dataclass
|
|
14
|
+
class DeviceMotionStatus:
|
|
15
|
+
name: str
|
|
16
|
+
status: MotionStatus
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class MotionState:
|
|
21
|
+
status: MotionStatus
|
|
22
|
+
devices: list[DeviceMotionStatus] = field(default_factory=list)
|
|
23
|
+
time: Time = field(default_factory=Time.now)
|
|
24
|
+
|
|
25
|
+
|
|
13
26
|
class IMotion(IReady, metaclass=ABCMeta):
|
|
14
27
|
"""The module controls a device that can move."""
|
|
15
28
|
|
|
16
29
|
__module__ = "pyobs.interfaces"
|
|
17
30
|
|
|
18
|
-
|
|
19
|
-
class DeviceMotionStatus:
|
|
20
|
-
name: str
|
|
21
|
-
status: MotionStatus
|
|
22
|
-
|
|
23
|
-
@dataclass
|
|
24
|
-
class State:
|
|
25
|
-
status: MotionStatus
|
|
26
|
-
devices: list[IMotion.DeviceMotionStatus] = field(default_factory=list)
|
|
27
|
-
time: Time = field(default_factory=Time.now)
|
|
31
|
+
state = MotionState
|
|
28
32
|
|
|
29
33
|
@abstractmethod
|
|
30
34
|
async def init(self, **kwargs: Any) -> None:
|
|
@@ -54,4 +58,4 @@ class IMotion(IReady, metaclass=ABCMeta):
|
|
|
54
58
|
...
|
|
55
59
|
|
|
56
60
|
|
|
57
|
-
__all__ = ["IMotion"]
|
|
61
|
+
__all__ = ["IMotion", "DeviceMotionStatus", "MotionState"]
|
pyobs/interfaces/IMultiFiber.py
CHANGED
|
@@ -8,24 +8,28 @@ from ..utils.time import Time
|
|
|
8
8
|
from .interface import Interface
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
@dataclass
|
|
12
|
+
class MultiFiberState:
|
|
13
|
+
fiber: str = ""
|
|
14
|
+
pixel_x: float = 0.0
|
|
15
|
+
pixel_y: float = 0.0
|
|
16
|
+
radius: float = 0.0
|
|
17
|
+
time: Time = field(default_factory=Time.now)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class MultiFiberCapabilities:
|
|
22
|
+
fiber_count: int = 0
|
|
23
|
+
|
|
24
|
+
|
|
11
25
|
class IMultiFiber(Interface, metaclass=ABCMeta):
|
|
12
26
|
"""An interface for multi-fiber setups that helps to set/get a fiber and retrieve position and size of the
|
|
13
27
|
current fiber on the acquisition/guiding image."""
|
|
14
28
|
|
|
15
29
|
__module__ = "pyobs.interfaces"
|
|
16
30
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
fiber_count: int = 0
|
|
20
|
-
fiber_names: list[str] = field(default_factory=list)
|
|
21
|
-
|
|
22
|
-
@dataclass
|
|
23
|
-
class State:
|
|
24
|
-
fiber: str = ""
|
|
25
|
-
pixel_x: float = 0.0
|
|
26
|
-
pixel_y: float = 0.0
|
|
27
|
-
radius: float = 0.0
|
|
28
|
-
time: Time = field(default_factory=Time.now)
|
|
31
|
+
state = MultiFiberState
|
|
32
|
+
capabilities = MultiFiberCapabilities
|
|
29
33
|
|
|
30
34
|
@abstractmethod
|
|
31
35
|
async def abort(self, **kwargs: Any) -> None:
|
|
@@ -42,4 +46,4 @@ class IMultiFiber(Interface, metaclass=ABCMeta):
|
|
|
42
46
|
...
|
|
43
47
|
|
|
44
48
|
|
|
45
|
-
__all__ = ["IMultiFiber"]
|
|
49
|
+
__all__ = ["IMultiFiber", "MultiFiberState", "MultiFiberCapabilities"]
|