From 0e290059f2548dd3d8987e4ad3d475eda7396485 Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Wed, 10 Jul 2024 14:36:28 +0200 Subject: [PATCH 1/3] datetime.utcnow() to datetime.utc(timezone.utc) --- pyobs/environment.py | 16 ++++++++-------- pyobs/modules/camera/basespectrograph.py | 6 +++--- pyobs/modules/camera/basevideo.py | 4 ++-- pyobs/modules/camera/dummycamera.py | 4 ++-- pyobs/modules/camera/dummyspectrograph.py | 4 ++-- pyobs/robotic/scripts/conditional.py | 4 ++-- pyobs/utils/average.py | 12 ++++++------ pyobs/utils/time.py | 8 ++++---- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/pyobs/environment.py b/pyobs/environment.py index 1bb12ca0..cf8f191d 100644 --- a/pyobs/environment.py +++ b/pyobs/environment.py @@ -1,4 +1,4 @@ -import datetime +from datetime import datetime, timezone, timedelta, tzinfo, date import functools import logging from typing import Union, Optional, Any, Dict @@ -62,7 +62,7 @@ def __init__( ) @property - def timezone(self) -> datetime.tzinfo: + def timezone(self) -> tzinfo: """Returns the timezone of the observatory.""" return self._timezone @@ -72,7 +72,7 @@ def location(self) -> Optional[EarthLocation]: return self._location @functools.lru_cache() - def localtime(self, utc: Optional[datetime.datetime] = None) -> datetime.datetime: + def localtime(self, utc: Optional[datetime] = None) -> datetime: """Returns the local time at the observatory, either for a given UTC time or for now, if none is given. Args: @@ -83,14 +83,14 @@ def localtime(self, utc: Optional[datetime.datetime] = None) -> datetime.datetim """ # get UTC if utc is None: - utc = datetime.datetime.utcnow() + utc = datetime.now(timezone.utc) # mark as UTC utc_dt = pytz.utc.localize(utc) # convert to local timezone return utc_dt.astimezone(self._timezone) @functools.lru_cache() - def night_obs(self, time: Optional[Union[datetime.datetime, Time]] = None) -> datetime.date: + def night_obs(self, time: Optional[Union[datetime, Time]] = None) -> date: """Returns the date of the night for the given night, i.e. the date of the start of the night. Args: @@ -109,18 +109,18 @@ def night_obs(self, time: Optional[Union[datetime.datetime, Time]] = None) -> da time = time.datetime # get local datetime - if not isinstance(time, datetime.datetime): + if not isinstance(time, datetime): raise ValueError("Invalid time") utc_dt = pytz.utc.localize(time) loc_dt = utc_dt.astimezone(self._timezone) # get night if loc_dt.hour < 15: - loc_dt += datetime.timedelta(days=-1) + loc_dt += timedelta(days=-1) return loc_dt.date() @functools.lru_cache() - def lst(self, time: Union[datetime.datetime, Time]) -> Longitude: + def lst(self, time: Union[datetime, Time]) -> Longitude: """Returns the local sidereal time for a given time. Args: diff --git a/pyobs/modules/camera/basespectrograph.py b/pyobs/modules/camera/basespectrograph.py index 75883816..5b521c43 100644 --- a/pyobs/modules/camera/basespectrograph.py +++ b/pyobs/modules/camera/basespectrograph.py @@ -1,5 +1,5 @@ import asyncio -import datetime +from datetime import datetime, timezone import logging from abc import ABCMeta, abstractmethod from typing import Tuple, Optional, Dict, Any, NamedTuple, List @@ -18,7 +18,7 @@ class ExposureInfo(NamedTuple): """Info about a running exposure.""" - start: datetime.datetime + start: datetime class BaseSpectrograph(Module, SpectrumFitsHeaderMixin, ISpectrograph, metaclass=ABCMeta): @@ -90,7 +90,7 @@ async def __expose(self, broadcast: bool) -> Tuple[Optional[fits.HDUList], Optio header_futures_before = await self.request_fits_headers(before=True) # do the exposure - self._exposure = ExposureInfo(start=datetime.datetime.utcnow()) + self._exposure = ExposureInfo(start=datetime.now(timezone.utc)) try: hdulist = await self._expose(abort_event=self.expose_abort) if hdulist is None or hdulist[0].data is None: diff --git a/pyobs/modules/camera/basevideo.py b/pyobs/modules/camera/basevideo.py index 475481ea..65a01ebd 100644 --- a/pyobs/modules/camera/basevideo.py +++ b/pyobs/modules/camera/basevideo.py @@ -1,6 +1,6 @@ from abc import ABCMeta from collections.abc import Coroutine -from datetime import datetime +from datetime import datetime, timezone import io import logging import time @@ -366,7 +366,7 @@ async def _set_image(self, data: NDArray[Any]) -> None: # store everything logging.info("Preparing to catch next image...") self._next_image = NextImage( - date_obs=datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.%f"), + date_obs=datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f"), image_type=self._image_type, header_futures=await self.request_fits_headers(), broadcast=broadcast, diff --git a/pyobs/modules/camera/dummycamera.py b/pyobs/modules/camera/dummycamera.py index 30706f1d..9aaedd4a 100644 --- a/pyobs/modules/camera/dummycamera.py +++ b/pyobs/modules/camera/dummycamera.py @@ -1,7 +1,7 @@ import asyncio import glob import logging -from datetime import datetime +from datetime import datetime, timezone from typing import Tuple, NamedTuple, Dict, Any, Optional, TYPE_CHECKING, List from pyobs.interfaces import IWindow, IBinning, ICooling, IGain @@ -122,7 +122,7 @@ async def _expose(self, exposure_time: float, open_shutter: bool, abort_event: a # start exposure log.info("Starting exposure with {0:s} shutter...".format("open" if open_shutter else "closed")) - date_obs = datetime.utcnow() + date_obs = datetime.now(timezone.utc) self._exposing = True # request image diff --git a/pyobs/modules/camera/dummyspectrograph.py b/pyobs/modules/camera/dummyspectrograph.py index 4d72aee4..1fbe620d 100644 --- a/pyobs/modules/camera/dummyspectrograph.py +++ b/pyobs/modules/camera/dummyspectrograph.py @@ -1,7 +1,7 @@ import logging import threading import time -from datetime import datetime +from datetime import datetime, timezone from typing import Any import numpy as np from astropy.io import fits @@ -43,7 +43,7 @@ async def _expose(self, abort_event: threading.Event) -> fits.HDUList: # do exposure log.info("Starting exposure...") exposure_time = 1.0 - date_obs = datetime.utcnow() + date_obs = datetime.now(timezone.utc) self._exposing = True steps = 10 for i in range(steps): diff --git a/pyobs/robotic/scripts/conditional.py b/pyobs/robotic/scripts/conditional.py index 1f240e6d..e3dbc091 100644 --- a/pyobs/robotic/scripts/conditional.py +++ b/pyobs/robotic/scripts/conditional.py @@ -1,6 +1,6 @@ from __future__ import annotations -import datetime +from datetime import datetime, timezone import logging from typing import Any, Dict, Optional, List, TYPE_CHECKING @@ -45,7 +45,7 @@ async def run( task_archive: Optional[TaskArchive] = None, ) -> None: # evaluate condition - ret = eval(self.condition, {"now": datetime.datetime.utcnow()}) + ret = eval(self.condition, {"now": datetime.now(timezone.utc)}) # run scripts if ret: diff --git a/pyobs/utils/average.py b/pyobs/utils/average.py index b5d06ee5..47f524b8 100644 --- a/pyobs/utils/average.py +++ b/pyobs/utils/average.py @@ -1,4 +1,4 @@ -import datetime +from datetime import datetime, timezone from typing import List, Optional, Tuple import numpy as np @@ -7,16 +7,16 @@ class RollingTimeAverage(object): def __init__(self, interval: float): self._interval = interval - self._values: List[Tuple[datetime.datetime, float]] = [] - self._start_time = datetime.datetime.utcnow() + self._values: List[Tuple[datetime, float]] = [] + self._start_time = datetime.now(timezone.utc) def clear(self) -> None: self._values = [] - self._start_time = datetime.datetime.utcnow() + self._start_time = datetime.now(timezone.utc) def add(self, value: float) -> None: # add value - now = datetime.datetime.utcnow() + now = datetime.now(timezone.utc) self._values.append((now, value)) # clean up @@ -28,7 +28,7 @@ def average(self, min_interval: Optional[float] = None) -> Optional[float]: return None # get time - now = datetime.datetime.utcnow() + now = datetime.now(timezone.utc) # go no values older than now-interval? if min_interval: diff --git a/pyobs/utils/time.py b/pyobs/utils/time.py index d313a2f2..67cc01e4 100644 --- a/pyobs/utils/time.py +++ b/pyobs/utils/time.py @@ -3,7 +3,7 @@ """ __title__ = "Time" -import datetime +from datetime import datetime, timezone, date, timedelta from typing import cast import astropy.time @@ -43,10 +43,10 @@ def now(cls) -> "Time": such a subclass) at the current time. """ # call `utcnow` immediately to be sure it's ASAP - dtnow = datetime.datetime.utcnow() + dtnow = datetime.now(timezone.utc) return cast(Time, Time(val=dtnow, format="datetime", scale="utc") + Time._now_offset) - def night_obs(self, observer: Observer) -> datetime.date: + def night_obs(self, observer: Observer) -> date: """Returns the night for this time, i.e. the date of the start of the current night. Args: @@ -65,7 +65,7 @@ def night_obs(self, observer: Observer) -> datetime.date: # get night if loc_dt.hour < 15: - loc_dt += datetime.timedelta(days=-1) + loc_dt += timedelta(days=-1) return loc_dt.date() From 971304b5e82ff8de4ea1f5f3816208b94d534a6c Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Sat, 3 Aug 2024 09:44:37 +0200 Subject: [PATCH 2/3] stop telescope after autofocus --- pyobs/robotic/lco/scripts/autofocus.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyobs/robotic/lco/scripts/autofocus.py b/pyobs/robotic/lco/scripts/autofocus.py index d474d13b..dd7bed77 100644 --- a/pyobs/robotic/lco/scripts/autofocus.py +++ b/pyobs/robotic/lco/scripts/autofocus.py @@ -1,5 +1,5 @@ import logging -from typing import Union, Tuple, Optional, Any +from typing import Union, Tuple, Optional, Any, cast from pyobs.interfaces import IRoof, ITelescope, IAcquisition, IAutoFocus from pyobs.robotic import TaskRunner @@ -154,5 +154,8 @@ async def run( raise ValueError("No autofocus given.") await autofocus.auto_focus(self._count, self._step, self._exptime) + # finally, stop telescope + await cast(ITelescope, telescope).stop_motion() + __all__ = ["LcoAutoFocusScript"] From 5b0692ce5284816d2b654625db65c9e6b7192b90 Mon Sep 17 00:00:00 2001 From: Tim-Oliver Husser Date: Sat, 3 Aug 2024 09:48:59 +0200 Subject: [PATCH 3/3] v1.14.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a27d93c..d3411096 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "pyobs-core" packages = [{ include = "pyobs" }] -version = "1.13.4" +version = "1.14.0" description = "robotic telescope software" authors = ["Tim-Oliver Husser "] license = "MIT"