pyobs-core 2.0.0.dev26__tar.gz → 2.0.0.dev28__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 (448) hide show
  1. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/PKG-INFO +1 -1
  2. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/rpc.py +56 -24
  3. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xmppcomm.py +3 -3
  4. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IAcquisition.py +4 -1
  5. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IAutoFocus.py +2 -1
  6. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ICalibrate.py +5 -1
  7. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IConfig.py +3 -2
  8. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IData.py +1 -0
  9. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IDataSequence.py +2 -1
  10. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IExposureTime.py +2 -0
  11. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IFilters.py +1 -1
  12. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IFlatField.py +3 -0
  13. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IFocusModel.py +7 -1
  14. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IFocuser.py +3 -1
  15. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IMode.py +1 -1
  16. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IMultiFiber.py +3 -0
  17. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingAltAz.py +2 -0
  18. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingBody.py +5 -2
  19. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingHeliocentricPolar.py +3 -1
  20. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +3 -1
  21. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingHelioprojective.py +3 -1
  22. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingOrbitalElements.py +6 -3
  23. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingRaDec.py +3 -0
  24. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IPointingSeries.py +5 -1
  25. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IRotation.py +5 -1
  26. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IRunnable.py +7 -1
  27. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IScriptRunner.py +3 -0
  28. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ISyncTarget.py +5 -1
  29. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ITrackingMode.py +1 -1
  30. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IWeather.py +4 -0
  31. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/basecamera.py +12 -13
  32. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/basespectrograph.py +8 -2
  33. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/basevideo.py +5 -1
  34. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/dummycamera.py +2 -1
  35. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/dummyspectrograph.py +3 -2
  36. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/flatfield/flatfield.py +7 -7
  37. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/flatfield/scheduler.py +7 -2
  38. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/focus/focusmodel.py +39 -6
  39. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/focus/focusseries.py +5 -5
  40. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/module.py +188 -35
  41. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/_base.py +2 -2
  42. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +2 -2
  43. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +1 -1
  44. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/guidingstatistics/uptime.py +1 -1
  45. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/scienceframeguiding.py +5 -1
  46. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/robotic/mastermind.py +7 -2
  47. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/robotic/scriptrunner.py +13 -3
  48. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/roof/basedome.py +1 -1
  49. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/roof/dummyroof.py +20 -13
  50. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/telescope/_dummytelescopebase.py +44 -18
  51. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/telescope/basetelescope.py +53 -14
  52. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/dummymode.py +3 -2
  53. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/weather/mockweather.py +5 -1
  54. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/weather/weather.py +13 -1
  55. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/astroplanscheduler.py +3 -1
  56. pyobs_core-2.0.0.dev28/pyobs/robotic/scripts/__init__.py +4 -0
  57. pyobs_core-2.0.0.dev28/pyobs/robotic/scripts/exceptions.py +12 -0
  58. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/imaging/autofocus.py +6 -1
  59. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/imaging/imaging.py +1 -1
  60. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/task.py +11 -11
  61. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/taskrunner.py +7 -4
  62. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/task.py +7 -0
  63. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/taskrunner.py +9 -5
  64. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/curvefit.py +13 -1
  65. pyobs_core-2.0.0.dev28/pyobs/utils/exceptions.py +195 -0
  66. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/focusseries/photometry.py +6 -1
  67. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/focusseries/projection.py +9 -8
  68. pyobs_core-2.0.0.dev28/pyobs/utils/threads/__init__.py +3 -0
  69. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/threads/lockwithabort.py +4 -7
  70. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyproject.toml +1 -1
  71. pyobs_core-2.0.0.dev26/pyobs/robotic/scripts/__init__.py +0 -3
  72. pyobs_core-2.0.0.dev26/pyobs/utils/exceptions.py +0 -290
  73. pyobs_core-2.0.0.dev26/pyobs/utils/threads/__init__.py +0 -3
  74. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/.gitignore +0 -0
  75. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/LICENSE +0 -0
  76. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/__init__.py +0 -0
  77. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/application.py +0 -0
  78. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/background_task.py +0 -0
  79. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/cli/__init__.py +0 -0
  80. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/cli/_cli.py +0 -0
  81. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/cli/pyobs.py +0 -0
  82. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/cli/pyobsd.py +0 -0
  83. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/cli/pyobsw.py +0 -0
  84. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/__init__.py +0 -0
  85. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/comm.py +0 -0
  86. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/commlogging.py +0 -0
  87. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/dummy/__init__.py +0 -0
  88. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/dummy/dummycomm.py +0 -0
  89. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/local/__init__.py +0 -0
  90. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/local/localcomm.py +0 -0
  91. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/local/localnetwork.py +0 -0
  92. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/proxy.py +0 -0
  93. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/__init__.py +0 -0
  94. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/serializer.py +0 -0
  95. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  96. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  97. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  98. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  99. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  100. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  101. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  102. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/comm/xmpp/xmppclient.py +0 -0
  103. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/__init__.py +0 -0
  104. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/badweather.py +0 -0
  105. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/event.py +0 -0
  106. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/exposurestatuschanged.py +0 -0
  107. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/filterchanged.py +0 -0
  108. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/focusfound.py +0 -0
  109. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/goodweather.py +0 -0
  110. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/log.py +0 -0
  111. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/modechanged.py +0 -0
  112. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/moduleclosed.py +0 -0
  113. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/moduleopened.py +0 -0
  114. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/motionstatuschanged.py +0 -0
  115. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/move.py +0 -0
  116. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/newimage.py +0 -0
  117. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/newspectrum.py +0 -0
  118. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/offsets.py +0 -0
  119. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/roofclosing.py +0 -0
  120. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/roofopened.py +0 -0
  121. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/taskfailed.py +0 -0
  122. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/taskfinished.py +0 -0
  123. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/taskstarted.py +0 -0
  124. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/events/testevent.py +0 -0
  125. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/__init__.py +0 -0
  126. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/image.py +0 -0
  127. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/__init__.py +0 -0
  128. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/altazoffsets.py +0 -0
  129. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/exptime.py +0 -0
  130. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/genericoffset.py +0 -0
  131. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/onskydistance.py +0 -0
  132. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/pixeloffsets.py +0 -0
  133. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/radecoffsets.py +0 -0
  134. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/meta/skyoffsets.py +0 -0
  135. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processor.py +0 -0
  136. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/__init__.py +0 -0
  137. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  138. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/annotation/__init__.py +0 -0
  139. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/annotation/_pillow.py +0 -0
  140. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/annotation/circle.py +0 -0
  141. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/annotation/crosshair.py +0 -0
  142. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/annotation/text.py +0 -0
  143. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/__init__.py +0 -0
  144. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  145. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  146. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  147. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  148. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  149. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  150. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/calibration/__init__.py +0 -0
  151. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  152. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  153. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/calibration/calibration.py +0 -0
  154. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/__init__.py +0 -0
  155. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  156. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  157. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/daophot.py +0 -0
  158. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/pysep.py +0 -0
  159. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/simpledisk.py +0 -0
  160. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  161. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/exptime/__init__.py +0 -0
  162. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/exptime/exptime.py +0 -0
  163. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/exptime/star.py +0 -0
  164. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/__init__.py +0 -0
  165. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  166. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/download.py +0 -0
  167. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/flip.py +0 -0
  168. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/grayscale.py +0 -0
  169. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/httpserver.py +0 -0
  170. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/normalize.py +0 -0
  171. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/save.py +0 -0
  172. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/saveimage.py +0 -0
  173. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/smooth.py +0 -0
  174. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/image/softbin.py +0 -0
  175. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/__init__.py +0 -0
  176. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/addmask.py +0 -0
  177. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  178. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/circularmask.py +0 -0
  179. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/createfilename.py +0 -0
  180. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  181. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/misc/removebackground.py +0 -0
  182. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/modules/__init__.py +0 -0
  183. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  184. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/__init__.py +0 -0
  185. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/astrometry.py +0 -0
  186. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  187. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  188. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  189. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  190. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  191. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/offsets.py +0 -0
  192. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  193. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/projected.py +0 -0
  194. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  195. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/__init__.py +0 -0
  196. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  197. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  198. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  199. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  200. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/photometry.py +0 -0
  201. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/photutil.py +0 -0
  202. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/photometry/pysep.py +0 -0
  203. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/wcs/__init__.py +0 -0
  204. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  205. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IAbortable.py +0 -0
  206. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IAutoGuiding.py +0 -0
  207. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IAutonomous.py +0 -0
  208. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IBinning.py +0 -0
  209. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ICamera.py +0 -0
  210. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ICooling.py +0 -0
  211. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IDome.py +0 -0
  212. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IExposure.py +0 -0
  213. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  214. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  215. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IGain.py +0 -0
  216. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IImageFormat.py +0 -0
  217. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IImageType.py +0 -0
  218. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IModule.py +0 -0
  219. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IMotion.py +0 -0
  220. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  221. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  222. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IReady.py +0 -0
  223. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IRoof.py +0 -0
  224. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IRunning.py +0 -0
  225. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ISpectrograph.py +0 -0
  226. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IStartStop.py +0 -0
  227. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IStructuredConfig.py +0 -0
  228. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ITelescope.py +0 -0
  229. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ITemperatures.py +0 -0
  230. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/ITrackingRate.py +0 -0
  231. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IVideo.py +0 -0
  232. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/IWindow.py +0 -0
  233. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/__init__.py +0 -0
  234. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/interfaces/interface.py +0 -0
  235. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/__init__.py +0 -0
  236. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/camerasettings.py +0 -0
  237. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/fitsheader.py +0 -0
  238. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/fitsnamespace.py +0 -0
  239. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/follow.py +0 -0
  240. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/motionstatus.py +0 -0
  241. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/pipeline.py +0 -0
  242. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/waitformotion.py +0 -0
  243. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/mixins/weatheraware.py +0 -0
  244. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/__init__.py +0 -0
  245. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/__init__.py +0 -0
  246. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/adaptive.py +0 -0
  247. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/dummyvideo.py +0 -0
  248. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/camera/pipelinecamera.py +0 -0
  249. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/flatfield/__init__.py +0 -0
  250. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/flatfield/pointing.py +0 -0
  251. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/focus/__init__.py +0 -0
  252. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/focus/dummyautofocus.py +0 -0
  253. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/image/__init__.py +0 -0
  254. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/image/imagewatcher.py +0 -0
  255. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/image/imagewriter.py +0 -0
  256. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/image/pipeline.py +0 -0
  257. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/image/seeing.py +0 -0
  258. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/__init__.py +0 -0
  259. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/_baseguiding.py +0 -0
  260. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/acquisition.py +0 -0
  261. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/autoguiding.py +0 -0
  262. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  263. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/dummyguiding.py +0 -0
  264. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  265. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  266. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/robotic/__init__.py +0 -0
  267. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/robotic/pointing.py +0 -0
  268. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/robotic/scheduler.py +0 -0
  269. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/roof/__init__.py +0 -0
  270. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/roof/baseroof.py +0 -0
  271. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/telescope/__init__.py +0 -0
  272. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
  273. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
  274. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
  275. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/test/__init__.py +0 -0
  276. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/test/standalone.py +0 -0
  277. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/__init__.py +0 -0
  278. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/fluentlogger.py +0 -0
  279. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/httpfilecache.py +0 -0
  280. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/kiosk.py +0 -0
  281. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/matrix.py +0 -0
  282. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/stellarium.py +0 -0
  283. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/telegram.py +0 -0
  284. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/utils/trigger.py +0 -0
  285. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/weather/__init__.py +0 -0
  286. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/weather/weather_api.py +0 -0
  287. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/modules/weather/weather_state.py +0 -0
  288. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/object.py +0 -0
  289. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/py.typed +0 -0
  290. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/__init__.py +0 -0
  291. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/observation.py +0 -0
  292. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/__init__.py +0 -0
  293. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  294. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  295. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  296. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  297. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  298. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  299. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  300. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/dataprovider.py +0 -0
  301. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  302. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  303. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  304. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  305. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  306. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  307. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  308. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  309. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/random.py +0 -0
  310. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  311. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  312. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  313. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
  314. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  315. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  316. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  317. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  318. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  319. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  320. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  321. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  322. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/targets/target.py +0 -0
  323. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  324. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  325. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
  326. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  327. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  328. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/control/__init__.py +0 -0
  329. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/control/cases.py +0 -0
  330. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/control/conditional.py +0 -0
  331. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/control/parallel.py +0 -0
  332. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/control/selector.py +0 -0
  333. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/control/sequential.py +0 -0
  334. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  335. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  336. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/script.py +0 -0
  337. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  338. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  339. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  340. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/scripts/utils/log.py +0 -0
  341. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/__init__.py +0 -0
  342. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/backend/__init__.py +0 -0
  343. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  344. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  345. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  346. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  347. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  348. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/__init__.py +0 -0
  349. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/_portal.py +0 -0
  350. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  351. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  352. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/configdb.py +0 -0
  353. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  354. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  355. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  356. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  357. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  358. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  359. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  360. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/memory/__init__.py +0 -0
  361. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  362. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  363. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/observationarchive.py +0 -0
  364. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/storage/taskarchive.py +0 -0
  365. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/__init__.py +0 -0
  366. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/archive/__init__.py +0 -0
  367. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/archive/archive.py +0 -0
  368. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  369. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  370. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  371. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  372. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  373. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  374. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  375. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
  376. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  377. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  378. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  379. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  380. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  381. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  382. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  383. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  384. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/__init__.py +0 -0
  385. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/average.py +0 -0
  386. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/cache.py +0 -0
  387. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/config.py +0 -0
  388. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/config_schema.py +0 -0
  389. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/coordinates.py +0 -0
  390. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/enums.py +0 -0
  391. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/fits.py +0 -0
  392. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/focusseries/__init__.py +0 -0
  393. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/focusseries/base.py +0 -0
  394. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/grids/__init__.py +0 -0
  395. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/grids/filters.py +0 -0
  396. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/grids/grid.py +0 -0
  397. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/grids/gridnode.py +0 -0
  398. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/grids/pipeline.py +0 -0
  399. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/__init__.py +0 -0
  400. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/__init__.py +0 -0
  401. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  402. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  403. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  404. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  405. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  406. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  407. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  408. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/http.py +0 -0
  409. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/influxdb.py +0 -0
  410. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/logger.py +0 -0
  411. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/logging/__init__.py +0 -0
  412. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/logging/context.py +0 -0
  413. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/logging/resolvableerror.py +0 -0
  414. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/modulegui.py +0 -0
  415. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/offsets/__init__.py +0 -0
  416. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  417. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/offsets/applyoffsets.py +0 -0
  418. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  419. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/parallel.py +0 -0
  420. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/pipeline/__init__.py +0 -0
  421. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/pipeline/night.py +0 -0
  422. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/pipeline/pipeline.py +0 -0
  423. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/publisher/__init__.py +0 -0
  424. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/publisher/csv.py +0 -0
  425. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/publisher/http.py +0 -0
  426. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/publisher/log.py +0 -0
  427. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/publisher/multi.py +0 -0
  428. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/publisher/publisher.py +0 -0
  429. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/serialization.py +0 -0
  430. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/shellcommand.py +0 -0
  431. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/time.py +0 -0
  432. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/utils/units.py +0 -0
  433. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/version.py +0 -0
  434. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/__init__.py +0 -0
  435. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/archivefile.py +0 -0
  436. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/bufferedfile.py +0 -0
  437. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/file.py +0 -0
  438. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/filelists/__init__.py +0 -0
  439. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/filelists/filelist.py +0 -0
  440. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/filelists/testing.py +0 -0
  441. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/httpfile.py +0 -0
  442. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/localfile.py +0 -0
  443. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/memfile.py +0 -0
  444. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/sftpfile.py +0 -0
  445. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/smbfile.py +0 -0
  446. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/sshfile.py +0 -0
  447. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/pyobs/vfs/tempfile.py +0 -0
  448. {pyobs_core-2.0.0.dev26 → pyobs_core-2.0.0.dev28}/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.dev26
3
+ Version: 2.0.0.dev28
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -96,9 +96,22 @@ def fault_to_xml(exception: Exception) -> ET.Element:
96
96
  value_elem = ET.Element(f"{{{_NS}}}value")
97
97
  pyobs_fault = ET.Element(f"{{{_PYOBS_NS}}}fault")
98
98
  exc_elem = ET.Element("exception")
99
- exc_elem.text = type(exception).__name__
99
+ # Fully-qualified name, not the bare class name -- domain exceptions can live anywhere, not
100
+ # just in pyobs.utils.exceptions (see PyobsError._registry / resolve()). If this is an
101
+ # UnclassifiedError wrapping something that was never a PyobsError to begin with (see
102
+ # Module.execute()'s classification), serialize the ORIGINAL type's name instead of
103
+ # "UnclassifiedError" itself -- original_type never crosses the wire as an attribute (only the
104
+ # class name and message do), so this is the only way it survives to the caller. The caller's
105
+ # own registry lookup then decides fresh: an unregistered builtin/vendor type still correctly
106
+ # falls back to UnclassifiedError, but this time with original_type actually populated.
107
+ original_type = getattr(exception, "original_type", None)
108
+ exc_elem.text = original_type if original_type else f"{type(exception).__module__}.{type(exception).__qualname__}"
100
109
  msg_elem = ET.Element("message")
101
- msg_elem.text = str(exception)
110
+ # the raw message, not str(exception) -- str() already prepends "<ClassName>", and
111
+ # reconstruction on the caller's side passes this straight back in as the new instance's
112
+ # message, so serializing str() here would bake in a doubled "<ClassName> <ClassName> ..." once
113
+ # the caller's own __str__ formats it again
114
+ msg_elem.text = getattr(exception, "message", None) or str(exception)
102
115
  pyobs_fault.append(exc_elem)
103
116
  pyobs_fault.append(msg_elem)
104
117
  value_elem.append(pyobs_fault)
@@ -107,16 +120,17 @@ def fault_to_xml(exception: Exception) -> ET.Element:
107
120
 
108
121
 
109
122
  def xml_to_fault(fault_elem: ET.Element) -> tuple[str, str]:
110
- """Parse <fault> and return (exception_class_name, message)."""
123
+ """Parse <fault> and return (exception_qualified_name, message)."""
124
+ _fallback_name = f"{exc.RemoteError.__module__}.{exc.RemoteError.__qualname__}"
111
125
  value_elem = fault_elem.find(f"{{{_NS}}}value")
112
126
  if value_elem is None:
113
- return "RemoteError", "Unknown error"
127
+ return _fallback_name, "Unknown error"
114
128
  pyobs_fault = value_elem.find(f"{{{_PYOBS_NS}}}fault")
115
129
  if pyobs_fault is None:
116
- return "RemoteError", "Unknown error"
130
+ return _fallback_name, "Unknown error"
117
131
  exc_el = pyobs_fault.find("exception")
118
132
  msg_el = pyobs_fault.find("message")
119
- exc_name = (exc_el.text if exc_el is not None else None) or "RemoteError"
133
+ exc_name = (exc_el.text if exc_el is not None else None) or _fallback_name
120
134
  msg = (msg_el.text if msg_el is not None else None) or ""
121
135
  return exc_name, msg
122
136
 
@@ -170,6 +184,13 @@ class RPC:
170
184
  iq.enable("rpc_query")
171
185
  pmethod = iq["rpc_query"]["method_call"]["method_name"]
172
186
 
187
+ # XEP-0009 already assigns this per call (used elsewhere as the Future dict key) -- reuse
188
+ # it as a correlation id so an operator can jump from a caller-side exception straight to
189
+ # the matching origin-side log line, instead of neither side pointing at the other
190
+ call_id: str | slixmpp.JID = iq["id"]
191
+ if isinstance(call_id, slixmpp.JID):
192
+ call_id = call_id.node
193
+
173
194
  try:
174
195
  if self._handler is None:
175
196
  return
@@ -208,7 +229,7 @@ class RPC:
208
229
  response.send()
209
230
 
210
231
  # Call method
211
- return_value = await self._handler.execute(pmethod, *params, sender=iq["from"].user)
232
+ return_value = await self._handler.execute(pmethod, *params, sender=iq["from"].user, call_id=call_id)
212
233
 
213
234
  # Serialize return value
214
235
  return_type = hints.get("return", type(None))
@@ -220,9 +241,12 @@ class RPC:
220
241
  self._client.plugin["xep_0009"].forbidden(iq).send()
221
242
 
222
243
  except Exception as e:
223
- if isinstance(e, exc.PyObsError):
224
- e.log(log, "ERROR", f"Exception in call to {pmethod}: {e}", exc_info=True)
225
- else:
244
+ # Module.execute() already classified and logged anything raised by the call itself
245
+ # (every transport gets the same treatment there now), so there's nothing left to do
246
+ # here but serialize and send the fault -- except for failures that never reached
247
+ # execute() at all (e.g. malformed RPC parameters during deserialization above), which
248
+ # this is the only place that will ever log
249
+ if not isinstance(e, exc.PyobsError):
226
250
  log.exception("Unexpected exception in %s.", pmethod)
227
251
  self._client.plugin["xep_0009"].send_fault(iq, fault_to_xml(e))
228
252
 
@@ -269,18 +293,22 @@ class RPC:
269
293
  fault_elem = iq["rpc_query"]["method_response"]["fault"]
270
294
  exc_name, msg = xml_to_fault(fault_elem)
271
295
 
272
- exception_class = getattr(exc, exc_name, None)
273
- if exception_class is None or not issubclass(exception_class, Exception):
274
- exception_class = exc.RemoteError
275
-
276
296
  sender = iq["from"].node
277
- if issubclass(exception_class, exc.RemoteError):
278
- exception = exception_class(message=msg, module=sender)
297
+ exception_class = exc.PyobsError.resolve(exc_name)
298
+ if exception_class is not None:
299
+ # real registered type (e.g. FocusError) -- raised as itself, not wrapped
300
+ exception: exc.PyobsError = exception_class(msg, remote_module=sender)
279
301
  else:
280
- exception = exception_class(msg)
302
+ # unresolvable: never a PyobsError to begin with, or its defining module was never
303
+ # imported in this process -- the qualified name string still survives as original_type
304
+ exception = exc.UnclassifiedError(msg, original_type=exc_name, remote_module=sender)
305
+
306
+ # same correlation id Module.execute() logged on the origin side -- an operator can jump
307
+ # straight from this caller-side exception to the matching detailed log line, by id
308
+ setattr(exception, "call_id", jid)
281
309
 
282
310
  if not future.done():
283
- future.set_exception(exc.InvocationError(module=sender, exception=exception))
311
+ future.set_exception(exception)
284
312
 
285
313
  async def _on_jabber_rpc_error(self, iq: Any) -> None:
286
314
  pmethod = self._client.plugin["xep_0009"].extract_method(iq["rpc_query"])
@@ -295,12 +323,16 @@ class RPC:
295
323
 
296
324
  sender = iq["from"].node
297
325
  e = {
298
- "item-not-found": exc.RemoteError(sender, f"No remote handler for {pmethod} at {iq['from']}!"),
299
- "forbidden": exc.RemoteError(sender, f"Forbidden to invoke {pmethod} at {iq['from']}!"),
300
- "undefined-condition": exc.RemoteError(sender, f"Unexpected problem invoking {pmethod} at {iq['from']}!"),
301
- "service-unavailable": exc.RemoteError(sender, f"Service at {iq['from']} is unavailable."),
302
- "remote-server-not-found": exc.RemoteError(sender, f"Could not find remote server for {iq['from']}."),
303
- }.get(condition, exc.RemoteError(sender, f"Unexpected exception at {iq['from']}!"))
326
+ "item-not-found": exc.RemoteError(f"No remote handler for {pmethod} at {iq['from']}!", module=sender),
327
+ "forbidden": exc.RemoteError(f"Forbidden to invoke {pmethod} at {iq['from']}!", module=sender),
328
+ "undefined-condition": exc.RemoteError(
329
+ f"Unexpected problem invoking {pmethod} at {iq['from']}!", module=sender
330
+ ),
331
+ "service-unavailable": exc.RemoteError(f"Service at {iq['from']} is unavailable.", module=sender),
332
+ "remote-server-not-found": exc.RemoteError(
333
+ f"Could not find remote server for {iq['from']}.", module=sender
334
+ ),
335
+ }.get(condition, exc.RemoteError(f"Unexpected exception at {iq['from']}!", module=sender))
304
336
 
305
337
  callback.set_exception(e)
306
338
 
@@ -503,10 +503,10 @@ class XmppComm(Comm):
503
503
  # RPC layer's jabber_rpc_error event handling ever gets a chance to act on it,
504
504
  # so the IQ-level "forbidden" condition (see Module ACLs) has to be read here.
505
505
  if e.iq["error"]["condition"] == "forbidden":
506
- raise exc.RemoteError(client, f"Forbidden to invoke {method} on {client}.")
507
- raise exc.RemoteError(client, f"Could not call {method} on {client}.")
506
+ raise exc.RemoteError(f"Forbidden to invoke {method} on {client}.", module=client)
507
+ raise exc.RemoteError(f"Could not call {method} on {client}.", module=client)
508
508
  except slixmpp.exceptions.IqTimeout:
509
- raise exc.RemoteTimeoutError(client, f"Call to {method} on {client} timed out.")
509
+ raise exc.RemoteTimeoutError(f"Call to {method} on {client} timed out.", module=client)
510
510
 
511
511
  async def _got_online(self, msg: Any) -> None:
512
512
  """If a new client connects, add it to list.
@@ -59,7 +59,10 @@ class IAcquisition(IRunning, IAbortable, metaclass=ABCMeta):
59
59
  Result with time, ra, dec, alt, az, and an offset in whichever frame the mount supports.
60
60
 
61
61
  Raises:
62
- ValueError: If target could not be acquired.
62
+ AbortedError: If the acquisition was aborted.
63
+ GeneralError: If a dependency (e.g. the camera) failed.
64
+ ImageError: If the calculated offset was too large or otherwise unusable.
65
+ AcquisitionError: If target could not be acquired within the given tolerance.
63
66
  """
64
67
  ...
65
68
 
@@ -54,7 +54,8 @@ class IAutoFocus(IRunning, IAbortable, metaclass=ABCMeta):
54
54
  Result of autofocus.
55
55
 
56
56
  Raises:
57
- ValueError: If focus could not be obtained.
57
+ AbortedError: If the autofocus series was aborted.
58
+ FocusError: If focus could not be obtained.
58
59
  """
59
60
  ...
60
61
 
@@ -11,7 +11,11 @@ class ICalibrate(Interface, metaclass=ABCMeta):
11
11
 
12
12
  @abstractmethod
13
13
  async def calibrate(self, **kwargs: Any) -> None:
14
- """Calibrate the device."""
14
+ """Calibrate the device.
15
+
16
+ Raises:
17
+ GeneralError: If calibration failed.
18
+ """
15
19
  ...
16
20
 
17
21
 
@@ -33,7 +33,7 @@ class IConfig(Interface, metaclass=ABCMeta):
33
33
  Current value.
34
34
 
35
35
  Raises:
36
- ValueError: If config item of given name does not exist.
36
+ InvalidArgumentError: If config item of given name does not exist.
37
37
  """
38
38
  ...
39
39
 
@@ -46,7 +46,8 @@ class IConfig(Interface, metaclass=ABCMeta):
46
46
  value: New value.
47
47
 
48
48
  Raises:
49
- ValueError: If config item of given name does not exist or value is invalid.
49
+ InvalidArgumentError: If config item of given name does not exist.
50
+ ValueError: If value is invalid.
50
51
  """
51
52
  ...
52
53
 
@@ -20,6 +20,7 @@ class IData(Interface, metaclass=ABCMeta):
20
20
  Name of image that was taken.
21
21
 
22
22
  Raises:
23
+ DeviceBusyError: If the device is already busy (exposing or running a sequence).
23
24
  GrabImageError: If there was a problem grabbing the image.
24
25
  """
25
26
  ...
@@ -38,7 +38,8 @@ class IDataSequence(IAbortable, metaclass=ABCMeta):
38
38
  during the wait.
39
39
 
40
40
  Raises:
41
- GrabImageError: If the device is already busy (exposing or already running a
41
+ InvalidArgumentError: If count or delay is out of range.
42
+ DeviceBusyError: If the device is already busy (exposing or already running a
42
43
  sequence).
43
44
  """
44
45
  ...
@@ -31,6 +31,8 @@ class IExposureTime(Interface, metaclass=ABCMeta):
31
31
 
32
32
  Raises:
33
33
  ValueError: If exposure time could not be set.
34
+ NotSupportedError: If this module doesn't support setting exposure time directly (e.g.
35
+ it's dictated by something else, like incoming science frames).
34
36
  """
35
37
  ...
36
38
 
@@ -35,7 +35,7 @@ class IFilters(IMotion, metaclass=ABCMeta):
35
35
  filter_name: Name of filter to set.
36
36
 
37
37
  Raises:
38
- ValueError: If an invalid filter was given.
38
+ InvalidArgumentError: If an invalid filter was given.
39
39
  MoveError: If filter wheel cannot be moved.
40
40
  """
41
41
  ...
@@ -21,6 +21,9 @@ class IFlatField(IAbortable, metaclass=ABCMeta):
21
21
 
22
22
  Returns:
23
23
  Number of images actually taken and total exposure time in seconds
24
+
25
+ Raises:
26
+ DeviceBusyError: If a flat-fielding run is already in progress.
24
27
  """
25
28
  ...
26
29
 
@@ -21,7 +21,13 @@ class IFocusModel(Interface, metaclass=ABCMeta):
21
21
 
22
22
  @abstractmethod
23
23
  async def set_optimal_focus(self, **kwargs: Any) -> None:
24
- """Sets optimal focus."""
24
+ """Sets optimal focus.
25
+
26
+ Raises:
27
+ WeatherDataError: If the weather station returned an invalid temperature reading.
28
+ FocusTimeoutError: If a temperature module didn't respond in time.
29
+ MissingSensorError: If a configured sensor isn't in a module's temperature data.
30
+ """
25
31
  ...
26
32
 
27
33
 
@@ -31,8 +31,9 @@ class IFocuser(IMotion, metaclass=ABCMeta):
31
31
  focus: New focus value in mm.
32
32
 
33
33
  Raises:
34
+ InvalidArgumentError: If given value is invalid.
35
+ AbortedError: If movement was aborted.
34
36
  MoveError: If telescope cannot be moved.
35
- InterruptedError: If movement was aborted.
36
37
  """
37
38
  ...
38
39
 
@@ -45,6 +46,7 @@ class IFocuser(IMotion, metaclass=ABCMeta):
45
46
 
46
47
  Raises:
47
48
  ValueError: If given value is invalid.
49
+ NotSupportedError: If this module doesn't support a separate focus offset.
48
50
  MoveError: If telescope cannot be moved.
49
51
  """
50
52
  ...
@@ -36,7 +36,7 @@ class IMode(Interface, metaclass=ABCMeta):
36
36
  group: Name of the group to set the mode for.
37
37
 
38
38
  Raises:
39
- ValueError: If an invalid mode or group was given.
39
+ InvalidArgumentError: If an invalid mode or group was given.
40
40
  MoveError: If mode selector cannot be moved.
41
41
  """
42
42
  ...
@@ -42,6 +42,9 @@ class IMultiFiber(Interface, metaclass=ABCMeta):
42
42
 
43
43
  Args:
44
44
  fiber: Name of fiber to set.
45
+
46
+ Raises:
47
+ InvalidArgumentError: If fiber name is invalid.
45
48
  """
46
49
  ...
47
50
 
@@ -34,6 +34,8 @@ class IPointingAltAz(Interface, metaclass=ABCMeta):
34
34
  az: Az in deg to move to.
35
35
 
36
36
  Raises:
37
+ NotSupportedError: If this device doesn't support Alt/Az pointing.
38
+ AltitudeLimitError: If the destination is below the configured altitude limit.
37
39
  MoveError: If device could not be moved.
38
40
  """
39
41
  ...
@@ -20,8 +20,11 @@ class IPointingBody(Interface, metaclass=ABCMeta):
20
20
  asteroid/comet designation known to JPL Horizons).
21
21
 
22
22
  Raises:
23
- MoveError: If telescope could not be moved.
24
- ValueError: If body name is not resolvable.
23
+ NotSupportedError: If this device doesn't support body tracking.
24
+ BodyResolutionError: If body name is not resolvable.
25
+ MoveError: If telescope could not be moved. Also propagates whatever the underlying
26
+ RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since tracking
27
+ a body is implemented as resolving it and then moving there.
25
28
  """
26
29
  ...
27
30
 
@@ -33,7 +33,9 @@ class IPointingHeliocentricPolar(Interface, metaclass=ABCMeta):
33
33
  psi: Position angle around the solar disk, in degrees.
34
34
 
35
35
  Raises:
36
- MoveError: If device could not be moved.
36
+ MoveError: If device could not be moved. Also propagates whatever the underlying
37
+ RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since this is
38
+ typically implemented as converting to RA/Dec and then moving there.
37
39
  """
38
40
  ...
39
41
 
@@ -35,7 +35,9 @@ class IPointingHeliographicStonyhurst(Interface, metaclass=ABCMeta):
35
35
  lat: Latitude in deg to track.
36
36
 
37
37
  Raises:
38
- MoveError: If device could not be moved.
38
+ MoveError: If device could not be moved. Also propagates whatever the underlying
39
+ RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since this is
40
+ typically implemented as converting to RA/Dec and then moving there.
39
41
  """
40
42
  ...
41
43
 
@@ -34,7 +34,9 @@ class IPointingHelioprojective(Interface, metaclass=ABCMeta):
34
34
  theta_y: The theta_y coordinate.
35
35
 
36
36
  Raises:
37
- MoveError: If device could not be moved.
37
+ MoveError: If device could not be moved. Also propagates whatever the underlying
38
+ RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since this is
39
+ typically implemented as converting to RA/Dec and then moving there.
38
40
  """
39
41
  ...
40
42
 
@@ -37,9 +37,12 @@ class IPointingOrbitalElements(Interface, metaclass=ABCMeta):
37
37
  elements: Orbital elements of the body to track.
38
38
 
39
39
  Raises:
40
- MoveError: If telescope could not be moved.
41
- ValueError: If elements are incomplete or inconsistent (neither mean_anomaly
42
- nor perihelion_time given).
40
+ NotSupportedError: If this device doesn't support orbital-element tracking.
41
+ InvalidOrbitalElementsError: If elements are incomplete or inconsistent (neither
42
+ mean_anomaly nor perihelion_time given).
43
+ MoveError: If telescope could not be moved. Also propagates whatever the underlying
44
+ RA/Dec move raises (e.g. MissingObserverError, AltitudeLimitError), since tracking
45
+ orbital elements is implemented as propagating them and then moving there.
43
46
  """
44
47
  ...
45
48
 
@@ -34,6 +34,9 @@ class IPointingRaDec(Interface, metaclass=ABCMeta):
34
34
  dec: Dec in deg to track.
35
35
 
36
36
  Raises:
37
+ NotSupportedError: If this device doesn't support RA/Dec pointing.
38
+ MissingObserverError: If no observer is configured.
39
+ AltitudeLimitError: If the destination is below the configured altitude limit.
37
40
  MoveError: If device could not be moved.
38
41
  """
39
42
  ...
@@ -12,7 +12,11 @@ class IPointingSeries(Interface, metaclass=ABCMeta):
12
12
 
13
13
  @abstractmethod
14
14
  async def add_pointing_measurement(self, **kwargs: Any) -> None:
15
- """Add a new measurement to the pointing series."""
15
+ """Add a new measurement to the pointing series.
16
+
17
+ Raises:
18
+ GeneralError: If the measurement could not be added.
19
+ """
16
20
  ...
17
21
 
18
22
 
@@ -24,7 +24,11 @@ class IRotation(IMotion, metaclass=ABCMeta):
24
24
 
25
25
  @abstractmethod
26
26
  async def set_rotation(self, angle: Annotated[float, Unit.DEGREES], **kwargs: Any) -> None:
27
- """Sets the rotation angle to the given value in degrees."""
27
+ """Sets the rotation angle to the given value in degrees.
28
+
29
+ Raises:
30
+ MoveError: If the device could not be rotated.
31
+ """
28
32
  ...
29
33
 
30
34
 
@@ -11,7 +11,13 @@ class IRunnable(IAbortable, metaclass=ABCMeta):
11
11
 
12
12
  @abstractmethod
13
13
  async def run(self, **kwargs: Any) -> None:
14
- """Perform module task"""
14
+ """Perform module task
15
+
16
+ Raises:
17
+ DeviceBusyError: If this task is already running.
18
+ ScriptError: ScriptRunner-based implementations wrap whatever the underlying script
19
+ raises that isn't already a domain exception.
20
+ """
15
21
  ...
16
22
 
17
23
 
@@ -15,6 +15,9 @@ class IScriptRunner(Interface, metaclass=ABCMeta):
15
15
 
16
16
  Args:
17
17
  script: Script to run.
18
+
19
+ Raises:
20
+ ScriptError: If the script failed.
18
21
  """
19
22
  ...
20
23
 
@@ -12,7 +12,11 @@ class ISyncTarget(Interface, metaclass=ABCMeta):
12
12
 
13
13
  @abstractmethod
14
14
  async def sync_target(self, **kwargs: Any) -> None:
15
- """Synchronize device on current target."""
15
+ """Synchronize device on current target.
16
+
17
+ Raises:
18
+ GeneralError: If synchronization failed.
19
+ """
16
20
  ...
17
21
 
18
22
 
@@ -46,7 +46,7 @@ class ITrackingMode(Interface, metaclass=ABCMeta):
46
46
 
47
47
  Raises:
48
48
  MoveError: If mode could not be set.
49
- ValueError: If mode is not in this module's capabilities.
49
+ InvalidArgumentError: If mode is not in this module's capabilities.
50
50
  """
51
51
  ...
52
52
 
@@ -42,6 +42,10 @@ class IWeather(IStartStop, metaclass=ABCMeta):
42
42
 
43
43
  Returns:
44
44
  Current reading for the given sensor.
45
+
46
+ Raises:
47
+ InvalidArgumentError: If station or sensor is unknown.
48
+ WeatherResponseError: If the underlying weather station's response is malformed.
45
49
  """
46
50
  ...
47
51
 
@@ -30,10 +30,6 @@ from pyobs.utils.enums import ExposureStatus, ImageType
30
30
  log = logging.getLogger(__name__)
31
31
 
32
32
 
33
- class CameraException(Exception):
34
- pass
35
-
36
-
37
33
  class ExposureInfo(NamedTuple):
38
34
  """Info about a running exposure."""
39
35
 
@@ -113,7 +109,7 @@ class BaseCamera(
113
109
  self._sequence_delay_abort = asyncio.Event()
114
110
 
115
111
  # register exception
116
- exc.register_exception(exc.GrabImageError, 3, timespan=600, callback=self._default_remote_error_callback)
112
+ self._register_exception(exc.GrabImageError, 3, timespan=600, callback=self._default_remote_error_callback)
117
113
 
118
114
  async def open(self) -> None:
119
115
  """Open module."""
@@ -226,6 +222,7 @@ class BaseCamera(
226
222
  The actual image.
227
223
 
228
224
  Raises:
225
+ AbortedError: If the exposure was cancelled via abort_event.
229
226
  GrabImageError: If exposure was not successful.
230
227
  """
231
228
  ...
@@ -268,7 +265,7 @@ class BaseCamera(
268
265
  if image is None or image.safe_data is None:
269
266
  raise exc.GrabImageError("Could not take image.")
270
267
 
271
- except exc.PyObsError:
268
+ except exc.PyobsError:
272
269
  # exposure was not successful (aborted?), so reset everything and re-raise
273
270
  self._exposure = None
274
271
  raise
@@ -349,12 +346,13 @@ class BaseCamera(
349
346
  Name of image that was taken.
350
347
 
351
348
  Raises:
349
+ DeviceBusyError: If the camera is already busy (exposing or running a sequence).
352
350
  GrabImageError: If there was a problem grabbing the image.
353
351
  """
354
352
 
355
353
  # are we exposing?
356
354
  if self._camera_status != ExposureStatus.IDLE:
357
- raise CameraException("Cannot start new exposure because camera is not idle.")
355
+ raise exc.DeviceBusyError("Cannot start new exposure because camera is not idle.")
358
356
  await self._change_exposure_status(ExposureStatus.EXPOSING)
359
357
 
360
358
  # expose
@@ -384,16 +382,17 @@ class BaseCamera(
384
382
  Does not apply after the last image.
385
383
 
386
384
  Raises:
387
- CameraException: If camera is already busy (exposing or already running a sequence).
385
+ InvalidArgumentError: If count or delay is out of range.
386
+ DeviceBusyError: If camera is already busy (exposing or already running a sequence).
388
387
  """
389
388
  if count < 1:
390
- raise ValueError("count must be >= 1.")
389
+ raise exc.InvalidArgumentError("count must be >= 1.")
391
390
  if delay < 0:
392
- raise ValueError("delay must be >= 0.")
391
+ raise exc.InvalidArgumentError("delay must be >= 0.")
393
392
 
394
393
  # already running a sequence, or mid-exposure outside of one?
395
394
  if self._sequence_count_left > 0 or self._camera_status != ExposureStatus.IDLE:
396
- raise CameraException("Cannot start new sequence because camera is not idle.")
395
+ raise exc.DeviceBusyError("Cannot start new sequence because camera is not idle.")
397
396
 
398
397
  log.info("Starting sequence of %d images...", count)
399
398
  self._sequence_count_left = count
@@ -406,7 +405,7 @@ class BaseCamera(
406
405
  while self._sequence_count_left > 0:
407
406
  try:
408
407
  await self.grab_data(broadcast=broadcast)
409
- except exc.PyObsError:
408
+ except exc.PyobsError:
410
409
  log.exception("Grab failed during sequence, aborting sequence.")
411
410
  break
412
411
  self._sequence_count_left -= 1
@@ -546,4 +545,4 @@ class BaseCamera(
546
545
  image.data = image.data[::-1, ::-1]
547
546
 
548
547
 
549
- __all__ = ["BaseCamera", "CameraException"]
548
+ __all__ = ["BaseCamera"]
@@ -12,6 +12,7 @@ from pyobs.events import ExposureStatusChangedEvent, NewSpectrumEvent
12
12
  from pyobs.interfaces import ExposureState, IExposure, ISpectrograph
13
13
  from pyobs.mixins.fitsheader import SpectrumFitsHeaderMixin
14
14
  from pyobs.modules import Module, timeout
15
+ from pyobs.utils import exceptions as exc
15
16
  from pyobs.utils.enums import ExposureStatus
16
17
 
17
18
  log = logging.getLogger(__name__)
@@ -80,6 +81,7 @@ class BaseSpectrograph(Module, SpectrumFitsHeaderMixin, ISpectrograph, IExposure
80
81
  The actual image and, if present, a filename.
81
82
 
82
83
  Raises:
84
+ AbortedError: If the exposure was cancelled via abort_event.
83
85
  ValueError: If exposure was not successful.
84
86
  """
85
87
  ...
@@ -169,17 +171,21 @@ class BaseSpectrograph(Module, SpectrumFitsHeaderMixin, ISpectrograph, IExposure
169
171
 
170
172
  Returns:
171
173
  Name of image that was taken.
174
+
175
+ Raises:
176
+ DeviceBusyError: If the spectrograph is already busy (exposing).
177
+ GrabImageError: If there was a problem grabbing the spectrum.
172
178
  """
173
179
 
174
180
  # are we exposing?
175
181
  if self._spectrograph_status != ExposureStatus.IDLE:
176
- raise ValueError("Cannot start new exposure because spectrograph is not idle.")
182
+ raise exc.DeviceBusyError("Cannot start new exposure because spectrograph is not idle.")
177
183
  await self._change_exposure_status(ExposureStatus.EXPOSING)
178
184
 
179
185
  # expose
180
186
  hdu, filename = await self.__expose(broadcast)
181
187
  if hdu is None:
182
- raise ValueError("Could not take spectrum.")
188
+ raise exc.GrabImageError("Could not take spectrum.")
183
189
  else:
184
190
  if filename is None:
185
191
  raise ValueError("Spectrum has not been saved, so cannot be retrieved by filename.")