pyobs-core 2.0.0.dev89__tar.gz → 2.0.0.dev91__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 (449) hide show
  1. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/PKG-INFO +1 -1
  2. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/application.py +10 -1
  3. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/weatheraware.py +1 -1
  4. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/basecamera.py +36 -3
  5. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/basevideo.py +1 -1
  6. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/image/imagewatcher.py +9 -1
  7. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/backend/observationarchive.py +26 -14
  8. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/backend/taskarchive.py +24 -11
  9. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/flatfielder.py +1 -1
  10. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyproject.toml +1 -1
  11. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/.gitignore +0 -0
  12. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/LICENSE +0 -0
  13. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/__init__.py +0 -0
  14. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/background_task.py +0 -0
  15. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/cli/__init__.py +0 -0
  16. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/cli/_cli.py +0 -0
  17. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/cli/pyobs.py +0 -0
  18. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/cli/pyobsd.py +0 -0
  19. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/cli/pyobsw.py +0 -0
  20. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/__init__.py +0 -0
  21. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/comm.py +0 -0
  22. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/commlogging.py +0 -0
  23. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/dummy/__init__.py +0 -0
  24. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/dummy/dummycomm.py +0 -0
  25. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/local/__init__.py +0 -0
  26. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/local/localcomm.py +0 -0
  27. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/local/localnetwork.py +0 -0
  28. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/proxy.py +0 -0
  29. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/__init__.py +0 -0
  30. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/rpc.py +0 -0
  31. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/serializer.py +0 -0
  32. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  33. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  34. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  35. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  36. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  37. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  38. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  39. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xmppclient.py +0 -0
  40. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/comm/xmpp/xmppcomm.py +0 -0
  41. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/__init__.py +0 -0
  42. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/badweather.py +0 -0
  43. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/event.py +0 -0
  44. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/exposurestatuschanged.py +0 -0
  45. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/filterchanged.py +0 -0
  46. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/focusfound.py +0 -0
  47. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/goodweather.py +0 -0
  48. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/log.py +0 -0
  49. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/modechanged.py +0 -0
  50. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/moduleclosed.py +0 -0
  51. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/moduleopened.py +0 -0
  52. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/motionstatuschanged.py +0 -0
  53. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/move.py +0 -0
  54. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/newimage.py +0 -0
  55. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/newspectrum.py +0 -0
  56. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/offsets.py +0 -0
  57. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/roofclosing.py +0 -0
  58. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/roofopened.py +0 -0
  59. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/taskfailed.py +0 -0
  60. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/taskfinished.py +0 -0
  61. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/taskstarted.py +0 -0
  62. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/events/testevent.py +0 -0
  63. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/__init__.py +0 -0
  64. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/image.py +0 -0
  65. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/__init__.py +0 -0
  66. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/altazoffsets.py +0 -0
  67. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/exptime.py +0 -0
  68. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/genericoffset.py +0 -0
  69. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/onskydistance.py +0 -0
  70. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/pixeloffsets.py +0 -0
  71. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/radecoffsets.py +0 -0
  72. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/meta/skyoffsets.py +0 -0
  73. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processor.py +0 -0
  74. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/__init__.py +0 -0
  75. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  76. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/annotation/__init__.py +0 -0
  77. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/annotation/_pillow.py +0 -0
  78. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/annotation/circle.py +0 -0
  79. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/annotation/crosshair.py +0 -0
  80. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/annotation/text.py +0 -0
  81. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/__init__.py +0 -0
  82. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  83. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  84. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  85. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  86. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  87. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  88. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/calibration/__init__.py +0 -0
  89. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  90. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  91. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/calibration/calibration.py +0 -0
  92. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/__init__.py +0 -0
  93. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  94. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  95. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/daophot.py +0 -0
  96. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/pysep.py +0 -0
  97. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/simpledisk.py +0 -0
  98. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  99. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/exptime/__init__.py +0 -0
  100. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/exptime/exptime.py +0 -0
  101. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/exptime/star.py +0 -0
  102. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/__init__.py +0 -0
  103. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  104. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/download.py +0 -0
  105. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/flip.py +0 -0
  106. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/grayscale.py +0 -0
  107. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/httpserver.py +0 -0
  108. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/normalize.py +0 -0
  109. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/save.py +0 -0
  110. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/saveimage.py +0 -0
  111. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/smooth.py +0 -0
  112. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/image/softbin.py +0 -0
  113. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/__init__.py +0 -0
  114. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/addmask.py +0 -0
  115. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  116. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/circularmask.py +0 -0
  117. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/createfilename.py +0 -0
  118. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  119. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/misc/removebackground.py +0 -0
  120. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/modules/__init__.py +0 -0
  121. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  122. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/__init__.py +0 -0
  123. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/astrometry.py +0 -0
  124. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  125. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  126. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  127. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  128. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  129. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/offsets.py +0 -0
  130. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  131. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/projected.py +0 -0
  132. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  133. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/__init__.py +0 -0
  134. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  135. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  136. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  137. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  138. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/photometry.py +0 -0
  139. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/photutil.py +0 -0
  140. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/photometry/pysep.py +0 -0
  141. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/wcs/__init__.py +0 -0
  142. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  143. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IAbortable.py +0 -0
  144. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IAcquisition.py +0 -0
  145. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IAutoFocus.py +0 -0
  146. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IAutoGuiding.py +0 -0
  147. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IAutonomous.py +0 -0
  148. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IBinning.py +0 -0
  149. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ICalibrate.py +0 -0
  150. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ICamera.py +0 -0
  151. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IConfig.py +0 -0
  152. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ICooling.py +0 -0
  153. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IData.py +0 -0
  154. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IDataSequence.py +0 -0
  155. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IDome.py +0 -0
  156. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IExposure.py +0 -0
  157. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IExposureTime.py +0 -0
  158. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IFilters.py +0 -0
  159. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  160. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  161. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IFlatField.py +0 -0
  162. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IFocusModel.py +0 -0
  163. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IFocuser.py +0 -0
  164. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IGain.py +0 -0
  165. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IImageFormat.py +0 -0
  166. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IImageType.py +0 -0
  167. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IMode.py +0 -0
  168. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IModule.py +0 -0
  169. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IMotion.py +0 -0
  170. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IMultiFiber.py +0 -0
  171. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  172. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  173. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingAltAz.py +0 -0
  174. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingBody.py +0 -0
  175. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingHeliocentricPolar.py +0 -0
  176. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +0 -0
  177. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  178. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingOrbitalElements.py +0 -0
  179. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingRaDec.py +0 -0
  180. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IPointingSeries.py +0 -0
  181. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IReady.py +0 -0
  182. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IRoof.py +0 -0
  183. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IRotation.py +0 -0
  184. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IRunnable.py +0 -0
  185. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IRunning.py +0 -0
  186. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IScriptRunner.py +0 -0
  187. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ISpectrograph.py +0 -0
  188. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IStartStop.py +0 -0
  189. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IStructuredConfig.py +0 -0
  190. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ISyncTarget.py +0 -0
  191. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ITelescope.py +0 -0
  192. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ITemperatures.py +0 -0
  193. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ITrackingMode.py +0 -0
  194. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/ITrackingRate.py +0 -0
  195. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IVideo.py +0 -0
  196. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IWeather.py +0 -0
  197. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/IWindow.py +0 -0
  198. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/__init__.py +0 -0
  199. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/interfaces/interface.py +0 -0
  200. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/__init__.py +0 -0
  201. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/camerasettings.py +0 -0
  202. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/fitsheader.py +0 -0
  203. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/fitsnamespace.py +0 -0
  204. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/follow.py +0 -0
  205. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/motionstatus.py +0 -0
  206. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/pipeline.py +0 -0
  207. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/mixins/waitformotion.py +0 -0
  208. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/__init__.py +0 -0
  209. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/__init__.py +0 -0
  210. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/adaptive.py +0 -0
  211. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/basespectrograph.py +0 -0
  212. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/dummycamera.py +0 -0
  213. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  214. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/dummyvideo.py +0 -0
  215. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/camera/pipelinecamera.py +0 -0
  216. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/flatfield/__init__.py +0 -0
  217. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/flatfield/flatfield.py +0 -0
  218. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/flatfield/pointing.py +0 -0
  219. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/flatfield/scheduler.py +0 -0
  220. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/focus/__init__.py +0 -0
  221. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/focus/dummyautofocus.py +0 -0
  222. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/focus/focusmodel.py +0 -0
  223. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/focus/focusseries.py +0 -0
  224. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/image/__init__.py +0 -0
  225. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/image/imagewriter.py +0 -0
  226. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/image/pipeline.py +0 -0
  227. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/image/seeing.py +0 -0
  228. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/module.py +0 -0
  229. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/__init__.py +0 -0
  230. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/_base.py +0 -0
  231. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/_baseguiding.py +0 -0
  232. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/acquisition.py +0 -0
  233. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/autoguiding.py +0 -0
  234. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  235. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/dummyguiding.py +0 -0
  236. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  237. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  238. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  239. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  240. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  241. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  242. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/robotic/__init__.py +0 -0
  243. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/robotic/mastermind.py +0 -0
  244. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/robotic/pointing.py +0 -0
  245. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/robotic/scheduler.py +0 -0
  246. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/robotic/scriptrunner.py +0 -0
  247. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/roof/__init__.py +0 -0
  248. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/roof/basedome.py +0 -0
  249. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/roof/baseroof.py +0 -0
  250. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/roof/dummyroof.py +0 -0
  251. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/telescope/__init__.py +0 -0
  252. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/telescope/_dummytelescopebase.py +0 -0
  253. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/telescope/basetelescope.py +0 -0
  254. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
  255. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
  256. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
  257. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/test/__init__.py +0 -0
  258. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/test/standalone.py +0 -0
  259. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/__init__.py +0 -0
  260. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/dummymode.py +0 -0
  261. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/fluentlogger.py +0 -0
  262. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/httpfilecache.py +0 -0
  263. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/kiosk.py +0 -0
  264. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/matrix.py +0 -0
  265. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/stellarium.py +0 -0
  266. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/telegram.py +0 -0
  267. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/utils/trigger.py +0 -0
  268. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/weather/__init__.py +0 -0
  269. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/weather/mockweather.py +0 -0
  270. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/weather/weather.py +0 -0
  271. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/weather/weather_api.py +0 -0
  272. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/modules/weather/weather_state.py +0 -0
  273. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/object.py +0 -0
  274. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/py.typed +0 -0
  275. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/__init__.py +0 -0
  276. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/observation.py +0 -0
  277. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/__init__.py +0 -0
  278. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/_executor.py +0 -0
  279. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
  280. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  281. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  282. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  283. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  284. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  285. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  286. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  287. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/dataprovider.py +0 -0
  288. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  289. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  290. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  291. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  292. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  293. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  294. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  295. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  296. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/random.py +0 -0
  297. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  298. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  299. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  300. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
  301. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  302. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  303. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  304. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  305. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  306. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  307. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  308. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  309. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/targets/target.py +0 -0
  310. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  311. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/__init__.py +0 -0
  312. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  313. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
  314. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  315. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  316. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/control/__init__.py +0 -0
  317. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/control/cases.py +0 -0
  318. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/control/conditional.py +0 -0
  319. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/control/parallel.py +0 -0
  320. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/control/selector.py +0 -0
  321. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/control/sequential.py +0 -0
  322. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/exceptions.py +0 -0
  323. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  324. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
  325. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
  326. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  327. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/script.py +0 -0
  328. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  329. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  330. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  331. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/scripts/utils/log.py +0 -0
  332. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/__init__.py +0 -0
  333. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/backend/__init__.py +0 -0
  334. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  335. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  336. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  337. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/__init__.py +0 -0
  338. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/_portal.py +0 -0
  339. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  340. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  341. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/configdb.py +0 -0
  342. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  343. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  344. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  345. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  346. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  347. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  348. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/task.py +0 -0
  349. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  350. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  351. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/memory/__init__.py +0 -0
  352. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  353. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  354. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/observationarchive.py +0 -0
  355. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/storage/taskarchive.py +0 -0
  356. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/task.py +0 -0
  357. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/taskrunner.py +0 -0
  358. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/__init__.py +0 -0
  359. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/archive/__init__.py +0 -0
  360. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/archive/archive.py +0 -0
  361. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  362. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  363. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  364. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  365. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  366. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  367. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  368. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  369. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  370. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  371. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  372. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  373. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  374. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  375. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  376. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/__init__.py +0 -0
  377. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/average.py +0 -0
  378. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/cache.py +0 -0
  379. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/config.py +0 -0
  380. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/config_schema.py +0 -0
  381. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/coordinates.py +0 -0
  382. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/curvefit.py +0 -0
  383. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/enums.py +0 -0
  384. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/exceptions.py +0 -0
  385. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/fits.py +0 -0
  386. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/focusseries/__init__.py +0 -0
  387. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/focusseries/base.py +0 -0
  388. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/focusseries/photometry.py +0 -0
  389. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/focusseries/projection.py +0 -0
  390. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/grids/__init__.py +0 -0
  391. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/grids/filters.py +0 -0
  392. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/grids/grid.py +0 -0
  393. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/grids/gridnode.py +0 -0
  394. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/grids/pipeline.py +0 -0
  395. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/__init__.py +0 -0
  396. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/__init__.py +0 -0
  397. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  398. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  399. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  400. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  401. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  402. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  403. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  404. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/http.py +0 -0
  405. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/influxdb.py +0 -0
  406. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/logger.py +0 -0
  407. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/logging/__init__.py +0 -0
  408. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/logging/context.py +0 -0
  409. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/logging/resolvableerror.py +0 -0
  410. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/modulegui.py +0 -0
  411. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/offsets/__init__.py +0 -0
  412. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  413. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/offsets/applyoffsets.py +0 -0
  414. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  415. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/parallel.py +0 -0
  416. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/pipeline/__init__.py +0 -0
  417. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/pipeline/pipeline.py +0 -0
  418. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/pipeline/progress.py +0 -0
  419. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/pipeline/reduction.py +0 -0
  420. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/pipeline/reduction_base.py +0 -0
  421. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/publisher/__init__.py +0 -0
  422. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/publisher/csv.py +0 -0
  423. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/publisher/http.py +0 -0
  424. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/publisher/log.py +0 -0
  425. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/publisher/multi.py +0 -0
  426. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/publisher/publisher.py +0 -0
  427. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/serialization.py +0 -0
  428. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/shellcommand.py +0 -0
  429. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/threads/__init__.py +0 -0
  430. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/threads/lockwithabort.py +0 -0
  431. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/time.py +0 -0
  432. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/units.py +0 -0
  433. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/utils/versions.py +0 -0
  434. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/version.py +0 -0
  435. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/__init__.py +0 -0
  436. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/archivefile.py +0 -0
  437. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/bufferedfile.py +0 -0
  438. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/file.py +0 -0
  439. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/filelists/__init__.py +0 -0
  440. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/filelists/filelist.py +0 -0
  441. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/filelists/testing.py +0 -0
  442. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/httpfile.py +0 -0
  443. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/localfile.py +0 -0
  444. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/memfile.py +0 -0
  445. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/sftpfile.py +0 -0
  446. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/smbfile.py +0 -0
  447. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/sshfile.py +0 -0
  448. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/tempfile.py +0 -0
  449. {pyobs_core-2.0.0.dev89 → pyobs_core-2.0.0.dev91}/pyobs/vfs/vfs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyobs-core
3
- Version: 2.0.0.dev89
3
+ Version: 2.0.0.dev91
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -260,7 +260,16 @@ class Application:
260
260
  # stem-mismatch check below. Give it the config file's own stem instead.
261
261
  cfg = {**cfg, "comm": {"class": f"{DummyComm.__module__}.{DummyComm.__name__}", "name": config_stem}}
262
262
  log.info("Creating module from class %s...", klass.__name__)
263
- self._module = get_object(cfg, Module)
263
+ try:
264
+ self._module = get_object(cfg, Module)
265
+ except Exception:
266
+ # The module-creation failure (bad kwargs, broken __init__ chain, ...) is
267
+ # otherwise only visible as an uncaught traceback on stderr -- which is
268
+ # /dev/null for daemonized modules (--pid-file, as started by pyobsd /
269
+ # pyobs-web-admin), so it silently vanishes from all logs. Record it through
270
+ # the configured handlers (file/journald) before propagating.
271
+ log.exception("Could not create module %s from config %s.", klass.__name__, config)
272
+ raise
264
273
 
265
274
  # a config file whose stem doesn't match its own module's name silently splits
266
275
  # PYOBS_MODULE log tagging in two: logging that falls through both execute()
@@ -84,7 +84,7 @@ class WeatherAwareMixin:
84
84
  if not self.__weatheraware_is_error_state:
85
85
  log.error("Telescope is in error mode, cannot park.")
86
86
  else:
87
- log.warning("Weather is bad, shutting down.")
87
+ log.info("Weather is bad, shutting down.")
88
88
  await msi.park()
89
89
 
90
90
  # save error state
@@ -524,9 +524,42 @@ class BaseCamera(
524
524
  is_top = max(top, img_top)
525
525
  is_bottom = min(top + height, img_top + img_height)
526
526
 
527
- # for simplicity we allow prescan/overscan only in one dimension
528
- if (left < is_left or left + width > is_right) and (top < is_top or top + height > is_bottom):
529
- log.warning("BIASSEC/TRIMSEC can only be calculated with a prescan/overscan on one axis only.")
527
+ # prescan/overscan exists only where the window extends beyond the visible frame
528
+ x_ovs = img_left < left or img_left + img_width > left + width
529
+ y_ovs = img_top < top or img_top + img_height > top + height
530
+
531
+ # window extends beyond the visible frame on both axes: the simple calculation
532
+ # below only supports prescan/overscan on one axis
533
+ if x_ovs and y_ovs:
534
+ log.warning(
535
+ "Cannot compute BIASSEC/TRIMSEC: window %dx%d at %d,%d has prescan/overscan on both axes "
536
+ "(only one axis is supported).",
537
+ img_width,
538
+ img_height,
539
+ img_left,
540
+ img_top,
541
+ )
542
+ return
543
+
544
+ # window lies fully inside the visible frame: there is no prescan/overscan at all
545
+ if (
546
+ not x_ovs
547
+ and not y_ovs
548
+ and (
549
+ img_left > left
550
+ or img_left + img_width < left + width
551
+ or img_top > top
552
+ or img_top + img_height < top + height
553
+ )
554
+ ):
555
+ log.info(
556
+ "No BIASSEC/TRIMSEC: window %dx%d at %d,%d lies fully inside the visible frame "
557
+ "(no prescan/overscan).",
558
+ img_width,
559
+ img_height,
560
+ img_left,
561
+ img_top,
562
+ )
530
563
  return
531
564
 
532
565
  # comments
@@ -33,7 +33,7 @@ INDEX_HTML = """
33
33
  <title>Title</title>
34
34
  </head>
35
35
  <body>
36
- <img src="/video.mjpg" width="100%">
36
+ <img src="video.mjpg" width="100%">
37
37
  </body>
38
38
  </html>
39
39
 
@@ -29,6 +29,12 @@ class ImageWatcher(Module):
29
29
 
30
30
  Watches a path for new files and stores them in all given destinations. Only if all operations were successful,
31
31
  the file is deleted.
32
+
33
+ New files are not processed immediately, but only after a wait time (``wait_time``) has passed since they were
34
+ detected. This is mainly to make sure the file is fully written before it is read: while the inotify watcher
35
+ only reports files after they have been closed for writing (``CLOSE_WRITE``), the polling watcher and the
36
+ initial scan in ``open()`` can see a file while its write is still in progress. The same wait time is also
37
+ used to delay re-processing of files whose destination copy failed (see ``_worker``).
32
38
  """
33
39
 
34
40
  __module__ = "pyobs.modules.image"
@@ -50,7 +56,9 @@ class ImageWatcher(Module):
50
56
  destinations: Filename patterns for destinations.
51
57
  poll: If True, watchpath is polled instead of watched by inotify.
52
58
  poll_interval: Interval for polling in seconds, if poll is True.
53
- wait_time: Time in seconds between adding file to list and processing it.
59
+ wait_time: Time in seconds between adding a file to the list and processing it. Gives a file that is
60
+ still being written time to finish (relevant for poll mode and the initial scan) and spaces out
61
+ re-queued files after failed destination copies.
54
62
  """
55
63
  Module.__init__(self, **kwargs)
56
64
 
@@ -32,6 +32,7 @@ class BackendObservationArchive(ObservationArchive):
32
32
  self._mode = mode
33
33
  self._aiohttp_session: aiohttp.ClientSession | None = None
34
34
  self._last_update: Time | None = None
35
+ self._last_marker: Time | None = None
35
36
  self._observations = ObservationList()
36
37
 
37
38
  if auto_update:
@@ -56,30 +57,41 @@ class BackendObservationArchive(ObservationArchive):
56
57
  return self._aiohttp_session
57
58
 
58
59
  async def _check_for_changes(self) -> None:
59
- """Update schedule in background."""
60
+ """Update schedule in background, gated on the backend's update marker."""
60
61
 
61
62
  while True:
62
63
  try:
63
- await self._update()
64
+ await self._poll()
64
65
  except Exception as e:
65
66
  log.error("Failed to update observations from backend: %s", e)
66
67
  await asyncio.sleep(5)
67
68
 
69
+ async def _poll(self) -> None:
70
+ """Re-download the schedule when the backend's ``last_observation_update`` marker moved.
71
+
72
+ The marker is a DB-derived ``Max(updated_at)`` (pyobs-robotic-backend#84), truthful across
73
+ gunicorn workers, so it is a safe refresh gate; see ``BackendTaskArchive._poll``. The
74
+ content comparison in :meth:`_update` still decides whether to fire ``on_tasks_changed``.
75
+ """
76
+ last_update = await self.last_update_time()
77
+ if self._last_marker is None or last_update > self._last_marker:
78
+ await self._update()
79
+ self._last_marker = last_update
80
+
68
81
  async def _update(self) -> None:
69
82
  """Fetch the schedule from the backend and apply it if anything changed.
70
83
 
71
- Re-fetches unconditionally on every poll instead of gating on the backend's
72
- ``last_observation_update`` marker (per-process Django ``LocMemCache``, unreliable across
73
- gunicorn workers -- see ``BackendTaskArchive``). Changes are detected by comparing full
74
- observation contents via ``model_dump(use_task_id=True)``, keyed by observation ID so a
75
- stable reordering of the same items is not mistaken for a change: the backend serializes
76
- ``task`` as a plain FK ID, while cached copies get their ``task`` replaced by a full
77
- ``Task`` when the mastermind calls ``fetch_task()``, so the ID normalization keeps both
78
- sides comparable. The comparison includes ``state`` (``Observation.__eq__`` ignores it),
79
- which matters for in-set transitions such as ``pending`` -> ``in_progress``; observations
80
- leaving the fetched set -- e.g. ``window_expired``, which the server-side ``state``/
81
- ``end_after`` filters drop -- are picked up as list shrinkage by the unconditional
82
- refetch.
84
+ Called by :meth:`_poll` after the backend marker moved (or on the first poll). Changes are
85
+ detected by comparing full observation contents via ``model_dump(use_task_id=True)``,
86
+ keyed by observation ID so a stable reordering of the same items is not mistaken for a
87
+ change: the backend serializes ``task`` as a plain FK ID, while cached copies get their
88
+ ``task`` replaced by a full ``Task`` when the mastermind calls ``fetch_task()``, so the ID
89
+ normalization keeps both sides comparable. The comparison includes ``state``
90
+ (``Observation.__eq__`` ignores it), which matters for in-set transitions such as
91
+ ``pending`` -> ``in_progress``; observations leaving the fetched set -- e.g.
92
+ ``window_expired``, which the server-side ``state``/``end_after`` filters drop -- are
93
+ picked up as list shrinkage on the next marker-triggered refetch (the ``mark_window_expired``
94
+ sweep stamps ``updated_at``, so expiry moves the marker within one sweep interval).
83
95
  """
84
96
  observations = await self._get_schedule()
85
97
  if {o.id: o.model_dump(use_task_id=True) for o in observations} != {
@@ -28,6 +28,7 @@ class BackendTaskArchive(TaskArchive):
28
28
  self._token = token
29
29
  self._aiohttp_session: aiohttp.ClientSession | None = None
30
30
  self._last_update: Time | None = None
31
+ self._last_marker: Time | None = None
31
32
  self._projects: list[Project] = list()
32
33
  self._tasks: list[Task] = list()
33
34
 
@@ -53,26 +54,38 @@ class BackendTaskArchive(TaskArchive):
53
54
  return self._aiohttp_session
54
55
 
55
56
  async def _check_for_changes(self) -> None:
56
- """Update tasks in background."""
57
+ """Update tasks in background, gated on the backend's update marker."""
57
58
  while True:
58
59
  try:
59
- await self._update()
60
+ await self._poll()
60
61
  except Exception as e:
61
62
  log.error("Failed to update tasks from backend: %s", e)
62
63
  await asyncio.sleep(5)
63
64
 
65
+ async def _poll(self) -> None:
66
+ """Re-download tasks/projects when the backend's ``last_task_update`` marker moved.
67
+
68
+ The marker is a DB-derived ``Max(updated_at)`` (pyobs-robotic-backend#84), truthful across
69
+ gunicorn workers, so it is a safe refresh gate. Without it the archive re-downloaded (and
70
+ re-compared) on every poll, and the content comparison misfired whenever runtime code
71
+ mutated a serialized task field (e.g. ``DynamicTarget.resolve()`` overwriting ``name``),
72
+ livelocking the scheduler. The content comparison in :meth:`_update` still decides whether
73
+ to fire ``on_tasks_changed``.
74
+ """
75
+ last_update = await self.last_update_time()
76
+ if self._last_marker is None or last_update > self._last_marker:
77
+ await self._update()
78
+ self._last_marker = last_update
79
+
64
80
  async def _update(self) -> None:
65
81
  """Fetch tasks/projects from the backend and apply them if anything changed.
66
82
 
67
- Re-fetches unconditionally on every poll instead of gating on the backend's
68
- ``last_task_update`` marker: that marker is computed from a per-process Django
69
- ``LocMemCache`` and is unreliable across gunicorn workers, so gating on it let the
70
- mastermind run stale tasks forever. Real changes are detected by comparing the downloaded
71
- content against the cached copy. The comparison uses ``model_dump()`` rather than pydantic
72
- ``==``, which also compares runtime attributes (e.g. ``Task._cant_run_reason`` set by
73
- ``can_run()``) and would flag unchanged tasks as changed on every poll; it is keyed by ID
74
- so that a stable reordering of the same items (e.g. an unordered backend queryset) is not
75
- mistaken for a change.
83
+ Called by :meth:`_poll` after the backend marker moved (or on the first poll); applies the
84
+ download only when the content actually differs from the cached copy. The comparison uses
85
+ ``model_dump()`` rather than pydantic ``==``, which also compares runtime attributes (e.g.
86
+ ``Task._cant_run_reason`` set by ``can_run()``) and would flag unchanged tasks as changed
87
+ on every poll; it is keyed by ID so that a stable reordering of the same items (e.g. an
88
+ unordered backend queryset) is not mistaken for a change.
76
89
  """
77
90
  projects = await self._get_projects()
78
91
  tasks = await self._get_tasks()
@@ -489,7 +489,7 @@ class FlatFielder(Object):
489
489
 
490
490
  # log and return
491
491
  if frac > self._allowed_offset_frac:
492
- log.warning("Deviation from target count (%.1f%%) is larger than allowed, retrying last image...", frac)
492
+ log.info("Deviation from target count (%.1f%%) is larger than allowed, retrying last image...", frac)
493
493
  return False
494
494
  else:
495
495
  log.info("Calculated new exposure time to be %.2fs.", self._exptime)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyobs-core"
3
- version = "2.0.0.dev89"
3
+ version = "2.0.0.dev91"
4
4
  description = "robotic telescope software"
5
5
  authors = [{ name = "Tim-Oliver Husser", email = "thusser@uni-goettingen.de" }]
6
6
  requires-python = ">=3.11"