ophyd-async 0.7.0a1__tar.gz → 0.8.0__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 (276) hide show
  1. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.copier-answers.yml +1 -1
  2. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/CONTRIBUTING.md +1 -1
  3. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_pypi.yml +2 -0
  4. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_release.yml +1 -1
  5. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_test.yml +1 -0
  6. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/ci.yml +2 -2
  7. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.pre-commit-config.yaml +8 -0
  8. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/Dockerfile +1 -1
  9. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/PKG-INFO +9 -12
  10. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/README.md +3 -3
  11. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/conf.py +2 -5
  12. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/examples/foo_detector.py +1 -1
  13. ophyd_async-0.8.0/docs/explanations/decisions/0008-signal-types.md +159 -0
  14. ophyd_async-0.8.0/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +140 -0
  15. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to/make-a-simple-device.rst +4 -4
  16. ophyd_async-0.8.0/docs/how-to/use_set_and_wait_for_other_value.md +45 -0
  17. ophyd_async-0.8.0/docs/images/ophyd-async-logo.svg +358 -0
  18. ophyd_async-0.8.0/docs/images/set_and_wait_for_other_value.svg +10 -0
  19. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/pyproject.toml +67 -17
  20. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/_version.py +2 -2
  21. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/__init__.py +34 -9
  22. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_detector.py +5 -10
  23. ophyd_async-0.8.0/src/ophyd_async/core/_device.py +343 -0
  24. ophyd_async-0.8.0/src/ophyd_async/core/_device_filler.py +269 -0
  25. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_device_save_loader.py +6 -7
  26. ophyd_async-0.8.0/src/ophyd_async/core/_mock_signal_backend.py +79 -0
  27. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_mock_signal_utils.py +25 -16
  28. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_protocol.py +28 -8
  29. ophyd_async-0.8.0/src/ophyd_async/core/_readable.py +260 -0
  30. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_signal.py +219 -163
  31. ophyd_async-0.8.0/src/ophyd_async/core/_signal_backend.py +164 -0
  32. ophyd_async-0.8.0/src/ophyd_async/core/_soft_signal_backend.py +181 -0
  33. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_status.py +22 -6
  34. ophyd_async-0.8.0/src/ophyd_async/core/_table.py +148 -0
  35. ophyd_async-0.8.0/src/ophyd_async/core/_utils.py +304 -0
  36. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adaravis/_aravis_controller.py +2 -2
  37. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adaravis/_aravis_io.py +8 -6
  38. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adcore/_core_io.py +5 -7
  39. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adcore/_core_logic.py +3 -1
  40. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adcore/_hdf_writer.py +2 -2
  41. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adcore/_single_trigger.py +6 -10
  42. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adcore/_utils.py +15 -10
  43. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adkinetix/__init__.py +2 -1
  44. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +6 -3
  45. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +4 -5
  46. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +2 -2
  47. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +3 -4
  48. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +2 -2
  49. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/advimba/__init__.py +4 -1
  50. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/advimba/_vimba_controller.py +6 -3
  51. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/advimba/_vimba_io.py +8 -9
  52. ophyd_async-0.8.0/src/ophyd_async/epics/core/__init__.py +26 -0
  53. ophyd_async-0.8.0/src/ophyd_async/epics/core/_aioca.py +323 -0
  54. ophyd_async-0.8.0/src/ophyd_async/epics/core/_epics_connector.py +53 -0
  55. ophyd_async-0.8.0/src/ophyd_async/epics/core/_epics_device.py +13 -0
  56. ophyd_async-0.8.0/src/ophyd_async/epics/core/_p4p.py +383 -0
  57. ophyd_async-0.8.0/src/ophyd_async/epics/core/_pvi_connector.py +91 -0
  58. ophyd_async-0.8.0/src/ophyd_async/epics/core/_signal.py +171 -0
  59. ophyd_async-0.8.0/src/ophyd_async/epics/core/_util.py +61 -0
  60. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/demo/_mover.py +4 -5
  61. ophyd_async-0.8.0/src/ophyd_async/epics/demo/_sensor.py +37 -0
  62. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/eiger/_eiger.py +1 -2
  63. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/eiger/_eiger_controller.py +7 -2
  64. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/eiger/_eiger_io.py +3 -5
  65. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/eiger/_odin_io.py +5 -5
  66. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/motor.py +4 -5
  67. ophyd_async-0.8.0/src/ophyd_async/epics/signal.py +11 -0
  68. ophyd_async-0.8.0/src/ophyd_async/epics/testing/__init__.py +24 -0
  69. ophyd_async-0.8.0/src/ophyd_async/epics/testing/_example_ioc.py +105 -0
  70. ophyd_async-0.8.0/src/ophyd_async/epics/testing/_utils.py +78 -0
  71. ophyd_async-0.8.0/src/ophyd_async/epics/testing/test_records.db +152 -0
  72. ophyd_async-0.8.0/src/ophyd_async/epics/testing/test_records_pva.db +177 -0
  73. ophyd_async-0.8.0/src/ophyd_async/fastcs/core.py +9 -0
  74. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/__init__.py +4 -4
  75. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/_block.py +23 -11
  76. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/_control.py +3 -5
  77. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/_hdf_panda.py +5 -19
  78. ophyd_async-0.8.0/src/ophyd_async/fastcs/panda/_table.py +87 -0
  79. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/_trigger.py +8 -8
  80. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/_writer.py +4 -7
  81. ophyd_async-0.8.0/src/ophyd_async/plan_stubs/_ensure_connected.py +33 -0
  82. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/plan_stubs/_fly.py +2 -2
  83. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/plan_stubs/_nd_attributes.py +5 -4
  84. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector_controller.py +1 -2
  85. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/_sim_motor.py +3 -4
  86. {ophyd_async-0.7.0a1/src/ophyd_async/tango/signal → ophyd_async-0.8.0/src/ophyd_async/tango/core}/__init__.py +9 -6
  87. ophyd_async-0.8.0/src/ophyd_async/tango/core/_base_device.py +132 -0
  88. {ophyd_async-0.7.0a1/src/ophyd_async/tango/signal → ophyd_async-0.8.0/src/ophyd_async/tango/core}/_signal.py +42 -53
  89. {ophyd_async-0.7.0a1/src/ophyd_async/tango/base_devices → ophyd_async-0.8.0/src/ophyd_async/tango/core}/_tango_readable.py +3 -4
  90. {ophyd_async-0.7.0a1/src/ophyd_async/tango/signal → ophyd_async-0.8.0/src/ophyd_async/tango/core}/_tango_transport.py +38 -40
  91. ophyd_async-0.8.0/src/ophyd_async/tango/demo/_counter.py +26 -0
  92. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/tango/demo/_mover.py +13 -13
  93. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async.egg-info/PKG-INFO +9 -12
  94. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async.egg-info/SOURCES.txt +31 -19
  95. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async.egg-info/requires.txt +5 -8
  96. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/system_tests/epics/eiger/test_eiger_system.py +1 -1
  97. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_device.py +74 -97
  98. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_device_collector.py +16 -2
  99. ophyd_async-0.8.0/tests/core/test_device_save_loader.py +317 -0
  100. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_flyer.py +8 -4
  101. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_log.py +2 -2
  102. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_mock_signal_backend.py +68 -70
  103. ophyd_async-0.8.0/tests/core/test_observe.py +117 -0
  104. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_readable.py +83 -68
  105. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_signal.py +117 -173
  106. ophyd_async-0.8.0/tests/core/test_soft_signal_backend.py +182 -0
  107. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_status.py +15 -6
  108. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_subset_enum.py +23 -31
  109. ophyd_async-0.8.0/tests/core/test_table.py +53 -0
  110. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_utils.py +39 -6
  111. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_watchable_async_status.py +19 -0
  112. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adaravis/test_aravis.py +5 -3
  113. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adcore/test_single_trigger.py +6 -10
  114. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adcore/test_writers.py +11 -8
  115. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adkinetix/test_kinetix.py +9 -6
  116. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adsimdetector/test_sim.py +13 -9
  117. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/advimba/test_vimba.py +7 -5
  118. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/conftest.py +6 -3
  119. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/demo/test_demo.py +51 -13
  120. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/eiger/test_eiger_controller.py +7 -8
  121. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/eiger/test_eiger_detector.py +1 -3
  122. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/eiger/test_odin_io.py +9 -22
  123. ophyd_async-0.8.0/tests/epics/pvi/test_pvi.py +173 -0
  124. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/signal/test_common.py +5 -16
  125. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/signal/test_signals.py +440 -425
  126. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/test_motor.py +22 -16
  127. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/db/panda.db +39 -46
  128. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/test_hdf_panda.py +9 -24
  129. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/test_panda_connect.py +21 -26
  130. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/test_panda_control.py +5 -13
  131. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/test_panda_utils.py +6 -14
  132. ophyd_async-0.7.0a1/tests/fastcs/panda/test_table.py → ophyd_async-0.8.0/tests/fastcs/panda/test_seq_table.py +45 -73
  133. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/test_trigger.py +13 -19
  134. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/fastcs/panda/test_writer.py +25 -46
  135. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/plan_stubs/test_ensure_connected.py +19 -5
  136. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/plan_stubs/test_fly.py +4 -11
  137. ophyd_async-0.8.0/tests/sim/__init__.py +0 -0
  138. ophyd_async-0.8.0/tests/sim/demo/__init__.py +0 -0
  139. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/sim/demo/test_sim_motor.py +2 -2
  140. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/sim/test_sim_detector.py +3 -0
  141. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/tango/test_base_device.py +12 -30
  142. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/tango/test_tango_signals.py +22 -25
  143. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/tango/test_tango_transport.py +34 -32
  144. ophyd_async-0.8.0/tests/test_data/test_yaml_save.yml +40 -0
  145. ophyd_async-0.7.0a1/docs/images/bluesky_ophyd_epics_devices_logo.svg +0 -389
  146. ophyd_async-0.7.0a1/docs/images/bluesky_ophyd_logo.svg +0 -323
  147. ophyd_async-0.7.0a1/src/ophyd_async/core/_device.py +0 -236
  148. ophyd_async-0.7.0a1/src/ophyd_async/core/_mock_signal_backend.py +0 -84
  149. ophyd_async-0.7.0a1/src/ophyd_async/core/_readable.py +0 -261
  150. ophyd_async-0.7.0a1/src/ophyd_async/core/_signal_backend.py +0 -97
  151. ophyd_async-0.7.0a1/src/ophyd_async/core/_soft_signal_backend.py +0 -244
  152. ophyd_async-0.7.0a1/src/ophyd_async/core/_table.py +0 -146
  153. ophyd_async-0.7.0a1/src/ophyd_async/core/_utils.py +0 -193
  154. ophyd_async-0.7.0a1/src/ophyd_async/epics/demo/_sensor.py +0 -36
  155. ophyd_async-0.7.0a1/src/ophyd_async/epics/pvi/__init__.py +0 -3
  156. ophyd_async-0.7.0a1/src/ophyd_async/epics/pvi/_pvi.py +0 -338
  157. ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/__init__.py +0 -21
  158. ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_aioca.py +0 -378
  159. ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_common.py +0 -57
  160. ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_epics_transport.py +0 -34
  161. ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_p4p.py +0 -518
  162. ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_signal.py +0 -114
  163. ophyd_async-0.7.0a1/src/ophyd_async/fastcs/panda/_table.py +0 -109
  164. ophyd_async-0.7.0a1/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -26
  165. ophyd_async-0.7.0a1/src/ophyd_async/tango/__init__.py +0 -45
  166. ophyd_async-0.7.0a1/src/ophyd_async/tango/base_devices/__init__.py +0 -4
  167. ophyd_async-0.7.0a1/src/ophyd_async/tango/base_devices/_base_device.py +0 -225
  168. ophyd_async-0.7.0a1/src/ophyd_async/tango/demo/_counter.py +0 -37
  169. ophyd_async-0.7.0a1/tests/core/test_device_save_loader.py +0 -327
  170. ophyd_async-0.7.0a1/tests/core/test_soft_signal_backend.py +0 -181
  171. ophyd_async-0.7.0a1/tests/epics/pvi/test_pvi.py +0 -202
  172. ophyd_async-0.7.0a1/tests/epics/signal/test_records.db +0 -354
  173. ophyd_async-0.7.0a1/tests/test_data/test_yaml_save.yml +0 -26
  174. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.codecov.yml +0 -0
  175. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.devcontainer/devcontainer.json +0 -0
  176. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.git-blame-ignore-revs +0 -0
  177. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  178. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/ISSUE_TEMPLATE/issue.md +0 -0
  179. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
  180. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/actions/install_requirements/action.yml +0 -0
  181. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/dependabot.yml +0 -0
  182. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/pages/index.html +0 -0
  183. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/pages/make_switcher.py +0 -0
  184. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_check.yml +0 -0
  185. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_dist.yml +0 -0
  186. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_docs.yml +0 -0
  187. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/_tox.yml +0 -0
  188. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.github/workflows/periodic.yml +0 -0
  189. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.gitignore +0 -0
  190. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/.mailmap +0 -0
  191. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/LICENSE +0 -0
  192. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/_api.rst +0 -0
  193. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/_templates/custom-module-template.rst +0 -0
  194. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/examples/epics_demo.py +0 -0
  195. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/examples/tango_demo.py +0 -0
  196. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
  197. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
  198. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
  199. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
  200. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
  201. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
  202. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
  203. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions/COPYME +0 -0
  204. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/decisions.md +0 -0
  205. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/design-goals.rst +0 -0
  206. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/event-loop-choice.rst +0 -0
  207. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations/flyscanning.rst +0 -0
  208. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/explanations.md +0 -0
  209. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/genindex.rst +0 -0
  210. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to/choose-interfaces-for-devices.md +0 -0
  211. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to/compound-devices.rst +0 -0
  212. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to/contribute.md +0 -0
  213. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to/make-a-standard-detector.rst +0 -0
  214. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to/write-tests-for-devices.rst +0 -0
  215. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/how-to.md +0 -0
  216. /ophyd_async-0.7.0a1/docs/images/ophyd_favicon.svg → /ophyd_async-0.8.0/docs/images/ophyd-favicon.svg +0 -0
  217. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/index.md +0 -0
  218. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/reference.md +0 -0
  219. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/tutorials/installation.md +0 -0
  220. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/tutorials/using-existing-devices.rst +0 -0
  221. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/docs/tutorials.md +0 -0
  222. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/setup.cfg +0 -0
  223. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/__init__.py +0 -0
  224. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/__main__.py +0 -0
  225. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_flyer.py +0 -0
  226. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_hdf_dataset.py +0 -0
  227. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_log.py +0 -0
  228. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/core/_providers.py +0 -0
  229. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/__init__.py +0 -0
  230. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
  231. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adaravis/_aravis.py +0 -0
  232. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adcore/__init__.py +0 -0
  233. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -0
  234. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
  235. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -0
  236. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
  237. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/adsimdetector/_sim.py +0 -0
  238. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/advimba/_vimba.py +0 -0
  239. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/demo/__init__.py +0 -0
  240. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/demo/mover.db +0 -0
  241. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/demo/sensor.db +0 -0
  242. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/epics/eiger/__init__.py +0 -0
  243. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/__init__.py +0 -0
  244. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
  245. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/fastcs/panda/_utils.py +0 -0
  246. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/plan_stubs/__init__.py +0 -0
  247. /ophyd_async-0.7.0a1/src/ophyd_async/sim/__init__.py → /ophyd_async-0.8.0/src/ophyd_async/py.typed +0 -0
  248. {ophyd_async-0.7.0a1/src/ophyd_async/sim/testing → ophyd_async-0.8.0/src/ophyd_async/sim}/__init__.py +0 -0
  249. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/__init__.py +0 -0
  250. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/_pattern_detector/__init__.py +0 -0
  251. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +0 -0
  252. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector_writer.py +0 -0
  253. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +0 -0
  254. {ophyd_async-0.7.0a1/tests/sim → ophyd_async-0.8.0/src/ophyd_async/sim/testing}/__init__.py +0 -0
  255. {ophyd_async-0.7.0a1/tests/sim/demo → ophyd_async-0.8.0/src/ophyd_async/tango}/__init__.py +0 -0
  256. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/tango/demo/__init__.py +0 -0
  257. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/tango/demo/_detector.py +0 -0
  258. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/tango/demo/_tango/__init__.py +0 -0
  259. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async/tango/demo/_tango/_servers.py +0 -0
  260. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
  261. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async.egg-info/entry_points.txt +0 -0
  262. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/src/ophyd_async.egg-info/top_level.txt +0 -0
  263. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/system_tests/epics/eiger/README.md +0 -0
  264. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
  265. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/conftest.py +0 -0
  266. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_protocol.py +0 -0
  267. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/core/test_providers.py +0 -0
  268. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adcore/test_drivers.py +0 -0
  269. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adcore/test_scans.py +0 -0
  270. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/adpilatus/test_pilatus.py +0 -0
  271. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/epics/test_areadetector_subclass_naming.py +0 -0
  272. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/sim/conftest.py +0 -0
  273. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/sim/test_pattern_generator.py +0 -0
  274. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/sim/test_sim_writer.py +0 -0
  275. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/sim/test_streaming_plan.py +0 -0
  276. {ophyd_async-0.7.0a1 → ophyd_async-0.8.0}/tests/test_cli.py +0 -0
@@ -1,5 +1,5 @@
1
1
  # Changes here will be overwritten by Copier
2
- _commit: 2.3.0
2
+ _commit: 2.5.0
3
3
  _src_path: gh:DiamondLightSource/python-copier-template
4
4
  author_email: tom.cobb@diamond.ac.uk
5
5
  author_name: Tom Cobb
@@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua
24
24
 
25
25
  This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects.
26
26
 
27
- For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.3.0/how-to.html).
27
+ For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.5.0/how-to.html).
@@ -15,3 +15,5 @@ jobs:
15
15
 
16
16
  - name: Publish to PyPI using trusted publishing
17
17
  uses: pypa/gh-action-pypi-publish@release/v1
18
+ with:
19
+ attestations: false
@@ -23,7 +23,7 @@ jobs:
23
23
  - name: Create GitHub Release
24
24
  # We pin to the SHA, not the tag, for security reasons.
25
25
  # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions
26
- uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
26
+ uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9
27
27
  with:
28
28
  prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }}
29
29
  files: "*"
@@ -49,6 +49,7 @@ jobs:
49
49
  with:
50
50
  python-version: ${{ inputs.python-version }}
51
51
  pip-install: ".[dev]"
52
+
52
53
  - name: Run tests
53
54
  run: tox -e tests
54
55
 
@@ -20,8 +20,8 @@ jobs:
20
20
  if: needs.check.outputs.branch-pr == ''
21
21
  strategy:
22
22
  matrix:
23
- runs-on: ["ubuntu-latest"] # can add windows-latest, macos-latest
24
- python-version: ["3.10","3.11"] # 3.12 should be added when p4p is updated
23
+ runs-on: ["ubuntu-latest", "windows-latest"] # can add macos-latest
24
+ python-version: ["3.10", "3.11"] # 3.12 should be added when p4p is updated
25
25
  include:
26
26
  # Include one that runs in the dev environment
27
27
  - runs-on: "ubuntu-latest"
@@ -22,3 +22,11 @@ repos:
22
22
  entry: ruff format --force-exclude
23
23
  types: [python]
24
24
  require_serial: true
25
+
26
+ - id: import-contracts
27
+ name: Ensure import directionality
28
+ pass_filenames: false
29
+ language: system
30
+ entry: lint-imports
31
+ types: [python]
32
+ require_serial: false
@@ -1,7 +1,7 @@
1
1
  # The devcontainer should use the developer target and run as root with podman
2
2
  # or docker with user namespaces.
3
3
  ARG PYTHON_VERSION=3.11
4
- FROM python:${PYTHON_VERSION} as developer
4
+ FROM python:${PYTHON_VERSION} AS developer
5
5
 
6
6
  # Allow Qt 6 (pyside6) UI to work in the container - also see apt-get below
7
7
  ENV MPLBACKEND=QtAgg
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ophyd-async
3
- Version: 0.7.0a1
3
+ Version: 0.8.0
4
4
  Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
5
5
  Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
6
6
  License: BSD 3-Clause License
@@ -41,12 +41,12 @@ Requires-Python: >=3.10
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
43
  Requires-Dist: networkx>=2.0
44
- Requires-Dist: numpy<2.0.0
44
+ Requires-Dist: numpy
45
45
  Requires-Dist: packaging
46
46
  Requires-Dist: pint
47
- Requires-Dist: bluesky>=1.13.0a3
48
- Requires-Dist: event_model
49
- Requires-Dist: p4p
47
+ Requires-Dist: bluesky>=1.13
48
+ Requires-Dist: event-model>=1.22.1
49
+ Requires-Dist: p4p>=4.2.0a3
50
50
  Requires-Dist: pyyaml
51
51
  Requires-Dist: colorlog
52
52
  Requires-Dist: pydantic>=2.0
@@ -64,13 +64,10 @@ Requires-Dist: ophyd_async[pva]; extra == "dev"
64
64
  Requires-Dist: ophyd_async[sim]; extra == "dev"
65
65
  Requires-Dist: ophyd_async[ca]; extra == "dev"
66
66
  Requires-Dist: ophyd_async[tango]; extra == "dev"
67
- Requires-Dist: black; extra == "dev"
68
- Requires-Dist: flake8; extra == "dev"
69
- Requires-Dist: flake8-isort; extra == "dev"
70
- Requires-Dist: Flake8-pyproject; extra == "dev"
71
67
  Requires-Dist: inflection; extra == "dev"
72
68
  Requires-Dist: ipython; extra == "dev"
73
69
  Requires-Dist: ipywidgets; extra == "dev"
70
+ Requires-Dist: import-linter; extra == "dev"
74
71
  Requires-Dist: matplotlib; extra == "dev"
75
72
  Requires-Dist: myst-parser; extra == "dev"
76
73
  Requires-Dist: numpydoc; extra == "dev"
@@ -104,9 +101,9 @@ Requires-Dist: types-pyyaml; extra == "dev"
104
101
  [![CI](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml/badge.svg)](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml)
105
102
  [![Coverage](https://codecov.io/gh/bluesky/ophyd-async/branch/main/graph/badge.svg)](https://codecov.io/gh/bluesky/ophyd-async)
106
103
  [![PyPI](https://img.shields.io/pypi/v/ophyd-async.svg)](https://pypi.org/project/ophyd-async)
107
- [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
104
+ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://choosealicense.com/licenses/bsd-3-clause)
108
105
 
109
- # ophyd-async
106
+ # ![ophyd-async](https://raw.githubusercontent.com/bluesky/ophyd-async/main/docs/images/ophyd-async-logo.svg)
110
107
 
111
108
  Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango.
112
109
 
@@ -116,7 +113,7 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
116
113
  | Documentation | <https://bluesky.github.io/ophyd-async> |
117
114
  | Releases | <https://github.com/bluesky/ophyd-async/releases> |
118
115
 
119
- Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
116
+ Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
120
117
  be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control
121
118
  systems.
122
119
 
@@ -1,9 +1,9 @@
1
1
  [![CI](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml/badge.svg)](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml)
2
2
  [![Coverage](https://codecov.io/gh/bluesky/ophyd-async/branch/main/graph/badge.svg)](https://codecov.io/gh/bluesky/ophyd-async)
3
3
  [![PyPI](https://img.shields.io/pypi/v/ophyd-async.svg)](https://pypi.org/project/ophyd-async)
4
- [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
4
+ [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://choosealicense.com/licenses/bsd-3-clause)
5
5
 
6
- # ophyd-async
6
+ # ![ophyd-async](https://raw.githubusercontent.com/bluesky/ophyd-async/main/docs/images/ophyd-async-logo.svg)
7
7
 
8
8
  Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango.
9
9
 
@@ -13,7 +13,7 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
13
13
  | Documentation | <https://bluesky.github.io/ophyd-async> |
14
14
  | Releases | <https://github.com/bluesky/ophyd-async/releases> |
15
15
 
16
- Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
16
+ Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
17
17
  be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control
18
18
  systems.
19
19
 
@@ -188,9 +188,6 @@ if not switcher_exists:
188
188
  # will fix the switcher at the end of the docs workflow, but never gets a chance
189
189
  # to complete as the docs build warns and fails.
190
190
  html_theme_options = {
191
- "logo": {
192
- "text": project,
193
- },
194
191
  "use_edit_page_button": True,
195
192
  "github_url": f"https://github.com/{github_user}/{github_repo}",
196
193
  "icon_links": [
@@ -230,8 +227,8 @@ html_show_sphinx = False
230
227
  html_show_copyright = False
231
228
 
232
229
  # Logo
233
- html_logo = "images/bluesky_ophyd_logo.svg"
234
- html_favicon = "images/ophyd_favicon.svg"
230
+ html_logo = "images/ophyd-async-logo.svg"
231
+ html_favicon = "images/ophyd-favicon.svg"
235
232
 
236
233
  # If False and a module has the __all__ attribute set, autosummary documents
237
234
  # every member listed in __all__ and no others. Default is True
@@ -10,7 +10,7 @@ from ophyd_async.core import (
10
10
  StandardDetector,
11
11
  )
12
12
  from ophyd_async.epics import adcore
13
- from ophyd_async.epics.signal import epics_signal_rw_rbv
13
+ from ophyd_async.epics.core import epics_signal_rw_rbv
14
14
 
15
15
 
16
16
  class FooDriver(adcore.ADBaseIO):
@@ -0,0 +1,159 @@
1
+ # 8. Settle on Signal Types
2
+ Date: 2024-10-18
3
+
4
+ ## Status
5
+
6
+ Accepted
7
+
8
+ ## Context
9
+
10
+ At present, soft Signals allow any sort of datatype, while CA, PVA, Tango restrict these to what the control system allows. This means that some soft signals when `describe()` is called on them will give `dtype=object` which is not understood by downstream tools. It also means that load/save will not necessarily understand how to serialize results. Finally we now require `dtype_numpy` for tiled, so arbitrary object types are not suitable even if they are serializable. We should restrict the datatypes allowed in Signals to objects that are serializable and are sensible to add support for in downstream tools.
11
+
12
+ ## Decision
13
+
14
+ We will allow the following:
15
+ - Primitives:
16
+ - `bool`
17
+ - `int`
18
+ - `float`
19
+ - `str`
20
+ - Enums:
21
+ - `StrictEnum` subclass which will be checked to have the same members as the CS
22
+ - `SubsetEnum` subclass which will be checked to be a subset of the CS members
23
+ - 1D arrays:
24
+ - `Array1D[np.bool_]`
25
+ - `Array1D[np.int8]`
26
+ - `Array1D[np.uint8]`
27
+ - `Array1D[np.int16]`
28
+ - `Array1D[np.uint16]`
29
+ - `Array1D[np.int32]`
30
+ - `Array1D[np.uint32]`
31
+ - `Array1D[np.int64]`
32
+ - `Array1D[np.uint64]`
33
+ - `Array1D[np.float32]`
34
+ - `Array1D[np.float64]`
35
+ - `Sequence[str]`
36
+ - `Sequence[MyEnum]` where `MyEnum` is a subclass of `StrictEnum` or `SubsetEnum`
37
+ - Specific structures:
38
+ - `np.ndarray` to represent arrays where dimensionality and dtype can change and must be read from CS
39
+ - `Table` subclass (which is a pydantic `BaseModel`) where all members are 1D arrays
40
+
41
+ ## Consequences
42
+
43
+ Clients will be expected to understand:
44
+ - Python primitives (with Enums serializing as strings)
45
+ - Numpy arrays
46
+ - Pydantic BaseModels
47
+
48
+ All of the above have sensible `dtype_numpy` fields, but `Table` will give a structured row-wise `dtype_numpy`, while the data will be serialized in a column-wise fashion.
49
+
50
+ The following breaking changes will be made to ophyd-async:
51
+
52
+ ## pvi structure changes
53
+ Structure now read from `.value` rather than `.pvi`. Supported in FastCS. Requires at least PandABlocks-ioc 0.10.0
54
+ ## `StrictEnum` is now requried for all strictly checked `Enums`
55
+ ```python
56
+ # old
57
+ from enum import Enum
58
+ class MyEnum(str, Enum):
59
+ ONE = "one"
60
+ TWO = "two"
61
+ # new
62
+ from ophyd_async.core import StrictEnum
63
+ class MyEnum(StrictEnum):
64
+ ONE = "one"
65
+ TWO = "two"
66
+ ```
67
+ ## `SubsetEnum` is now an `Enum` subclass:
68
+ ```python
69
+ from ophyd_async.core import SubsetEnum
70
+ # old
71
+ MySubsetEnum = SubsetEnum["one", "two"]
72
+ # new
73
+ class MySubsetEnum(SubsetEnum):
74
+ ONE = "one"
75
+ TWO = "two"
76
+ ```
77
+ ## Use python primitives for scalar types instead of numpy types
78
+ ```python
79
+ # old
80
+ import numpy as np
81
+ x = epics_signal_rw(np.int32, "PV")
82
+ # new
83
+ x = epics_signal_rw(int, "PV")
84
+ ```
85
+ ## Use `Array1D` for 1D arrays instead of `npt.NDArray`
86
+ ```python
87
+ import numpy as np
88
+ # old
89
+ import numpy.typing as npt
90
+ x = epics_signal_rw(npt.NDArray[np.int32], "PV")
91
+ # new
92
+ from ophyd_async.core import Array1D
93
+ x = epics_signal_rw(Array1D[np.int32], "PV")
94
+ ```
95
+ ## Use `Sequence[str]` for arrays of strings instead of `npt.NDArray[np.str_]`
96
+ ```python
97
+ import numpy as np
98
+ # old
99
+ import numpy.typing as npt
100
+ x = epics_signal_rw(npt.NDArray[np.str_], "PV")
101
+ # new
102
+ from collections.abc import Sequence
103
+ x = epics_signal_rw(Sequence[str], "PV")
104
+ ```
105
+ ## `MockSignalBackend` requires a real backend
106
+ ```python
107
+ # old
108
+ fake_set_signal = SignalRW(MockSignalBackend(float))
109
+ # new
110
+ fake_set_signal = soft_signal_rw(float)
111
+ await fake_set_signal.connect(mock=True)
112
+ ```
113
+ ## `get_mock_put` is no longer passed timeout as it is handled in `Signal`
114
+ ```python
115
+ # old
116
+ get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY, timeout=ANY)
117
+ # new
118
+ get_mock_put(driver.capture).assert_called_once_with(Writing.ON, wait=ANY)
119
+ ```
120
+ ## `super().__init__` required for `Device` subclasses
121
+ ```python
122
+ # old
123
+ class MyDevice(Device):
124
+ def __init__(self, name: str = ""):
125
+ self.signal, self.backend_put = soft_signal_r_and_setter(int)
126
+ # new
127
+ class MyDevice(Device):
128
+ def __init__(self, name: str = ""):
129
+ self.signal, self.backend_put = soft_signal_r_and_setter(int)
130
+ super().__init__(name=name)
131
+ ```
132
+ ## Arbitrary `BaseModel`s not supported, pending use cases for them
133
+ The `Table` type has been suitable for everything we have seen so far, if you need an arbitrary `BaseModel` subclass then please make an issue
134
+ ## Child `Device`s set parent on attach, and can't be public children of more than one parent
135
+ ```python
136
+ class SourceDevice(Device):
137
+ def __init__(self, name: str = ""):
138
+ self.signal = soft_signal_rw(int)
139
+ super().__init__(name=name)
140
+
141
+ # old
142
+ class ReferenceDevice(Device):
143
+ def __init__(self, signal: SignalRW[int], name: str = ""):
144
+ self.signal = signal
145
+ super().__init__(name=name)
146
+
147
+ def set(self, value) -> AsyncStatus:
148
+ return self.signal.set(value + 1)
149
+ # new
150
+ from ophyd_async.core import Reference
151
+
152
+ class ReferenceDevice(Device):
153
+ def __init__(self, signal: SignalRW[int], name: str = ""):
154
+ self._signal_ref = Reference(signal)
155
+ super().__init__(name=name)
156
+
157
+ def set(self, value) -> AsyncStatus:
158
+ return self._signal_ref().set(value + 1)
159
+ ```
@@ -0,0 +1,140 @@
1
+ # 9. Procedural vs Declarative Devices
2
+
3
+ Date: 01/10/24
4
+
5
+ ## Status
6
+
7
+ Accepted
8
+
9
+ ## Context
10
+
11
+ In [](./0006-procedural-device-definitions.rst) we decided we preferred the procedural approach to devices, because of the issue of applying structure like `DeviceVector`. Since then we have `FastCS` and `Tango` support which use a declarative approach. We need to decide whether we are happy with this situation, or whether we should go all in one way or the other. A suitable test Device would be:
12
+
13
+ ```python
14
+ class EpicsProceduralDevice(StandardReadable):
15
+ def __init__(self, prefix: str, num_values: int, name="") -> None:
16
+ with self.add_children_as_readables():
17
+ self.value = DeviceVector(
18
+ {
19
+ i: epics_signal_r(float, f"{prefix}Value{i}")
20
+ for i in range(1, num_values + 1)
21
+ }
22
+ )
23
+ with self.add_children_as_readables(ConfigSignal):
24
+ self.mode = epics_signal_rw(EnergyMode, prefix + "Mode")
25
+ super().__init__(name=name)
26
+ ```
27
+
28
+ and a Tango/FastCS procedural equivalent would be (if we add support to StandardReadable for Format.HINTED_SIGNAL and Format.CONFIG_SIGNAL annotations):
29
+ ```python
30
+ class TangoDeclarativeDevice(StandardReadable, TangoDevice):
31
+ value: Annotated[DeviceVector[SignalR[float]], Format.HINTED_SIGNAL]
32
+ mode: Annotated[SignalRW[EnergyMode], Format.CONFIG_SIGNAL]
33
+ ```
34
+
35
+ But we could specify the Tango one procedurally (with some slight ugliness around the DeviceVector):
36
+ ```python
37
+ class TangoProceduralDevice(StandardReadable):
38
+ def __init__(self, prefix: str, name="") -> None:
39
+ with self.add_children_as_readables():
40
+ self.value = DeviceVector({0: tango_signal_r(float)})
41
+ with self.add_children_as_readables(ConfigSignal):
42
+ self.mode = tango_signal_rw(EnergyMode)
43
+ super().__init__(name=name, connector=TangoConnector(prefix))
44
+ ```
45
+
46
+ or the EPICS one could be declarative:
47
+ ```python
48
+ class EpicsDeclarativeDevice(StandardReadable, EpicsDevice):
49
+ value: Annotated[
50
+ DeviceVector[SignalR[float]], Format.HINTED_SIGNAL, EpicsSuffix("Value%d", "num_values")
51
+ ]
52
+ mode: Annotated[SignalRW[EnergyMode], Format.CONFIG_SIGNAL, EpicsSuffix("Mode")]
53
+ ```
54
+
55
+ Which do we prefer?
56
+
57
+ ## Decision
58
+
59
+ We decided that the declarative approach is to be preferred until we need to write formatted strings. At that point we should drop to an `__init__` method and a for loop. This is not a step towards only supporting the declarative approach and there are no plans to drop the procedural approach.
60
+
61
+ The two approaches now look like:
62
+
63
+ ```python
64
+ class Sensor(StandardReadable, EpicsDevice):
65
+ """A demo sensor that produces a scalar value based on X and Y Movers"""
66
+
67
+ value: A[SignalR[float], PvSuffix("Value"), Format.HINTED_SIGNAL]
68
+ mode: A[SignalRW[EnergyMode], PvSuffix("Mode"), Format.CONFIG_SIGNAL]
69
+
70
+
71
+ class SensorGroup(StandardReadable):
72
+ def __init__(self, prefix: str, name: str = "", sensor_count: int = 3) -> None:
73
+ with self.add_children_as_readables():
74
+ self.sensors = DeviceVector(
75
+ {i: Sensor(f"{prefix}{i}:") for i in range(1, sensor_count + 1)}
76
+ )
77
+ super().__init__(name)
78
+ ```
79
+
80
+ ## Consequences
81
+
82
+ We need to:
83
+ - Add support for reading annotations and `PvSuffix` in an `ophyd_async.epics.core.EpicsDevice` baseclass
84
+ - Do the `Format.HINTED_SIGNAL` and `Format.CONFIG_SIGNAL` flags in annotations for `StandardReadable`
85
+ - Ensure we can always drop to `__init__`
86
+
87
+
88
+ ## pvi structure changes
89
+ Structure read from `.value` now includes `DeviceVector` support. Requires at least PandABlocks-ioc 0.11.2
90
+
91
+ ## Epics `signal` module moves
92
+ `ophyd_async.epics.signal` moves to `ophyd_async.epics.core` with a backwards compat module that emits deprecation warning.
93
+ ```python
94
+ # old
95
+ from ophyd_async.epics.signal import epics_signal_rw
96
+ # new
97
+ from ophyd_async.epics.core import epics_signal_rw
98
+ ```
99
+
100
+ ## `StandardReadable` wrappers change to `StandardReadableFormat`
101
+ `StandardReadable` wrappers change to enum members of `StandardReadableFormat` (normally imported as `Format`)
102
+ ```python
103
+ # old
104
+ from ophyd_async.core import ConfigSignal, HintedSignal
105
+ class MyDevice(StandardReadable):
106
+ def __init__(self):
107
+ self.add_readables([sig1], ConfigSignal)
108
+ self.add_readables([sig2], HintedSignal)
109
+ self.add_readables([sig3], HintedSignal.uncached)
110
+ # new
111
+ from ophyd_async.core import StandardReadableFormat as Format
112
+ class MyDevice(StandardReadable):
113
+ def __init__(self):
114
+ self.add_readables([sig1], Format.CONFIG_SIGNAL)
115
+ self.add_readables([sig2], Format.HINTED_SIGNAL)
116
+ self.add_readables([sig3], Format.HINTED_UNCACHED_SIGNAL
117
+ ```
118
+
119
+ ## Declarative Devices are now available
120
+ ```python
121
+ # old
122
+ from ophyd_async.core import ConfigSignal, HintedSignal
123
+ from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw
124
+
125
+ class Sensor(StandardReadable):
126
+ def __init__(self, prefix: str, name="") -> None:
127
+ with self.add_children_as_readables(HintedSignal):
128
+ self.value = epics_signal_r(float, prefix + "Value")
129
+ with self.add_children_as_readables(ConfigSignal):
130
+ self.mode = epics_signal_rw(EnergyMode, prefix + "Mode")
131
+ super().__init__(name=name)
132
+ # new
133
+ from typing import Annotated as A
134
+ from ophyd_async.core import StandardReadableFormat as Format
135
+ from ophyd_async.epics.core import EpicsDevice, PvSuffix, epics_signal_r, epics_signal_rw
136
+
137
+ class Sensor(StandardReadable, EpicsDevice):
138
+ value: A[SignalR[float], PvSuffix("Value"), Format.HINTED_SIGNAL]
139
+ mode: A[SignalRW[EnergyMode], PvSuffix("Mode"), Format.CONFIG_SIGNAL]
140
+ ```
@@ -1,6 +1,6 @@
1
1
  .. note::
2
2
 
3
- Ophyd async is included on a provisional basis until the v1.0 release and
3
+ Ophyd async is included on a provisional basis until the v1.0 release and
4
4
  may change API on minor release numbers before then
5
5
 
6
6
  Make a Simple Device
@@ -31,7 +31,7 @@ its Python type, which could be:
31
31
  - A primitive (`str`, `int`, `float`)
32
32
  - An array (`numpy.typing.NDArray` ie. ``numpy.typing.NDArray[numpy.uint16]`` or ``Sequence[str]``)
33
33
  - An enum (`enum.Enum`) which **must** also extend `str`
34
- - `str` and ``EnumClass(str, Enum)`` are the only valid ``datatype`` for an enumerated signal.
34
+ - `str` and ``EnumClass(StrictEnum)`` are the only valid ``datatype`` for an enumerated signal.
35
35
 
36
36
  The rest of the arguments are PV connection information, in this case the PV suffix.
37
37
 
@@ -45,7 +45,7 @@ Finally `super().__init__() <StandardReadable>` is called with:
45
45
  without renaming
46
46
 
47
47
  All signals passed into this init method will be monitored between ``stage()``
48
- and ``unstage()`` and their cached values returned on ``read()`` and
48
+ and ``unstage()`` and their cached values returned on ``read()`` and
49
49
  ``read_configuration()`` for perfomance.
50
50
 
51
51
  Movable
@@ -64,7 +64,7 @@ informing watchers of the progress. When it gets to the requested value it
64
64
  completes. This co-routine is wrapped in a timeout handler, and passed to an
65
65
  `AsyncStatus` which will start executing it as soon as the Run Engine adds a
66
66
  callback to it. The ``stop()`` method then pokes a PV if the move needs to be
67
- interrupted.
67
+ interrupted.
68
68
 
69
69
  Assembly
70
70
  --------
@@ -0,0 +1,45 @@
1
+ # `set_and_wait_for_other_value`
2
+
3
+ The `set_and_wait_for_other_value` function (defined in `_signal.py`) is a utility designed to:
4
+
5
+ 1. **Set a signal**.
6
+ 2. **Wait for another signal to reach a specified value (`match_value`)**.
7
+
8
+ The behavior of the function depends on the value of the `wait_for_set_completion` parameter:
9
+
10
+ - **If `wait_for_set_completion = True`:**
11
+ The function returns at **1** (see diagram below), which occurs when the "set operation" is complete.
12
+
13
+ - **If `wait_for_set_completion = False`:**
14
+ The function returns at **2**, which occurs when the `match_signal` reaches the `match_value`.
15
+
16
+ In **AreaDetector**, the `wait_for_set_completion` parameter should generally be set to **`False`**, as the preferred behavior is to return when the `match_signal` achieves the `match_value`.
17
+
18
+ ---
19
+
20
+ ## Behavior Diagram:
21
+
22
+ ![wait_for_set_completion](../images/set_and_wait_for_other_value.svg)
23
+
24
+ ---
25
+
26
+ ## Example Usage
27
+
28
+ ```python
29
+ # Example code snippet for using set_and_wait_for_other_value in an AreaDetector driver
30
+ self._arm_status = set_and_wait_for_other_value(
31
+ self._drv.arm,
32
+ 1,
33
+ self._drv.state,
34
+ "ready",
35
+ timeout=DEFAULT_TIMEOUT,
36
+ wait_for_set_completion=False,
37
+ )
38
+ ```
39
+
40
+ In this **AreaDetector driver**, the function ensures that the detector's `arm_status` reaches `"ready"` before capturing data. To achieve this:
41
+
42
+ - The detector is instructed to transition to the "armed" state by setting the driver's `arm` signal to `1`.
43
+ - The function waits until the driver's `state` signal equals `"ready"`.
44
+
45
+ This approach ensures that data capture is only initiated once the detector is fully prepared.