pyobs-core 2.0.0.dev27__tar.gz → 2.0.0.dev29__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.dev27 → pyobs_core-2.0.0.dev29}/PKG-INFO +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/application.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/comm.py +15 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/rpc.py +56 -24
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xmppclient.py +30 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xmppcomm.py +35 -3
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IAcquisition.py +4 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IAutoFocus.py +2 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ICalibrate.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IConfig.py +3 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IData.py +1 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IDataSequence.py +2 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IExposureTime.py +2 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IFilters.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IFlatField.py +3 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IFocusModel.py +7 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IFocuser.py +3 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IMode.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IMultiFiber.py +3 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingAltAz.py +2 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingBody.py +5 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingHeliocentricPolar.py +3 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +3 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingHelioprojective.py +3 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingOrbitalElements.py +6 -3
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingRaDec.py +3 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingSeries.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IRotation.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IRunnable.py +7 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IScriptRunner.py +3 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ISyncTarget.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ITrackingMode.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IWeather.py +4 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/fitsnamespace.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/basecamera.py +12 -13
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/basespectrograph.py +8 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/basevideo.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/dummycamera.py +2 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/dummyspectrograph.py +3 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/flatfield/flatfield.py +7 -7
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/flatfield/scheduler.py +7 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/focus/focusmodel.py +39 -6
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/focus/focusseries.py +5 -5
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/module.py +226 -38
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/_base.py +2 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/scienceframeguiding.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/robotic/mastermind.py +7 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/robotic/scriptrunner.py +13 -3
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/roof/basedome.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/roof/dummyroof.py +20 -13
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/telescope/_dummytelescopebase.py +44 -18
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/telescope/basetelescope.py +53 -14
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/dummymode.py +3 -2
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/weather/mockweather.py +5 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/weather/weather.py +13 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/astroplanscheduler.py +3 -1
- pyobs_core-2.0.0.dev29/pyobs/robotic/scripts/__init__.py +4 -0
- pyobs_core-2.0.0.dev29/pyobs/robotic/scripts/exceptions.py +12 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/imaging/autofocus.py +6 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/imaging/imaging.py +1 -1
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/task.py +11 -11
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/taskrunner.py +7 -4
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/task.py +7 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/taskrunner.py +9 -5
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/enums.py +2 -0
- pyobs_core-2.0.0.dev29/pyobs/utils/exceptions.py +204 -0
- pyobs_core-2.0.0.dev29/pyobs/utils/threads/__init__.py +3 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/threads/lockwithabort.py +4 -7
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyproject.toml +1 -1
- pyobs_core-2.0.0.dev27/pyobs/robotic/scripts/__init__.py +0 -3
- pyobs_core-2.0.0.dev27/pyobs/utils/exceptions.py +0 -290
- pyobs_core-2.0.0.dev27/pyobs/utils/threads/__init__.py +0 -3
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/.gitignore +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/LICENSE +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/background_task.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/cli/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/cli/_cli.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/cli/pyobs.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/cli/pyobsd.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/cli/pyobsw.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/commlogging.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/dummy/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/dummy/dummycomm.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/local/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/local/localcomm.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/local/localnetwork.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/proxy.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/serializer.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/badweather.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/event.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/exposurestatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/filterchanged.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/focusfound.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/goodweather.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/log.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/modechanged.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/moduleclosed.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/moduleopened.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/motionstatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/move.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/newimage.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/newspectrum.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/offsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/roofclosing.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/roofopened.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/taskfailed.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/taskfinished.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/taskstarted.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/events/testevent.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/image.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/altazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/exptime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/genericoffset.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/onskydistance.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/radecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/meta/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processor.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/_daobackgroundremover.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/annotation/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/annotation/_pillow.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/annotation/circle.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/annotation/crosshair.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/annotation/text.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/astrometry/dotnet.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/calibration/calibration.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/_source_catalog.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/daophot.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/pysep.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/simpledisk.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/detection/sourcedetection.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/exptime/star.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/addfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/download.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/flip.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/grayscale.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/httpserver.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/normalize.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/save.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/saveimage.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/smooth.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/image/softbin.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/addmask.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/circularmask.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/createfilename.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/misc/removebackground.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/brighteststar.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/fitsheader.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/offsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/projected.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/offsets/spilled_light.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/photometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/photutil.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/photometry/pysep.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/wcs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IAbortable.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IAutoGuiding.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IAutonomous.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IBinning.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ICamera.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ICooling.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IDome.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IExposure.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IGain.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IImageFormat.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IImageType.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IModule.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IMotion.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IReady.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IRoof.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IRunning.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ISpectrograph.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IStartStop.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IStructuredConfig.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ITelescope.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ITemperatures.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/ITrackingRate.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IVideo.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IWindow.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/interface.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/camerasettings.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/fitsheader.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/follow.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/motionstatus.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/waitformotion.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/mixins/weatheraware.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/adaptive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/dummyvideo.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/camera/pipelinecamera.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/flatfield/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/flatfield/pointing.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/focus/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/focus/dummyautofocus.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/image/imagewatcher.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/image/imagewriter.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/image/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/image/seeing.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/_baseguiding.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/acquisition.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/autoguiding.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/dummyacquisition.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/dummyguiding.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/robotic/pointing.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/robotic/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/roof/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/roof/baseroof.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/telescope/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/test/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/test/standalone.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/fluentlogger.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/httpfilecache.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/kiosk.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/matrix.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/stellarium.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/telegram.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/utils/trigger.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/weather/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/weather/weather_api.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/modules/weather/weather_state.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/object.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/py.typed +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/observation.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/dataprovider.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/constant.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/follow.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/interval.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/merit.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/random.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/merits/transit.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/targets/target.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/control/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/control/cases.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/control/conditional.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/control/parallel.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/control/selector.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/control/sequential.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/scripts/utils/log.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/backend/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/_portal.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/configdb.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/memory/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/storage/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/archive/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/archive/archive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/archive/local_archive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/average.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/cache.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/config.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/config_schema.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/coordinates.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/curvefit.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/fits.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/focusseries/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/focusseries/base.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/focusseries/photometry.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/focusseries/projection.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/grids/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/grids/filters.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/grids/grid.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/grids/gridnode.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/grids/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/binningwidget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/exposewidget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/http.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/influxdb.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/logger.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/logging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/logging/context.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/logging/resolvableerror.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/modulegui.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/offsets/applyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/parallel.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/pipeline/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/pipeline/night.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/pipeline/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/publisher/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/publisher/csv.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/publisher/http.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/publisher/log.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/publisher/multi.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/publisher/publisher.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/serialization.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/shellcommand.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/time.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/utils/units.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/version.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/archivefile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/bufferedfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/file.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/filelists/__init__.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/filelists/filelist.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/filelists/testing.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/httpfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/localfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/memfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/sftpfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/smbfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/sshfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/vfs/tempfile.py +0 -0
- {pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/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
|
|
|
@@ -96,9 +96,22 @@ def fault_to_xml(exception: Exception) -> ET.Element:
|
|
|
96
96
|
value_elem = ET.Element(f"{{{_NS}}}value")
|
|
97
97
|
pyobs_fault = ET.Element(f"{{{_PYOBS_NS}}}fault")
|
|
98
98
|
exc_elem = ET.Element("exception")
|
|
99
|
-
|
|
99
|
+
# Fully-qualified name, not the bare class name -- domain exceptions can live anywhere, not
|
|
100
|
+
# just in pyobs.utils.exceptions (see PyobsError._registry / resolve()). If this is an
|
|
101
|
+
# UnclassifiedError wrapping something that was never a PyobsError to begin with (see
|
|
102
|
+
# Module.execute()'s classification), serialize the ORIGINAL type's name instead of
|
|
103
|
+
# "UnclassifiedError" itself -- original_type never crosses the wire as an attribute (only the
|
|
104
|
+
# class name and message do), so this is the only way it survives to the caller. The caller's
|
|
105
|
+
# own registry lookup then decides fresh: an unregistered builtin/vendor type still correctly
|
|
106
|
+
# falls back to UnclassifiedError, but this time with original_type actually populated.
|
|
107
|
+
original_type = getattr(exception, "original_type", None)
|
|
108
|
+
exc_elem.text = original_type if original_type else f"{type(exception).__module__}.{type(exception).__qualname__}"
|
|
100
109
|
msg_elem = ET.Element("message")
|
|
101
|
-
|
|
110
|
+
# the raw message, not str(exception) -- str() already prepends "<ClassName>", and
|
|
111
|
+
# reconstruction on the caller's side passes this straight back in as the new instance's
|
|
112
|
+
# message, so serializing str() here would bake in a doubled "<ClassName> <ClassName> ..." once
|
|
113
|
+
# the caller's own __str__ formats it again
|
|
114
|
+
msg_elem.text = getattr(exception, "message", None) or str(exception)
|
|
102
115
|
pyobs_fault.append(exc_elem)
|
|
103
116
|
pyobs_fault.append(msg_elem)
|
|
104
117
|
value_elem.append(pyobs_fault)
|
|
@@ -107,16 +120,17 @@ def fault_to_xml(exception: Exception) -> ET.Element:
|
|
|
107
120
|
|
|
108
121
|
|
|
109
122
|
def xml_to_fault(fault_elem: ET.Element) -> tuple[str, str]:
|
|
110
|
-
"""Parse <fault> and return (
|
|
123
|
+
"""Parse <fault> and return (exception_qualified_name, message)."""
|
|
124
|
+
_fallback_name = f"{exc.RemoteError.__module__}.{exc.RemoteError.__qualname__}"
|
|
111
125
|
value_elem = fault_elem.find(f"{{{_NS}}}value")
|
|
112
126
|
if value_elem is None:
|
|
113
|
-
return
|
|
127
|
+
return _fallback_name, "Unknown error"
|
|
114
128
|
pyobs_fault = value_elem.find(f"{{{_PYOBS_NS}}}fault")
|
|
115
129
|
if pyobs_fault is None:
|
|
116
|
-
return
|
|
130
|
+
return _fallback_name, "Unknown error"
|
|
117
131
|
exc_el = pyobs_fault.find("exception")
|
|
118
132
|
msg_el = pyobs_fault.find("message")
|
|
119
|
-
exc_name = (exc_el.text if exc_el is not None else None) or
|
|
133
|
+
exc_name = (exc_el.text if exc_el is not None else None) or _fallback_name
|
|
120
134
|
msg = (msg_el.text if msg_el is not None else None) or ""
|
|
121
135
|
return exc_name, msg
|
|
122
136
|
|
|
@@ -170,6 +184,13 @@ class RPC:
|
|
|
170
184
|
iq.enable("rpc_query")
|
|
171
185
|
pmethod = iq["rpc_query"]["method_call"]["method_name"]
|
|
172
186
|
|
|
187
|
+
# XEP-0009 already assigns this per call (used elsewhere as the Future dict key) -- reuse
|
|
188
|
+
# it as a correlation id so an operator can jump from a caller-side exception straight to
|
|
189
|
+
# the matching origin-side log line, instead of neither side pointing at the other
|
|
190
|
+
call_id: str | slixmpp.JID = iq["id"]
|
|
191
|
+
if isinstance(call_id, slixmpp.JID):
|
|
192
|
+
call_id = call_id.node
|
|
193
|
+
|
|
173
194
|
try:
|
|
174
195
|
if self._handler is None:
|
|
175
196
|
return
|
|
@@ -208,7 +229,7 @@ class RPC:
|
|
|
208
229
|
response.send()
|
|
209
230
|
|
|
210
231
|
# Call method
|
|
211
|
-
return_value = await self._handler.execute(pmethod, *params, sender=iq["from"].user)
|
|
232
|
+
return_value = await self._handler.execute(pmethod, *params, sender=iq["from"].user, call_id=call_id)
|
|
212
233
|
|
|
213
234
|
# Serialize return value
|
|
214
235
|
return_type = hints.get("return", type(None))
|
|
@@ -220,9 +241,12 @@ class RPC:
|
|
|
220
241
|
self._client.plugin["xep_0009"].forbidden(iq).send()
|
|
221
242
|
|
|
222
243
|
except Exception as e:
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
244
|
+
# Module.execute() already classified and logged anything raised by the call itself
|
|
245
|
+
# (every transport gets the same treatment there now), so there's nothing left to do
|
|
246
|
+
# here but serialize and send the fault -- except for failures that never reached
|
|
247
|
+
# execute() at all (e.g. malformed RPC parameters during deserialization above), which
|
|
248
|
+
# this is the only place that will ever log
|
|
249
|
+
if not isinstance(e, exc.PyobsError):
|
|
226
250
|
log.exception("Unexpected exception in %s.", pmethod)
|
|
227
251
|
self._client.plugin["xep_0009"].send_fault(iq, fault_to_xml(e))
|
|
228
252
|
|
|
@@ -269,18 +293,22 @@ class RPC:
|
|
|
269
293
|
fault_elem = iq["rpc_query"]["method_response"]["fault"]
|
|
270
294
|
exc_name, msg = xml_to_fault(fault_elem)
|
|
271
295
|
|
|
272
|
-
exception_class = getattr(exc, exc_name, None)
|
|
273
|
-
if exception_class is None or not issubclass(exception_class, Exception):
|
|
274
|
-
exception_class = exc.RemoteError
|
|
275
|
-
|
|
276
296
|
sender = iq["from"].node
|
|
277
|
-
|
|
278
|
-
|
|
297
|
+
exception_class = exc.PyobsError.resolve(exc_name)
|
|
298
|
+
if exception_class is not None:
|
|
299
|
+
# real registered type (e.g. FocusError) -- raised as itself, not wrapped
|
|
300
|
+
exception: exc.PyobsError = exception_class(msg, remote_module=sender)
|
|
279
301
|
else:
|
|
280
|
-
|
|
302
|
+
# unresolvable: never a PyobsError to begin with, or its defining module was never
|
|
303
|
+
# imported in this process -- the qualified name string still survives as original_type
|
|
304
|
+
exception = exc.UnclassifiedError(msg, original_type=exc_name, remote_module=sender)
|
|
305
|
+
|
|
306
|
+
# same correlation id Module.execute() logged on the origin side -- an operator can jump
|
|
307
|
+
# straight from this caller-side exception to the matching detailed log line, by id
|
|
308
|
+
setattr(exception, "call_id", jid)
|
|
281
309
|
|
|
282
310
|
if not future.done():
|
|
283
|
-
future.set_exception(
|
|
311
|
+
future.set_exception(exception)
|
|
284
312
|
|
|
285
313
|
async def _on_jabber_rpc_error(self, iq: Any) -> None:
|
|
286
314
|
pmethod = self._client.plugin["xep_0009"].extract_method(iq["rpc_query"])
|
|
@@ -295,12 +323,16 @@ class RPC:
|
|
|
295
323
|
|
|
296
324
|
sender = iq["from"].node
|
|
297
325
|
e = {
|
|
298
|
-
"item-not-found": exc.RemoteError(
|
|
299
|
-
"forbidden": exc.RemoteError(
|
|
300
|
-
"undefined-condition": exc.RemoteError(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
326
|
+
"item-not-found": exc.RemoteError(f"No remote handler for {pmethod} at {iq['from']}!", module=sender),
|
|
327
|
+
"forbidden": exc.RemoteError(f"Forbidden to invoke {pmethod} at {iq['from']}!", module=sender),
|
|
328
|
+
"undefined-condition": exc.RemoteError(
|
|
329
|
+
f"Unexpected problem invoking {pmethod} at {iq['from']}!", module=sender
|
|
330
|
+
),
|
|
331
|
+
"service-unavailable": exc.RemoteError(f"Service at {iq['from']} is unavailable.", module=sender),
|
|
332
|
+
"remote-server-not-found": exc.RemoteError(
|
|
333
|
+
f"Could not find remote server for {iq['from']}.", module=sender
|
|
334
|
+
),
|
|
335
|
+
}.get(condition, exc.RemoteError(f"Unexpected exception at {iq['from']}!", module=sender))
|
|
304
336
|
|
|
305
337
|
callback.set_exception(e)
|
|
306
338
|
|
|
@@ -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
|
|
@@ -503,10 +521,10 @@ class XmppComm(Comm):
|
|
|
503
521
|
# RPC layer's jabber_rpc_error event handling ever gets a chance to act on it,
|
|
504
522
|
# so the IQ-level "forbidden" condition (see Module ACLs) has to be read here.
|
|
505
523
|
if e.iq["error"]["condition"] == "forbidden":
|
|
506
|
-
raise exc.RemoteError(
|
|
507
|
-
raise exc.RemoteError(
|
|
524
|
+
raise exc.RemoteError(f"Forbidden to invoke {method} on {client}.", module=client)
|
|
525
|
+
raise exc.RemoteError(f"Could not call {method} on {client}.", module=client)
|
|
508
526
|
except slixmpp.exceptions.IqTimeout:
|
|
509
|
-
raise exc.RemoteTimeoutError(
|
|
527
|
+
raise exc.RemoteTimeoutError(f"Call to {method} on {client} timed out.", module=client)
|
|
510
528
|
|
|
511
529
|
async def _got_online(self, msg: Any) -> None:
|
|
512
530
|
"""If a new client connects, add it to list.
|
|
@@ -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)
|
|
@@ -59,7 +59,10 @@ class IAcquisition(IRunning, IAbortable, metaclass=ABCMeta):
|
|
|
59
59
|
Result with time, ra, dec, alt, az, and an offset in whichever frame the mount supports.
|
|
60
60
|
|
|
61
61
|
Raises:
|
|
62
|
-
|
|
62
|
+
AbortedError: If the acquisition was aborted.
|
|
63
|
+
GeneralError: If a dependency (e.g. the camera) failed.
|
|
64
|
+
ImageError: If the calculated offset was too large or otherwise unusable.
|
|
65
|
+
AcquisitionError: If target could not be acquired within the given tolerance.
|
|
63
66
|
"""
|
|
64
67
|
...
|
|
65
68
|
|
|
@@ -54,7 +54,8 @@ class IAutoFocus(IRunning, IAbortable, metaclass=ABCMeta):
|
|
|
54
54
|
Result of autofocus.
|
|
55
55
|
|
|
56
56
|
Raises:
|
|
57
|
-
|
|
57
|
+
AbortedError: If the autofocus series was aborted.
|
|
58
|
+
FocusError: If focus could not be obtained.
|
|
58
59
|
"""
|
|
59
60
|
...
|
|
60
61
|
|
|
@@ -11,7 +11,11 @@ class ICalibrate(Interface, metaclass=ABCMeta):
|
|
|
11
11
|
|
|
12
12
|
@abstractmethod
|
|
13
13
|
async def calibrate(self, **kwargs: Any) -> None:
|
|
14
|
-
"""Calibrate the device.
|
|
14
|
+
"""Calibrate the device.
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
GeneralError: If calibration failed.
|
|
18
|
+
"""
|
|
15
19
|
...
|
|
16
20
|
|
|
17
21
|
|
|
@@ -33,7 +33,7 @@ class IConfig(Interface, metaclass=ABCMeta):
|
|
|
33
33
|
Current value.
|
|
34
34
|
|
|
35
35
|
Raises:
|
|
36
|
-
|
|
36
|
+
InvalidArgumentError: If config item of given name does not exist.
|
|
37
37
|
"""
|
|
38
38
|
...
|
|
39
39
|
|
|
@@ -46,7 +46,8 @@ class IConfig(Interface, metaclass=ABCMeta):
|
|
|
46
46
|
value: New value.
|
|
47
47
|
|
|
48
48
|
Raises:
|
|
49
|
-
|
|
49
|
+
InvalidArgumentError: If config item of given name does not exist.
|
|
50
|
+
ValueError: If value is invalid.
|
|
50
51
|
"""
|
|
51
52
|
...
|
|
52
53
|
|
|
@@ -38,7 +38,8 @@ class IDataSequence(IAbortable, metaclass=ABCMeta):
|
|
|
38
38
|
during the wait.
|
|
39
39
|
|
|
40
40
|
Raises:
|
|
41
|
-
|
|
41
|
+
InvalidArgumentError: If count or delay is out of range.
|
|
42
|
+
DeviceBusyError: If the device is already busy (exposing or already running a
|
|
42
43
|
sequence).
|
|
43
44
|
"""
|
|
44
45
|
...
|
|
@@ -31,6 +31,8 @@ class IExposureTime(Interface, metaclass=ABCMeta):
|
|
|
31
31
|
|
|
32
32
|
Raises:
|
|
33
33
|
ValueError: If exposure time could not be set.
|
|
34
|
+
NotSupportedError: If this module doesn't support setting exposure time directly (e.g.
|
|
35
|
+
it's dictated by something else, like incoming science frames).
|
|
34
36
|
"""
|
|
35
37
|
...
|
|
36
38
|
|
|
@@ -35,7 +35,7 @@ class IFilters(IMotion, metaclass=ABCMeta):
|
|
|
35
35
|
filter_name: Name of filter to set.
|
|
36
36
|
|
|
37
37
|
Raises:
|
|
38
|
-
|
|
38
|
+
InvalidArgumentError: If an invalid filter was given.
|
|
39
39
|
MoveError: If filter wheel cannot be moved.
|
|
40
40
|
"""
|
|
41
41
|
...
|
|
@@ -21,7 +21,13 @@ class IFocusModel(Interface, metaclass=ABCMeta):
|
|
|
21
21
|
|
|
22
22
|
@abstractmethod
|
|
23
23
|
async def set_optimal_focus(self, **kwargs: Any) -> None:
|
|
24
|
-
"""Sets optimal focus.
|
|
24
|
+
"""Sets optimal focus.
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
WeatherDataError: If the weather station returned an invalid temperature reading.
|
|
28
|
+
FocusTimeoutError: If a temperature module didn't respond in time.
|
|
29
|
+
MissingSensorError: If a configured sensor isn't in a module's temperature data.
|
|
30
|
+
"""
|
|
25
31
|
...
|
|
26
32
|
|
|
27
33
|
|
|
@@ -31,8 +31,9 @@ class IFocuser(IMotion, metaclass=ABCMeta):
|
|
|
31
31
|
focus: New focus value in mm.
|
|
32
32
|
|
|
33
33
|
Raises:
|
|
34
|
+
InvalidArgumentError: If given value is invalid.
|
|
35
|
+
AbortedError: If movement was aborted.
|
|
34
36
|
MoveError: If telescope cannot be moved.
|
|
35
|
-
InterruptedError: If movement was aborted.
|
|
36
37
|
"""
|
|
37
38
|
...
|
|
38
39
|
|
|
@@ -45,6 +46,7 @@ class IFocuser(IMotion, metaclass=ABCMeta):
|
|
|
45
46
|
|
|
46
47
|
Raises:
|
|
47
48
|
ValueError: If given value is invalid.
|
|
49
|
+
NotSupportedError: If this module doesn't support a separate focus offset.
|
|
48
50
|
MoveError: If telescope cannot be moved.
|
|
49
51
|
"""
|
|
50
52
|
...
|
|
@@ -36,7 +36,7 @@ class IMode(Interface, metaclass=ABCMeta):
|
|
|
36
36
|
group: Name of the group to set the mode for.
|
|
37
37
|
|
|
38
38
|
Raises:
|
|
39
|
-
|
|
39
|
+
InvalidArgumentError: If an invalid mode or group was given.
|
|
40
40
|
MoveError: If mode selector cannot be moved.
|
|
41
41
|
"""
|
|
42
42
|
...
|
|
@@ -34,6 +34,8 @@ class IPointingAltAz(Interface, metaclass=ABCMeta):
|
|
|
34
34
|
az: Az in deg to move to.
|
|
35
35
|
|
|
36
36
|
Raises:
|
|
37
|
+
NotSupportedError: If this device doesn't support Alt/Az pointing.
|
|
38
|
+
AltitudeLimitError: If the destination is below the configured altitude limit.
|
|
37
39
|
MoveError: If device could not be moved.
|
|
38
40
|
"""
|
|
39
41
|
...
|
|
@@ -20,8 +20,11 @@ class IPointingBody(Interface, metaclass=ABCMeta):
|
|
|
20
20
|
asteroid/comet designation known to JPL Horizons).
|
|
21
21
|
|
|
22
22
|
Raises:
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
NotSupportedError: If this device doesn't support body tracking.
|
|
24
|
+
BodyResolutionError: If body name is not resolvable.
|
|
25
|
+
MoveError: If telescope could not be moved. Also propagates whatever the underlying
|
|
26
|
+
RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since tracking
|
|
27
|
+
a body is implemented as resolving it and then moving there.
|
|
25
28
|
"""
|
|
26
29
|
...
|
|
27
30
|
|
{pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingHeliocentricPolar.py
RENAMED
|
@@ -33,7 +33,9 @@ class IPointingHeliocentricPolar(Interface, metaclass=ABCMeta):
|
|
|
33
33
|
psi: Position angle around the solar disk, in degrees.
|
|
34
34
|
|
|
35
35
|
Raises:
|
|
36
|
-
MoveError: If device could not be moved.
|
|
36
|
+
MoveError: If device could not be moved. Also propagates whatever the underlying
|
|
37
|
+
RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since this is
|
|
38
|
+
typically implemented as converting to RA/Dec and then moving there.
|
|
37
39
|
"""
|
|
38
40
|
...
|
|
39
41
|
|
|
@@ -35,7 +35,9 @@ class IPointingHeliographicStonyhurst(Interface, metaclass=ABCMeta):
|
|
|
35
35
|
lat: Latitude in deg to track.
|
|
36
36
|
|
|
37
37
|
Raises:
|
|
38
|
-
MoveError: If device could not be moved.
|
|
38
|
+
MoveError: If device could not be moved. Also propagates whatever the underlying
|
|
39
|
+
RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since this is
|
|
40
|
+
typically implemented as converting to RA/Dec and then moving there.
|
|
39
41
|
"""
|
|
40
42
|
...
|
|
41
43
|
|
{pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingHelioprojective.py
RENAMED
|
@@ -34,7 +34,9 @@ class IPointingHelioprojective(Interface, metaclass=ABCMeta):
|
|
|
34
34
|
theta_y: The theta_y coordinate.
|
|
35
35
|
|
|
36
36
|
Raises:
|
|
37
|
-
MoveError: If device could not be moved.
|
|
37
|
+
MoveError: If device could not be moved. Also propagates whatever the underlying
|
|
38
|
+
RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since this is
|
|
39
|
+
typically implemented as converting to RA/Dec and then moving there.
|
|
38
40
|
"""
|
|
39
41
|
...
|
|
40
42
|
|
{pyobs_core-2.0.0.dev27 → pyobs_core-2.0.0.dev29}/pyobs/interfaces/IPointingOrbitalElements.py
RENAMED
|
@@ -37,9 +37,12 @@ class IPointingOrbitalElements(Interface, metaclass=ABCMeta):
|
|
|
37
37
|
elements: Orbital elements of the body to track.
|
|
38
38
|
|
|
39
39
|
Raises:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
nor perihelion_time given).
|
|
40
|
+
NotSupportedError: If this device doesn't support orbital-element tracking.
|
|
41
|
+
InvalidOrbitalElementsError: If elements are incomplete or inconsistent (neither
|
|
42
|
+
mean_anomaly nor perihelion_time given).
|
|
43
|
+
MoveError: If telescope could not be moved. Also propagates whatever the underlying
|
|
44
|
+
RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since tracking
|
|
45
|
+
orbital elements is implemented as propagating them and then moving there.
|
|
43
46
|
"""
|
|
44
47
|
...
|
|
45
48
|
|
|
@@ -34,6 +34,9 @@ class IPointingRaDec(Interface, metaclass=ABCMeta):
|
|
|
34
34
|
dec: Dec in deg to track.
|
|
35
35
|
|
|
36
36
|
Raises:
|
|
37
|
+
NotSupportedError: If this device doesn't support RA/Dec pointing.
|
|
38
|
+
MissingObserverError: If no observer is configured.
|
|
39
|
+
AltitudeLimitError: If the destination is below the configured altitude limit.
|
|
37
40
|
MoveError: If device could not be moved.
|
|
38
41
|
"""
|
|
39
42
|
...
|
|
@@ -12,7 +12,11 @@ class IPointingSeries(Interface, metaclass=ABCMeta):
|
|
|
12
12
|
|
|
13
13
|
@abstractmethod
|
|
14
14
|
async def add_pointing_measurement(self, **kwargs: Any) -> None:
|
|
15
|
-
"""Add a new measurement to the pointing series.
|
|
15
|
+
"""Add a new measurement to the pointing series.
|
|
16
|
+
|
|
17
|
+
Raises:
|
|
18
|
+
GeneralError: If the measurement could not be added.
|
|
19
|
+
"""
|
|
16
20
|
...
|
|
17
21
|
|
|
18
22
|
|
|
@@ -24,7 +24,11 @@ class IRotation(IMotion, metaclass=ABCMeta):
|
|
|
24
24
|
|
|
25
25
|
@abstractmethod
|
|
26
26
|
async def set_rotation(self, angle: Annotated[float, Unit.DEGREES], **kwargs: Any) -> None:
|
|
27
|
-
"""Sets the rotation angle to the given value in degrees.
|
|
27
|
+
"""Sets the rotation angle to the given value in degrees.
|
|
28
|
+
|
|
29
|
+
Raises:
|
|
30
|
+
MoveError: If the device could not be rotated.
|
|
31
|
+
"""
|
|
28
32
|
...
|
|
29
33
|
|
|
30
34
|
|
|
@@ -11,7 +11,13 @@ class IRunnable(IAbortable, metaclass=ABCMeta):
|
|
|
11
11
|
|
|
12
12
|
@abstractmethod
|
|
13
13
|
async def run(self, **kwargs: Any) -> None:
|
|
14
|
-
"""Perform module task
|
|
14
|
+
"""Perform module task
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
DeviceBusyError: If this task is already running.
|
|
18
|
+
ScriptError: ScriptRunner-based implementations wrap whatever the underlying script
|
|
19
|
+
raises that isn't already a domain exception.
|
|
20
|
+
"""
|
|
15
21
|
...
|
|
16
22
|
|
|
17
23
|
|
|
@@ -12,7 +12,11 @@ class ISyncTarget(Interface, metaclass=ABCMeta):
|
|
|
12
12
|
|
|
13
13
|
@abstractmethod
|
|
14
14
|
async def sync_target(self, **kwargs: Any) -> None:
|
|
15
|
-
"""Synchronize device on current target.
|
|
15
|
+
"""Synchronize device on current target.
|
|
16
|
+
|
|
17
|
+
Raises:
|
|
18
|
+
GeneralError: If synchronization failed.
|
|
19
|
+
"""
|
|
16
20
|
...
|
|
17
21
|
|
|
18
22
|
|