pyobs-core 2.0.0.dev18__tar.gz → 2.0.0.dev19__tar.gz
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_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/PKG-INFO +1 -1
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/cli/pyobsd.py +2 -2
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/comm.py +12 -20
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/local/localcomm.py +4 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/serializer.py +8 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xmppcomm.py +7 -3
- pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingBody.py +29 -0
- pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingHeliocentricPolar.py +41 -0
- pyobs_core-2.0.0.dev18/pyobs/interfaces/IPointingHGS.py → pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingHeliographicStonyhurst.py +7 -6
- pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingOrbitalElements.py +47 -0
- pyobs_core-2.0.0.dev19/pyobs/interfaces/ITrackingMode.py +54 -0
- pyobs_core-2.0.0.dev19/pyobs/interfaces/ITrackingRate.py +54 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/__init__.py +20 -3
- pyobs_core-2.0.0.dev19/pyobs/interfaces/interface.py +77 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/fitsheader.py +16 -12
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/basevideo.py +3 -9
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/module.py +10 -17
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/_baseguiding.py +2 -1
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/acquisition.py +2 -1
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/mastermind.py +1 -1
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/scheduler.py +3 -3
- pyobs_core-2.0.0.dev19/pyobs/modules/telescope/__init__.py +13 -0
- pyobs_core-2.0.0.dev18/pyobs/modules/telescope/dummytelescope.py → pyobs_core-2.0.0.dev19/pyobs/modules/telescope/_dummytelescopebase.py +52 -30
- pyobs_core-2.0.0.dev19/pyobs/modules/telescope/basetelescope.py +815 -0
- pyobs_core-2.0.0.dev19/pyobs/modules/telescope/dummyaltaztelescope.py +46 -0
- pyobs_core-2.0.0.dev19/pyobs/modules/telescope/dummyradectelescope.py +55 -0
- pyobs_core-2.0.0.dev19/pyobs/modules/telescope/dummysolartelescope.py +149 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/__init__.py +1 -2
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/object.py +15 -17
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/flatfielder.py +1 -1
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/enums.py +6 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/filters.py +6 -6
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/serialization.py +0 -3
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyproject.toml +1 -1
- pyobs_core-2.0.0.dev18/pyobs/interfaces/interface.py +0 -36
- pyobs_core-2.0.0.dev18/pyobs/modules/telescope/__init__.py +0 -11
- pyobs_core-2.0.0.dev18/pyobs/modules/telescope/basetelescope.py +0 -353
- pyobs_core-2.0.0.dev18/pyobs/modules/utils/autonomouswarning.py +0 -153
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/.gitignore +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/LICENSE +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/application.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/background_task.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/cli/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/cli/_cli.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/cli/pyobs.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/cli/pyobsw.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/commlogging.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/dummy/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/dummy/dummycomm.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/local/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/local/localnetwork.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/proxy.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/rpc.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xmppclient.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/badweather.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/event.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/exposurestatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/filterchanged.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/focusfound.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/goodweather.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/log.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/modechanged.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/moduleclosed.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/moduleopened.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/motionstatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/move.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/newimage.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/newspectrum.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/offsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/roofclosing.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/roofopened.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/taskfailed.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/taskfinished.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/taskstarted.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/events/testevent.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/image.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/altazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/exptime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/genericoffset.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/onskydistance.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/radecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processor.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/_daobackgroundremover.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/_pillow.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/circle.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/crosshair.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/text.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/dotnet.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/calibration.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/_source_catalog.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/daophot.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/pysep.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/simpledisk.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/sourcedetection.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/exptime/star.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/addfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/download.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/flip.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/grayscale.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/httpserver.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/normalize.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/save.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/saveimage.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/smooth.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/softbin.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/addmask.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/circularmask.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/createfilename.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/removebackground.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/brighteststar.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/fitsheader.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/offsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/projected.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/spilled_light.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/photometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/photutil.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/pysep.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/wcs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAbortable.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAcquisition.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAutoFocus.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAutoGuiding.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAutonomous.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IBinning.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ICalibrate.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ICamera.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IConfig.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ICooling.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IData.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IDome.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IExposure.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IExposureTime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFilters.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFlatField.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFocusModel.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFocuser.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IGain.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IImageFormat.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IImageType.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IMode.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IModule.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IMotion.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IMultiFiber.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingAltAz.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingRaDec.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingSeries.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IReady.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRoof.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRotation.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRunnable.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRunning.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IScriptRunner.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ISpectrograph.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IStartStop.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IStructuredConfig.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ISyncTarget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ITelescope.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ITemperatures.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IVideo.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IWeather.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IWindow.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/camerasettings.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/fitsnamespace.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/follow.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/motionstatus.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/waitformotion.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/mixins/weatheraware.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/adaptive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/basecamera.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/basespectrograph.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/dummycamera.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/dummyspectrograph.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/dummyvideo.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/pipelinecamera.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/flatfield.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/pointing.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/dummyautofocus.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/focusmodel.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/focusseries.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/imagewatcher.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/imagewriter.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/seeing.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/_base.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/autoguiding.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/dummyacquisition.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/dummyguiding.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/pointing.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/scriptrunner.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/basedome.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/baseroof.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/dummyroof.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/test/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/test/standalone.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/dummymode.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/fluentlogger.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/httpfilecache.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/kiosk.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/matrix.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/stellarium.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/telegram.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/trigger.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/mockweather.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/weather.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/weather_api.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/weather_state.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/py.typed +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/observation.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/dataprovider.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/constant.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/follow.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/interval.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/merit.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/random.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/transit.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/target.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/cases.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/conditional.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/parallel.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/selector.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/sequential.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/log.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/backend/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/_portal.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/configdb.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/task.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/memory/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/task.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/taskrunner.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/archive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/local_archive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/average.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/cache.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/config.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/config_schema.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/coordinates.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/curvefit.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/exceptions.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/fits.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/base.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/photometry.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/projection.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/grid.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/gridnode.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/binningwidget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/exposewidget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/http.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/influxdb.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/logger.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/logging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/logging/context.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/logging/resolvableerror.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/modulegui.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/applyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/parallel.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/pipeline/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/pipeline/night.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/pipeline/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/csv.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/http.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/log.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/multi.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/publisher.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/shellcommand.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/threads/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/threads/lockwithabort.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/time.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/utils/units.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/version.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/archivefile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/bufferedfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/file.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/filelists/__init__.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/filelists/filelist.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/filelists/testing.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/httpfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/localfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/memfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/sftpfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/smbfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/sshfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/tempfile.py +0 -0
- {pyobs_core-2.0.0.dev18 → pyobs_core-2.0.0.dev19}/pyobs/vfs/vfs.py +0 -0
|
@@ -91,7 +91,7 @@ class PyobsDaemonCLI(CLI):
|
|
|
91
91
|
case "status":
|
|
92
92
|
daemon.status(print_json=self._config["json"])
|
|
93
93
|
case "list":
|
|
94
|
-
daemon.
|
|
94
|
+
daemon.list_modules()
|
|
95
95
|
case "logs":
|
|
96
96
|
daemon.logs(self._config["args"])
|
|
97
97
|
|
|
@@ -295,7 +295,7 @@ class PyobsDaemon:
|
|
|
295
295
|
else:
|
|
296
296
|
print(f"{module:<30} {'stopped':<8}")
|
|
297
297
|
|
|
298
|
-
def
|
|
298
|
+
def list_modules(self) -> None:
|
|
299
299
|
print("\n".join(self._list_configs()))
|
|
300
300
|
|
|
301
301
|
def logs(self, args: list[str]) -> None:
|
|
@@ -7,9 +7,9 @@ import logging
|
|
|
7
7
|
from collections.abc import Callable, Coroutine
|
|
8
8
|
from typing import TYPE_CHECKING, Any, overload
|
|
9
9
|
|
|
10
|
-
import pyobs.interfaces
|
|
11
10
|
from pyobs.events import Event, LogEvent, ModuleClosedEvent
|
|
12
11
|
from pyobs.interfaces import Interface
|
|
12
|
+
from pyobs.interfaces.interface import get_registered_interface
|
|
13
13
|
from pyobs.utils.enums import ModuleState
|
|
14
14
|
|
|
15
15
|
from .commlogging import CommLoggingHandler
|
|
@@ -337,28 +337,13 @@ class Comm:
|
|
|
337
337
|
list of interface classes.
|
|
338
338
|
"""
|
|
339
339
|
|
|
340
|
-
# get interface classes
|
|
341
|
-
inspection = inspect.getmembers(pyobs.interfaces, predicate=inspect.isclass)
|
|
342
|
-
|
|
343
340
|
# loop interfaces
|
|
344
341
|
interface_classes = []
|
|
345
342
|
for interface_name in interfaces:
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
if interface_name == cls_name and issubclass(cls, Interface):
|
|
351
|
-
# found it!
|
|
352
|
-
found = True
|
|
353
|
-
|
|
354
|
-
# then add it to the list of all interfaces
|
|
355
|
-
interface_classes.append(cls)
|
|
356
|
-
|
|
357
|
-
# there can only be one...
|
|
358
|
-
break
|
|
359
|
-
|
|
360
|
-
# not found?
|
|
361
|
-
if not found:
|
|
343
|
+
cls = get_registered_interface(interface_name)
|
|
344
|
+
if cls is not None:
|
|
345
|
+
interface_classes.append(cls)
|
|
346
|
+
else:
|
|
362
347
|
log.error('Could not find interface "%s" for client.', interface_name)
|
|
363
348
|
return interface_classes
|
|
364
349
|
|
|
@@ -541,6 +526,13 @@ class Comm:
|
|
|
541
526
|
def _get_own_state(self, interface: type[Interface]) -> Any:
|
|
542
527
|
return None
|
|
543
528
|
|
|
529
|
+
def get_own_capabilities(self, interface: type[Interface]) -> Any:
|
|
530
|
+
"""Return the capabilities published by this module for the given interface, or None."""
|
|
531
|
+
return self._get_own_capabilities(interface)
|
|
532
|
+
|
|
533
|
+
def _get_own_capabilities(self, interface: type[Interface]) -> Any:
|
|
534
|
+
return None
|
|
535
|
+
|
|
544
536
|
async def subscribe_state(
|
|
545
537
|
self,
|
|
546
538
|
module: str,
|
|
@@ -117,6 +117,10 @@ class LocalComm(Comm):
|
|
|
117
117
|
"""Store capabilities locally."""
|
|
118
118
|
self._capabilities[interface] = capabilities
|
|
119
119
|
|
|
120
|
+
def _get_own_capabilities(self, interface: type[Interface]) -> Any:
|
|
121
|
+
"""Return this client's own published capabilities."""
|
|
122
|
+
return self._capabilities.get(interface)
|
|
123
|
+
|
|
120
124
|
async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
121
125
|
"""Fetch capabilities from a remote module."""
|
|
122
126
|
if interface.capabilities is None:
|
|
@@ -32,6 +32,7 @@ import types as _builtin_types
|
|
|
32
32
|
from enum import StrEnum
|
|
33
33
|
from typing import Annotated, Any, Union, get_args, get_origin, get_type_hints
|
|
34
34
|
|
|
35
|
+
import numpy as np
|
|
35
36
|
from slixmpp.xmlstream import ET
|
|
36
37
|
|
|
37
38
|
from ...interfaces.interface import Interface as _Interface
|
|
@@ -65,6 +66,13 @@ def value_to_xml(value: Any, type_hint: Any) -> ET.Element:
|
|
|
65
66
|
if get_origin(type_hint) is Annotated:
|
|
66
67
|
type_hint = get_args(type_hint)[0]
|
|
67
68
|
|
|
69
|
+
# Normalize numpy scalars (np.float64, np.int64, np.bool_, ...) to native
|
|
70
|
+
# Python types. np.float64 subclasses float but repr()s as "np.float64(x)"
|
|
71
|
+
# since numpy 2.0, which corrupts <double> text; numpy integer types don't
|
|
72
|
+
# subclass int at all and would otherwise fall through to <string>.
|
|
73
|
+
if isinstance(value, np.generic):
|
|
74
|
+
value = value.item()
|
|
75
|
+
|
|
68
76
|
# None / void
|
|
69
77
|
if value is None:
|
|
70
78
|
elem = ET.Element("nil")
|
|
@@ -18,11 +18,11 @@ from slixmpp.xmlstream import ET
|
|
|
18
18
|
from slixmpp.xmlstream.handler import Callback
|
|
19
19
|
from slixmpp.xmlstream.matcher import MatchXMLMask
|
|
20
20
|
|
|
21
|
-
import pyobs.interfaces
|
|
22
21
|
from pyobs.comm import Comm
|
|
23
22
|
from pyobs.events import Event, LogEvent, ModuleClosedEvent, ModuleOpenedEvent
|
|
24
23
|
from pyobs.events.event import EventFactory
|
|
25
24
|
from pyobs.interfaces import Interface
|
|
25
|
+
from pyobs.interfaces.interface import get_registered_interface
|
|
26
26
|
from pyobs.utils import exceptions as exc
|
|
27
27
|
from pyobs.utils.enums import ModuleState
|
|
28
28
|
|
|
@@ -406,8 +406,8 @@ class XmppComm(Comm):
|
|
|
406
406
|
interface_names = []
|
|
407
407
|
for feature in features:
|
|
408
408
|
name, _, version = feature[len(prefix) :].rpartition(":")
|
|
409
|
-
local_cls =
|
|
410
|
-
if local_cls is not None and
|
|
409
|
+
local_cls = get_registered_interface(name)
|
|
410
|
+
if local_cls is not None and str(local_cls.version) == version:
|
|
411
411
|
interface_names.append(name)
|
|
412
412
|
|
|
413
413
|
# IModule not in list?
|
|
@@ -896,6 +896,10 @@ class XmppComm(Comm):
|
|
|
896
896
|
self._capabilities[interface] = capabilities
|
|
897
897
|
log.info("Published capabilities for %s", interface.__name__)
|
|
898
898
|
|
|
899
|
+
def _get_own_capabilities(self, interface: type[Interface]) -> Any:
|
|
900
|
+
"""Return this client's own published capabilities."""
|
|
901
|
+
return self._capabilities.get(interface)
|
|
902
|
+
|
|
899
903
|
async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
900
904
|
"""Fetch and deserialize capabilities for a remote module's interface."""
|
|
901
905
|
if interface.capabilities is None:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from .interface import Interface
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IPointingBody(Interface, metaclass=ABCMeta):
|
|
10
|
+
"""Points at and tracks a named solar-system body."""
|
|
11
|
+
|
|
12
|
+
__module__ = "pyobs.interfaces"
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
async def track_body(self, body: str, **kwargs: Any) -> None:
|
|
16
|
+
"""Starts tracking a named solar-system body.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
body: Name resolvable to an ephemeris (e.g. 'moon', 'mars', 'jupiter', or an
|
|
20
|
+
asteroid/comet designation known to JPL Horizons).
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
MoveError: If telescope could not be moved.
|
|
24
|
+
ValueError: If body name is not resolvable.
|
|
25
|
+
"""
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
__all__ = ["IPointingBody"]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Annotated, Any
|
|
6
|
+
|
|
7
|
+
from ..utils.enums import Unit
|
|
8
|
+
from ..utils.time import Time
|
|
9
|
+
from .interface import Interface
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class HeliocentricPolarState:
|
|
14
|
+
mu: float
|
|
15
|
+
psi: Annotated[float, Unit.DEGREES]
|
|
16
|
+
time: Time = field(default_factory=Time.now)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IPointingHeliocentricPolar(Interface, metaclass=ABCMeta):
|
|
20
|
+
"""The module can move to Heliocentric Polar (Mu/Psi) coordinates, usually combined with
|
|
21
|
+
:class:`~pyobs.interfaces.ITelescope`."""
|
|
22
|
+
|
|
23
|
+
__module__ = "pyobs.interfaces"
|
|
24
|
+
|
|
25
|
+
state = HeliocentricPolarState
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
async def move_heliocentric_polar(self, mu: float, psi: Annotated[float, Unit.DEGREES], **kwargs: Any) -> None:
|
|
29
|
+
"""Moves on given coordinates.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
mu: Cosine of the angular distance from Sun centre, dimensionless (0..1).
|
|
33
|
+
psi: Position angle around the solar disk, in degrees.
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
MoveError: If device could not be moved.
|
|
37
|
+
"""
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
__all__ = ["IPointingHeliocentricPolar", "HeliocentricPolarState"]
|
|
@@ -10,21 +10,22 @@ from .interface import Interface
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@dataclass
|
|
13
|
-
class
|
|
13
|
+
class HeliographicStonyhurstState:
|
|
14
14
|
lon: Annotated[float, Unit.DEGREES]
|
|
15
15
|
lat: Annotated[float, Unit.DEGREES]
|
|
16
16
|
time: Time = field(default_factory=Time.now)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class
|
|
20
|
-
"""The module can move to
|
|
19
|
+
class IPointingHeliographicStonyhurst(Interface, metaclass=ABCMeta):
|
|
20
|
+
"""The module can move to Heliographic Stonyhurst (lon/lat) coordinates, a frame fixed to the Sun's
|
|
21
|
+
rotating surface, usually combined with :class:`~pyobs.interfaces.ITelescope`."""
|
|
21
22
|
|
|
22
23
|
__module__ = "pyobs.interfaces"
|
|
23
24
|
|
|
24
|
-
state =
|
|
25
|
+
state = HeliographicStonyhurstState
|
|
25
26
|
|
|
26
27
|
@abstractmethod
|
|
27
|
-
async def
|
|
28
|
+
async def move_heliographic_stonyhurst(
|
|
28
29
|
self, lon: Annotated[float, Unit.DEGREES], lat: Annotated[float, Unit.DEGREES], **kwargs: Any
|
|
29
30
|
) -> None:
|
|
30
31
|
"""Moves on given coordinates.
|
|
@@ -39,4 +40,4 @@ class IPointingHGS(Interface, metaclass=ABCMeta):
|
|
|
39
40
|
...
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
__all__ = ["
|
|
43
|
+
__all__ = ["IPointingHeliographicStonyhurst", "HeliographicStonyhurstState"]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Annotated, Any
|
|
6
|
+
|
|
7
|
+
from ..utils.enums import Unit
|
|
8
|
+
from ..utils.time import Time
|
|
9
|
+
from .interface import Interface
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class OrbitalElements:
|
|
14
|
+
epoch: Time
|
|
15
|
+
semi_major_axis: Annotated[float, Unit.AU]
|
|
16
|
+
eccentricity: float
|
|
17
|
+
inclination: Annotated[float, Unit.DEGREES]
|
|
18
|
+
longitude_ascending_node: Annotated[float, Unit.DEGREES]
|
|
19
|
+
argument_of_periapsis: Annotated[float, Unit.DEGREES]
|
|
20
|
+
mean_anomaly: Annotated[float, Unit.DEGREES] | None = None
|
|
21
|
+
"""Mean anomaly at epoch, in degrees. Required for elliptical orbits (eccentricity < 1)."""
|
|
22
|
+
perihelion_time: Time | None = None
|
|
23
|
+
"""Time of perihelion passage. Required for near-parabolic/cometary orbits
|
|
24
|
+
(eccentricity close to or at 1), where mean anomaly is not well-defined."""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class IPointingOrbitalElements(Interface, metaclass=ABCMeta):
|
|
28
|
+
"""Points at and tracks a body defined by orbital elements (asteroid, comet, NEO)."""
|
|
29
|
+
|
|
30
|
+
__module__ = "pyobs.interfaces"
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
async def track_orbital_elements(self, elements: OrbitalElements, **kwargs: Any) -> None:
|
|
34
|
+
"""Starts tracking a body defined by orbital elements.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
elements: Orbital elements of the body to track.
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
MoveError: If telescope could not be moved.
|
|
41
|
+
ValueError: If elements are incomplete or inconsistent (neither mean_anomaly
|
|
42
|
+
nor perihelion_time given).
|
|
43
|
+
"""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
__all__ = ["IPointingOrbitalElements", "OrbitalElements"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from enum import StrEnum
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from ..utils.time import Time
|
|
9
|
+
from .interface import Interface
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TrackingMode(StrEnum):
|
|
13
|
+
"""Discrete, hardware-native tracking rate."""
|
|
14
|
+
|
|
15
|
+
SIDEREAL = "sidereal"
|
|
16
|
+
SOLAR = "solar"
|
|
17
|
+
LUNAR = "lunar"
|
|
18
|
+
OFF = "off"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class TrackingModeState:
|
|
23
|
+
mode: TrackingMode
|
|
24
|
+
time: Time = field(default_factory=Time.now)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class TrackingModeCapabilities:
|
|
29
|
+
modes: list[TrackingMode]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ITrackingMode(Interface, metaclass=ABCMeta):
|
|
33
|
+
"""The module supports switching between discrete, hardware-native tracking rates."""
|
|
34
|
+
|
|
35
|
+
__module__ = "pyobs.interfaces"
|
|
36
|
+
|
|
37
|
+
state = TrackingModeState
|
|
38
|
+
capabilities = TrackingModeCapabilities
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
async def set_tracking_mode(self, mode: TrackingMode, **kwargs: Any) -> None:
|
|
42
|
+
"""Switches to the given tracking mode.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
mode: Tracking mode to switch to.
|
|
46
|
+
|
|
47
|
+
Raises:
|
|
48
|
+
MoveError: If mode could not be set.
|
|
49
|
+
ValueError: If mode is not in this module's capabilities.
|
|
50
|
+
"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
__all__ = ["ITrackingMode", "TrackingMode", "TrackingModeState", "TrackingModeCapabilities"]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Annotated, Any
|
|
6
|
+
|
|
7
|
+
from ..utils.enums import Unit
|
|
8
|
+
from ..utils.time import Time
|
|
9
|
+
from .interface import Interface
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class TrackingRateState:
|
|
14
|
+
ra_rate: Annotated[float, Unit.ARCSEC_PER_SEC]
|
|
15
|
+
dec_rate: Annotated[float, Unit.ARCSEC_PER_SEC]
|
|
16
|
+
time: Time = field(default_factory=Time.now)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class TrackingRateCapabilities:
|
|
21
|
+
min_update_interval: Annotated[float, Unit.SECONDS]
|
|
22
|
+
"""Minimum time between successive set_tracking_rate calls this hardware/protocol accepts,
|
|
23
|
+
independent of whether the value actually changed. Populated per-driver from whatever its
|
|
24
|
+
protocol allows; 0 if the hardware has no such floor."""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ITrackingRate(Interface, metaclass=ABCMeta):
|
|
28
|
+
"""The module accepts an arbitrary non-sidereal tracking rate as an absolute RA/Dec offset."""
|
|
29
|
+
|
|
30
|
+
__module__ = "pyobs.interfaces"
|
|
31
|
+
|
|
32
|
+
state = TrackingRateState
|
|
33
|
+
capabilities = TrackingRateCapabilities
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
async def set_tracking_rate(
|
|
37
|
+
self,
|
|
38
|
+
ra_rate: Annotated[float, Unit.ARCSEC_PER_SEC],
|
|
39
|
+
dec_rate: Annotated[float, Unit.ARCSEC_PER_SEC],
|
|
40
|
+
**kwargs: Any,
|
|
41
|
+
) -> None:
|
|
42
|
+
"""Sets an absolute tracking rate on the sky, in arcsec/sec.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
ra_rate: Rate in RA, arcsec/sec on the sky.
|
|
46
|
+
dec_rate: Rate in Dec, arcsec/sec on the sky.
|
|
47
|
+
|
|
48
|
+
Raises:
|
|
49
|
+
MoveError: If rate could not be set.
|
|
50
|
+
"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
__all__ = ["ITrackingRate", "TrackingRateState", "TrackingRateCapabilities"]
|
|
@@ -43,8 +43,11 @@ from .interface import Interface
|
|
|
43
43
|
from .IOffsetsAltAz import AltAzOffsetState, IOffsetsAltAz
|
|
44
44
|
from .IOffsetsRaDec import IOffsetsRaDec, RaDecOffsetState
|
|
45
45
|
from .IPointingAltAz import AltAzState, IPointingAltAz
|
|
46
|
+
from .IPointingBody import IPointingBody
|
|
47
|
+
from .IPointingHeliocentricPolar import HeliocentricPolarState, IPointingHeliocentricPolar
|
|
48
|
+
from .IPointingHeliographicStonyhurst import HeliographicStonyhurstState, IPointingHeliographicStonyhurst
|
|
46
49
|
from .IPointingHelioprojective import HelioprojectiveState, IPointingHelioprojective
|
|
47
|
-
from .
|
|
50
|
+
from .IPointingOrbitalElements import IPointingOrbitalElements, OrbitalElements
|
|
48
51
|
from .IPointingRaDec import IPointingRaDec, RaDecState
|
|
49
52
|
from .IPointingSeries import IPointingSeries
|
|
50
53
|
from .IReady import IReady, ReadyState
|
|
@@ -59,6 +62,8 @@ from .IStructuredConfig import ConfigAppliedState, ConfigFieldSchema, ConfigSche
|
|
|
59
62
|
from .ISyncTarget import ISyncTarget
|
|
60
63
|
from .ITelescope import ITelescope
|
|
61
64
|
from .ITemperatures import ITemperatures, SensorReading, TemperaturesState
|
|
65
|
+
from .ITrackingMode import ITrackingMode, TrackingMode, TrackingModeCapabilities, TrackingModeState
|
|
66
|
+
from .ITrackingRate import ITrackingRate, TrackingRateCapabilities, TrackingRateState
|
|
62
67
|
from .IVideo import IVideo, VideoCapabilities
|
|
63
68
|
from .IWeather import IWeather, WeatherSensorReading, WeatherState
|
|
64
69
|
from .IWindow import IWindow, WindowCapabilities, WindowState
|
|
@@ -127,10 +132,15 @@ __all__ = [
|
|
|
127
132
|
"MultiFiberState",
|
|
128
133
|
"IPointingAltAz",
|
|
129
134
|
"AltAzState",
|
|
135
|
+
"IPointingBody",
|
|
136
|
+
"IPointingHeliocentricPolar",
|
|
137
|
+
"HeliocentricPolarState",
|
|
138
|
+
"IPointingHeliographicStonyhurst",
|
|
139
|
+
"HeliographicStonyhurstState",
|
|
130
140
|
"IPointingHelioprojective",
|
|
131
141
|
"HelioprojectiveState",
|
|
132
|
-
"
|
|
133
|
-
"
|
|
142
|
+
"IPointingOrbitalElements",
|
|
143
|
+
"OrbitalElements",
|
|
134
144
|
"IPointingRaDec",
|
|
135
145
|
"RaDecState",
|
|
136
146
|
"IPointingSeries",
|
|
@@ -153,6 +163,13 @@ __all__ = [
|
|
|
153
163
|
"ITemperatures",
|
|
154
164
|
"SensorReading",
|
|
155
165
|
"TemperaturesState",
|
|
166
|
+
"ITrackingMode",
|
|
167
|
+
"TrackingMode",
|
|
168
|
+
"TrackingModeState",
|
|
169
|
+
"TrackingModeCapabilities",
|
|
170
|
+
"ITrackingRate",
|
|
171
|
+
"TrackingRateState",
|
|
172
|
+
"TrackingRateCapabilities",
|
|
156
173
|
"IOffsetsAltAz",
|
|
157
174
|
"AltAzOffsetState",
|
|
158
175
|
"IOffsetsRaDec",
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from abc import ABCMeta
|
|
2
|
+
from typing import Any, ClassVar
|
|
3
|
+
|
|
4
|
+
_REGISTRY: dict[str, "type[Interface]"] = {}
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Interface(metaclass=ABCMeta):
|
|
8
|
+
"""Base class for all interfaces in pyobs."""
|
|
9
|
+
|
|
10
|
+
version: int = 1
|
|
11
|
+
state: ClassVar[type | None] = None
|
|
12
|
+
capabilities: ClassVar[type | None] = None
|
|
13
|
+
|
|
14
|
+
__module__ = "pyobs.interfaces"
|
|
15
|
+
|
|
16
|
+
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
17
|
+
super().__init_subclass__(**kwargs)
|
|
18
|
+
|
|
19
|
+
# only genuine interface definitions get registered. Concrete module
|
|
20
|
+
# classes (e.g. `class BaseCamera(Module, ICamera, IExposureTime,
|
|
21
|
+
# IImageType)`) also transitively subclass Interface, but always mix
|
|
22
|
+
# in at least one base that isn't itself an Interface subclass
|
|
23
|
+
# (Module, a FITS-header mixin, ...). A base only counts as "pure"
|
|
24
|
+
# if it's Interface itself or is already registered -- issubclass(
|
|
25
|
+
# base, Interface) alone isn't enough, since e.g. BaseCamera
|
|
26
|
+
# transitively satisfies that (via ICamera) despite mixing in
|
|
27
|
+
# Module, which would let DummyCamera(BaseCamera, ...) register
|
|
28
|
+
# too. Checking registry membership instead propagates purity down
|
|
29
|
+
# the whole chain, since BaseCamera itself never gets registered.
|
|
30
|
+
def _is_pure(base: type) -> bool:
|
|
31
|
+
return base is Interface or _REGISTRY.get(base.__name__) is base
|
|
32
|
+
|
|
33
|
+
if not all(_is_pure(base) for base in cls.__bases__):
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
existing = _REGISTRY.get(cls.__name__)
|
|
37
|
+
if existing is not None and existing is not cls:
|
|
38
|
+
raise TypeError(
|
|
39
|
+
f"Interface name '{cls.__name__}' is already registered by "
|
|
40
|
+
f"{existing.__module__}.{existing.__qualname__}; "
|
|
41
|
+
f"choose a distinct name for {cls.__module__}.{cls.__qualname__}."
|
|
42
|
+
)
|
|
43
|
+
_REGISTRY[cls.__name__] = cls
|
|
44
|
+
|
|
45
|
+
def get_state(self, interface: "type[Interface]") -> Any | None:
|
|
46
|
+
"""Return the last received state for the given interface, or None."""
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
def get_capabilities(self, interface: "type[Interface]") -> Any | None:
|
|
50
|
+
"""Return the capabilities for the given interface, or None."""
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
async def wait_for_state(self, interface: "type[Interface]", timeout: float = 10.0) -> Any | None:
|
|
54
|
+
"""Return state immediately if available, otherwise wait for the first update."""
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def has_own_state(cls) -> bool:
|
|
59
|
+
"""True if this interface defines its own state, as opposed to merely inheriting
|
|
60
|
+
one from a component interface it combines (e.g. ICamera inheriting IExposure's
|
|
61
|
+
state). Modules publish state under the interface that actually defines it, so
|
|
62
|
+
composite interfaces would otherwise be (wrongly) treated as publishing state too.
|
|
63
|
+
"""
|
|
64
|
+
return "state" in cls.__dict__
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def get_registered_interface(name: str) -> "type[Interface] | None":
|
|
68
|
+
"""Look up a registered interface class by name, or None if unknown."""
|
|
69
|
+
return _REGISTRY.get(name)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def registered_interfaces() -> "dict[str, type[Interface]]":
|
|
73
|
+
"""All currently-registered interface classes, keyed by name."""
|
|
74
|
+
return dict(_REGISTRY)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
__all__ = ["Interface", "get_registered_interface", "registered_interfaces"]
|
|
@@ -161,26 +161,25 @@ class FitsHeaderMixin:
|
|
|
161
161
|
# basic stuff
|
|
162
162
|
hdr["EQUINOX"] = (2000.0, "Equinox of celestial coordinate system")
|
|
163
163
|
|
|
164
|
-
# do we have a location?
|
|
165
|
-
if module.
|
|
166
|
-
loc = module.
|
|
164
|
+
# do we have an observer (and thus a location)?
|
|
165
|
+
if module._observer is not None:
|
|
166
|
+
loc = module._observer.location
|
|
167
167
|
# add location of telescope
|
|
168
168
|
hdr["LONGITUD"] = (float(loc.lon.degree), "Longitude of the telescope [deg E]")
|
|
169
169
|
hdr["LATITUDE"] = (float(loc.lat.degree), "Latitude of the telescope [deg N]")
|
|
170
170
|
hdr["HEIGHT"] = (float(loc.height.value), "Altitude of the telescope [m]")
|
|
171
171
|
|
|
172
172
|
# add local sidereal time
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
hdr["LST"] = (f"{h:02d}:{m:02d}:{s:05.2f}", "Local sidereal time")
|
|
173
|
+
lst = module._observer.local_sidereal_time(date_obs)
|
|
174
|
+
lst_hours = float(lst.hour)
|
|
175
|
+
h = int(lst_hours)
|
|
176
|
+
m = int((lst_hours - h) * 60)
|
|
177
|
+
s = (lst_hours - h - m / 60) * 3600
|
|
178
|
+
hdr["LST"] = (f"{h:02d}:{m:02d}:{s:05.2f}", "Local sidereal time")
|
|
180
179
|
|
|
181
180
|
# date of night this observation is in
|
|
182
|
-
if self._fitsheadermixin_night_obs:
|
|
183
|
-
hdr["DAY-OBS"] = (date_obs.night_obs(module._observer).strftime("%Y-%m-%d"), "Night of observation")
|
|
181
|
+
if self._fitsheadermixin_night_obs and module._observer is not None:
|
|
182
|
+
hdr["DAY-OBS"] = (date_obs.night_obs(module._observer).strftime("%Y-%m-%d"), "Night of observation")
|
|
184
183
|
else:
|
|
185
184
|
hdr["DAY-OBS"] = (date_obs.strftime("%Y-%m-%d"), "Day of observation")
|
|
186
185
|
|
|
@@ -195,6 +194,11 @@ class FitsHeaderMixin:
|
|
|
195
194
|
# get header
|
|
196
195
|
hdr = image.header
|
|
197
196
|
|
|
197
|
+
# need DAY-OBS, which is only set if DATE-OBS was found earlier
|
|
198
|
+
if "DAY-OBS" not in hdr:
|
|
199
|
+
log.warning("No DAY-OBS found in FITS header, cannot add FRAMENUM.")
|
|
200
|
+
return
|
|
201
|
+
|
|
198
202
|
# get night from header
|
|
199
203
|
night = hdr["DAY-OBS"]
|
|
200
204
|
|
|
@@ -121,7 +121,6 @@ class BaseVideo(Module, ImageFitsHeaderMixin, IVideo, IImageType, metaclass=ABCM
|
|
|
121
121
|
self._is_listening = False
|
|
122
122
|
self._port = http_port
|
|
123
123
|
self._interval = interval
|
|
124
|
-
self._new_image_event = asyncio.Event()
|
|
125
124
|
self._video_path = video_path
|
|
126
125
|
self._frame_num = 0
|
|
127
126
|
self._live_view = live_view
|
|
@@ -377,10 +376,6 @@ class BaseVideo(Module, ImageFitsHeaderMixin, IVideo, IImageType, metaclass=ABCM
|
|
|
377
376
|
self._last_image = LastImage(data=data, image=image, jpeg=jpeg, filename=filename)
|
|
378
377
|
self._frame_num += 1
|
|
379
378
|
|
|
380
|
-
# signal it
|
|
381
|
-
self._new_image_event.set()
|
|
382
|
-
self._new_image_event = asyncio.Event()
|
|
383
|
-
|
|
384
379
|
# prepare next image
|
|
385
380
|
if len(self._image_requests) > 0:
|
|
386
381
|
# broadcast?
|
|
@@ -395,9 +390,6 @@ class BaseVideo(Module, ImageFitsHeaderMixin, IVideo, IImageType, metaclass=ABCM
|
|
|
395
390
|
broadcast=broadcast,
|
|
396
391
|
)
|
|
397
392
|
|
|
398
|
-
# reset
|
|
399
|
-
self._image_request = None
|
|
400
|
-
|
|
401
393
|
async def _create_image(self, data: NDArray[Any], next_image: NextImage) -> tuple[Image, str]:
|
|
402
394
|
"""Create an Image object from numpy array.
|
|
403
395
|
|
|
@@ -436,6 +428,7 @@ class BaseVideo(Module, ImageFitsHeaderMixin, IVideo, IImageType, metaclass=ABCM
|
|
|
436
428
|
filename = self.format_filename(image)
|
|
437
429
|
if filename is None:
|
|
438
430
|
filename = "image.fits"
|
|
431
|
+
image.header["FNAME"] = filename
|
|
439
432
|
|
|
440
433
|
# store it and return filename
|
|
441
434
|
log.info("Writing image %s to cache...", filename)
|
|
@@ -475,7 +468,8 @@ class BaseVideo(Module, ImageFitsHeaderMixin, IVideo, IImageType, metaclass=ABCM
|
|
|
475
468
|
await asyncio.sleep(0.01)
|
|
476
469
|
|
|
477
470
|
# remove from list
|
|
478
|
-
self.
|
|
471
|
+
async with self._image_request_lock:
|
|
472
|
+
self._image_requests.remove(image_request)
|
|
479
473
|
|
|
480
474
|
# no image?
|
|
481
475
|
if image_request.image is None or image_request.filename is None:
|