pyobs-core 2.0.0.dev5__tar.gz → 2.0.0.dev7__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.dev5 → pyobs_core-2.0.0.dev7}/PKG-INFO +2 -1
  2. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/application.py +22 -2
  3. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/cli/pyobsd.py +2 -2
  4. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/comm.py +7 -0
  5. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/local/localcomm.py +4 -0
  6. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/proxy.py +6 -3
  7. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/rpc.py +4 -4
  8. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/serializer.py +2 -2
  9. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009/binding.py +2 -2
  10. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xmppcomm.py +11 -6
  11. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/event.py +2 -0
  12. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/image.py +6 -4
  13. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/skyoffsets.py +3 -3
  14. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/annotation/_pillow.py +1 -1
  15. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/annotation/text.py +1 -1
  16. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/daophot.py +2 -2
  17. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/download.py +1 -1
  18. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/normalize.py +1 -1
  19. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/catalogcircularmask.py +1 -1
  20. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/modules/getfitsheaders.py +1 -1
  21. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/brighteststar.py +1 -1
  22. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/brighteststar_guiding.py +1 -1
  23. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/spilled_light.py +7 -6
  24. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/_photometry_calculator.py +2 -2
  25. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/wcs/solarhelioprojective.py +1 -1
  26. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/__init__.py +0 -3
  27. pyobs_core-2.0.0.dev7/pyobs/interfaces/interface.py +27 -0
  28. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/camerasettings.py +3 -3
  29. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/fitsheader.py +1 -1
  30. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/follow.py +25 -7
  31. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/basecamera.py +1 -1
  32. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/basevideo.py +1 -1
  33. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/dummycamera.py +4 -3
  34. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/flatfield/flatfield.py +6 -3
  35. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/focus/focusmodel.py +12 -7
  36. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/focus/focusseries.py +14 -7
  37. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/image/imagewatcher.py +1 -1
  38. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/module.py +3 -2
  39. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/acquisition.py +21 -7
  40. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/autoguiding.py +6 -3
  41. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/robotic/scheduler.py +4 -4
  42. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/roof/basedome.py +3 -2
  43. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/kiosk.py +7 -4
  44. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/matrix.py +1 -1
  45. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/stellarium.py +2 -1
  46. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/telegram.py +1 -1
  47. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/object.py +1 -1
  48. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/observation.py +1 -1
  49. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/astroplanscheduler.py +3 -3
  50. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/timeconstraint.py +1 -1
  51. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/dataprovider.py +1 -1
  52. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/aftertime.py +1 -1
  53. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/beforetime.py +1 -1
  54. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/timewindow.py +1 -1
  55. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/ondemandscheduler.py +1 -1
  56. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/helioprojectiveradialarget.py +1 -1
  57. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/calibration/darkbias.py +5 -2
  58. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/calibration/pointing.py +2 -1
  59. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/calibration/skyflats.py +5 -3
  60. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/imaging/autofocus.py +3 -2
  61. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/imaging/imaging.py +12 -4
  62. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/filesystem/observationarchive.py +4 -4
  63. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/_portal.py +1 -1
  64. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/mockobservationarchive.py +1 -1
  65. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/scripts/autofocus.py +5 -3
  66. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/scripts/default.py +10 -4
  67. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/archive/pyobs_archive.py +1 -1
  68. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/exptime/stellarexptime.py +8 -3
  69. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/exptimeeval.py +4 -4
  70. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/flatfielder.py +11 -3
  71. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/scheduler.py +1 -1
  72. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/grids/filters.py +1 -1
  73. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/grids/grid.py +3 -3
  74. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/grids/pipeline.py +1 -1
  75. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/binningwidget.py +1 -1
  76. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/datadisplaywidget.py +6 -6
  77. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/exposewidget.py +7 -7
  78. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/exposuretimewidget.py +2 -2
  79. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/imageformatwidget.py +1 -1
  80. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/windowingwidget.py +4 -4
  81. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/influxdb.py +3 -3
  82. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/modulegui.py +1 -1
  83. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/offsets/applyaltazoffsets.py +4 -3
  84. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/offsets/applyoffsets.py +8 -4
  85. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/offsets/applyradecoffsets.py +4 -3
  86. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/serialization.py +1 -1
  87. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/time.py +2 -2
  88. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/httpfile.py +1 -1
  89. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/memfile.py +1 -1
  90. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/smbfile.py +1 -1
  91. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyproject.toml +2 -1
  92. pyobs_core-2.0.0.dev5/pyobs/interfaces/interface.py +0 -16
  93. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/.gitignore +0 -0
  94. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/LICENSE +0 -0
  95. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/__init__.py +0 -0
  96. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/background_task.py +0 -0
  97. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/cli/__init__.py +0 -0
  98. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/cli/_cli.py +0 -0
  99. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/cli/pyobs.py +0 -0
  100. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/cli/pyobsw.py +0 -0
  101. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/__init__.py +0 -0
  102. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/commlogging.py +0 -0
  103. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/dummy/__init__.py +0 -0
  104. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/dummy/dummycomm.py +0 -0
  105. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/local/__init__.py +0 -0
  106. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/local/localnetwork.py +0 -0
  107. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/__init__.py +0 -0
  108. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  109. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  110. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  111. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  112. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  113. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  114. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/comm/xmpp/xmppclient.py +0 -0
  115. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/__init__.py +0 -0
  116. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/badweather.py +0 -0
  117. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/exposurestatuschanged.py +0 -0
  118. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/filterchanged.py +0 -0
  119. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/focusfound.py +0 -0
  120. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/goodweather.py +0 -0
  121. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/log.py +0 -0
  122. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/modechanged.py +0 -0
  123. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/moduleclosed.py +0 -0
  124. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/moduleopened.py +0 -0
  125. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/motionstatuschanged.py +0 -0
  126. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/move.py +0 -0
  127. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/newimage.py +0 -0
  128. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/newspectrum.py +0 -0
  129. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/offsets.py +0 -0
  130. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/roofclosing.py +0 -0
  131. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/roofopened.py +0 -0
  132. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/taskfailed.py +0 -0
  133. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/taskfinished.py +0 -0
  134. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/taskstarted.py +0 -0
  135. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/events/testevent.py +0 -0
  136. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/__init__.py +0 -0
  137. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/__init__.py +0 -0
  138. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/altazoffsets.py +0 -0
  139. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/exptime.py +0 -0
  140. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/genericoffset.py +0 -0
  141. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/onskydistance.py +0 -0
  142. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/pixeloffsets.py +0 -0
  143. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/meta/radecoffsets.py +0 -0
  144. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processor.py +0 -0
  145. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/__init__.py +0 -0
  146. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  147. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/annotation/__init__.py +0 -0
  148. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/annotation/circle.py +0 -0
  149. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/annotation/crosshair.py +0 -0
  150. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/__init__.py +0 -0
  151. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  152. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  153. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  154. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  155. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  156. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  157. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/calibration/__init__.py +0 -0
  158. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  159. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  160. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/calibration/calibration.py +0 -0
  161. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/__init__.py +0 -0
  162. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  163. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  164. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/pysep.py +0 -0
  165. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/simpledisk.py +0 -0
  166. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  167. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/exptime/__init__.py +0 -0
  168. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/exptime/exptime.py +0 -0
  169. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/exptime/star.py +0 -0
  170. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/__init__.py +0 -0
  171. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  172. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/flip.py +0 -0
  173. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/grayscale.py +0 -0
  174. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/httpserver.py +0 -0
  175. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/save.py +0 -0
  176. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/saveimage.py +0 -0
  177. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/smooth.py +0 -0
  178. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/image/softbin.py +0 -0
  179. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/__init__.py +0 -0
  180. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/addmask.py +0 -0
  181. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/circularmask.py +0 -0
  182. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/createfilename.py +0 -0
  183. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  184. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/misc/removebackground.py +0 -0
  185. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/modules/__init__.py +0 -0
  186. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/__init__.py +0 -0
  187. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/astrometry.py +0 -0
  188. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  189. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  190. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  191. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/offsets.py +0 -0
  192. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  193. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/offsets/projected.py +0 -0
  194. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/__init__.py +0 -0
  195. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  196. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  197. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  198. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/photometry.py +0 -0
  199. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/photutil.py +0 -0
  200. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/photometry/pysep.py +0 -0
  201. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/images/processors/wcs/__init__.py +0 -0
  202. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IAbortable.py +0 -0
  203. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IAcquisition.py +0 -0
  204. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IAutoFocus.py +0 -0
  205. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IAutoGuiding.py +0 -0
  206. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IAutonomous.py +0 -0
  207. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IBinning.py +0 -0
  208. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ICalibrate.py +0 -0
  209. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ICamera.py +0 -0
  210. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IConfig.py +0 -0
  211. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ICooling.py +0 -0
  212. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IData.py +0 -0
  213. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IDome.py +0 -0
  214. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IExposure.py +0 -0
  215. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IExposureTime.py +0 -0
  216. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IFilters.py +0 -0
  217. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  218. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  219. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IFlatField.py +0 -0
  220. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IFocusModel.py +0 -0
  221. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IFocuser.py +0 -0
  222. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IGain.py +0 -0
  223. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IImageFormat.py +0 -0
  224. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IImageType.py +0 -0
  225. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IMode.py +0 -0
  226. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IModule.py +0 -0
  227. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IMotion.py +0 -0
  228. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IMultiFiber.py +0 -0
  229. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  230. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  231. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IPointingAltAz.py +0 -0
  232. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IPointingHGS.py +0 -0
  233. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  234. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IPointingRaDec.py +0 -0
  235. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IPointingSeries.py +0 -0
  236. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IReady.py +0 -0
  237. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IRoof.py +0 -0
  238. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IRotation.py +0 -0
  239. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IRunnable.py +0 -0
  240. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IRunning.py +0 -0
  241. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IScriptRunner.py +0 -0
  242. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ISpectrograph.py +0 -0
  243. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IStartStop.py +0 -0
  244. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ISyncTarget.py +0 -0
  245. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ITelescope.py +0 -0
  246. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/ITemperatures.py +0 -0
  247. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IVideo.py +0 -0
  248. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IWeather.py +0 -0
  249. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/interfaces/IWindow.py +0 -0
  250. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/__init__.py +0 -0
  251. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/fitsnamespace.py +0 -0
  252. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/motionstatus.py +0 -0
  253. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/pipeline.py +0 -0
  254. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/waitformotion.py +0 -0
  255. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/mixins/weatheraware.py +0 -0
  256. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/__init__.py +0 -0
  257. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/__init__.py +0 -0
  258. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/adaptive.py +0 -0
  259. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/basespectrograph.py +0 -0
  260. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  261. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/dummyvideo.py +0 -0
  262. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/camera/pipelinecamera.py +0 -0
  263. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/flatfield/__init__.py +0 -0
  264. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/flatfield/pointing.py +0 -0
  265. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/flatfield/scheduler.py +0 -0
  266. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/focus/__init__.py +0 -0
  267. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/image/__init__.py +0 -0
  268. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/image/imagewriter.py +0 -0
  269. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/image/pipeline.py +0 -0
  270. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/image/seeing.py +0 -0
  271. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/__init__.py +0 -0
  272. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/_base.py +0 -0
  273. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/_baseguiding.py +0 -0
  274. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  275. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/dummyguiding.py +0 -0
  276. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  277. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  278. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  279. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  280. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  281. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  282. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/robotic/__init__.py +0 -0
  283. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/robotic/mastermind.py +0 -0
  284. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/robotic/pointing.py +0 -0
  285. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/robotic/scriptrunner.py +0 -0
  286. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/roof/__init__.py +0 -0
  287. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/roof/baseroof.py +0 -0
  288. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/roof/dummyroof.py +0 -0
  289. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/telescope/__init__.py +0 -0
  290. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/telescope/basetelescope.py +0 -0
  291. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/telescope/dummytelescope.py +0 -0
  292. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/test/__init__.py +0 -0
  293. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/test/standalone.py +0 -0
  294. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/__init__.py +0 -0
  295. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/autonomouswarning.py +0 -0
  296. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/dummymode.py +0 -0
  297. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/fluentlogger.py +0 -0
  298. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/httpfilecache.py +0 -0
  299. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/utils/trigger.py +0 -0
  300. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/weather/__init__.py +0 -0
  301. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/weather/weather.py +0 -0
  302. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/weather/weather_api.py +0 -0
  303. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/modules/weather/weather_state.py +0 -0
  304. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/py.typed +0 -0
  305. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/__init__.py +0 -0
  306. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/__init__.py +0 -0
  307. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  308. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  309. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  310. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  311. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  312. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  313. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  314. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  315. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  316. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  317. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  318. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  319. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/random.py +0 -0
  320. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  321. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  322. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  323. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  324. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  325. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  326. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  327. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  328. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/targets/target.py +0 -0
  329. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  330. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/__init__.py +0 -0
  331. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  332. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/control/__init__.py +0 -0
  333. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/control/cases.py +0 -0
  334. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/control/conditional.py +0 -0
  335. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/control/parallel.py +0 -0
  336. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/control/selector.py +0 -0
  337. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/control/sequential.py +0 -0
  338. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  339. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  340. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/script.py +0 -0
  341. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  342. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  343. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  344. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/scripts/utils/log.py +0 -0
  345. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/__init__.py +0 -0
  346. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/backend/__init__.py +0 -0
  347. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  348. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  349. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  350. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  351. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/__init__.py +0 -0
  352. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  353. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  354. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/configdb.py +0 -0
  355. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  356. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  357. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  358. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/task.py +0 -0
  359. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  360. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  361. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/memory/__init__.py +0 -0
  362. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  363. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  364. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/observationarchive.py +0 -0
  365. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/storage/taskarchive.py +0 -0
  366. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/task.py +0 -0
  367. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/taskrunner.py +0 -0
  368. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/__init__.py +0 -0
  369. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/archive/__init__.py +0 -0
  370. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/archive/archive.py +0 -0
  371. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  372. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  373. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  374. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  375. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  376. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  377. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  378. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  379. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  380. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  381. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  382. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/__init__.py +0 -0
  383. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/average.py +0 -0
  384. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/cache.py +0 -0
  385. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/config.py +0 -0
  386. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/coordinates.py +0 -0
  387. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/curvefit.py +0 -0
  388. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/enums.py +0 -0
  389. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/exceptions.py +0 -0
  390. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/fits.py +0 -0
  391. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/focusseries/__init__.py +0 -0
  392. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/focusseries/base.py +0 -0
  393. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/focusseries/photometry.py +0 -0
  394. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/focusseries/projection.py +0 -0
  395. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/grids/__init__.py +0 -0
  396. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/grids/gridnode.py +0 -0
  397. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/__init__.py +0 -0
  398. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/__init__.py +0 -0
  399. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  400. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/http.py +0 -0
  401. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/logger.py +0 -0
  402. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/logging/__init__.py +0 -0
  403. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/logging/context.py +0 -0
  404. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/logging/resolvableerror.py +0 -0
  405. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/offsets/__init__.py +0 -0
  406. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/parallel.py +0 -0
  407. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/pipeline/__init__.py +0 -0
  408. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/pipeline/night.py +0 -0
  409. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/pipeline/pipeline.py +0 -0
  410. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/publisher/__init__.py +0 -0
  411. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/publisher/csv.py +0 -0
  412. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/publisher/http.py +0 -0
  413. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/publisher/log.py +0 -0
  414. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/publisher/multi.py +0 -0
  415. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/publisher/publisher.py +0 -0
  416. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/shellcommand.py +0 -0
  417. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/threads/__init__.py +0 -0
  418. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/threads/lockwithabort.py +0 -0
  419. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/utils/types.py +0 -0
  420. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/version.py +0 -0
  421. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/__init__.py +0 -0
  422. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/archivefile.py +0 -0
  423. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/bufferedfile.py +0 -0
  424. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/file.py +0 -0
  425. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/filelists/__init__.py +0 -0
  426. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/filelists/filelist.py +0 -0
  427. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/filelists/testing.py +0 -0
  428. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/localfile.py +0 -0
  429. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/sftpfile.py +0 -0
  430. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/sshfile.py +0 -0
  431. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/pyobs/vfs/tempfile.py +0 -0
  432. {pyobs_core-2.0.0.dev5 → pyobs_core-2.0.0.dev7}/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.dev5
3
+ Version: 2.0.0.dev7
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)
@@ -514,6 +514,13 @@ class Comm:
514
514
  def _get_client_state(self, module: str) -> tuple[ModuleState, str] | None:
515
515
  return None
516
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
+
517
524
  async def subscribe_state(
518
525
  self,
519
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}"
@@ -55,7 +55,7 @@ class Proxy:
55
55
 
56
56
  # add interfaces as base classes
57
57
  cls = self.__class__
58
- self.__class__ = cls.__class__("Proxy", tuple([cls] + interfaces), {}) # type: ignore
58
+ self.__class__ = type("Proxy", tuple([cls] + interfaces), {})
59
59
 
60
60
  # create methods
61
61
  self._methods = self._create_methods()
@@ -139,6 +139,9 @@ class Proxy:
139
139
  for interface in self._interfaces:
140
140
  # loop all methods:
141
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
142
145
  # set method
143
146
  my_func = types.MethodType(self._remote_function_wrapper(func_name), self)
144
147
  setattr(self, func_name, my_func)
@@ -174,11 +177,11 @@ class Proxy:
174
177
  """Clear all cached state. Called by Comm when the remote module disconnects."""
175
178
  self._state.clear()
176
179
 
177
- def state(self, interface: type[Interface]) -> Any | None:
180
+ def get_state(self, interface: type[Interface]) -> Any | None:
178
181
  """Latest known state for the given interface, or None if nothing has arrived yet."""
179
182
  return self._state.get(interface)
180
183
 
181
- def capabilities(self, interface: type[Interface]) -> Any | None:
184
+ def get_capabilities(self, interface: type[Interface]) -> Any | None:
182
185
  """Capabilities for the given interface, populated once at Proxy construction."""
183
186
  return self._capabilities.get(interface)
184
187
 
@@ -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)
@@ -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]
@@ -34,7 +34,6 @@ from .IFocusModel import IFocusModel
34
34
  from .IGain import GainState, IGain
35
35
  from .IImageFormat import IImageFormat, ImageFormatCapabilities, ImageFormatState
36
36
  from .IImageType import IImageType, ImageTypeState
37
- from .ILatLon import ILatLon, LatLonCapabilities
38
37
  from .IMode import IMode, ModeCapabilities, ModeState
39
38
  from .IModule import IModule, ModuleCapabilities
40
39
  from .IMotion import DeviceMotionStatus, IMotion, MotionState
@@ -65,8 +64,6 @@ from .IWindow import IWindow, WindowCapabilities, WindowState
65
64
  __all__ = [
66
65
  "IAbortable",
67
66
  "IAcquisition",
68
- "ILatLon",
69
- "LatLonCapabilities",
70
67
  "IAutoFocus",
71
68
  "IAutoGuiding",
72
69
  "IAutonomous",
@@ -0,0 +1,27 @@
1
+ from abc import ABCMeta
2
+ from typing import Any, ClassVar
3
+
4
+
5
+ class Interface(metaclass=ABCMeta):
6
+ """Base class for all interfaces in pyobs."""
7
+
8
+ version: int = 1
9
+ state: ClassVar[type | None] = None
10
+ capabilities: ClassVar[type | None] = None
11
+
12
+ __module__ = "pyobs.interfaces"
13
+
14
+ def get_state(self, interface: "type[Interface]") -> Any | None:
15
+ """Return the last received state for the given interface, or None."""
16
+ return None
17
+
18
+ def get_capabilities(self, interface: "type[Interface]") -> Any | None:
19
+ """Return the capabilities for the given interface, or None."""
20
+ return None
21
+
22
+ async def wait_for_state(self, interface: "type[Interface]", timeout: float = 10.0) -> Any | None:
23
+ """Return state immediately if available, otherwise wait for the first update."""
24
+ return None
25
+
26
+
27
+ __all__ = ["Interface"]
@@ -54,9 +54,9 @@ class CameraSettingsMixin:
54
54
  await camera.set_binning(self.__camerasettings_binning, self.__camerasettings_binning)
55
55
  if isinstance(camera, IWindow):
56
56
  log.info("Set window to full frame...")
57
- full_frame = await camera.get_full_frame()
58
- if full_frame is not None:
59
- await camera.set_window(*full_frame)
57
+ cap = camera.get_capabilities(IWindow)
58
+ if cap is not None:
59
+ await camera.set_window(cap.full_frame_x, cap.full_frame_y, cap.full_frame_width, cap.full_frame_height)
60
60
  else:
61
61
  raise ValueError("Could not get full frame size.")
62
62
 
@@ -185,7 +185,7 @@ class FitsHeaderMixin:
185
185
 
186
186
  # date of night this observation is in
187
187
  if self._fitsheadermixin_night_obs:
188
- hdr["DAY-OBS"] = (date_obs.night_obs(module._observer).strftime("%Y-%m-%d"), "Night of observation")
188
+ hdr["DAY-OBS"] = (date_obs.night_obs(module._observer).strftime("%Y-%m-%d"), "Night of observation") # type: ignore[arg-type]
189
189
  else:
190
190
  hdr["DAY-OBS"] = (date_obs.strftime("%Y-%m-%d"), "Day of observation")
191
191
 
@@ -6,7 +6,8 @@ from typing import Any
6
6
  import astropy.units as u
7
7
  from astropy.coordinates import SkyCoord
8
8
 
9
- from pyobs.interfaces import IPointingAltAz, IPointingRaDec, IReady
9
+ from pyobs.comm import Proxy
10
+ from pyobs.interfaces import AltAzState, IPointingAltAz, IPointingRaDec, IReady, RaDecState, ReadyState
10
11
  from pyobs.modules import Module
11
12
  from pyobs.utils import exceptions as exc
12
13
 
@@ -26,10 +27,26 @@ async def get_coords(
26
27
  Return from method call.
27
28
  """
28
29
 
29
- if mode == IPointingAltAz and isinstance(obj, IPointingAltAz):
30
- return await obj.get_altaz()
31
- elif mode == IPointingRaDec and isinstance(obj, IPointingRaDec):
32
- return await obj.get_radec()
30
+ if mode == IPointingAltAz:
31
+ if isinstance(obj, Proxy):
32
+ state: AltAzState | None = obj.get_state(IPointingAltAz)
33
+ elif isinstance(obj, Module):
34
+ state = obj.comm.get_own_state(IPointingAltAz)
35
+ else:
36
+ state = None
37
+ if state is None:
38
+ raise ValueError("No AltAz state available.")
39
+ return state.alt, state.az
40
+ elif mode == IPointingRaDec:
41
+ if isinstance(obj, Proxy):
42
+ state2: RaDecState | None = obj.get_state(IPointingRaDec)
43
+ elif isinstance(obj, Module):
44
+ state2 = obj.comm.get_own_state(IPointingRaDec)
45
+ else:
46
+ state2 = None
47
+ if state2 is None:
48
+ raise ValueError("No RaDec state available.")
49
+ return state2.ra, state2.dec
33
50
  else:
34
51
  raise ValueError("Unknown mode.")
35
52
 
@@ -117,8 +134,9 @@ class FollowMixin:
117
134
  connected = True
118
135
  while True:
119
136
  # not ready?
120
- if isinstance(self, IReady):
121
- if not await self.is_ready() and this.__follow_only_when_ready:
137
+ if isinstance(self, IReady) and isinstance(self, Module):
138
+ ready_state: ReadyState | None = self.comm.get_own_state(IReady)
139
+ if (ready_state is None or not ready_state.ready) and this.__follow_only_when_ready:
122
140
  await asyncio.sleep(this.__follow_interval)
123
141
  continue
124
142
 
@@ -39,7 +39,7 @@ class ExposureInfo(NamedTuple):
39
39
  exposure_time: float
40
40
 
41
41
 
42
- async def calc_expose_timeout(camera: IExposureTime, *args: Any, **kwargs: Any) -> float:
42
+ async def calc_expose_timeout(camera: BaseCamera, *args: Any, **kwargs: Any) -> float:
43
43
  """Calculates timeout for expose()."""
44
44
  return camera._exposure_time + 30
45
45
 
@@ -333,7 +333,7 @@ class BaseVideo(Module, ImageFitsHeaderMixin, IVideo, IImageType, metaclass=ABCM
333
333
 
334
334
  # flip image?
335
335
  if self._flip:
336
- data: NDArray[Any] = np.flip(data, axis=0) # type: ignore
336
+ data: NDArray[Any] = np.flip(data, axis=0)
337
337
 
338
338
  # got a requested image in the queue?
339
339
  image, filename = None, None