pyobs-core 2.0.0.dev17__tar.gz → 2.0.0.dev19__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 (447) hide show
  1. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/PKG-INFO +1 -1
  2. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/cli/pyobsd.py +34 -5
  3. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/comm.py +12 -20
  4. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/local/localcomm.py +4 -0
  5. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/serializer.py +8 -0
  6. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xmppcomm.py +7 -3
  7. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IModule.py +10 -1
  8. pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingBody.py +29 -0
  9. pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingHeliocentricPolar.py +41 -0
  10. pyobs_core-2.0.0.dev17/pyobs/interfaces/IPointingHGS.py → pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingHeliographicStonyhurst.py +7 -6
  11. pyobs_core-2.0.0.dev19/pyobs/interfaces/IPointingOrbitalElements.py +47 -0
  12. pyobs_core-2.0.0.dev19/pyobs/interfaces/ITrackingMode.py +54 -0
  13. pyobs_core-2.0.0.dev19/pyobs/interfaces/ITrackingRate.py +54 -0
  14. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/__init__.py +22 -4
  15. pyobs_core-2.0.0.dev19/pyobs/interfaces/interface.py +77 -0
  16. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/fitsheader.py +16 -12
  17. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/basevideo.py +3 -9
  18. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/module.py +44 -8
  19. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/_baseguiding.py +2 -1
  20. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/acquisition.py +2 -1
  21. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/mastermind.py +1 -1
  22. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/scheduler.py +3 -3
  23. pyobs_core-2.0.0.dev19/pyobs/modules/telescope/__init__.py +13 -0
  24. pyobs_core-2.0.0.dev17/pyobs/modules/telescope/dummytelescope.py → pyobs_core-2.0.0.dev19/pyobs/modules/telescope/_dummytelescopebase.py +63 -35
  25. pyobs_core-2.0.0.dev19/pyobs/modules/telescope/basetelescope.py +815 -0
  26. pyobs_core-2.0.0.dev19/pyobs/modules/telescope/dummyaltaztelescope.py +46 -0
  27. pyobs_core-2.0.0.dev19/pyobs/modules/telescope/dummyradectelescope.py +55 -0
  28. pyobs_core-2.0.0.dev19/pyobs/modules/telescope/dummysolartelescope.py +149 -0
  29. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/__init__.py +1 -2
  30. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/object.py +15 -17
  31. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/flatfielder.py +1 -1
  32. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/enums.py +6 -0
  33. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/filters.py +6 -6
  34. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/serialization.py +0 -3
  35. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyproject.toml +1 -1
  36. pyobs_core-2.0.0.dev17/pyobs/interfaces/interface.py +0 -36
  37. pyobs_core-2.0.0.dev17/pyobs/modules/telescope/__init__.py +0 -11
  38. pyobs_core-2.0.0.dev17/pyobs/modules/telescope/basetelescope.py +0 -353
  39. pyobs_core-2.0.0.dev17/pyobs/modules/utils/autonomouswarning.py +0 -153
  40. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/.gitignore +0 -0
  41. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/LICENSE +0 -0
  42. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/__init__.py +0 -0
  43. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/application.py +0 -0
  44. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/background_task.py +0 -0
  45. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/cli/__init__.py +0 -0
  46. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/cli/_cli.py +0 -0
  47. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/cli/pyobs.py +0 -0
  48. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/cli/pyobsw.py +0 -0
  49. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/__init__.py +0 -0
  50. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/commlogging.py +0 -0
  51. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/dummy/__init__.py +0 -0
  52. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/dummy/dummycomm.py +0 -0
  53. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/local/__init__.py +0 -0
  54. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/local/localnetwork.py +0 -0
  55. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/proxy.py +0 -0
  56. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/__init__.py +0 -0
  57. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/rpc.py +0 -0
  58. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  59. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  60. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  61. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  62. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  63. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  64. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  65. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/comm/xmpp/xmppclient.py +0 -0
  66. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/__init__.py +0 -0
  67. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/badweather.py +0 -0
  68. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/event.py +0 -0
  69. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/exposurestatuschanged.py +0 -0
  70. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/filterchanged.py +0 -0
  71. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/focusfound.py +0 -0
  72. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/goodweather.py +0 -0
  73. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/log.py +0 -0
  74. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/modechanged.py +0 -0
  75. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/moduleclosed.py +0 -0
  76. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/moduleopened.py +0 -0
  77. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/motionstatuschanged.py +0 -0
  78. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/move.py +0 -0
  79. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/newimage.py +0 -0
  80. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/newspectrum.py +0 -0
  81. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/offsets.py +0 -0
  82. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/roofclosing.py +0 -0
  83. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/roofopened.py +0 -0
  84. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/taskfailed.py +0 -0
  85. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/taskfinished.py +0 -0
  86. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/taskstarted.py +0 -0
  87. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/events/testevent.py +0 -0
  88. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/__init__.py +0 -0
  89. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/image.py +0 -0
  90. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/__init__.py +0 -0
  91. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/altazoffsets.py +0 -0
  92. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/exptime.py +0 -0
  93. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/genericoffset.py +0 -0
  94. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/onskydistance.py +0 -0
  95. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/pixeloffsets.py +0 -0
  96. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/radecoffsets.py +0 -0
  97. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/meta/skyoffsets.py +0 -0
  98. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processor.py +0 -0
  99. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/__init__.py +0 -0
  100. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  101. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/__init__.py +0 -0
  102. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/_pillow.py +0 -0
  103. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/circle.py +0 -0
  104. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/crosshair.py +0 -0
  105. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/annotation/text.py +0 -0
  106. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/__init__.py +0 -0
  107. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  108. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  109. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  110. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  111. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  112. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  113. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/__init__.py +0 -0
  114. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  115. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  116. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/calibration/calibration.py +0 -0
  117. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/__init__.py +0 -0
  118. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  119. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  120. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/daophot.py +0 -0
  121. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/pysep.py +0 -0
  122. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/simpledisk.py +0 -0
  123. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  124. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/exptime/__init__.py +0 -0
  125. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/exptime/exptime.py +0 -0
  126. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/exptime/star.py +0 -0
  127. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/__init__.py +0 -0
  128. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  129. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/download.py +0 -0
  130. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/flip.py +0 -0
  131. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/grayscale.py +0 -0
  132. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/httpserver.py +0 -0
  133. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/normalize.py +0 -0
  134. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/save.py +0 -0
  135. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/saveimage.py +0 -0
  136. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/smooth.py +0 -0
  137. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/image/softbin.py +0 -0
  138. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/__init__.py +0 -0
  139. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/addmask.py +0 -0
  140. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  141. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/circularmask.py +0 -0
  142. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/createfilename.py +0 -0
  143. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  144. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/misc/removebackground.py +0 -0
  145. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/modules/__init__.py +0 -0
  146. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  147. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/__init__.py +0 -0
  148. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/astrometry.py +0 -0
  149. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  150. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  151. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  152. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  153. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  154. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/offsets.py +0 -0
  155. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  156. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/projected.py +0 -0
  157. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  158. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/__init__.py +0 -0
  159. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  160. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  161. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  162. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  163. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/photometry.py +0 -0
  164. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/photutil.py +0 -0
  165. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/photometry/pysep.py +0 -0
  166. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/wcs/__init__.py +0 -0
  167. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  168. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAbortable.py +0 -0
  169. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAcquisition.py +0 -0
  170. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAutoFocus.py +0 -0
  171. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAutoGuiding.py +0 -0
  172. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IAutonomous.py +0 -0
  173. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IBinning.py +0 -0
  174. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ICalibrate.py +0 -0
  175. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ICamera.py +0 -0
  176. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IConfig.py +0 -0
  177. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ICooling.py +0 -0
  178. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IData.py +0 -0
  179. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IDome.py +0 -0
  180. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IExposure.py +0 -0
  181. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IExposureTime.py +0 -0
  182. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFilters.py +0 -0
  183. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  184. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  185. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFlatField.py +0 -0
  186. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFocusModel.py +0 -0
  187. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IFocuser.py +0 -0
  188. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IGain.py +0 -0
  189. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IImageFormat.py +0 -0
  190. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IImageType.py +0 -0
  191. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IMode.py +0 -0
  192. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IMotion.py +0 -0
  193. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IMultiFiber.py +0 -0
  194. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  195. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  196. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingAltAz.py +0 -0
  197. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  198. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingRaDec.py +0 -0
  199. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IPointingSeries.py +0 -0
  200. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IReady.py +0 -0
  201. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRoof.py +0 -0
  202. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRotation.py +0 -0
  203. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRunnable.py +0 -0
  204. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IRunning.py +0 -0
  205. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IScriptRunner.py +0 -0
  206. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ISpectrograph.py +0 -0
  207. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IStartStop.py +0 -0
  208. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IStructuredConfig.py +0 -0
  209. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ISyncTarget.py +0 -0
  210. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ITelescope.py +0 -0
  211. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/ITemperatures.py +0 -0
  212. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IVideo.py +0 -0
  213. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IWeather.py +0 -0
  214. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/interfaces/IWindow.py +0 -0
  215. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/__init__.py +0 -0
  216. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/camerasettings.py +0 -0
  217. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/fitsnamespace.py +0 -0
  218. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/follow.py +0 -0
  219. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/motionstatus.py +0 -0
  220. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/pipeline.py +0 -0
  221. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/waitformotion.py +0 -0
  222. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/mixins/weatheraware.py +0 -0
  223. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/__init__.py +0 -0
  224. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/__init__.py +0 -0
  225. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/adaptive.py +0 -0
  226. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/basecamera.py +0 -0
  227. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/basespectrograph.py +0 -0
  228. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/dummycamera.py +0 -0
  229. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  230. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/dummyvideo.py +0 -0
  231. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/camera/pipelinecamera.py +0 -0
  232. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/__init__.py +0 -0
  233. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/flatfield.py +0 -0
  234. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/pointing.py +0 -0
  235. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/flatfield/scheduler.py +0 -0
  236. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/__init__.py +0 -0
  237. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/dummyautofocus.py +0 -0
  238. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/focusmodel.py +0 -0
  239. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/focus/focusseries.py +0 -0
  240. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/__init__.py +0 -0
  241. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/imagewatcher.py +0 -0
  242. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/imagewriter.py +0 -0
  243. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/pipeline.py +0 -0
  244. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/image/seeing.py +0 -0
  245. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/__init__.py +0 -0
  246. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/_base.py +0 -0
  247. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/autoguiding.py +0 -0
  248. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  249. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/dummyguiding.py +0 -0
  250. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  251. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  252. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  253. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  254. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  255. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  256. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/__init__.py +0 -0
  257. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/pointing.py +0 -0
  258. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/robotic/scriptrunner.py +0 -0
  259. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/__init__.py +0 -0
  260. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/basedome.py +0 -0
  261. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/baseroof.py +0 -0
  262. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/roof/dummyroof.py +0 -0
  263. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/test/__init__.py +0 -0
  264. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/test/standalone.py +0 -0
  265. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/dummymode.py +0 -0
  266. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/fluentlogger.py +0 -0
  267. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/httpfilecache.py +0 -0
  268. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/kiosk.py +0 -0
  269. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/matrix.py +0 -0
  270. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/stellarium.py +0 -0
  271. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/telegram.py +0 -0
  272. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/utils/trigger.py +0 -0
  273. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/__init__.py +0 -0
  274. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/mockweather.py +0 -0
  275. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/weather.py +0 -0
  276. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/weather_api.py +0 -0
  277. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/modules/weather/weather_state.py +0 -0
  278. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/py.typed +0 -0
  279. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/__init__.py +0 -0
  280. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/observation.py +0 -0
  281. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/__init__.py +0 -0
  282. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
  283. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  284. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  285. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  286. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  287. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  288. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  289. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  290. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/dataprovider.py +0 -0
  291. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  292. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  293. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  294. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  295. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  296. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  297. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  298. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  299. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/random.py +0 -0
  300. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  301. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  302. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  303. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
  304. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  305. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  306. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  307. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  308. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  309. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  310. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  311. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  312. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/targets/target.py +0 -0
  313. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  314. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/__init__.py +0 -0
  315. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  316. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
  317. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  318. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  319. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/__init__.py +0 -0
  320. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/cases.py +0 -0
  321. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/conditional.py +0 -0
  322. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/parallel.py +0 -0
  323. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/selector.py +0 -0
  324. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/control/sequential.py +0 -0
  325. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  326. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
  327. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
  328. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  329. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/script.py +0 -0
  330. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  331. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  332. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  333. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/scripts/utils/log.py +0 -0
  334. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/__init__.py +0 -0
  335. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/backend/__init__.py +0 -0
  336. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  337. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  338. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  339. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  340. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  341. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/__init__.py +0 -0
  342. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/_portal.py +0 -0
  343. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  344. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  345. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/configdb.py +0 -0
  346. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  347. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  348. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  349. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  350. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  351. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  352. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/task.py +0 -0
  353. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  354. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  355. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/memory/__init__.py +0 -0
  356. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  357. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  358. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/observationarchive.py +0 -0
  359. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/storage/taskarchive.py +0 -0
  360. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/task.py +0 -0
  361. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/taskrunner.py +0 -0
  362. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/__init__.py +0 -0
  363. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/__init__.py +0 -0
  364. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/archive.py +0 -0
  365. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  366. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  367. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  368. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  369. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  370. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  371. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  372. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  373. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  374. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  375. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  376. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  377. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  378. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  379. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  380. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/__init__.py +0 -0
  381. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/average.py +0 -0
  382. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/cache.py +0 -0
  383. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/config.py +0 -0
  384. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/config_schema.py +0 -0
  385. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/coordinates.py +0 -0
  386. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/curvefit.py +0 -0
  387. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/exceptions.py +0 -0
  388. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/fits.py +0 -0
  389. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/__init__.py +0 -0
  390. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/base.py +0 -0
  391. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/photometry.py +0 -0
  392. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/focusseries/projection.py +0 -0
  393. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/__init__.py +0 -0
  394. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/grid.py +0 -0
  395. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/gridnode.py +0 -0
  396. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/grids/pipeline.py +0 -0
  397. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/__init__.py +0 -0
  398. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/__init__.py +0 -0
  399. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  400. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  401. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  402. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  403. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  404. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  405. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  406. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/http.py +0 -0
  407. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/influxdb.py +0 -0
  408. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/logger.py +0 -0
  409. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/logging/__init__.py +0 -0
  410. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/logging/context.py +0 -0
  411. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/logging/resolvableerror.py +0 -0
  412. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/modulegui.py +0 -0
  413. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/__init__.py +0 -0
  414. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  415. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/applyoffsets.py +0 -0
  416. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  417. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/parallel.py +0 -0
  418. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/pipeline/__init__.py +0 -0
  419. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/pipeline/night.py +0 -0
  420. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/pipeline/pipeline.py +0 -0
  421. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/__init__.py +0 -0
  422. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/csv.py +0 -0
  423. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/http.py +0 -0
  424. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/log.py +0 -0
  425. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/multi.py +0 -0
  426. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/publisher/publisher.py +0 -0
  427. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/shellcommand.py +0 -0
  428. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/threads/__init__.py +0 -0
  429. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/threads/lockwithabort.py +0 -0
  430. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/time.py +0 -0
  431. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/utils/units.py +0 -0
  432. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/version.py +0 -0
  433. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/__init__.py +0 -0
  434. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/archivefile.py +0 -0
  435. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/bufferedfile.py +0 -0
  436. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/file.py +0 -0
  437. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/filelists/__init__.py +0 -0
  438. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/filelists/filelist.py +0 -0
  439. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/filelists/testing.py +0 -0
  440. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/httpfile.py +0 -0
  441. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/localfile.py +0 -0
  442. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/memfile.py +0 -0
  443. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/sftpfile.py +0 -0
  444. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/smbfile.py +0 -0
  445. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/sshfile.py +0 -0
  446. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/pyobs/vfs/tempfile.py +0 -0
  447. {pyobs_core-2.0.0.dev17 → pyobs_core-2.0.0.dev19}/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.dev17
3
+ Version: 2.0.0.dev19
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import argparse
3
4
  import glob
4
5
  import json
5
6
  import logging
@@ -49,9 +50,9 @@ class PyobsDaemonCLI(CLI):
49
50
  )
50
51
  self._parser.add_argument(
51
52
  "--syslog",
52
- action="store_true",
53
- help="send module logs to systemd journal",
54
- default=self._config.get("syslog", False),
53
+ action=argparse.BooleanOptionalAction,
54
+ help="send module logs to systemd journal (use --no-syslog to disable)",
55
+ default=self._config.get("syslog", True),
55
56
  )
56
57
  self._parser.add_argument("--chuid", type=str, default=self._config.get("chuid", "pyobs:pyobs"))
57
58
  self._parser.add_argument("-v", "--verbose", action="store_true")
@@ -63,6 +64,9 @@ class PyobsDaemonCLI(CLI):
63
64
  sp.add_parser("restart", help="restart modules").add_argument("modules", type=str, nargs="*")
64
65
  sp.add_parser("status", help="status of modules").add_argument("--json", action="store_true")
65
66
  sp.add_parser("list", help="list of modules")
67
+ sp.add_parser("logs", help="show/follow module logs via journalctl").add_argument(
68
+ "args", nargs=argparse.REMAINDER, help="[module] [journalctl arguments...]"
69
+ )
66
70
 
67
71
  def run(self) -> None:
68
72
  # init daemon
@@ -87,7 +91,9 @@ class PyobsDaemonCLI(CLI):
87
91
  case "status":
88
92
  daemon.status(print_json=self._config["json"])
89
93
  case "list":
90
- daemon.list()
94
+ daemon.list_modules()
95
+ case "logs":
96
+ daemon.logs(self._config["args"])
91
97
 
92
98
 
93
99
  class PyobsDaemon:
@@ -289,9 +295,24 @@ class PyobsDaemon:
289
295
  else:
290
296
  print(f"{module:<30} {'stopped':<8}")
291
297
 
292
- def list(self) -> None:
298
+ def list_modules(self) -> None:
293
299
  print("\n".join(self._list_configs()))
294
300
 
301
+ def logs(self, args: list[str]) -> None:
302
+ """Show/follow module logs by exec'ing into journalctl."""
303
+ match_args = ["SYSLOG_IDENTIFIER=pyobs"]
304
+ remainder = list(args)
305
+ # "--" may have been auto-inserted by main() to work around argparse.REMAINDER
306
+ # refusing to swallow a leading flag (e.g. "pyobsd logs -f") — drop it here.
307
+ if remainder and remainder[0] == "--":
308
+ remainder.pop(0)
309
+ if remainder and remainder[0] in self._list_configs():
310
+ match_args.append(f"PYOBS_MODULE={remainder.pop(0)}")
311
+ cmd = ["journalctl", *match_args, *remainder]
312
+ if self._verbose:
313
+ print(f"[DEBUG] Executing: {' '.join(cmd)}")
314
+ os.execvp("journalctl", cmd)
315
+
295
316
  # ── process management ────────────────────────────────────────────────────
296
317
 
297
318
  def _start_service(self, module: str) -> None:
@@ -388,6 +409,14 @@ class PyobsDaemon:
388
409
 
389
410
 
390
411
  def main() -> None:
412
+ # argparse.REMAINDER can't swallow a leading flag (e.g. "pyobsd logs -f")
413
+ # unless a "--" already precedes it — insert one automatically so users
414
+ # don't need to type it themselves.
415
+ if "logs" in sys.argv:
416
+ idx = sys.argv.index("logs") + 1
417
+ if idx < len(sys.argv) and sys.argv[idx].startswith("-") and sys.argv[idx] != "--":
418
+ sys.argv.insert(idx, "--")
419
+
391
420
  cli = PyobsDaemonCLI()
392
421
  cli()
393
422
 
@@ -7,9 +7,9 @@ import logging
7
7
  from collections.abc import Callable, Coroutine
8
8
  from typing import TYPE_CHECKING, Any, overload
9
9
 
10
- import pyobs.interfaces
11
10
  from pyobs.events import Event, LogEvent, ModuleClosedEvent
12
11
  from pyobs.interfaces import Interface
12
+ from pyobs.interfaces.interface import get_registered_interface
13
13
  from pyobs.utils.enums import ModuleState
14
14
 
15
15
  from .commlogging import CommLoggingHandler
@@ -337,28 +337,13 @@ class Comm:
337
337
  list of interface classes.
338
338
  """
339
339
 
340
- # get interface classes
341
- inspection = inspect.getmembers(pyobs.interfaces, predicate=inspect.isclass)
342
-
343
340
  # loop interfaces
344
341
  interface_classes = []
345
342
  for interface_name in interfaces:
346
- # loop all classes
347
- found = False
348
- for cls_name, cls in inspection:
349
- # class needs to face same name and implement Interface
350
- if interface_name == cls_name and issubclass(cls, Interface):
351
- # found it!
352
- found = True
353
-
354
- # then add it to the list of all interfaces
355
- interface_classes.append(cls)
356
-
357
- # there can only be one...
358
- break
359
-
360
- # not found?
361
- if not found:
343
+ cls = get_registered_interface(interface_name)
344
+ if cls is not None:
345
+ interface_classes.append(cls)
346
+ else:
362
347
  log.error('Could not find interface "%s" for client.', interface_name)
363
348
  return interface_classes
364
349
 
@@ -541,6 +526,13 @@ class Comm:
541
526
  def _get_own_state(self, interface: type[Interface]) -> Any:
542
527
  return None
543
528
 
529
+ def get_own_capabilities(self, interface: type[Interface]) -> Any:
530
+ """Return the capabilities published by this module for the given interface, or None."""
531
+ return self._get_own_capabilities(interface)
532
+
533
+ def _get_own_capabilities(self, interface: type[Interface]) -> Any:
534
+ return None
535
+
544
536
  async def subscribe_state(
545
537
  self,
546
538
  module: str,
@@ -117,6 +117,10 @@ class LocalComm(Comm):
117
117
  """Store capabilities locally."""
118
118
  self._capabilities[interface] = capabilities
119
119
 
120
+ def _get_own_capabilities(self, interface: type[Interface]) -> Any:
121
+ """Return this client's own published capabilities."""
122
+ return self._capabilities.get(interface)
123
+
120
124
  async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
121
125
  """Fetch capabilities from a remote module."""
122
126
  if interface.capabilities is None:
@@ -32,6 +32,7 @@ import types as _builtin_types
32
32
  from enum import StrEnum
33
33
  from typing import Annotated, Any, Union, get_args, get_origin, get_type_hints
34
34
 
35
+ import numpy as np
35
36
  from slixmpp.xmlstream import ET
36
37
 
37
38
  from ...interfaces.interface import Interface as _Interface
@@ -65,6 +66,13 @@ def value_to_xml(value: Any, type_hint: Any) -> ET.Element:
65
66
  if get_origin(type_hint) is Annotated:
66
67
  type_hint = get_args(type_hint)[0]
67
68
 
69
+ # Normalize numpy scalars (np.float64, np.int64, np.bool_, ...) to native
70
+ # Python types. np.float64 subclasses float but repr()s as "np.float64(x)"
71
+ # since numpy 2.0, which corrupts <double> text; numpy integer types don't
72
+ # subclass int at all and would otherwise fall through to <string>.
73
+ if isinstance(value, np.generic):
74
+ value = value.item()
75
+
68
76
  # None / void
69
77
  if value is None:
70
78
  elem = ET.Element("nil")
@@ -18,11 +18,11 @@ from slixmpp.xmlstream import ET
18
18
  from slixmpp.xmlstream.handler import Callback
19
19
  from slixmpp.xmlstream.matcher import MatchXMLMask
20
20
 
21
- import pyobs.interfaces
22
21
  from pyobs.comm import Comm
23
22
  from pyobs.events import Event, LogEvent, ModuleClosedEvent, ModuleOpenedEvent
24
23
  from pyobs.events.event import EventFactory
25
24
  from pyobs.interfaces import Interface
25
+ from pyobs.interfaces.interface import get_registered_interface
26
26
  from pyobs.utils import exceptions as exc
27
27
  from pyobs.utils.enums import ModuleState
28
28
 
@@ -406,8 +406,8 @@ class XmppComm(Comm):
406
406
  interface_names = []
407
407
  for feature in features:
408
408
  name, _, version = feature[len(prefix) :].rpartition(":")
409
- local_cls = getattr(pyobs.interfaces, name, None)
410
- if local_cls is not None and issubclass(local_cls, Interface) and str(local_cls.version) == version:
409
+ local_cls = get_registered_interface(name)
410
+ if local_cls is not None and str(local_cls.version) == version:
411
411
  interface_names.append(name)
412
412
 
413
413
  # IModule not in list?
@@ -896,6 +896,10 @@ class XmppComm(Comm):
896
896
  self._capabilities[interface] = capabilities
897
897
  log.info("Published capabilities for %s", interface.__name__)
898
898
 
899
+ def _get_own_capabilities(self, interface: type[Interface]) -> Any:
900
+ """Return this client's own published capabilities."""
901
+ return self._capabilities.get(interface)
902
+
899
903
  async def _get_capabilities(self, module: str, interface: type[Interface]) -> Any | None:
900
904
  """Fetch and deserialize capabilities for a remote module's interface."""
901
905
  if interface.capabilities is None:
@@ -7,10 +7,19 @@ from typing import Any
7
7
  from .interface import Interface
8
8
 
9
9
 
10
+ @dataclass
11
+ class ModuleLocation:
12
+ longitude: float = 0.0
13
+ latitude: float = 0.0
14
+ elevation: float = 0.0
15
+ timezone: str = "utc"
16
+
17
+
10
18
  @dataclass
11
19
  class ModuleCapabilities:
12
20
  label: str = ""
13
21
  version: str = ""
22
+ location: ModuleLocation | None = None
14
23
 
15
24
 
16
25
  class IModule(Interface, metaclass=ABCMeta):
@@ -31,4 +40,4 @@ class IModule(Interface, metaclass=ABCMeta):
31
40
  ...
32
41
 
33
42
 
34
- __all__ = ["IModule", "ModuleCapabilities"]
43
+ __all__ = ["IModule", "ModuleCapabilities", "ModuleLocation"]
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABCMeta, abstractmethod
4
+ from typing import Any
5
+
6
+ from .interface import Interface
7
+
8
+
9
+ class IPointingBody(Interface, metaclass=ABCMeta):
10
+ """Points at and tracks a named solar-system body."""
11
+
12
+ __module__ = "pyobs.interfaces"
13
+
14
+ @abstractmethod
15
+ async def track_body(self, body: str, **kwargs: Any) -> None:
16
+ """Starts tracking a named solar-system body.
17
+
18
+ Args:
19
+ body: Name resolvable to an ephemeris (e.g. 'moon', 'mars', 'jupiter', or an
20
+ asteroid/comet designation known to JPL Horizons).
21
+
22
+ Raises:
23
+ MoveError: If telescope could not be moved.
24
+ ValueError: If body name is not resolvable.
25
+ """
26
+ ...
27
+
28
+
29
+ __all__ = ["IPointingBody"]
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABCMeta, abstractmethod
4
+ from dataclasses import dataclass, field
5
+ from typing import Annotated, Any
6
+
7
+ from ..utils.enums import Unit
8
+ from ..utils.time import Time
9
+ from .interface import Interface
10
+
11
+
12
+ @dataclass
13
+ class HeliocentricPolarState:
14
+ mu: float
15
+ psi: Annotated[float, Unit.DEGREES]
16
+ time: Time = field(default_factory=Time.now)
17
+
18
+
19
+ class IPointingHeliocentricPolar(Interface, metaclass=ABCMeta):
20
+ """The module can move to Heliocentric Polar (Mu/Psi) coordinates, usually combined with
21
+ :class:`~pyobs.interfaces.ITelescope`."""
22
+
23
+ __module__ = "pyobs.interfaces"
24
+
25
+ state = HeliocentricPolarState
26
+
27
+ @abstractmethod
28
+ async def move_heliocentric_polar(self, mu: float, psi: Annotated[float, Unit.DEGREES], **kwargs: Any) -> None:
29
+ """Moves on given coordinates.
30
+
31
+ Args:
32
+ mu: Cosine of the angular distance from Sun centre, dimensionless (0..1).
33
+ psi: Position angle around the solar disk, in degrees.
34
+
35
+ Raises:
36
+ MoveError: If device could not be moved.
37
+ """
38
+ ...
39
+
40
+
41
+ __all__ = ["IPointingHeliocentricPolar", "HeliocentricPolarState"]
@@ -10,21 +10,22 @@ from .interface import Interface
10
10
 
11
11
 
12
12
  @dataclass
13
- class HGSState:
13
+ class HeliographicStonyhurstState:
14
14
  lon: Annotated[float, Unit.DEGREES]
15
15
  lat: Annotated[float, Unit.DEGREES]
16
16
  time: Time = field(default_factory=Time.now)
17
17
 
18
18
 
19
- class IPointingHGS(Interface, metaclass=ABCMeta):
20
- """The module can move to Mu/Psi coordinates, usually combined with :class:`~pyobs.interfaces.ITelescope`."""
19
+ class IPointingHeliographicStonyhurst(Interface, metaclass=ABCMeta):
20
+ """The module can move to Heliographic Stonyhurst (lon/lat) coordinates, a frame fixed to the Sun's
21
+ rotating surface, usually combined with :class:`~pyobs.interfaces.ITelescope`."""
21
22
 
22
23
  __module__ = "pyobs.interfaces"
23
24
 
24
- state = HGSState
25
+ state = HeliographicStonyhurstState
25
26
 
26
27
  @abstractmethod
27
- async def move_hgs_lon_lat(
28
+ async def move_heliographic_stonyhurst(
28
29
  self, lon: Annotated[float, Unit.DEGREES], lat: Annotated[float, Unit.DEGREES], **kwargs: Any
29
30
  ) -> None:
30
31
  """Moves on given coordinates.
@@ -39,4 +40,4 @@ class IPointingHGS(Interface, metaclass=ABCMeta):
39
40
  ...
40
41
 
41
42
 
42
- __all__ = ["IPointingHGS", "HGSState"]
43
+ __all__ = ["IPointingHeliographicStonyhurst", "HeliographicStonyhurstState"]
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABCMeta, abstractmethod
4
+ from dataclasses import dataclass
5
+ from typing import Annotated, Any
6
+
7
+ from ..utils.enums import Unit
8
+ from ..utils.time import Time
9
+ from .interface import Interface
10
+
11
+
12
+ @dataclass
13
+ class OrbitalElements:
14
+ epoch: Time
15
+ semi_major_axis: Annotated[float, Unit.AU]
16
+ eccentricity: float
17
+ inclination: Annotated[float, Unit.DEGREES]
18
+ longitude_ascending_node: Annotated[float, Unit.DEGREES]
19
+ argument_of_periapsis: Annotated[float, Unit.DEGREES]
20
+ mean_anomaly: Annotated[float, Unit.DEGREES] | None = None
21
+ """Mean anomaly at epoch, in degrees. Required for elliptical orbits (eccentricity < 1)."""
22
+ perihelion_time: Time | None = None
23
+ """Time of perihelion passage. Required for near-parabolic/cometary orbits
24
+ (eccentricity close to or at 1), where mean anomaly is not well-defined."""
25
+
26
+
27
+ class IPointingOrbitalElements(Interface, metaclass=ABCMeta):
28
+ """Points at and tracks a body defined by orbital elements (asteroid, comet, NEO)."""
29
+
30
+ __module__ = "pyobs.interfaces"
31
+
32
+ @abstractmethod
33
+ async def track_orbital_elements(self, elements: OrbitalElements, **kwargs: Any) -> None:
34
+ """Starts tracking a body defined by orbital elements.
35
+
36
+ Args:
37
+ elements: Orbital elements of the body to track.
38
+
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).
43
+ """
44
+ ...
45
+
46
+
47
+ __all__ = ["IPointingOrbitalElements", "OrbitalElements"]
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABCMeta, abstractmethod
4
+ from dataclasses import dataclass, field
5
+ from enum import StrEnum
6
+ from typing import Any
7
+
8
+ from ..utils.time import Time
9
+ from .interface import Interface
10
+
11
+
12
+ class TrackingMode(StrEnum):
13
+ """Discrete, hardware-native tracking rate."""
14
+
15
+ SIDEREAL = "sidereal"
16
+ SOLAR = "solar"
17
+ LUNAR = "lunar"
18
+ OFF = "off"
19
+
20
+
21
+ @dataclass
22
+ class TrackingModeState:
23
+ mode: TrackingMode
24
+ time: Time = field(default_factory=Time.now)
25
+
26
+
27
+ @dataclass
28
+ class TrackingModeCapabilities:
29
+ modes: list[TrackingMode]
30
+
31
+
32
+ class ITrackingMode(Interface, metaclass=ABCMeta):
33
+ """The module supports switching between discrete, hardware-native tracking rates."""
34
+
35
+ __module__ = "pyobs.interfaces"
36
+
37
+ state = TrackingModeState
38
+ capabilities = TrackingModeCapabilities
39
+
40
+ @abstractmethod
41
+ async def set_tracking_mode(self, mode: TrackingMode, **kwargs: Any) -> None:
42
+ """Switches to the given tracking mode.
43
+
44
+ Args:
45
+ mode: Tracking mode to switch to.
46
+
47
+ Raises:
48
+ MoveError: If mode could not be set.
49
+ ValueError: If mode is not in this module's capabilities.
50
+ """
51
+ ...
52
+
53
+
54
+ __all__ = ["ITrackingMode", "TrackingMode", "TrackingModeState", "TrackingModeCapabilities"]
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ from abc import ABCMeta, abstractmethod
4
+ from dataclasses import dataclass, field
5
+ from typing import Annotated, Any
6
+
7
+ from ..utils.enums import Unit
8
+ from ..utils.time import Time
9
+ from .interface import Interface
10
+
11
+
12
+ @dataclass
13
+ class TrackingRateState:
14
+ ra_rate: Annotated[float, Unit.ARCSEC_PER_SEC]
15
+ dec_rate: Annotated[float, Unit.ARCSEC_PER_SEC]
16
+ time: Time = field(default_factory=Time.now)
17
+
18
+
19
+ @dataclass
20
+ class TrackingRateCapabilities:
21
+ min_update_interval: Annotated[float, Unit.SECONDS]
22
+ """Minimum time between successive set_tracking_rate calls this hardware/protocol accepts,
23
+ independent of whether the value actually changed. Populated per-driver from whatever its
24
+ protocol allows; 0 if the hardware has no such floor."""
25
+
26
+
27
+ class ITrackingRate(Interface, metaclass=ABCMeta):
28
+ """The module accepts an arbitrary non-sidereal tracking rate as an absolute RA/Dec offset."""
29
+
30
+ __module__ = "pyobs.interfaces"
31
+
32
+ state = TrackingRateState
33
+ capabilities = TrackingRateCapabilities
34
+
35
+ @abstractmethod
36
+ async def set_tracking_rate(
37
+ self,
38
+ ra_rate: Annotated[float, Unit.ARCSEC_PER_SEC],
39
+ dec_rate: Annotated[float, Unit.ARCSEC_PER_SEC],
40
+ **kwargs: Any,
41
+ ) -> None:
42
+ """Sets an absolute tracking rate on the sky, in arcsec/sec.
43
+
44
+ Args:
45
+ ra_rate: Rate in RA, arcsec/sec on the sky.
46
+ dec_rate: Rate in Dec, arcsec/sec on the sky.
47
+
48
+ Raises:
49
+ MoveError: If rate could not be set.
50
+ """
51
+ ...
52
+
53
+
54
+ __all__ = ["ITrackingRate", "TrackingRateState", "TrackingRateCapabilities"]
@@ -36,15 +36,18 @@ from .IGain import GainState, IGain
36
36
  from .IImageFormat import IImageFormat, ImageFormatCapabilities, ImageFormatState
37
37
  from .IImageType import IImageType, ImageTypeState
38
38
  from .IMode import IMode, ModeCapabilities, ModeState
39
- from .IModule import IModule, ModuleCapabilities
39
+ from .IModule import IModule, ModuleCapabilities, ModuleLocation
40
40
  from .IMotion import DeviceMotionStatus, IMotion, MotionState
41
41
  from .IMultiFiber import IMultiFiber, MultiFiberCapabilities, MultiFiberState
42
42
  from .interface import Interface
43
43
  from .IOffsetsAltAz import AltAzOffsetState, IOffsetsAltAz
44
44
  from .IOffsetsRaDec import IOffsetsRaDec, RaDecOffsetState
45
45
  from .IPointingAltAz import AltAzState, IPointingAltAz
46
+ from .IPointingBody import IPointingBody
47
+ from .IPointingHeliocentricPolar import HeliocentricPolarState, IPointingHeliocentricPolar
48
+ from .IPointingHeliographicStonyhurst import HeliographicStonyhurstState, IPointingHeliographicStonyhurst
46
49
  from .IPointingHelioprojective import HelioprojectiveState, IPointingHelioprojective
47
- from .IPointingHGS import HGSState, IPointingHGS
50
+ from .IPointingOrbitalElements import IPointingOrbitalElements, OrbitalElements
48
51
  from .IPointingRaDec import IPointingRaDec, RaDecState
49
52
  from .IPointingSeries import IPointingSeries
50
53
  from .IReady import IReady, ReadyState
@@ -59,6 +62,8 @@ from .IStructuredConfig import ConfigAppliedState, ConfigFieldSchema, ConfigSche
59
62
  from .ISyncTarget import ISyncTarget
60
63
  from .ITelescope import ITelescope
61
64
  from .ITemperatures import ITemperatures, SensorReading, TemperaturesState
65
+ from .ITrackingMode import ITrackingMode, TrackingMode, TrackingModeCapabilities, TrackingModeState
66
+ from .ITrackingRate import ITrackingRate, TrackingRateCapabilities, TrackingRateState
62
67
  from .IVideo import IVideo, VideoCapabilities
63
68
  from .IWeather import IWeather, WeatherSensorReading, WeatherState
64
69
  from .IWindow import IWindow, WindowCapabilities, WindowState
@@ -118,6 +123,7 @@ __all__ = [
118
123
  "ModeState",
119
124
  "IModule",
120
125
  "ModuleCapabilities",
126
+ "ModuleLocation",
121
127
  "IMotion",
122
128
  "DeviceMotionStatus",
123
129
  "MotionState",
@@ -126,10 +132,15 @@ __all__ = [
126
132
  "MultiFiberState",
127
133
  "IPointingAltAz",
128
134
  "AltAzState",
135
+ "IPointingBody",
136
+ "IPointingHeliocentricPolar",
137
+ "HeliocentricPolarState",
138
+ "IPointingHeliographicStonyhurst",
139
+ "HeliographicStonyhurstState",
129
140
  "IPointingHelioprojective",
130
141
  "HelioprojectiveState",
131
- "IPointingHGS",
132
- "HGSState",
142
+ "IPointingOrbitalElements",
143
+ "OrbitalElements",
133
144
  "IPointingRaDec",
134
145
  "RaDecState",
135
146
  "IPointingSeries",
@@ -152,6 +163,13 @@ __all__ = [
152
163
  "ITemperatures",
153
164
  "SensorReading",
154
165
  "TemperaturesState",
166
+ "ITrackingMode",
167
+ "TrackingMode",
168
+ "TrackingModeState",
169
+ "TrackingModeCapabilities",
170
+ "ITrackingRate",
171
+ "TrackingRateState",
172
+ "TrackingRateCapabilities",
155
173
  "IOffsetsAltAz",
156
174
  "AltAzOffsetState",
157
175
  "IOffsetsRaDec",
@@ -0,0 +1,77 @@
1
+ from abc import ABCMeta
2
+ from typing import Any, ClassVar
3
+
4
+ _REGISTRY: dict[str, "type[Interface]"] = {}
5
+
6
+
7
+ class Interface(metaclass=ABCMeta):
8
+ """Base class for all interfaces in pyobs."""
9
+
10
+ version: int = 1
11
+ state: ClassVar[type | None] = None
12
+ capabilities: ClassVar[type | None] = None
13
+
14
+ __module__ = "pyobs.interfaces"
15
+
16
+ def __init_subclass__(cls, **kwargs: Any) -> None:
17
+ super().__init_subclass__(**kwargs)
18
+
19
+ # only genuine interface definitions get registered. Concrete module
20
+ # classes (e.g. `class BaseCamera(Module, ICamera, IExposureTime,
21
+ # IImageType)`) also transitively subclass Interface, but always mix
22
+ # in at least one base that isn't itself an Interface subclass
23
+ # (Module, a FITS-header mixin, ...). A base only counts as "pure"
24
+ # if it's Interface itself or is already registered -- issubclass(
25
+ # base, Interface) alone isn't enough, since e.g. BaseCamera
26
+ # transitively satisfies that (via ICamera) despite mixing in
27
+ # Module, which would let DummyCamera(BaseCamera, ...) register
28
+ # too. Checking registry membership instead propagates purity down
29
+ # the whole chain, since BaseCamera itself never gets registered.
30
+ def _is_pure(base: type) -> bool:
31
+ return base is Interface or _REGISTRY.get(base.__name__) is base
32
+
33
+ if not all(_is_pure(base) for base in cls.__bases__):
34
+ return
35
+
36
+ existing = _REGISTRY.get(cls.__name__)
37
+ if existing is not None and existing is not cls:
38
+ raise TypeError(
39
+ f"Interface name '{cls.__name__}' is already registered by "
40
+ f"{existing.__module__}.{existing.__qualname__}; "
41
+ f"choose a distinct name for {cls.__module__}.{cls.__qualname__}."
42
+ )
43
+ _REGISTRY[cls.__name__] = cls
44
+
45
+ def get_state(self, interface: "type[Interface]") -> Any | None:
46
+ """Return the last received state for the given interface, or None."""
47
+ return None
48
+
49
+ def get_capabilities(self, interface: "type[Interface]") -> Any | None:
50
+ """Return the capabilities for the given interface, or None."""
51
+ return None
52
+
53
+ async def wait_for_state(self, interface: "type[Interface]", timeout: float = 10.0) -> Any | None:
54
+ """Return state immediately if available, otherwise wait for the first update."""
55
+ return None
56
+
57
+ @classmethod
58
+ def has_own_state(cls) -> bool:
59
+ """True if this interface defines its own state, as opposed to merely inheriting
60
+ one from a component interface it combines (e.g. ICamera inheriting IExposure's
61
+ state). Modules publish state under the interface that actually defines it, so
62
+ composite interfaces would otherwise be (wrongly) treated as publishing state too.
63
+ """
64
+ return "state" in cls.__dict__
65
+
66
+
67
+ def get_registered_interface(name: str) -> "type[Interface] | None":
68
+ """Look up a registered interface class by name, or None if unknown."""
69
+ return _REGISTRY.get(name)
70
+
71
+
72
+ def registered_interfaces() -> "dict[str, type[Interface]]":
73
+ """All currently-registered interface classes, keyed by name."""
74
+ return dict(_REGISTRY)
75
+
76
+
77
+ __all__ = ["Interface", "get_registered_interface", "registered_interfaces"]