diff --git a/pyobs/mixins/fitsheader.py b/pyobs/mixins/fitsheader.py index 9bb0bfa5..9c567b00 100644 --- a/pyobs/mixins/fitsheader.py +++ b/pyobs/mixins/fitsheader.py @@ -1,7 +1,10 @@ from __future__ import annotations + +import asyncio import logging import math import os +from asyncio import Task from collections.abc import Coroutine from typing import Union, Dict, Any, Tuple, Optional, List, cast import astropy.units as u @@ -63,7 +66,7 @@ async def request_fits_headers(self, before: bool = True) -> Dict[str, Coroutine """ # init - futures: Dict[str, Coroutine] = {} + futures: Dict[str, Task] = {} # we can only do this with a comm module module = cast(Module, self) @@ -76,10 +79,14 @@ async def request_fits_headers(self, before: bool = True) -> Dict[str, Coroutine log.debug("Requesting FITS headers from %s...", client) if before: proxy1 = await module.proxy(client, IFitsHeaderBefore) - futures[client] = proxy1.get_fits_header_before(self._fitsheadermixin_fits_namespaces) + futures[client] = asyncio.create_task( + proxy1.get_fits_header_before(self._fitsheadermixin_fits_namespaces) + ) else: proxy2 = await module.proxy(client, IFitsHeaderAfter) - futures[client] = proxy2.get_fits_header_after(self._fitsheadermixin_fits_namespaces) + futures[client] = asyncio.create_task( + proxy2.get_fits_header_after(self._fitsheadermixin_fits_namespaces) + ) # finished return futures diff --git a/pyobs/modules/focus/focusseries.py b/pyobs/modules/focus/focusseries.py index 6619dae5..3fdb7009 100644 --- a/pyobs/modules/focus/focusseries.py +++ b/pyobs/modules/focus/focusseries.py @@ -5,7 +5,7 @@ from numpy.typing import NDArray from pyobs.interfaces import IAutoFocus -from pyobs.events import FocusFoundEvent +from pyobs.events import FocusFoundEvent, BadWeatherEvent, Event from pyobs.interfaces import IExposureTime, IImageType, IFocuser, IFilters, IData from pyobs.object import get_object from pyobs.mixins import CameraSettingsMixin @@ -50,6 +50,7 @@ def __init__( self._filters = filters self._offset = offset self._abort = threading.Event() + self._running = False # create focus series self._series: FocusSeries = get_object(series, FocusSeries) @@ -73,6 +74,7 @@ async def open(self) -> None: # register event await self.comm.register_event(FocusFoundEvent) + await self.comm.register_event(BadWeatherEvent, self._on_bad_weather) # check focuser and camera try: @@ -100,8 +102,16 @@ async def auto_focus(self, count: int, step: float, exposure_time: float, **kwar Raises: FileNotFoundException: If image could not be downloaded. """ - log.info("Performing auto-focus...") + try: + log.info("Performing auto-focus...") + self._running = True + return await self._auto_focus(count, step, exposure_time, **kwargs) + + finally: + self._running = False + + async def _auto_focus(self, count: int, step: float, exposure_time: float, **kwargs: Any) -> Tuple[float, float]: # get focuser log.info("Getting proxy for focuser...") focuser = await self.proxy(self._focuser, IFocuser) @@ -236,5 +246,24 @@ async def abort(self, **kwargs: Any) -> None: """Abort current actions.""" self._abort.set() + async def _on_bad_weather(self, event: Event, sender: str) -> bool: + """Abort series if a bad weather event occurs. + + Args: + event: The bad weather event. + sender: Who sent it. + """ + + # check + if not isinstance(event, BadWeatherEvent): + raise ValueError("Wrong event type.") + + # park + if self._running: + log.warning("Aborting focus series due to bad weather.") + self._abort.set() + return True + return False + __all__ = ["AutoFocusSeries"] diff --git a/pyproject.toml b/pyproject.toml index 35e92d07..4e163e93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "pyobs-core" packages = [{ include = "pyobs" }] -version = "1.4.13" +version = "1.4.14" description = "robotic telescope software" authors = ["Tim-Oliver Husser "] license = "MIT" @@ -22,21 +22,21 @@ asyncinotify = "^4.0.2" sep = { version = "^1.2.1", platform = "linux", optional = true } python-daemon = "^3.0.1" reproject = { version = "^0.12.0", optional = true } -pandas = { version = "^2.1.0", optional = true } -astroplan = { version = "^0.9", optional = true } -paramiko = { version = "^3.3.1", optional = true } -py-expression-eval = { version = "^0.3.14", optional = true } +pandas = "^2.1.0" +astroplan = "^0.9" +paramiko = "^3.3.1" +py-expression-eval = "^0.3.14" requests = { version = "^2.31.0", optional = true } ccdproc = { version = "^2.4.1", optional = true } photutils = { version = "^1.9.0", optional = true } lmfit = { version = "^1.2.2", optional = true } tornado = { version = "^6.3.3", optional = true } python-telegram-bot = { version = "^20.5", optional = true } -aiohttp = { version = "^3.8.5", optional = true } +aiohttp = "^3.8.5" [tool.poetry.extras] -full = ['asyncinotify', 'sep', 'python-daemon', 'reproject', 'pandas', 'astroplan', 'paramiko', - 'py-expression-eval', 'requests', 'ccdproc', 'photutils', 'lmfit', 'tornado', 'python-telegram-bot', +full = ['asyncinotify', 'sep', 'python-daemon', 'reproject', 'pandas', 'paramiko', + 'requests', 'ccdproc', 'photutils', 'lmfit', 'tornado', 'python-telegram-bot', 'aiohttp'] [tool.poetry.dev-dependencies]