pyobs-core 2.0.0.dev28__tar.gz → 2.0.0.dev30__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.dev28 → pyobs_core-2.0.0.dev30}/PKG-INFO +1 -1
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/application.py +1 -1
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/comm.py +15 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xmppclient.py +30 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xmppcomm.py +32 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/fitsnamespace.py +1 -1
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/weatheraware.py +9 -2
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/module.py +38 -3
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/enums.py +2 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/exceptions.py +9 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyproject.toml +1 -1
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/.gitignore +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/LICENSE +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/background_task.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/cli/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/cli/_cli.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/cli/pyobs.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/cli/pyobsd.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/cli/pyobsw.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/commlogging.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/dummy/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/dummy/dummycomm.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/local/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/local/localcomm.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/local/localnetwork.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/proxy.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/rpc.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/serializer.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/badweather.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/event.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/exposurestatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/filterchanged.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/focusfound.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/goodweather.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/log.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/modechanged.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/moduleclosed.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/moduleopened.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/motionstatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/move.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/newimage.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/newspectrum.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/offsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/roofclosing.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/roofopened.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/taskfailed.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/taskfinished.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/taskstarted.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/events/testevent.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/image.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/altazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/exptime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/genericoffset.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/onskydistance.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/radecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/meta/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processor.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/_daobackgroundremover.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/_pillow.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/circle.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/crosshair.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/text.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/dotnet.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/calibration/calibration.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/_source_catalog.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/daophot.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/pysep.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/simpledisk.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/sourcedetection.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/exptime/star.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/addfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/download.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/flip.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/grayscale.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/httpserver.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/normalize.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/save.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/saveimage.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/smooth.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/softbin.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/addmask.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/circularmask.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/createfilename.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/removebackground.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/brighteststar.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/fitsheader.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/offsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/projected.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/spilled_light.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/photometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/photutil.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/photometry/pysep.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/wcs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IAbortable.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IAcquisition.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IAutoFocus.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IAutoGuiding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IAutonomous.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IBinning.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ICalibrate.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ICamera.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IConfig.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ICooling.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IData.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IDataSequence.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IDome.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IExposure.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IExposureTime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IFilters.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IFlatField.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IFocusModel.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IFocuser.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IGain.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IImageFormat.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IImageType.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IMode.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IModule.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IMotion.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IMultiFiber.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingAltAz.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingBody.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingHeliocentricPolar.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingOrbitalElements.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingRaDec.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IPointingSeries.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IReady.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IRoof.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IRotation.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IRunnable.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IRunning.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IScriptRunner.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ISpectrograph.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IStartStop.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IStructuredConfig.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ISyncTarget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ITelescope.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ITemperatures.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ITrackingMode.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/ITrackingRate.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IVideo.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IWeather.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/IWindow.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/interfaces/interface.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/camerasettings.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/fitsheader.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/follow.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/motionstatus.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/mixins/waitformotion.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/adaptive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/basecamera.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/basespectrograph.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/basevideo.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/dummycamera.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/dummyspectrograph.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/dummyvideo.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/camera/pipelinecamera.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/flatfield/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/flatfield/flatfield.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/flatfield/pointing.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/flatfield/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/focus/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/focus/dummyautofocus.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/focus/focusmodel.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/focus/focusseries.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/image/imagewatcher.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/image/imagewriter.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/image/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/image/seeing.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/_base.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/_baseguiding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/acquisition.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/autoguiding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/dummyacquisition.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/dummyguiding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/robotic/mastermind.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/robotic/pointing.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/robotic/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/robotic/scriptrunner.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/roof/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/roof/basedome.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/roof/baseroof.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/roof/dummyroof.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/telescope/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/telescope/_dummytelescopebase.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/telescope/basetelescope.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/test/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/test/standalone.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/dummymode.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/fluentlogger.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/httpfilecache.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/kiosk.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/matrix.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/stellarium.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/telegram.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/utils/trigger.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/weather/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/weather/mockweather.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/weather/weather.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/weather/weather_api.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/modules/weather/weather_state.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/object.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/py.typed +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/observation.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/dataprovider.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/constant.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/follow.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/interval.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/merit.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/random.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/merits/transit.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/targets/target.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/control/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/control/cases.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/control/conditional.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/control/parallel.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/control/selector.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/control/sequential.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/exceptions.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/scripts/utils/log.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/backend/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/_portal.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/configdb.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/task.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/memory/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/storage/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/task.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/taskrunner.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/archive/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/archive/archive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/archive/local_archive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/average.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/cache.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/config.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/config_schema.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/coordinates.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/curvefit.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/fits.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/focusseries/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/focusseries/base.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/focusseries/photometry.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/focusseries/projection.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/grids/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/grids/filters.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/grids/grid.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/grids/gridnode.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/grids/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/binningwidget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/exposewidget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/http.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/influxdb.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/logger.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/logging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/logging/context.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/logging/resolvableerror.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/modulegui.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/offsets/applyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/parallel.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/pipeline/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/pipeline/night.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/pipeline/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/publisher/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/publisher/csv.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/publisher/http.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/publisher/log.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/publisher/multi.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/publisher/publisher.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/serialization.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/shellcommand.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/threads/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/threads/lockwithabort.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/time.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/utils/units.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/version.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/archivefile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/bufferedfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/file.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/filelists/__init__.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/filelists/filelist.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/filelists/testing.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/httpfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/localfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/memfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/sftpfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/smbfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/sshfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/tempfile.py +0 -0
- {pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/vfs/vfs.py +0 -0
|
@@ -530,6 +530,21 @@ class Comm:
|
|
|
530
530
|
async def _set_presence(self, state: ModuleState, error_string: str = "") -> None:
|
|
531
531
|
pass
|
|
532
532
|
|
|
533
|
+
async def mark_ready(self) -> None:
|
|
534
|
+
"""Signal that the module has finished its own startup (reached ModuleState.READY) and is
|
|
535
|
+
safe for peers to discover.
|
|
536
|
+
|
|
537
|
+
Called by Module once it transitions to READY. Transports that announce a module to peers
|
|
538
|
+
independently of RPC dispatch (e.g. XmppComm's XMPP presence, which drives other modules'
|
|
539
|
+
peer-discovery reaction) hold that announcement back until this fires, so peers never read
|
|
540
|
+
capabilities that are still mid-publish. Transports without such an announcement (e.g.
|
|
541
|
+
LocalComm) don't need to override this.
|
|
542
|
+
"""
|
|
543
|
+
await self._mark_ready()
|
|
544
|
+
|
|
545
|
+
async def _mark_ready(self) -> None:
|
|
546
|
+
pass
|
|
547
|
+
|
|
533
548
|
def get_client_state(self, module: str) -> tuple[ModuleState, str] | None:
|
|
534
549
|
"""Return the last known presence state of a connected module.
|
|
535
550
|
|
|
@@ -34,6 +34,9 @@ class XmppClient(slixmpp.ClientXMPP):
|
|
|
34
34
|
self._jid_conflict = False
|
|
35
35
|
self._conflict_reason: str | None = None
|
|
36
36
|
|
|
37
|
+
# module startup gating -- see send_presence()/mark_ready() below
|
|
38
|
+
self._module_ready = False
|
|
39
|
+
|
|
37
40
|
# auto-accept invitations
|
|
38
41
|
self.auto_authorize = True
|
|
39
42
|
|
|
@@ -58,6 +61,33 @@ class XmppClient(slixmpp.ClientXMPP):
|
|
|
58
61
|
self.add_event_handler("stream_error", self._stream_error)
|
|
59
62
|
self.add_filter("in", self._filter_messages)
|
|
60
63
|
|
|
64
|
+
def send_presence(self, *args: Any, **kwargs: Any) -> Any:
|
|
65
|
+
"""Override slixmpp's send_presence to hold back every presence broadcast -- the initial
|
|
66
|
+
online announcement (session_start) as well as re-broadcasts triggered by capability
|
|
67
|
+
updates (XmppComm._register_events) or lifecycle state changes (XmppComm._set_presence) --
|
|
68
|
+
until mark_ready() fires. This keeps the module invisible to peers' online-discovery
|
|
69
|
+
(_got_online/ModuleOpenedEvent) while it's still starting up, so peers never read
|
|
70
|
+
capabilities that are still mid-publish. Calls made before mark_ready() are simply dropped;
|
|
71
|
+
mark_ready() sends its own presence once, which is enough to announce the module (any
|
|
72
|
+
entity-capabilities hash update from a dropped call in the meantime is still picked up,
|
|
73
|
+
since update_caps() itself isn't gated).
|
|
74
|
+
"""
|
|
75
|
+
if not self._module_ready:
|
|
76
|
+
return None
|
|
77
|
+
return super().send_presence(*args, **kwargs)
|
|
78
|
+
|
|
79
|
+
def mark_ready(self) -> None:
|
|
80
|
+
"""Allow send_presence() to actually transmit from here on -- called either once the owning
|
|
81
|
+
Module first reaches ModuleState.READY (on the live, already-connected client: announce
|
|
82
|
+
immediately), or by XmppComm._connect() on a freshly created client for a reconnect after
|
|
83
|
+
the module was already READY (not connected yet -- session_start() will send presence as
|
|
84
|
+
soon as it fires, now that gating allows it). No-op if already marked ready."""
|
|
85
|
+
if self._module_ready:
|
|
86
|
+
return
|
|
87
|
+
self._module_ready = True
|
|
88
|
+
if self._connect_event.is_set():
|
|
89
|
+
self.send_presence()
|
|
90
|
+
|
|
61
91
|
def reconnect(self, wait: int | float = 2.0, reason: str = "Reconnecting") -> Any:
|
|
62
92
|
"""Disconnect only, instead of slixmpp's default reconnect-in-place.
|
|
63
93
|
|
|
@@ -170,6 +170,12 @@ class XmppComm(Comm):
|
|
|
170
170
|
self._xmpp: XmppClient | None = None
|
|
171
171
|
self._rpc: RPC | None = None
|
|
172
172
|
|
|
173
|
+
# module readiness (see mark_ready()) -- lives here rather than solely on XmppClient
|
|
174
|
+
# because _connect() replaces self._xmpp with a brand-new instance on every reconnect,
|
|
175
|
+
# and a reconnect after the module is already READY must announce presence immediately
|
|
176
|
+
# rather than re-gating it
|
|
177
|
+
self._module_ready = False
|
|
178
|
+
|
|
173
179
|
# pubsub for states
|
|
174
180
|
self._pubsub_service = f"pubsub.{self._domain}"
|
|
175
181
|
self._state_node_handlers: dict[str, tuple[type[Interface], list[Callable[[Any], None]]]] = {}
|
|
@@ -213,6 +219,18 @@ class XmppComm(Comm):
|
|
|
213
219
|
# create client
|
|
214
220
|
self._xmpp = XmppClient(self._jid, self._password)
|
|
215
221
|
|
|
222
|
+
# presence gating (see mark_ready()) only applies to a comm with an actual Module
|
|
223
|
+
# attached that hasn't finished starting yet -- a module-less XmppComm (a GUI, an
|
|
224
|
+
# admin tool, a bare observer in tests) has no such lifecycle and must announce
|
|
225
|
+
# itself immediately as before, or peers relying on presence-based discovery would
|
|
226
|
+
# never see it. Likewise, if the module already reached READY on a previous
|
|
227
|
+
# connection, tell the new client right away -- it isn't connected yet, so this
|
|
228
|
+
# doesn't send anything itself, but it means session_start() will announce presence
|
|
229
|
+
# immediately once (re)connected instead of holding it back as if this were the
|
|
230
|
+
# initial startup.
|
|
231
|
+
if self._module_ready or not self.has_module:
|
|
232
|
+
self._xmpp.mark_ready()
|
|
233
|
+
|
|
216
234
|
# self._xmpp = slixmpp.ClientXMPP(self._jid, password)
|
|
217
235
|
# Register directly with an XML mask rather than via pubsub_publish.
|
|
218
236
|
# slixmpp's StanzaPath matcher requires plugins to be lazily loaded
|
|
@@ -957,6 +975,14 @@ class XmppComm(Comm):
|
|
|
957
975
|
CLOSED → handled by normal disconnect (unavailable)
|
|
958
976
|
error_string rides as <status> text when state is ERROR.
|
|
959
977
|
"""
|
|
978
|
+
# publishing any lifecycle state at all is itself a readiness signal -- covers direct
|
|
979
|
+
# set_presence() callers that don't go through Module.set_state() (see mark_ready()).
|
|
980
|
+
# Idempotent: unlocks send_presence() once, then this call's own send below goes through.
|
|
981
|
+
# Goes through self._mark_ready() (not just self.client.mark_ready()) so self._module_ready
|
|
982
|
+
# is set too -- otherwise a later reconnect (_connect() creates a brand-new XmppClient)
|
|
983
|
+
# would re-gate presence on the new client despite this module already being announced.
|
|
984
|
+
await self._mark_ready()
|
|
985
|
+
|
|
960
986
|
_show_map: dict[ModuleState, str | None] = {
|
|
961
987
|
ModuleState.READY: None,
|
|
962
988
|
ModuleState.ERROR: "dnd",
|
|
@@ -966,6 +992,12 @@ class XmppComm(Comm):
|
|
|
966
992
|
status = error_string if state == ModuleState.ERROR and error_string else None
|
|
967
993
|
self.client.send_presence(pshow=show, pstatus=status)
|
|
968
994
|
|
|
995
|
+
async def _mark_ready(self) -> None:
|
|
996
|
+
"""See Comm.mark_ready(). Remembers readiness on self (survives client recreation on
|
|
997
|
+
reconnect, see _connect()) and lets the live client announce presence now."""
|
|
998
|
+
self._module_ready = True
|
|
999
|
+
self.client.mark_ready()
|
|
1000
|
+
|
|
969
1001
|
async def _subscribe_presence(self, module: str, callback: Callable[[ModuleState, str], None]) -> None:
|
|
970
1002
|
self._presence_callbacks.setdefault(module, []).append(callback)
|
|
971
1003
|
result = self._get_client_state(module)
|
|
@@ -17,7 +17,7 @@ class FitsNamespaceMixin:
|
|
|
17
17
|
self.__namespaces = {} if fits_namespaces is None else fits_namespaces
|
|
18
18
|
|
|
19
19
|
def _filter_fits_namespace(
|
|
20
|
-
self, hdr: dict[str, FitsHeaderEntry], sender: str, namespaces: list[str] | None = None
|
|
20
|
+
self, hdr: dict[str, FitsHeaderEntry], sender: str, namespaces: list[str] | None = None, **kwargs: Any
|
|
21
21
|
) -> dict[str, FitsHeaderEntry]:
|
|
22
22
|
"""Filter FITS header keywords by given namespaces. If no namespaces are given, let all through. Always
|
|
23
23
|
let keywords with this module's name as namespace pass.
|
|
@@ -24,6 +24,7 @@ class WeatherAwareMixin:
|
|
|
24
24
|
self.__last_park_attempt: float | None = None
|
|
25
25
|
self.__weatheraware_is_error_state = False
|
|
26
26
|
self.__weatheraware_lock = asyncio.Lock()
|
|
27
|
+
self.__weather_check_failures = 0
|
|
27
28
|
this = self
|
|
28
29
|
if isinstance(self, Module):
|
|
29
30
|
if weather is not None:
|
|
@@ -122,10 +123,16 @@ class WeatherAwareMixin:
|
|
|
122
123
|
async with module.proxy(this.__weather, IWeather) as proxy:
|
|
123
124
|
weather_state = await proxy.wait_for_state(IWeather, timeout=5.0)
|
|
124
125
|
this.__is_weather_good = weather_state.good if weather_state is not None else False
|
|
126
|
+
this.__weather_check_failures = 0
|
|
125
127
|
|
|
126
128
|
except Exception:
|
|
127
|
-
# could
|
|
128
|
-
|
|
129
|
+
# could not reach the weather module. This can be a real outage, but
|
|
130
|
+
# right after startup it's usually just that presence/roster hasn't
|
|
131
|
+
# settled yet, so don't jump to "bad weather" (and park) on the very
|
|
132
|
+
# first hiccup -- only once it persists across a few checks.
|
|
133
|
+
this.__weather_check_failures += 1
|
|
134
|
+
if this.__weather_check_failures >= 3:
|
|
135
|
+
this.__is_weather_good = False
|
|
129
136
|
|
|
130
137
|
# if not good, park now
|
|
131
138
|
if this.__is_weather_good is False:
|
|
@@ -148,8 +148,9 @@ class Module(Object, IModule, IConfig):
|
|
|
148
148
|
self._device_name = self.comm.name
|
|
149
149
|
self._label = label if label is not None else self._device_name
|
|
150
150
|
|
|
151
|
-
# state
|
|
152
|
-
|
|
151
|
+
# state -- starts STARTING, moved to READY once Application finishes the full open() chain
|
|
152
|
+
# (see Module.execute()'s guard and Application._main)
|
|
153
|
+
self._state = ModuleState.STARTING
|
|
153
154
|
self._error_string = ""
|
|
154
155
|
|
|
155
156
|
# own?
|
|
@@ -175,6 +176,12 @@ class Module(Object, IModule, IConfig):
|
|
|
175
176
|
# per-type logging contract a module author gets to opt out of.
|
|
176
177
|
_UNSUPPRESSIBLE: tuple[type[exc.PyobsError], ...] = (exc.ModuleError, exc.UnclassifiedError)
|
|
177
178
|
|
|
179
|
+
# methods still callable while the module is ModuleState.STARTING -- introspection/recovery
|
|
180
|
+
# only, nothing that touches a device that may not be initialized yet. get_version/get_label
|
|
181
|
+
# are deliberately not listed: they aren't declared on IModule, so they never appear in
|
|
182
|
+
# self._methods and can't be called via execute() at all, in any state.
|
|
183
|
+
_STARTING_WHITELIST: tuple[str, ...] = ("get_permitted_methods", "reset_error")
|
|
184
|
+
|
|
178
185
|
def _disable_exception_logging(self, *exceptions: type[exc.PyobsError]) -> None:
|
|
179
186
|
"""Declare that the given PyobsError types (and their subclasses) fire often enough that even the
|
|
180
187
|
default quiet INFO line is too much, and should not be logged locally at all -- the caller already
|
|
@@ -320,6 +327,25 @@ class Module(Object, IModule, IConfig):
|
|
|
320
327
|
ConfigCapabilities(caps=self._config_caps),
|
|
321
328
|
)
|
|
322
329
|
|
|
330
|
+
async def startup(self) -> None:
|
|
331
|
+
"""Open the module and mark it ready for RPC dispatch.
|
|
332
|
+
|
|
333
|
+
Runs the full open() override chain (base Module setup plus every subclass's own
|
|
334
|
+
setup) and only then transitions ModuleState.STARTING -> READY, so Module.execute()
|
|
335
|
+
starts accepting non-whitelisted calls exactly once startup has actually finished.
|
|
336
|
+
Every caller that opens a module standalone (Application, MultiModule) should call
|
|
337
|
+
this instead of open() directly -- otherwise the module stays in STARTING forever.
|
|
338
|
+
Callers that need finer-grained control (e.g. tests exercising STARTING behavior
|
|
339
|
+
directly) can call open() and set_state() separately instead.
|
|
340
|
+
|
|
341
|
+
Named startup() rather than start() because start() is already IStartStop's abstract
|
|
342
|
+
RPC method -- a plain start() here would be silently shadowed by any module
|
|
343
|
+
implementing that interface (guiding, mastermind, scheduler, weather, kiosk, ...),
|
|
344
|
+
which would then never leave STARTING under Application/MultiModule.
|
|
345
|
+
"""
|
|
346
|
+
await self.open()
|
|
347
|
+
await self.set_state(ModuleState.READY)
|
|
348
|
+
|
|
323
349
|
async def close(self) -> None:
|
|
324
350
|
"""Close module."""
|
|
325
351
|
await Object.close(self)
|
|
@@ -539,6 +565,10 @@ class Module(Object, IModule, IConfig):
|
|
|
539
565
|
KeyError: If method does not exist.
|
|
540
566
|
"""
|
|
541
567
|
|
|
568
|
+
# is module still starting up?
|
|
569
|
+
if self._state == ModuleState.STARTING and method not in self._STARTING_WHITELIST:
|
|
570
|
+
raise exc.ModuleStartingError("Module is still starting up, please try again shortly.")
|
|
571
|
+
|
|
542
572
|
# is module in error state?
|
|
543
573
|
if self._state == ModuleState.ERROR:
|
|
544
574
|
# if called method is not from IModule, raise error
|
|
@@ -771,6 +801,11 @@ class Module(Object, IModule, IConfig):
|
|
|
771
801
|
if self._comm is not None:
|
|
772
802
|
await self._comm.set_presence(state, error_string if error_string is not None else self._error_string)
|
|
773
803
|
|
|
804
|
+
# first time reaching READY, tell the transport it may now announce this module to
|
|
805
|
+
# peers -- e.g. XmppComm delays its initial XMPP presence until here, see mark_ready()
|
|
806
|
+
if state == ModuleState.READY:
|
|
807
|
+
await self._comm.mark_ready()
|
|
808
|
+
|
|
774
809
|
async def get_state(self, **kwargs: Any) -> ModuleState: # type: ignore[override]
|
|
775
810
|
"""Returns current state of module."""
|
|
776
811
|
return self._state
|
|
@@ -917,7 +952,7 @@ class MultiModule(Module):
|
|
|
917
952
|
|
|
918
953
|
_module_name_var.set(name)
|
|
919
954
|
try:
|
|
920
|
-
await mod.
|
|
955
|
+
await mod.startup()
|
|
921
956
|
await mod.main()
|
|
922
957
|
except asyncio.CancelledError:
|
|
923
958
|
pass
|
|
@@ -14,12 +14,14 @@ class ModuleState(StrEnum):
|
|
|
14
14
|
|
|
15
15
|
Attributes:
|
|
16
16
|
CLOSED: Module is closed.
|
|
17
|
+
STARTING: Module is starting up and not yet ready to accept commands.
|
|
17
18
|
READY: Module is ready.
|
|
18
19
|
ERROR: Module has an error.
|
|
19
20
|
LOCAL: Module is in local mode and cannot be used remotely.
|
|
20
21
|
"""
|
|
21
22
|
|
|
22
23
|
CLOSED = "closed"
|
|
24
|
+
STARTING = "starting"
|
|
23
25
|
READY = "ready"
|
|
24
26
|
ERROR = "error"
|
|
25
27
|
LOCAL = "local"
|
|
@@ -122,6 +122,15 @@ class DeviceBusyError(PyobsError):
|
|
|
122
122
|
pass
|
|
123
123
|
|
|
124
124
|
|
|
125
|
+
class ModuleStartingError(PyobsError):
|
|
126
|
+
"""The module hasn't finished its own startup yet (still inside `open()`, e.g. connecting to
|
|
127
|
+
hardware) and isn't safe to command -- distinct from DeviceBusyError, which means the module is
|
|
128
|
+
fully up but its device is occupied with another operation. Back off and retry once the module
|
|
129
|
+
reports ModuleState.READY, rather than treating this as a domain failure."""
|
|
130
|
+
|
|
131
|
+
pass
|
|
132
|
+
|
|
133
|
+
|
|
125
134
|
class NotSupportedError(PyobsError):
|
|
126
135
|
"""This module doesn't support the requested operation at all -- a capability the module only
|
|
127
136
|
optionally implements (e.g. an alt/az-only telescope asked to move_radec) isn't available,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/_daobackgroundremover.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/__init__.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/_pillow.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/circle.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/crosshair.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/annotation/text.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/astrometry.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/astrometry/dotnet.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/calibration/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/calibration/calibration.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/daophot.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/pysep.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/detection/simpledisk.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/exptime/__init__.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/exptime/exptime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/addfitsheaders.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/grayscale.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/httpserver.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/normalize.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/image/saveimage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/circularmask.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/createfilename.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/imagesourcefilter.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/misc/removebackground.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/modules/__init__.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/modules/getfitsheaders.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/__init__.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/astrometry.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/brighteststar.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/dummyoffsets.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/dummyskyoffsets.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/fitsheader.py
RENAMED
|
File without changes
|
{pyobs_core-2.0.0.dev28 → pyobs_core-2.0.0.dev30}/pyobs/images/processors/offsets/offsets.py
RENAMED
|
File without changes
|