pyobs-core 2.0.0.dev4__tar.gz → 2.0.0.dev6__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.
Files changed (432) hide show
  1. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/PKG-INFO +2 -1
  2. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/application.py +22 -2
  3. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/cli/pyobsd.py +2 -2
  4. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/comm.py +20 -11
  5. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/local/localcomm.py +5 -1
  6. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/proxy.py +19 -4
  7. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/rpc.py +4 -4
  8. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/serializer.py +2 -2
  9. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009/binding.py +2 -2
  10. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xmppcomm.py +13 -8
  11. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/event.py +2 -0
  12. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/image.py +6 -4
  13. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/skyoffsets.py +3 -3
  14. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/annotation/_pillow.py +1 -1
  15. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/annotation/text.py +1 -1
  16. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/daophot.py +2 -2
  17. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/download.py +1 -1
  18. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/normalize.py +1 -1
  19. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/catalogcircularmask.py +1 -1
  20. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/modules/getfitsheaders.py +1 -1
  21. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/brighteststar.py +1 -1
  22. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/brighteststar_guiding.py +1 -1
  23. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/spilled_light.py +7 -6
  24. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/_photometry_calculator.py +2 -2
  25. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/wcs/solarhelioprojective.py +1 -1
  26. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IBinning.py +7 -5
  27. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IConfig.py +7 -6
  28. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IFilters.py +7 -5
  29. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IImageFormat.py +7 -5
  30. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IMode.py +7 -5
  31. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IModule.py +8 -5
  32. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IMultiFiber.py +7 -6
  33. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IVideo.py +7 -4
  34. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IWindow.py +10 -5
  35. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/__init__.py +18 -10
  36. pyobs_core-2.0.0.dev6/pyobs/interfaces/interface.py +27 -0
  37. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/camerasettings.py +3 -3
  38. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/fitsheader.py +1 -1
  39. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/follow.py +25 -7
  40. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/basecamera.py +1 -1
  41. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/basevideo.py +3 -3
  42. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/dummycamera.py +19 -5
  43. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/flatfield/flatfield.py +6 -3
  44. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/focus/focusmodel.py +12 -7
  45. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/focus/focusseries.py +14 -7
  46. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/image/imagewatcher.py +1 -1
  47. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/module.py +9 -10
  48. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/acquisition.py +21 -7
  49. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/autoguiding.py +6 -3
  50. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/robotic/scheduler.py +4 -4
  51. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/roof/basedome.py +3 -2
  52. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/telescope/dummytelescope.py +2 -1
  53. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/dummymode.py +2 -2
  54. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/kiosk.py +7 -4
  55. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/matrix.py +1 -1
  56. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/stellarium.py +2 -1
  57. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/telegram.py +1 -1
  58. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/object.py +1 -1
  59. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/observation.py +1 -1
  60. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/astroplanscheduler.py +3 -3
  61. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/timeconstraint.py +1 -1
  62. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/dataprovider.py +1 -1
  63. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/aftertime.py +1 -1
  64. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/beforetime.py +1 -1
  65. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/timewindow.py +1 -1
  66. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/ondemandscheduler.py +1 -1
  67. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/helioprojectiveradialarget.py +1 -1
  68. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/calibration/darkbias.py +5 -2
  69. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/calibration/pointing.py +2 -1
  70. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/calibration/skyflats.py +5 -3
  71. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/imaging/autofocus.py +3 -2
  72. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/imaging/imaging.py +12 -4
  73. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/filesystem/observationarchive.py +4 -4
  74. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/_portal.py +1 -1
  75. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/mockobservationarchive.py +1 -1
  76. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/scripts/autofocus.py +5 -3
  77. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/scripts/default.py +10 -4
  78. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/archive/pyobs_archive.py +1 -1
  79. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/exptime/stellarexptime.py +8 -3
  80. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/exptimeeval.py +4 -4
  81. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/flatfielder.py +11 -3
  82. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/scheduler.py +1 -1
  83. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/grids/filters.py +1 -1
  84. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/grids/grid.py +3 -3
  85. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/grids/pipeline.py +1 -1
  86. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/binningwidget.py +1 -1
  87. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/datadisplaywidget.py +6 -6
  88. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/exposewidget.py +7 -7
  89. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/exposuretimewidget.py +2 -2
  90. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/imageformatwidget.py +1 -1
  91. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/windowingwidget.py +4 -4
  92. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/influxdb.py +3 -3
  93. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/modulegui.py +1 -1
  94. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/offsets/applyaltazoffsets.py +4 -3
  95. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/offsets/applyoffsets.py +8 -4
  96. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/offsets/applyradecoffsets.py +4 -3
  97. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/serialization.py +1 -1
  98. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/time.py +2 -2
  99. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/httpfile.py +1 -1
  100. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/memfile.py +1 -1
  101. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/smbfile.py +1 -1
  102. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyproject.toml +2 -1
  103. pyobs_core-2.0.0.dev4/pyobs/interfaces/interface.py +0 -15
  104. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/.gitignore +0 -0
  105. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/LICENSE +0 -0
  106. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/__init__.py +0 -0
  107. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/background_task.py +0 -0
  108. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/cli/__init__.py +0 -0
  109. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/cli/_cli.py +0 -0
  110. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/cli/pyobs.py +0 -0
  111. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/cli/pyobsw.py +0 -0
  112. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/__init__.py +0 -0
  113. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/commlogging.py +0 -0
  114. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/dummy/__init__.py +0 -0
  115. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/dummy/dummycomm.py +0 -0
  116. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/local/__init__.py +0 -0
  117. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/local/localnetwork.py +0 -0
  118. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/__init__.py +0 -0
  119. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  120. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  121. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  122. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  123. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  124. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  125. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/comm/xmpp/xmppclient.py +0 -0
  126. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/__init__.py +0 -0
  127. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/badweather.py +0 -0
  128. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/exposurestatuschanged.py +0 -0
  129. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/filterchanged.py +0 -0
  130. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/focusfound.py +0 -0
  131. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/goodweather.py +0 -0
  132. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/log.py +0 -0
  133. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/modechanged.py +0 -0
  134. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/moduleclosed.py +0 -0
  135. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/moduleopened.py +0 -0
  136. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/motionstatuschanged.py +0 -0
  137. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/move.py +0 -0
  138. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/newimage.py +0 -0
  139. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/newspectrum.py +0 -0
  140. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/offsets.py +0 -0
  141. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/roofclosing.py +0 -0
  142. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/roofopened.py +0 -0
  143. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/taskfailed.py +0 -0
  144. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/taskfinished.py +0 -0
  145. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/taskstarted.py +0 -0
  146. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/events/testevent.py +0 -0
  147. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/__init__.py +0 -0
  148. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/__init__.py +0 -0
  149. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/altazoffsets.py +0 -0
  150. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/exptime.py +0 -0
  151. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/genericoffset.py +0 -0
  152. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/onskydistance.py +0 -0
  153. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/pixeloffsets.py +0 -0
  154. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/meta/radecoffsets.py +0 -0
  155. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processor.py +0 -0
  156. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/__init__.py +0 -0
  157. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  158. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/annotation/__init__.py +0 -0
  159. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/annotation/circle.py +0 -0
  160. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/annotation/crosshair.py +0 -0
  161. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/__init__.py +0 -0
  162. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  163. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  164. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  165. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  166. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  167. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  168. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/calibration/__init__.py +0 -0
  169. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  170. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  171. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/calibration/calibration.py +0 -0
  172. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/__init__.py +0 -0
  173. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  174. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  175. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/pysep.py +0 -0
  176. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/simpledisk.py +0 -0
  177. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  178. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/exptime/__init__.py +0 -0
  179. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/exptime/exptime.py +0 -0
  180. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/exptime/star.py +0 -0
  181. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/__init__.py +0 -0
  182. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  183. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/flip.py +0 -0
  184. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/grayscale.py +0 -0
  185. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/httpserver.py +0 -0
  186. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/save.py +0 -0
  187. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/saveimage.py +0 -0
  188. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/smooth.py +0 -0
  189. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/image/softbin.py +0 -0
  190. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/__init__.py +0 -0
  191. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/addmask.py +0 -0
  192. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/circularmask.py +0 -0
  193. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/createfilename.py +0 -0
  194. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  195. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/misc/removebackground.py +0 -0
  196. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/modules/__init__.py +0 -0
  197. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/__init__.py +0 -0
  198. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/astrometry.py +0 -0
  199. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  200. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  201. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  202. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/offsets.py +0 -0
  203. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  204. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/offsets/projected.py +0 -0
  205. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/__init__.py +0 -0
  206. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  207. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  208. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  209. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/photometry.py +0 -0
  210. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/photutil.py +0 -0
  211. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/photometry/pysep.py +0 -0
  212. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/images/processors/wcs/__init__.py +0 -0
  213. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IAbortable.py +0 -0
  214. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IAcquisition.py +0 -0
  215. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IAutoFocus.py +0 -0
  216. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IAutoGuiding.py +0 -0
  217. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IAutonomous.py +0 -0
  218. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ICalibrate.py +0 -0
  219. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ICamera.py +0 -0
  220. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ICooling.py +0 -0
  221. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IData.py +0 -0
  222. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IDome.py +0 -0
  223. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IExposure.py +0 -0
  224. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IExposureTime.py +0 -0
  225. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  226. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  227. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IFlatField.py +0 -0
  228. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IFocusModel.py +0 -0
  229. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IFocuser.py +0 -0
  230. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IGain.py +0 -0
  231. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IImageType.py +0 -0
  232. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IMotion.py +0 -0
  233. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  234. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  235. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IPointingAltAz.py +0 -0
  236. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IPointingHGS.py +0 -0
  237. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  238. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IPointingRaDec.py +0 -0
  239. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IPointingSeries.py +0 -0
  240. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IReady.py +0 -0
  241. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IRoof.py +0 -0
  242. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IRotation.py +0 -0
  243. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IRunnable.py +0 -0
  244. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IRunning.py +0 -0
  245. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IScriptRunner.py +0 -0
  246. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ISpectrograph.py +0 -0
  247. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IStartStop.py +0 -0
  248. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ISyncTarget.py +0 -0
  249. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ITelescope.py +0 -0
  250. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/ITemperatures.py +0 -0
  251. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/interfaces/IWeather.py +0 -0
  252. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/__init__.py +0 -0
  253. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/fitsnamespace.py +0 -0
  254. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/motionstatus.py +0 -0
  255. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/pipeline.py +0 -0
  256. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/waitformotion.py +0 -0
  257. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/mixins/weatheraware.py +0 -0
  258. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/__init__.py +0 -0
  259. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/__init__.py +0 -0
  260. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/adaptive.py +0 -0
  261. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/basespectrograph.py +0 -0
  262. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  263. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/dummyvideo.py +0 -0
  264. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/camera/pipelinecamera.py +0 -0
  265. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/flatfield/__init__.py +0 -0
  266. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/flatfield/pointing.py +0 -0
  267. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/flatfield/scheduler.py +0 -0
  268. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/focus/__init__.py +0 -0
  269. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/image/__init__.py +0 -0
  270. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/image/imagewriter.py +0 -0
  271. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/image/pipeline.py +0 -0
  272. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/image/seeing.py +0 -0
  273. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/__init__.py +0 -0
  274. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/_base.py +0 -0
  275. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/_baseguiding.py +0 -0
  276. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  277. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/dummyguiding.py +0 -0
  278. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  279. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  280. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  281. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  282. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  283. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  284. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/robotic/__init__.py +0 -0
  285. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/robotic/mastermind.py +0 -0
  286. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/robotic/pointing.py +0 -0
  287. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/robotic/scriptrunner.py +0 -0
  288. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/roof/__init__.py +0 -0
  289. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/roof/baseroof.py +0 -0
  290. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/roof/dummyroof.py +0 -0
  291. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/telescope/__init__.py +0 -0
  292. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/telescope/basetelescope.py +0 -0
  293. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/test/__init__.py +0 -0
  294. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/test/standalone.py +0 -0
  295. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/__init__.py +0 -0
  296. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/autonomouswarning.py +0 -0
  297. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/fluentlogger.py +0 -0
  298. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/httpfilecache.py +0 -0
  299. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/utils/trigger.py +0 -0
  300. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/weather/__init__.py +0 -0
  301. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/weather/weather.py +0 -0
  302. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/weather/weather_api.py +0 -0
  303. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/modules/weather/weather_state.py +0 -0
  304. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/py.typed +0 -0
  305. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/__init__.py +0 -0
  306. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/__init__.py +0 -0
  307. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  308. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  309. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  310. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  311. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  312. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  313. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  314. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  315. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  316. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  317. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  318. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  319. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/random.py +0 -0
  320. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  321. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  322. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  323. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  324. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  325. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  326. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  327. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  328. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/targets/target.py +0 -0
  329. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  330. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/__init__.py +0 -0
  331. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  332. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/control/__init__.py +0 -0
  333. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/control/cases.py +0 -0
  334. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/control/conditional.py +0 -0
  335. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/control/parallel.py +0 -0
  336. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/control/selector.py +0 -0
  337. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/control/sequential.py +0 -0
  338. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  339. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  340. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/script.py +0 -0
  341. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  342. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  343. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  344. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/scripts/utils/log.py +0 -0
  345. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/__init__.py +0 -0
  346. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/backend/__init__.py +0 -0
  347. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  348. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  349. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  350. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  351. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/__init__.py +0 -0
  352. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  353. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  354. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/configdb.py +0 -0
  355. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  356. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  357. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  358. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/task.py +0 -0
  359. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  360. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  361. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/memory/__init__.py +0 -0
  362. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  363. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  364. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/observationarchive.py +0 -0
  365. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/storage/taskarchive.py +0 -0
  366. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/task.py +0 -0
  367. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/taskrunner.py +0 -0
  368. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/__init__.py +0 -0
  369. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/archive/__init__.py +0 -0
  370. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/archive/archive.py +0 -0
  371. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  372. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  373. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  374. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  375. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  376. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  377. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  378. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  379. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  380. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  381. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  382. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/__init__.py +0 -0
  383. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/average.py +0 -0
  384. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/cache.py +0 -0
  385. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/config.py +0 -0
  386. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/coordinates.py +0 -0
  387. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/curvefit.py +0 -0
  388. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/enums.py +0 -0
  389. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/exceptions.py +0 -0
  390. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/fits.py +0 -0
  391. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/focusseries/__init__.py +0 -0
  392. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/focusseries/base.py +0 -0
  393. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/focusseries/photometry.py +0 -0
  394. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/focusseries/projection.py +0 -0
  395. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/grids/__init__.py +0 -0
  396. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/grids/gridnode.py +0 -0
  397. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/__init__.py +0 -0
  398. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/__init__.py +0 -0
  399. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  400. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/http.py +0 -0
  401. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/logger.py +0 -0
  402. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/logging/__init__.py +0 -0
  403. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/logging/context.py +0 -0
  404. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/logging/resolvableerror.py +0 -0
  405. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/offsets/__init__.py +0 -0
  406. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/parallel.py +0 -0
  407. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/pipeline/__init__.py +0 -0
  408. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/pipeline/night.py +0 -0
  409. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/pipeline/pipeline.py +0 -0
  410. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/publisher/__init__.py +0 -0
  411. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/publisher/csv.py +0 -0
  412. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/publisher/http.py +0 -0
  413. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/publisher/log.py +0 -0
  414. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/publisher/multi.py +0 -0
  415. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/publisher/publisher.py +0 -0
  416. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/shellcommand.py +0 -0
  417. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/threads/__init__.py +0 -0
  418. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/threads/lockwithabort.py +0 -0
  419. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/utils/types.py +0 -0
  420. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/version.py +0 -0
  421. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/__init__.py +0 -0
  422. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/archivefile.py +0 -0
  423. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/bufferedfile.py +0 -0
  424. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/file.py +0 -0
  425. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/filelists/__init__.py +0 -0
  426. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/filelists/filelist.py +0 -0
  427. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/filelists/testing.py +0 -0
  428. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/localfile.py +0 -0
  429. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/sftpfile.py +0 -0
  430. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/sshfile.py +0 -0
  431. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/tempfile.py +0 -0
  432. {pyobs_core-2.0.0.dev4 → pyobs_core-2.0.0.dev6}/pyobs/vfs/vfs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobs-core
3
- Version: 2.0.0.dev4
3
+ Version: 2.0.0.dev6
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -8,6 +8,7 @@ License-File: LICENSE
8
8
  Requires-Python: >=3.11
9
9
  Requires-Dist: aiohttp<4,>=3.11.18
10
10
  Requires-Dist: astroplan<0.11,>=0.10.1
11
+ Requires-Dist: astropy-iers-data>=0.2026.6.22.1.23.34
11
12
  Requires-Dist: astropy<8,>=7.0.1
12
13
  Requires-Dist: astropydantic>=0.0.5
13
14
  Requires-Dist: astroquery<0.5,>=0.4.10
@@ -19,6 +19,26 @@ from pyobs.utils.logging.context import ModuleNameFilter
19
19
  log = logging.getLogger(__name__)
20
20
 
21
21
 
22
+ # --- IERS offline fallback ---------------------------------------------
23
+ # When PYOBS_IERS_OFFLINE=1, skip live IERS/USNO downloads and rely on the
24
+ # astropy-iers-data snapshot bundled with the installed astropy package.
25
+ # Useful when the upstream IERS servers are down/unreachable, or when
26
+ # running on a telescope control machine without outbound internet access.
27
+ if os.environ.get("PYOBS_IERS_OFFLINE", "").lower() in ("1", "true", "yes"):
28
+ from astropy.utils.iers import conf as iers_conf
29
+
30
+ iers_conf.auto_download = False
31
+ iers_conf.auto_max_age = None
32
+ iers_conf.iers_degraded_accuracy = "warn"
33
+
34
+ log.warning(
35
+ "PYOBS_IERS_OFFLINE is set — disabling IERS auto-download and "
36
+ "relying on the bundled astropy-iers-data snapshot. Earth "
37
+ "orientation/UT1-UTC accuracy may degrade for predictions far "
38
+ "from the snapshot date."
39
+ )
40
+ # -------------------------------------------------------------------------
41
+
22
42
  # turn RuntimeWarnings into errors
23
43
  warnings.filterwarnings("error", category=RuntimeWarning)
24
44
 
@@ -89,9 +109,9 @@ class Application:
89
109
 
90
110
  # systemd journal handler?
91
111
  if syslog:
92
- from logging_journald import JournaldLogHandler # type: ignore[import-untyped]
112
+ from logging_journald import JournaldLogHandler
93
113
 
94
- class PyobsJournaldLogHandler(JournaldLogHandler): # type: ignore[misc]
114
+ class PyobsJournaldLogHandler(JournaldLogHandler):
95
115
  """JournaldLogHandler that adds SYSLOG_IDENTIFIER=pyobs and PYOBS_MODULE per record."""
96
116
 
97
117
  def __init__(self, **kw: Any) -> None:
@@ -340,9 +340,9 @@ class PyobsDaemon:
340
340
  stdout, stderr = proc.communicate(timeout=2)
341
341
  print(f"Warning: {module} launched but PID not confirmed.")
342
342
  if stdout:
343
- print(f" stdout: {stdout.decode(errors='replace').strip()}")
343
+ print(f" stdout: {stdout.decode(errors='replace').strip()}") # type: ignore[attr-defined]
344
344
  if stderr:
345
- print(f" stderr: {stderr.decode(errors='replace').strip()}")
345
+ print(f" stderr: {stderr.decode(errors='replace').strip()}") # type: ignore[attr-defined]
346
346
 
347
347
  def _stop_service(self, module: str) -> None:
348
348
  pid = self._running_pid(module)
@@ -4,7 +4,6 @@ import asyncio
4
4
  import functools
5
5
  import inspect
6
6
  import logging
7
- import sys
8
7
  from collections.abc import Callable, Coroutine
9
8
  from typing import TYPE_CHECKING, Any, overload
10
9
 
@@ -132,12 +131,20 @@ class Comm:
132
131
  except IndexError:
133
132
  return None
134
133
 
134
+ # collect capabilities (fixed at proxy construction time)
135
+ capabilities: dict[type[Interface], Any] = {}
136
+ for interface in interfaces:
137
+ if interface.capabilities is not None:
138
+ cap = await self._get_capabilities(client, interface)
139
+ if cap is not None:
140
+ capabilities[interface] = cap
141
+
135
142
  # create new proxy
136
- proxy = Proxy(self, client, interfaces)
143
+ proxy = Proxy(self, client, interfaces, capabilities)
137
144
 
138
145
  # subscribe to state
139
146
  for interface in interfaces:
140
- if getattr(interface, "State", None) is not None:
147
+ if interface.state is not None:
141
148
  await self.subscribe_state(client, interface, functools.partial(proxy.update_state, interface))
142
149
 
143
150
  self._proxies[client] = proxy
@@ -450,22 +457,17 @@ class Comm:
450
457
  async def _set_state(self, interface: type[Interface], state: Any) -> None:
451
458
  pass
452
459
 
453
- @staticmethod
454
- def _interface_from_capabilities(caps_cls: type) -> type:
455
- outer_name = caps_cls.__qualname__.rsplit(".", 1)[0]
456
- return getattr(sys.modules[caps_cls.__module__], outer_name)
457
-
458
- async def set_capabilities(self, capabilities: Any) -> None:
460
+ async def set_capabilities(self, interface: type[Interface], capabilities: Any) -> None:
459
461
  """Publish capabilities for this module.
460
462
 
461
- Called by Module.open() for each interface that defines a Capabilities
463
+ Called by Module.open() for each interface that defines a capabilities
462
464
  dataclass. Not intended to be called directly by module authors after
463
465
  that point — capabilities are fixed for the module lifetime.
464
466
 
465
467
  Args:
468
+ interface: Interface type the capabilities belong to.
466
469
  capabilities: Capabilities dataclass instance.
467
470
  """
468
- interface = Comm._interface_from_capabilities(type(capabilities))
469
471
  await self._set_capabilities(interface, capabilities)
470
472
 
471
473
  async def _set_capabilities(self, interface: type[Interface], capabilities: Any) -> None:
@@ -512,6 +514,13 @@ class Comm:
512
514
  def _get_client_state(self, module: str) -> tuple[ModuleState, str] | None:
513
515
  return None
514
516
 
517
+ def get_own_state(self, interface: type[Interface]) -> Any:
518
+ """Return the last state published by this module for the given interface, or None."""
519
+ return self._get_own_state(interface)
520
+
521
+ def _get_own_state(self, interface: type[Interface]) -> Any:
522
+ return None
523
+
515
524
  async def subscribe_state(
516
525
  self,
517
526
  module: str,
@@ -79,6 +79,10 @@ class LocalComm(Comm):
79
79
  # State
80
80
  # -------------------------------------------------------------------------
81
81
 
82
+ def _get_own_state(self, interface: type[Interface]) -> Any:
83
+ node = f"pyobs:state:{self._name}:{interface.__name__}:{interface.version}"
84
+ return self._states.get(node)
85
+
82
86
  async def _set_state(self, interface: type[Interface], state: Any) -> None:
83
87
  """Publish state locally and dispatch to subscribers."""
84
88
  node = f"pyobs:state:{self._name}:{interface.__name__}:{interface.version}"
@@ -120,7 +124,7 @@ class LocalComm(Comm):
120
124
 
121
125
  async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
122
126
  """Fetch capabilities from a remote module."""
123
- if not hasattr(interface, "Capabilities"):
127
+ if interface.capabilities is None:
124
128
  return None
125
129
  try:
126
130
  remote = self._network.get_client(module)
@@ -21,13 +21,20 @@ class Proxy:
21
21
 
22
22
  __module__ = "pyobs.comm"
23
23
 
24
- def __init__(self, comm: Comm, client: str, interfaces: list[type[Interface]]):
24
+ def __init__(
25
+ self,
26
+ comm: Comm,
27
+ client: str,
28
+ interfaces: list[type[Interface]],
29
+ capabilities: dict[type[Interface], Any] | None = None,
30
+ ):
25
31
  """Creates a new proxy.
26
32
 
27
33
  Args:
28
34
  comm: Comm object to use for connection.
29
35
  client: Name of client to connect to.
30
36
  interfaces: List of interfaces supported by client.
37
+ capabilities: Pre-populated capabilities dict, keyed by interface type.
31
38
  """
32
39
 
33
40
  # set client and interfaces
@@ -48,13 +55,14 @@ class Proxy:
48
55
 
49
56
  # add interfaces as base classes
50
57
  cls = self.__class__
51
- self.__class__ = cls.__class__("Proxy", tuple([cls] + interfaces), {}) # type: ignore
58
+ self.__class__ = type("Proxy", tuple([cls] + interfaces), {})
52
59
 
53
60
  # create methods
54
61
  self._methods = self._create_methods()
55
62
 
56
- # store state
63
+ # store state and capabilities
57
64
  self._state: dict[type[Interface], Any] = {}
65
+ self._capabilities: dict[type[Interface], Any] = capabilities if capabilities is not None else {}
58
66
 
59
67
  @property
60
68
  def name(self) -> str:
@@ -131,6 +139,9 @@ class Proxy:
131
139
  for interface in self._interfaces:
132
140
  # loop all methods:
133
141
  for func_name, func in inspect.getmembers(interface, predicate=inspect.isfunction):
142
+ # skip base Interface infrastructure methods — Proxy provides its own implementations
143
+ if func_name in Interface.__dict__:
144
+ continue
134
145
  # set method
135
146
  my_func = types.MethodType(self._remote_function_wrapper(func_name), self)
136
147
  setattr(self, func_name, my_func)
@@ -166,10 +177,14 @@ class Proxy:
166
177
  """Clear all cached state. Called by Comm when the remote module disconnects."""
167
178
  self._state.clear()
168
179
 
169
- def state(self, interface: type[Interface]) -> Any | None:
180
+ def get_state(self, interface: type[Interface]) -> Any | None:
170
181
  """Latest known state for the given interface, or None if nothing has arrived yet."""
171
182
  return self._state.get(interface)
172
183
 
184
+ def get_capabilities(self, interface: type[Interface]) -> Any | None:
185
+ """Capabilities for the given interface, populated once at Proxy construction."""
186
+ return self._capabilities.get(interface)
187
+
173
188
  async def wait_for_state(
174
189
  self,
175
190
  interface: type[Interface],
@@ -115,8 +115,8 @@ def xml_to_fault(fault_elem: ET.Element) -> tuple[str, str]:
115
115
  return "RemoteError", "Unknown error"
116
116
  exc_el = pyobs_fault.find("exception")
117
117
  msg_el = pyobs_fault.find("message")
118
- exc_name = exc_el.text if exc_el is not None else "RemoteError"
119
- msg = msg_el.text if msg_el is not None else ""
118
+ exc_name = (exc_el.text if exc_el is not None else None) or "RemoteError"
119
+ msg = (msg_el.text if msg_el is not None else None) or ""
120
120
  return exc_name, msg
121
121
 
122
122
 
@@ -201,7 +201,7 @@ class RPC:
201
201
  if hasattr(method, "timeout"):
202
202
  timeout = await getattr(method, "timeout")(self._handler, **ba.arguments)
203
203
  if timeout:
204
- response = self._client.plugin["xep_0009_timeout"].make_iq_method_timeout(
204
+ response = self._client.plugin["xep_0009_timeout"].make_iq_method_timeout( # type: ignore[typeddict-item]
205
205
  iq["id"], iq["from"], int(timeout)
206
206
  )
207
207
  response.send()
@@ -272,7 +272,7 @@ class RPC:
272
272
  if issubclass(exception_class, exc.RemoteError):
273
273
  exception = exception_class(message=msg, module=sender)
274
274
  else:
275
- exception = exception_class(message=msg)
275
+ exception = exception_class(msg)
276
276
 
277
277
  if not future.done():
278
278
  future.set_exception(exc.InvocationError(module=sender, exception=exception))
@@ -174,10 +174,10 @@ def xml_to_value(elem: ET.Element, type_hint: Any) -> Any:
174
174
  return elem.text == "true"
175
175
 
176
176
  if tag == "int":
177
- return int(elem.text)
177
+ return int(elem.text) if elem.text is not None else 0
178
178
 
179
179
  if tag == "double":
180
- return float(elem.text)
180
+ return float(elem.text) if elem.text is not None else 0.0
181
181
 
182
182
  if tag == "string":
183
183
  text = elem.text or ""
@@ -42,7 +42,7 @@ def py2xml(*args: Any) -> ET.Element:
42
42
  return params
43
43
 
44
44
 
45
- def _py2xml(*args: Any) -> ET.Element:
45
+ def _py2xml(*args: Any) -> ET.Element: # type: ignore[return]
46
46
  for x in args:
47
47
  val = ET.Element(f"{{{_namespace}}}value")
48
48
  if x is None:
@@ -100,7 +100,7 @@ def xml2py(params: ET.Element) -> list[Any]:
100
100
  return vals
101
101
 
102
102
 
103
- def _xml2py(value: ET) -> Any:
103
+ def _xml2py(value: Any) -> Any:
104
104
  namespace = "jabber:iq:rpc"
105
105
  find_value = value.find
106
106
  if find_value(f"{{{namespace}}}nil") is not None:
@@ -185,6 +185,7 @@ class XmppComm(Comm):
185
185
  self._state_node_handlers: dict[str, tuple[type[Interface], list[Callable[[Any], None]]]] = {}
186
186
  self._client_states: dict[str, tuple[ModuleState, str]] = {} # jid -> (state, error_string)
187
187
  self._capabilities: dict[type, Any] = {} # interface → Capabilities instance
188
+ self._own_states: dict[type, Any] = {} # interface → last published state for this module
188
189
  self._presence_callbacks: dict[str, list[Callable[[ModuleState, str], None]]] = {}
189
190
 
190
191
  def _set_module(self, module: Module) -> None:
@@ -273,7 +274,7 @@ class XmppComm(Comm):
273
274
 
274
275
  # connect
275
276
  await self._xmpp.connect(host=server, port=port)
276
- self._xmpp.init_plugins() # type: ignore
277
+ self._xmpp.init_plugins()
277
278
 
278
279
  # wait for connected
279
280
  if not await self._xmpp.wait_connect():
@@ -657,7 +658,7 @@ class XmppComm(Comm):
657
658
  interface, callbacks = self._state_node_handlers[node]
658
659
  item_xml = items_xml.find(f"{{{pubsub_ns}}}item")
659
660
  payload = list(item_xml)[0] if item_xml is not None and len(item_xml) > 0 else None
660
- if payload is not None:
661
+ if payload is not None and interface.state is not None:
661
662
  state_obj = _xml_to_dataclass(payload, interface.state)
662
663
  for callback in callbacks:
663
664
  callback(state_obj)
@@ -727,7 +728,7 @@ class XmppComm(Comm):
727
728
  await asyncio.sleep(self._safe_send_wait)
728
729
 
729
730
  # never should reach this
730
- raise slixmpp.exceptions.IqTimeout(iq) # type: ignore
731
+ raise slixmpp.exceptions.IqTimeout(iq)
731
732
 
732
733
  def cast_to_simple_pre(self, value: Any, annotation: Any | None = None) -> tuple[bool, Any]:
733
734
  """Special treatment of single parameters when converting them to be sent via Comm.
@@ -785,13 +786,17 @@ class XmppComm(Comm):
785
786
  items_xml = pubsub_xml.find(f"{{{pubsub_ns}}}items") if pubsub_xml is not None else None
786
787
  item_xml = items_xml.find(f"{{{pubsub_ns}}}item") if items_xml is not None else None
787
788
  payload = list(item_xml)[0] if item_xml is not None and len(item_xml) > 0 else None
788
- if payload is not None:
789
+ if payload is not None and interface.state is not None:
789
790
  callback(_xml_to_dataclass(payload, interface.state))
790
791
  except (slixmpp.exceptions.IqError, slixmpp.exceptions.IqTimeout):
791
792
  pass
792
793
 
794
+ def _get_own_state(self, interface: type[Interface]) -> Any:
795
+ return self._own_states.get(interface)
796
+
793
797
  async def _set_state(self, interface: type[Interface], state: Any) -> None:
794
- node = self._state_node(self._module.name, interface)
798
+ self._own_states[interface] = state
799
+ node = self._state_node(self._module.name, interface) # type: ignore[union-attr]
795
800
  stanza = StateStanza()
796
801
  stanza.xml = _dataclass_to_xml(state, self._state_namespace(interface))
797
802
  await self._safe_send(self.client["xep_0060"].publish, self._pubsub_service, node, payload=stanza)
@@ -828,7 +833,7 @@ class XmppComm(Comm):
828
833
 
829
834
  async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
830
835
  """Fetch and deserialize capabilities for a remote module's interface."""
831
- if not hasattr(interface, "Capabilities"):
836
+ if interface.capabilities is None:
832
837
  return None
833
838
  # Use full JID (with resource) if we know it — bare JID may not route correctly
834
839
  full_jid = next(
@@ -848,7 +853,7 @@ class XmppComm(Comm):
848
853
  for elem in child:
849
854
  tag = elem.tag.split("}")[-1]
850
855
  if tag == "capabilities" and f"{{{ns}}}" in elem.tag:
851
- return _xml_to_dataclass(elem, interface.Capabilities)
856
+ return _xml_to_dataclass(elem, interface.capabilities)
852
857
  return None
853
858
 
854
859
  async def _set_presence(self, state: ModuleState, error_string: str = "") -> None:
@@ -900,7 +905,7 @@ class XmppComm(Comm):
900
905
  items_xml = pubsub_xml.find(f"{{{pubsub_ns}}}items") if pubsub_xml is not None else None
901
906
  item_xml = items_xml.find(f"{{{pubsub_ns}}}item") if items_xml is not None else None
902
907
  payload = list(item_xml)[0] if item_xml is not None and len(item_xml) > 0 else None
903
- if payload is not None and node in self._state_node_handlers:
908
+ if payload is not None and node in self._state_node_handlers and interface.state is not None:
904
909
  _, callbacks = self._state_node_handlers[node]
905
910
  state_obj = _xml_to_dataclass(payload, interface.state)
906
911
  for cb in callbacks:
@@ -52,6 +52,8 @@ class EventFactory:
52
52
  # create class
53
53
  cls: Event | None = None
54
54
  for p in EventFactory.packages:
55
+ if p is None:
56
+ continue
55
57
  # import package
56
58
  parts = p.split(".")
57
59
  pkg = __import__(parts[0])
@@ -403,11 +403,13 @@ class Image:
403
403
  # import PIL Image
404
404
  import PIL.Image
405
405
 
406
- # copy data
407
- data: NDArray[Any] = np.copy(self._data) # type: ignore
408
- if data is None:
406
+ # check data
407
+ if self._data is None:
409
408
  raise ValueError("No data in image.")
410
409
 
410
+ # copy data
411
+ data: NDArray[Any] = np.copy(self._data)
412
+
411
413
  # no vmin/vmax?
412
414
  if vmin is None or vmax is None:
413
415
  flattened = sorted(data.flatten())
@@ -569,7 +571,7 @@ class Image:
569
571
  @property
570
572
  def meta(self) -> dict[Any, Any]:
571
573
  if self._meta is None:
572
- self._meta = {}
574
+ self._meta = {} # type: ignore[assignment]
573
575
  return self._meta
574
576
 
575
577
  @meta.setter
@@ -8,7 +8,7 @@ class SkyOffsets:
8
8
  self.coord0 = coord0
9
9
  self.coord1 = coord1
10
10
 
11
- def separation(self, frame: BaseCoordinateFrame = None) -> Angle:
11
+ def separation(self, frame: BaseCoordinateFrame | None = None) -> Angle:
12
12
  """Returns separatation between both coordinates, either in their own or a given frame.
13
13
 
14
14
  Args:
@@ -22,7 +22,7 @@ class SkyOffsets:
22
22
  coord0, coord1 = self._to_frame(frame)
23
23
  return coord0.separation(coord1)
24
24
 
25
- def spherical_offsets(self, frame: BaseCoordinateFrame = None) -> tuple[Angle, Angle]:
25
+ def spherical_offsets(self, frame: BaseCoordinateFrame | None = None) -> tuple[Angle, Angle]:
26
26
  """Calculates spherical offset from first coordinate to second.
27
27
 
28
28
  Args:
@@ -37,7 +37,7 @@ class SkyOffsets:
37
37
  off0, off1 = coord0.spherical_offsets_to(coord1.frame)
38
38
  return off0, off1
39
39
 
40
- def _to_frame(self, frame: BaseCoordinateFrame = None) -> tuple[SkyCoord, SkyCoord]:
40
+ def _to_frame(self, frame: BaseCoordinateFrame | None = None) -> tuple[SkyCoord, SkyCoord]:
41
41
  """
42
42
 
43
43
  Args:
@@ -29,7 +29,7 @@ class PillowHelper:
29
29
  @staticmethod
30
30
  def value(image: Image, value: float | int | str) -> float | int:
31
31
  if isinstance(value, str):
32
- return image.header[value] # type: ignore
32
+ return image.header[value]
33
33
  return value
34
34
 
35
35
  @staticmethod
@@ -188,7 +188,7 @@ class Text(ImageProcessor):
188
188
  x, y = PillowHelper.position(image, self._x, self._y, self._wcs)
189
189
  fill = PillowHelper.color(self._fill)
190
190
  try:
191
- text = self._text.format(**image.header) # noqa: UP031
191
+ text = self._text.format(**image.header) # noqa: UP031 # type: ignore[arg-type]
192
192
  except KeyError:
193
193
  text = self._text
194
194
 
@@ -142,7 +142,7 @@ class DaophotSourceDetection(SourceDetection):
142
142
  daofind = DAOStarFinder(fwhm=self.fwhm, threshold=self.threshold * std)
143
143
 
144
144
  loop = asyncio.get_running_loop()
145
- return await loop.run_in_executor(None, daofind, data)
145
+ return await loop.run_in_executor(None, daofind, data) # type: ignore[arg-type]
146
146
 
147
147
  async def __call__(self, image: Image) -> Image:
148
148
  """Find stars in given image and append catalog.
@@ -164,7 +164,7 @@ class DaophotSourceDetection(SourceDetection):
164
164
  _, median, std = sigma_clipped_stats(background_corrected_data, sigma=3.0)
165
165
 
166
166
  median_corrected_data = background_corrected_data - median
167
- sources = await self._find_stars(median_corrected_data, std)
167
+ sources = await self._find_stars(median_corrected_data, int(std))
168
168
 
169
169
  sources_catalog = _SourceCatalog.from_table(sources)
170
170
  sources_catalog.apply_fits_origin_convention()
@@ -37,7 +37,7 @@ class EncodedImageConverter(ImageConverter):
37
37
  # move axis
38
38
  data = np.moveaxis(data, 2, 0)
39
39
 
40
- image = Image(data=data) # type: ignore
40
+ image = Image(data=data)
41
41
  image.header["DATE-OBS"] = datetime.now().isoformat()
42
42
  image.header["EXPTIME"] = 0
43
43
 
@@ -118,7 +118,7 @@ class Normalize(ImageProcessor):
118
118
  return image
119
119
 
120
120
  output_image = image.copy()
121
- output_image.data = ((output_image.data - vmin) / (vmax - vmin) * 255.0).astype(np.uint8)
121
+ output_image.data = ((output_image.data - vmin) / (vmax - vmin) * 255.0).astype(np.uint8) # type: ignore[assignment]
122
122
 
123
123
  return output_image
124
124
 
@@ -142,7 +142,7 @@ class CatalogCircularMask(ImageProcessor):
142
142
  if isinstance(self._center[0], str) and isinstance(self._center[1], str):
143
143
  return image.header[self._center[0]], image.header[self._center[1]]
144
144
  else:
145
- return self._center
145
+ return self._center # type: ignore[return-value]
146
146
 
147
147
 
148
148
  __all__ = ["CatalogCircularMask"]
@@ -103,7 +103,7 @@ class GetFitsHeaders(ImageProcessor):
103
103
  for sender in self._senders:
104
104
  # request headers
105
105
  async with self.proxy(sender, IFitsHeaderBefore) as proxy:
106
- requests.append(asyncio.create_task(proxy.get_fits_header_before(self._namespace)))
106
+ requests.append(asyncio.create_task(proxy.get_fits_header_before(self._namespace))) # type: ignore[arg-type]
107
107
 
108
108
  # copy image
109
109
  out = image.copy()
@@ -126,7 +126,7 @@ class BrightestStarOffsets(Offsets):
126
126
 
127
127
  @staticmethod
128
128
  def _get_brightest_star_position(catalog: Table) -> tuple[float, float]:
129
- brightest_star: Row = max(catalog, key=lambda row: row["flux"])
129
+ brightest_star: Row = max(catalog, key=lambda row: row["flux"]) # type: ignore[type-var]
130
130
  return brightest_star["x"], brightest_star["y"]
131
131
 
132
132
  @staticmethod
@@ -154,7 +154,7 @@ class BrightestStarGuiding(Offsets):
154
154
 
155
155
  @staticmethod
156
156
  def _get_brightest_star_position(catalog: Table) -> tuple[float, float]:
157
- brightest_star: Row = max(catalog, key=lambda row: row["flux"])
157
+ brightest_star: Row = max(catalog, key=lambda row: row["flux"]) # type: ignore[type-var]
158
158
  log.info("Found brightest star at x=%.2f, y=%.2f", brightest_star["x"], brightest_star["y"])
159
159
  return brightest_star["x"], brightest_star["y"]
160
160
 
@@ -79,8 +79,8 @@ class Ring:
79
79
  ny, nx = self.data.shape
80
80
  x, y = np.arange(0, nx), np.arange(0, ny)
81
81
  x_coordinates, y_coordinates = np.meshgrid(x, y)
82
- section_mask = (min_angle < self.get_angle_from_position(x_coordinates, y_coordinates)) & (
83
- max_angle > self.get_angle_from_position(x_coordinates, y_coordinates)
82
+ section_mask = (min_angle < self.get_angle_from_position(x_coordinates, y_coordinates)) & ( # type: ignore[call-overload]
83
+ max_angle > self.get_angle_from_position(x_coordinates, y_coordinates) # type: ignore[call-overload]
84
84
  )
85
85
  section = self.data.copy()
86
86
  section *= section_mask
@@ -251,8 +251,8 @@ class SpilledLightGuiding(Offsets):
251
251
  Offsets.__init__(self, **kwargs)
252
252
 
253
253
  self._fibers = fibers
254
- self._fibre_position: Any[tuple[float, float], None] = None
255
- self._inner_radius: Any[float, None] = None
254
+ self._fibre_position: tuple[float, float] = (0.0, 0.0)
255
+ self._inner_radius: float = 0.0
256
256
  self._radius_ratio = radius_ratio
257
257
  self._max_relative_sigma = max_relative_sigma
258
258
  self._section_angular_width = section_angular_width
@@ -300,8 +300,9 @@ class SpilledLightGuiding(Offsets):
300
300
 
301
301
  async def _load_fibre_information(self) -> None:
302
302
  async with self.comm.proxy(self._fibers, IMultiFiber) as proxy:
303
- self._fibre_position = await proxy.get_pixel_position()
304
- self._inner_radius = await proxy.get_radius()
303
+ fiber_state = proxy.get_state(IMultiFiber)
304
+ self._fibre_position = (fiber_state.pixel_x, fiber_state.pixel_y) if fiber_state is not None else (0.0, 0.0)
305
+ self._inner_radius = fiber_state.radius if fiber_state is not None else 0.0
305
306
 
306
307
  async def _correct_for_binning(self, binning: int) -> None:
307
308
  self._fibre_position = (self._fibre_position[0] / binning, self._fibre_position[1] / binning)
@@ -1,6 +1,6 @@
1
1
  from abc import ABCMeta, abstractmethod
2
2
 
3
- from astropy.table import QTable
3
+ from astropy.table import Table
4
4
 
5
5
  from pyobs.images import Image
6
6
 
@@ -10,7 +10,7 @@ class _PhotometryCalculator(metaclass=ABCMeta):
10
10
 
11
11
  @property
12
12
  @abstractmethod
13
- def catalog(self) -> QTable: ...
13
+ def catalog(self) -> Table | None: ...
14
14
 
15
15
  @abstractmethod
16
16
  def set_data(self, image: Image) -> None: ...
@@ -115,7 +115,7 @@ class SolarHelioprojective(ImageProcessor):
115
115
  Returns:
116
116
  Image with new WCS.
117
117
  """
118
- import sunpy.coordinates # type: ignore
118
+ import sunpy.coordinates
119
119
 
120
120
  obs_time = Time(image.header["DATE-OBS"], scale="utc")
121
121
  cdelt = sunpy.coordinates.sun.angular_radius(obs_time).degree / image.header[self._keyword_radius]
@@ -15,16 +15,18 @@ class BinningState:
15
15
  time: Time = field(default_factory=Time.now)
16
16
 
17
17
 
18
+ @dataclass
19
+ class BinningCapabilities:
20
+ binnings: list[BinningState] = field(default_factory=list)
21
+
22
+
18
23
  class IBinning(Interface, metaclass=ABCMeta):
19
24
  """The camera supports binning, to be used together with :class:`~pyobs.interfaces.ICamera`."""
20
25
 
21
26
  __module__ = "pyobs.interfaces"
22
27
 
23
28
  state = BinningState
24
-
25
- @dataclass
26
- class Capabilities:
27
- binnings: list[BinningState] = field(default_factory=list)
29
+ capabilities = BinningCapabilities
28
30
 
29
31
  @abstractmethod
30
32
  async def set_binning(self, x: int, y: int, **kwargs: Any) -> None:
@@ -40,4 +42,4 @@ class IBinning(Interface, metaclass=ABCMeta):
40
42
  ...
41
43
 
42
44
 
43
- __all__ = ["IBinning", "BinningState"]
45
+ __all__ = ["IBinning", "BinningState", "BinningCapabilities"]
@@ -7,16 +7,17 @@ from typing import Any
7
7
  from .interface import Interface
8
8
 
9
9
 
10
+ @dataclass
11
+ class ConfigCapabilities:
12
+ caps: dict[str, tuple[bool, bool, bool]] = field(default_factory=dict)
13
+
14
+
10
15
  class IConfig(Interface, metaclass=ABCMeta):
11
16
  """The module allows access to some of its configuration options."""
12
17
 
13
18
  __module__ = "pyobs.interfaces"
14
19
 
15
- @dataclass
16
- class Capabilities:
17
- readable: list[str] = field(default_factory=list)
18
- writable: list[str] = field(default_factory=list)
19
- options: dict[str, list[str]] = field(default_factory=dict)
20
+ capabilities = ConfigCapabilities
20
21
 
21
22
  @abstractmethod
22
23
  async def get_config_value(self, name: str, **kwargs: Any) -> Any:
@@ -47,4 +48,4 @@ class IConfig(Interface, metaclass=ABCMeta):
47
48
  ...
48
49
 
49
50
 
50
- __all__ = ["IConfig"]
51
+ __all__ = ["IConfig", "ConfigCapabilities"]