pyobs-core 2.0.0.dev1__tar.gz → 2.0.0.dev3__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.dev1 → pyobs_core-2.0.0.dev3}/PKG-INFO +1 -1
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/application.py +11 -2
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/comm.py +95 -5
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/commlogging.py +5 -2
- pyobs_core-2.0.0.dev3/pyobs/comm/local/localcomm.py +157 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/proxy.py +25 -0
- pyobs_core-2.0.0.dev3/pyobs/comm/xmpp/rpc.py +303 -0
- pyobs_core-2.0.0.dev3/pyobs/comm/xmpp/serializer.py +338 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +6 -19
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xmppcomm.py +230 -98
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/log.py +18 -2
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IBinning.py +12 -18
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IConfig.py +6 -24
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/ICooling.py +8 -20
- pyobs_core-2.0.0.dev3/pyobs/interfaces/IExposure.py +26 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IExposureTime.py +9 -18
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IFilters.py +9 -16
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IFocuser.py +10 -18
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IGain.py +10 -18
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IImageFormat.py +11 -18
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IImageType.py +9 -9
- pyobs_core-2.0.0.dev3/pyobs/interfaces/IMode.py +40 -0
- pyobs_core-2.0.0.dev3/pyobs/interfaces/IModule.py +26 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IMotion.py +13 -12
- pyobs_core-2.0.0.dev3/pyobs/interfaces/IMultiFiber.py +45 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IOffsetsAltAz.py +8 -11
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IOffsetsRaDec.py +8 -11
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IPointingAltAz.py +8 -9
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IPointingHGS.py +8 -11
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IPointingHelioprojective.py +8 -11
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IPointingRaDec.py +8 -9
- pyobs_core-2.0.0.dev3/pyobs/interfaces/IReady.py +21 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IRotation.py +9 -5
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IRunning.py +9 -0
- pyobs_core-2.0.0.dev3/pyobs/interfaces/ITemperatures.py +30 -0
- pyobs_core-2.0.0.dev3/pyobs/interfaces/IVideo.py +19 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IWindow.py +12 -16
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/__init__.py +0 -1
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/interface.py +0 -2
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/fitsheader.py +5 -2
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/motionstatus.py +9 -12
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/waitformotion.py +6 -3
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/weatheraware.py +1 -1
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/basecamera.py +26 -38
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/basespectrograph.py +0 -8
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/basevideo.py +5 -21
- pyobs_core-2.0.0.dev3/pyobs/modules/camera/dummycamera.py +328 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/dummyspectrograph.py +0 -11
- pyobs_core-2.0.0.dev3/pyobs/modules/camera/dummyvideo.py +69 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/pipelinecamera.py +1 -10
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/flatfield/flatfield.py +9 -24
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/module.py +49 -4
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/autoguiding.py +1 -11
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/scienceframeguiding.py +0 -16
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/roof/baseroof.py +8 -11
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/roof/dummyroof.py +3 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/telescope/basetelescope.py +16 -27
- pyobs_core-2.0.0.dev3/pyobs/modules/telescope/dummytelescope.py +302 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/dummymode.py +12 -35
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/control/selector.py +2 -1
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/utils/callmodule.py +39 -17
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/parallel.py +15 -3
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyproject.toml +7 -1
- pyobs_core-2.0.0.dev1/pyobs/comm/dbus/__init__.py +0 -3
- pyobs_core-2.0.0.dev1/pyobs/comm/dbus/dbuscomm.py +0 -591
- pyobs_core-2.0.0.dev1/pyobs/comm/dbus/patch.py +0 -112
- pyobs_core-2.0.0.dev1/pyobs/comm/local/localcomm.py +0 -98
- pyobs_core-2.0.0.dev1/pyobs/comm/xmpp/rpc.py +0 -274
- pyobs_core-2.0.0.dev1/pyobs/interfaces/IExposure.py +0 -33
- pyobs_core-2.0.0.dev1/pyobs/interfaces/ILatLon.py +0 -41
- pyobs_core-2.0.0.dev1/pyobs/interfaces/IMode.py +0 -62
- pyobs_core-2.0.0.dev1/pyobs/interfaces/IModule.py +0 -40
- pyobs_core-2.0.0.dev1/pyobs/interfaces/IMultiFiber.py +0 -73
- pyobs_core-2.0.0.dev1/pyobs/interfaces/IReady.py +0 -22
- pyobs_core-2.0.0.dev1/pyobs/interfaces/ITemperatures.py +0 -25
- pyobs_core-2.0.0.dev1/pyobs/interfaces/IVideo.py +0 -22
- pyobs_core-2.0.0.dev1/pyobs/modules/camera/dummycamera.py +0 -313
- pyobs_core-2.0.0.dev1/pyobs/modules/telescope/dummytelescope.py +0 -346
- pyobs_core-2.0.0.dev1/pyobs/utils/simulation/__init__.py +0 -11
- pyobs_core-2.0.0.dev1/pyobs/utils/simulation/camera.py +0 -284
- pyobs_core-2.0.0.dev1/pyobs/utils/simulation/telescope.py +0 -200
- pyobs_core-2.0.0.dev1/pyobs/utils/simulation/world.py +0 -107
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/.gitignore +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/LICENSE +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/background_task.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/cli/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/cli/_cli.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/cli/pyobs.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/cli/pyobsd.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/cli/pyobsw.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/dummy/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/dummy/dummycomm.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/local/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/local/localnetwork.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/comm/xmpp/xmppclient.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/badweather.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/event.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/exposurestatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/filterchanged.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/focusfound.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/goodweather.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/modechanged.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/moduleclosed.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/moduleopened.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/motionstatuschanged.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/move.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/newimage.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/newspectrum.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/offsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/roofclosing.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/roofopened.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/taskfailed.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/taskfinished.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/taskstarted.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/events/testevent.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/image.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/altazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/exptime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/genericoffset.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/onskydistance.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/radecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/meta/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processor.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/_daobackgroundremover.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/annotation/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/annotation/_pillow.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/annotation/circle.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/annotation/crosshair.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/annotation/text.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/astrometry/dotnet.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/calibration/calibration.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/_source_catalog.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/daophot.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/pysep.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/simpledisk.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/detection/sourcedetection.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/exptime/star.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/addfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/download.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/flip.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/grayscale.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/httpserver.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/normalize.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/save.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/saveimage.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/smooth.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/image/softbin.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/addmask.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/circularmask.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/createfilename.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/misc/removebackground.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/astrometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/brighteststar.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/fitsheader.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/offsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/projected.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/offsets/spilled_light.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/photometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/photutil.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/photometry/pysep.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/wcs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IAbortable.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IAcquisition.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IAutoFocus.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IAutoGuiding.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IAutonomous.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/ICalibrate.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/ICamera.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IData.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IDome.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IFlatField.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IFocusModel.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IPointingSeries.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IRoof.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IRunnable.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IScriptRunner.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/ISpectrograph.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IStartStop.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/ISyncTarget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/ITelescope.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/interfaces/IWeather.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/camerasettings.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/fitsnamespace.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/follow.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/mixins/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/camera/adaptive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/flatfield/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/flatfield/pointing.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/flatfield/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/focus/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/focus/focusmodel.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/focus/focusseries.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/image/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/image/imagewatcher.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/image/imagewriter.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/image/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/image/seeing.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/_base.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/_baseguiding.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/acquisition.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/dummyacquisition.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/dummyguiding.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/robotic/mastermind.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/robotic/pointing.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/robotic/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/robotic/scriptrunner.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/roof/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/roof/basedome.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/telescope/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/test/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/test/standalone.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/autonomouswarning.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/fluentlogger.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/httpfilecache.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/kiosk.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/matrix.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/stellarium.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/telegram.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/utils/trigger.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/weather/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/weather/weather.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/weather/weather_api.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/modules/weather/weather_state.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/object.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/py.typed +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/observation.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/dataprovider.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/constant.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/follow.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/interval.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/merit.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/random.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/merits/transit.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/helioprojectiveradialarget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/targets/target.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/control/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/control/cases.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/control/conditional.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/control/parallel.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/control/sequential.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/scripts/utils/log.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/backend/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/_portal.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/configdb.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/task.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/memory/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/observationarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/storage/taskarchive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/task.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/taskrunner.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/archive/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/archive/archive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/archive/local_archive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/exptime/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/exptime/exptime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/average.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/cache.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/config.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/coordinates.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/curvefit.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/enums.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/exceptions.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/fits.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/focusseries/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/focusseries/base.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/focusseries/photometry.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/focusseries/projection.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/grids/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/grids/filters.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/grids/grid.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/grids/gridnode.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/grids/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/binningwidget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/exposewidget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/http.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/influxdb.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/logger.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/logging/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/logging/context.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/logging/resolvableerror.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/modulegui.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/offsets/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/offsets/applyoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/pipeline/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/pipeline/night.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/pipeline/pipeline.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/publisher/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/publisher/csv.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/publisher/http.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/publisher/log.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/publisher/multi.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/publisher/publisher.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/serialization.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/shellcommand.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/threads/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/threads/lockwithabort.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/time.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/utils/types.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/version.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/archivefile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/bufferedfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/file.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/filelists/__init__.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/filelists/filelist.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/filelists/testing.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/httpfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/localfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/memfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/sftpfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/smbfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/sshfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/tempfile.py +0 -0
- {pyobs_core-2.0.0.dev1 → pyobs_core-2.0.0.dev3}/pyobs/vfs/vfs.py +0 -0
|
@@ -140,8 +140,17 @@ class Application:
|
|
|
140
140
|
class_name = cfg["class"]
|
|
141
141
|
klass = get_class_from_string(class_name)
|
|
142
142
|
|
|
143
|
-
# create event loop
|
|
144
|
-
|
|
143
|
+
# create event loop — if top-level class doesn't override new_event_loop,
|
|
144
|
+
# check child modules for one that does (e.g. pyobs_gui.GUI in a MultiModule)
|
|
145
|
+
loop_class = klass
|
|
146
|
+
if klass.new_event_loop is Module.new_event_loop:
|
|
147
|
+
for mod_cfg in cfg.get("modules", {}).values():
|
|
148
|
+
if isinstance(mod_cfg, dict) and "class" in mod_cfg:
|
|
149
|
+
child_klass = get_class_from_string(mod_cfg["class"])
|
|
150
|
+
if child_klass.new_event_loop is not Module.new_event_loop:
|
|
151
|
+
loop_class = child_klass
|
|
152
|
+
break
|
|
153
|
+
self._loop = loop_class.new_event_loop()
|
|
145
154
|
asyncio.set_event_loop(self._loop)
|
|
146
155
|
|
|
147
156
|
# create module and open it
|
|
@@ -4,12 +4,14 @@ import asyncio
|
|
|
4
4
|
import functools
|
|
5
5
|
import inspect
|
|
6
6
|
import logging
|
|
7
|
+
import sys
|
|
7
8
|
from collections.abc import Callable, Coroutine
|
|
8
9
|
from typing import TYPE_CHECKING, Any, overload
|
|
9
10
|
|
|
10
11
|
import pyobs.interfaces
|
|
11
12
|
from pyobs.events import Event, LogEvent, ModuleClosedEvent
|
|
12
13
|
from pyobs.interfaces import Interface
|
|
14
|
+
from pyobs.utils.enums import ModuleState
|
|
13
15
|
|
|
14
16
|
from .commlogging import CommLoggingHandler
|
|
15
17
|
from .proxy import Proxy, ProxyType, _ProxyContext
|
|
@@ -18,6 +20,7 @@ if TYPE_CHECKING:
|
|
|
18
20
|
from pyobs.modules import Module
|
|
19
21
|
|
|
20
22
|
StateCallback = Callable[[Any], None]
|
|
23
|
+
PresenceCallback = Callable[["ModuleState", str], None]
|
|
21
24
|
|
|
22
25
|
log = logging.getLogger(__name__)
|
|
23
26
|
|
|
@@ -64,9 +67,14 @@ class Comm:
|
|
|
64
67
|
"""Open module."""
|
|
65
68
|
|
|
66
69
|
# add handler to global logger
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
root_logger = logging.getLogger()
|
|
71
|
+
if not any(isinstance(h, CommLoggingHandler) for h in root_logger.handlers):
|
|
72
|
+
from pyobs.utils.logging.context import ModuleNameFilter
|
|
73
|
+
|
|
74
|
+
handler = CommLoggingHandler(self)
|
|
75
|
+
handler.setLevel(logging.INFO)
|
|
76
|
+
handler.addFilter(ModuleNameFilter())
|
|
77
|
+
root_logger.addHandler(handler)
|
|
70
78
|
|
|
71
79
|
# start logging thread
|
|
72
80
|
self._logging_task = asyncio.create_task(self._logging())
|
|
@@ -129,7 +137,7 @@ class Comm:
|
|
|
129
137
|
|
|
130
138
|
# subscribe to state
|
|
131
139
|
for interface in interfaces:
|
|
132
|
-
if getattr(interface, "
|
|
140
|
+
if getattr(interface, "State", None) is not None:
|
|
133
141
|
await self.subscribe_state(client, interface, functools.partial(proxy.update_state, interface))
|
|
134
142
|
|
|
135
143
|
self._proxies[client] = proxy
|
|
@@ -430,18 +438,86 @@ class Comm:
|
|
|
430
438
|
) -> None:
|
|
431
439
|
pass
|
|
432
440
|
|
|
433
|
-
|
|
441
|
+
@staticmethod
|
|
442
|
+
def _interface_from_state(state_cls: type) -> type:
|
|
443
|
+
outer_name = state_cls.__qualname__.rsplit(".", 1)[0]
|
|
444
|
+
return getattr(sys.modules[state_cls.__module__], outer_name)
|
|
445
|
+
|
|
446
|
+
async def set_state(self, state: Any) -> None:
|
|
434
447
|
"""Publish state for this module.
|
|
435
448
|
|
|
436
449
|
Args:
|
|
437
450
|
interface: Interface type for the state.
|
|
438
451
|
state: State object to publish.
|
|
439
452
|
"""
|
|
453
|
+
interface = Comm._interface_from_state(type(state))
|
|
440
454
|
await self._set_state(interface, state)
|
|
441
455
|
|
|
442
456
|
async def _set_state(self, interface: type[Interface], state: Any) -> None:
|
|
443
457
|
pass
|
|
444
458
|
|
|
459
|
+
@staticmethod
|
|
460
|
+
def _interface_from_capabilities(caps_cls: type) -> type:
|
|
461
|
+
outer_name = caps_cls.__qualname__.rsplit(".", 1)[0]
|
|
462
|
+
return getattr(sys.modules[caps_cls.__module__], outer_name)
|
|
463
|
+
|
|
464
|
+
async def set_capabilities(self, capabilities: Any) -> None:
|
|
465
|
+
"""Publish capabilities for this module.
|
|
466
|
+
|
|
467
|
+
Called by Module.open() for each interface that defines a Capabilities
|
|
468
|
+
dataclass. Not intended to be called directly by module authors after
|
|
469
|
+
that point — capabilities are fixed for the module lifetime.
|
|
470
|
+
|
|
471
|
+
Args:
|
|
472
|
+
capabilities: Capabilities dataclass instance.
|
|
473
|
+
"""
|
|
474
|
+
interface = Comm._interface_from_capabilities(type(capabilities))
|
|
475
|
+
await self._set_capabilities(interface, capabilities)
|
|
476
|
+
|
|
477
|
+
async def _set_capabilities(self, interface: type[Interface], capabilities: Any) -> None:
|
|
478
|
+
pass
|
|
479
|
+
|
|
480
|
+
async def get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
481
|
+
"""Fetch and deserialize capabilities for a remote module's interface.
|
|
482
|
+
|
|
483
|
+
Args:
|
|
484
|
+
module: Module name (e.g. "camera").
|
|
485
|
+
interface: Interface class whose Capabilities dataclass to fetch.
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
Deserialized Capabilities dataclass instance, or None if not published.
|
|
489
|
+
"""
|
|
490
|
+
return await self._get_capabilities(module, interface)
|
|
491
|
+
|
|
492
|
+
async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
493
|
+
return None
|
|
494
|
+
|
|
495
|
+
async def set_presence(self, state: ModuleState, error_string: str = "") -> None:
|
|
496
|
+
"""Publish presence for this module (module lifecycle state).
|
|
497
|
+
|
|
498
|
+
Called automatically by Module.set_state — not intended to be called
|
|
499
|
+
directly by module authors.
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
state: Current module lifecycle state.
|
|
503
|
+
error_string: Error message, used when state is ERROR.
|
|
504
|
+
"""
|
|
505
|
+
await self._set_presence(state, error_string)
|
|
506
|
+
|
|
507
|
+
async def _set_presence(self, state: ModuleState, error_string: str = "") -> None:
|
|
508
|
+
pass
|
|
509
|
+
|
|
510
|
+
def get_client_state(self, module: str) -> tuple[ModuleState, str] | None:
|
|
511
|
+
"""Return the last known presence state of a connected module.
|
|
512
|
+
|
|
513
|
+
Returns (ModuleState, error_string) or None if the module is not connected.
|
|
514
|
+
This replaces the old get_state()/get_error_string() RPC pattern.
|
|
515
|
+
"""
|
|
516
|
+
return self._get_client_state(module)
|
|
517
|
+
|
|
518
|
+
def _get_client_state(self, module: str) -> tuple[ModuleState, str] | None:
|
|
519
|
+
return None
|
|
520
|
+
|
|
445
521
|
async def subscribe_state(
|
|
446
522
|
self,
|
|
447
523
|
module: str,
|
|
@@ -491,6 +567,20 @@ class Comm:
|
|
|
491
567
|
) -> None:
|
|
492
568
|
pass
|
|
493
569
|
|
|
570
|
+
async def subscribe_presence(self, module: str, callback: PresenceCallback) -> None:
|
|
571
|
+
"""Subscribe to presence updates for a given module.
|
|
572
|
+
|
|
573
|
+
Delivers the current value immediately, then on every change.
|
|
574
|
+
|
|
575
|
+
Args:
|
|
576
|
+
module: Name of remote module.
|
|
577
|
+
callback: Called with (ModuleState, error_string) on each update.
|
|
578
|
+
"""
|
|
579
|
+
await self._subscribe_presence(module, callback)
|
|
580
|
+
|
|
581
|
+
async def _subscribe_presence(self, module: str, callback: PresenceCallback) -> None:
|
|
582
|
+
pass
|
|
583
|
+
|
|
494
584
|
def _send_event_to_module(self, event: Event, from_client: str) -> None:
|
|
495
585
|
"""Send an event to all connected modules.
|
|
496
586
|
|
|
@@ -34,9 +34,12 @@ class CommLoggingHandler(logging.Handler):
|
|
|
34
34
|
# format message
|
|
35
35
|
msg = self._formatter.format(rec) # noqa: UP031
|
|
36
36
|
|
|
37
|
-
# create and send event
|
|
37
|
+
# create and send event — use pyobs_module if set (MultiModule context)
|
|
38
38
|
time = datetime.fromtimestamp(rec.created, tz=UTC).strftime("%Y-%m-%dT%H:%M:%S.%f")
|
|
39
|
-
|
|
39
|
+
sender = getattr(rec, "pyobs_module", "") or ""
|
|
40
|
+
entry = LogEvent(
|
|
41
|
+
time, rec.levelname, os.path.basename(rec.pathname), rec.funcName, rec.lineno, msg, sender=sender
|
|
42
|
+
)
|
|
40
43
|
self._comm.log_message(entry)
|
|
41
44
|
|
|
42
45
|
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable, Coroutine
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from pyobs.comm import Comm
|
|
7
|
+
from pyobs.comm.comm import PresenceCallback
|
|
8
|
+
from pyobs.events import Event
|
|
9
|
+
from pyobs.interfaces import Interface
|
|
10
|
+
from pyobs.utils.enums import ModuleState
|
|
11
|
+
from pyobs.utils.types import cast_response_to_real
|
|
12
|
+
|
|
13
|
+
from .localnetwork import LocalNetwork
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class LocalComm(Comm):
|
|
17
|
+
def __init__(self, name: str, *args: Any, **kwargs: Any):
|
|
18
|
+
Comm.__init__(self, *args, **kwargs)
|
|
19
|
+
|
|
20
|
+
self._name = name
|
|
21
|
+
self._network = LocalNetwork()
|
|
22
|
+
self._network.connect_client(self)
|
|
23
|
+
|
|
24
|
+
# in-memory state and capabilities storage
|
|
25
|
+
self._states: dict[str, Any] = {} # node -> state object
|
|
26
|
+
self._state_handlers: dict[str, list[tuple[type[Interface], Callable[[Any], None]]]] = {}
|
|
27
|
+
self._capabilities: dict[type[Interface], Any] = {} # interface -> Capabilities object
|
|
28
|
+
self._presence: tuple[ModuleState, str] = (ModuleState.READY, "")
|
|
29
|
+
self._presence_callbacks: dict[str, list[PresenceCallback]] = {}
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def name(self) -> str:
|
|
33
|
+
"""Name of this client."""
|
|
34
|
+
return self._name
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def clients(self) -> list[str]:
|
|
38
|
+
"""Returns list of currently connected clients."""
|
|
39
|
+
return self._network.get_client_names()
|
|
40
|
+
|
|
41
|
+
async def get_interfaces(self, client: str) -> list[type[Interface]]:
|
|
42
|
+
"""Returns list of interfaces for given client."""
|
|
43
|
+
remote_client = self._network.get_client(client)
|
|
44
|
+
return [] if not remote_client.has_module else remote_client.module.interfaces
|
|
45
|
+
|
|
46
|
+
async def _supports_interface(self, client: str, interface: type[Interface]) -> bool:
|
|
47
|
+
"""Checks whether the given client supports the given interface."""
|
|
48
|
+
interfaces = await self.get_interfaces(client)
|
|
49
|
+
return interface in interfaces
|
|
50
|
+
|
|
51
|
+
async def execute(self, client: str, method: str, annotation: dict[str, Any], *args: Any) -> Any:
|
|
52
|
+
"""Execute a given method on a remote client."""
|
|
53
|
+
remote_client = self._network.get_client(client)
|
|
54
|
+
if remote_client.module is None:
|
|
55
|
+
raise ValueError
|
|
56
|
+
simple_results = await remote_client.module.execute(method, *args, sender=self.name)
|
|
57
|
+
real_results = cast_response_to_real(
|
|
58
|
+
simple_results, annotation["return"], self.cast_to_real_pre, self.cast_to_real_post
|
|
59
|
+
)
|
|
60
|
+
return real_results
|
|
61
|
+
|
|
62
|
+
async def send_event(self, event: Event) -> None:
|
|
63
|
+
"""Send an event to other clients."""
|
|
64
|
+
from pyobs.events import LogEvent as _LogEvent
|
|
65
|
+
|
|
66
|
+
sender = self.name
|
|
67
|
+
if isinstance(event, _LogEvent) and event.sender:
|
|
68
|
+
sender = event.sender
|
|
69
|
+
remote_clients = self._network.get_clients()
|
|
70
|
+
for client in remote_clients:
|
|
71
|
+
client._send_event_to_module(event, sender)
|
|
72
|
+
|
|
73
|
+
async def _register_events(
|
|
74
|
+
self, events: list[type[Event]], handler: Callable[[Event, str], Coroutine[Any, Any, bool]] | None = None
|
|
75
|
+
) -> None:
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
# -------------------------------------------------------------------------
|
|
79
|
+
# State
|
|
80
|
+
# -------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
async def _set_state(self, interface: type[Interface], state: Any) -> None:
|
|
83
|
+
"""Publish state locally and dispatch to subscribers."""
|
|
84
|
+
node = f"pyobs:state:{self._name}:{interface.__name__}:{interface.version}"
|
|
85
|
+
self._states[node] = state
|
|
86
|
+
|
|
87
|
+
# dispatch to all subscribers for this node
|
|
88
|
+
if node in self._state_handlers:
|
|
89
|
+
for _, callback in self._state_handlers[node]:
|
|
90
|
+
callback(state)
|
|
91
|
+
|
|
92
|
+
async def _subscribe_state(self, module: str, interface: type[Interface], callback: Callable[[Any], None]) -> None:
|
|
93
|
+
"""Subscribe to state updates from a remote module."""
|
|
94
|
+
node = f"pyobs:state:{module}:{interface.__name__}:{interface.version}"
|
|
95
|
+
|
|
96
|
+
if node not in self._state_handlers:
|
|
97
|
+
self._state_handlers[node] = []
|
|
98
|
+
self._state_handlers[node].append((interface, callback))
|
|
99
|
+
|
|
100
|
+
# also register on the remote comm so it can dispatch to us
|
|
101
|
+
try:
|
|
102
|
+
remote = self._network.get_client(module)
|
|
103
|
+
if node not in remote._state_handlers:
|
|
104
|
+
remote._state_handlers[node] = []
|
|
105
|
+
remote._state_handlers[node].append((interface, callback))
|
|
106
|
+
|
|
107
|
+
# deliver current value immediately if available
|
|
108
|
+
if node in remote._states:
|
|
109
|
+
callback(remote._states[node])
|
|
110
|
+
except KeyError:
|
|
111
|
+
pass # remote not connected yet
|
|
112
|
+
|
|
113
|
+
# -------------------------------------------------------------------------
|
|
114
|
+
# Capabilities
|
|
115
|
+
# -------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
async def _set_capabilities(self, interface: type[Interface], capabilities: Any) -> None:
|
|
118
|
+
"""Store capabilities locally."""
|
|
119
|
+
self._capabilities[interface] = capabilities
|
|
120
|
+
|
|
121
|
+
async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
|
|
122
|
+
"""Fetch capabilities from a remote module."""
|
|
123
|
+
if not hasattr(interface, "Capabilities"):
|
|
124
|
+
return None
|
|
125
|
+
try:
|
|
126
|
+
remote = self._network.get_client(module)
|
|
127
|
+
return remote._capabilities.get(interface)
|
|
128
|
+
except KeyError:
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
# -------------------------------------------------------------------------
|
|
132
|
+
# Presence
|
|
133
|
+
# -------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
async def _set_presence(self, state: ModuleState, error_string: str = "") -> None:
|
|
136
|
+
"""Store presence state and dispatch to all subscribers."""
|
|
137
|
+
self._presence = (state, error_string)
|
|
138
|
+
for client in self._network.get_clients():
|
|
139
|
+
for cb in client._presence_callbacks.get(self._name, []):
|
|
140
|
+
cb(state, error_string)
|
|
141
|
+
|
|
142
|
+
def _get_client_state(self, module: str) -> tuple[ModuleState, str] | None:
|
|
143
|
+
"""Return presence state of a connected module."""
|
|
144
|
+
try:
|
|
145
|
+
remote = self._network.get_client(module)
|
|
146
|
+
return remote._presence
|
|
147
|
+
except KeyError:
|
|
148
|
+
return None
|
|
149
|
+
|
|
150
|
+
async def _subscribe_presence(self, module: str, callback: PresenceCallback) -> None:
|
|
151
|
+
"""Register a presence callback and deliver the current state immediately."""
|
|
152
|
+
self._presence_callbacks.setdefault(module, []).append(callback)
|
|
153
|
+
try:
|
|
154
|
+
remote = self._network.get_client(module)
|
|
155
|
+
callback(*remote._presence)
|
|
156
|
+
except KeyError:
|
|
157
|
+
pass
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import inspect
|
|
4
5
|
import types
|
|
5
6
|
from collections.abc import Coroutine
|
|
@@ -169,6 +170,30 @@ class Proxy:
|
|
|
169
170
|
"""Latest known state for the given interface, or None if nothing has arrived yet."""
|
|
170
171
|
return self._state.get(interface)
|
|
171
172
|
|
|
173
|
+
async def wait_for_state(
|
|
174
|
+
self,
|
|
175
|
+
interface: type[Interface],
|
|
176
|
+
timeout: float = 10.0,
|
|
177
|
+
) -> Any:
|
|
178
|
+
"""Return state immediately if available, otherwise wait for the first update."""
|
|
179
|
+
if self._state.get(interface) is not None:
|
|
180
|
+
return self._state[interface]
|
|
181
|
+
|
|
182
|
+
event = asyncio.Event()
|
|
183
|
+
|
|
184
|
+
def _notify(state: Any) -> None:
|
|
185
|
+
self._state[interface] = state
|
|
186
|
+
event.set()
|
|
187
|
+
|
|
188
|
+
# patch in a one-shot notifier alongside the existing callback
|
|
189
|
+
await self._comm.subscribe_state(self._client, interface, _notify)
|
|
190
|
+
try:
|
|
191
|
+
await asyncio.wait_for(event.wait(), timeout=timeout)
|
|
192
|
+
finally:
|
|
193
|
+
await self._comm.unsubscribe_state(self._client, interface, _notify)
|
|
194
|
+
|
|
195
|
+
return self._state.get(interface)
|
|
196
|
+
|
|
172
197
|
|
|
173
198
|
class _ProxyContext(Generic[ProxyType]):
|
|
174
199
|
"""Returned by Comm.proxy() / Object.proxy() / Comm.safe_proxy(). Must be used as:
|