ophyd-async 0.8.0a6__tar.gz → 0.9.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.
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.copier-answers.yml +1 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.devcontainer/devcontainer.json +4 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/CONTRIBUTING.md +1 -1
- ophyd_async-0.9.0/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +10 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/pages/make_switcher.py +1 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_test.yml +1 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/ci.yml +1 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.gitignore +3 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.pre-commit-config.yaml +8 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/PKG-INFO +4 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/examples/epics_demo.py +7 -7
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/examples/tango_demo.py +5 -5
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +1 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/event-loop-choice.rst +8 -8
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/compound-devices.rst +2 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/make-a-simple-device.rst +4 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/write-tests-for-devices.rst +6 -6
- ophyd_async-0.9.0/docs/images/set_and_wait_for_other_value.svg +2 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/tutorials/using-existing-devices.rst +2 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/pyproject.toml +34 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/_version.py +2 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/__init__.py +15 -46
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_detector.py +68 -44
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_device.py +120 -79
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_device_filler.py +17 -8
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_flyer.py +2 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_protocol.py +0 -28
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_readable.py +30 -23
- ophyd_async-0.9.0/src/ophyd_async/core/_settings.py +104 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_signal.py +91 -151
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_signal_backend.py +4 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_soft_signal_backend.py +2 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_table.py +18 -10
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_utils.py +30 -5
- ophyd_async-0.9.0/src/ophyd_async/core/_yaml_settings.py +64 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adandor/__init__.py +9 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adandor/_andor.py +45 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adandor/_andor_controller.py +49 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adandor/_andor_io.py +36 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adaravis/__init__.py +3 -1
- ophyd_async-0.9.0/src/ophyd_async/epics/adaravis/_aravis.py +47 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adaravis/_aravis_controller.py +21 -30
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adaravis/_aravis_io.py +4 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/__init__.py +15 -8
- ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_core_detector.py +41 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_core_io.py +56 -31
- ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_core_logic.py +121 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_core_writer.py +219 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_hdf_writer.py +33 -59
- ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_jpeg_writer.py +26 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_single_trigger.py +5 -4
- ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_tiff_writer.py +26 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_utils.py +37 -36
- ophyd_async-0.9.0/src/ophyd_async/epics/adkinetix/_kinetix.py +49 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +42 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +7 -7
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adpilatus/__init__.py +2 -2
- ophyd_async-0.9.0/src/ophyd_async/epics/adpilatus/_pilatus.py +46 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +101 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +5 -5
- ophyd_async-0.9.0/src/ophyd_async/epics/adsimdetector/__init__.py +7 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/adsimdetector/_sim.py +51 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/advimba/_vimba.py +43 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/advimba/_vimba_controller.py +52 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/advimba/_vimba_io.py +23 -23
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_aioca.py +52 -21
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_p4p.py +59 -16
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_pvi_connector.py +4 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_signal.py +9 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_util.py +10 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_eiger_controller.py +4 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_eiger_io.py +3 -3
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/motor.py +26 -15
- ophyd_async-0.9.0/src/ophyd_async/epics/sim/_ioc.py +29 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/_mover.py +12 -6
- {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/_sensor.py +2 -2
- ophyd_async-0.9.0/src/ophyd_async/epics/testing/__init__.py +24 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/testing/_example_ioc.py +91 -0
- ophyd_async-0.9.0/src/ophyd_async/epics/testing/_utils.py +50 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/testing/test_records.db +22 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/core.py +2 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/__init__.py +0 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_block.py +9 -9
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_control.py +9 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_hdf_panda.py +7 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_table.py +4 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_trigger.py +7 -7
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/plan_stubs/__init__.py +14 -0
- ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_ensure_connected.py +27 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/plan_stubs/_fly.py +2 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/plan_stubs/_nd_attributes.py +7 -5
- ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_panda.py +13 -0
- ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_settings.py +125 -0
- ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_wait_for_awaitable.py +13 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_detector_controller.py +9 -2
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_generator.py +13 -6
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_sim_motor.py +34 -32
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_signal.py +3 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_tango_transport.py +13 -15
- {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_mover.py +5 -2
- ophyd_async-0.9.0/src/ophyd_async/testing/__init__.py +52 -0
- ophyd_async-0.9.0/src/ophyd_async/testing/__pytest_assert_rewrite.py +4 -0
- ophyd_async-0.9.0/src/ophyd_async/testing/_assert.py +176 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/core → ophyd_async-0.9.0/src/ophyd_async/testing}/_mock_signal_utils.py +15 -11
- ophyd_async-0.9.0/src/ophyd_async/testing/_one_of_everything.py +126 -0
- ophyd_async-0.9.0/src/ophyd_async/testing/_wait_for_pending.py +22 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/PKG-INFO +4 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/SOURCES.txt +47 -31
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/requires.txt +1 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/system_tests/epics/eiger/test_eiger_system.py +4 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/conftest.py +67 -12
- ophyd_async-0.8.0a6/tests/core/test_device_collector.py → ophyd_async-0.9.0/tests/core/test_auto_init_devices.py +27 -17
- ophyd_async-0.9.0/tests/core/test_detector.py +120 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_device.py +44 -6
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_flyer.py +32 -37
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_mock_signal_backend.py +11 -10
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_observe.py +26 -7
- ophyd_async-0.9.0/tests/core/test_protocol.py +18 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_readable.py +30 -11
- ophyd_async-0.9.0/tests/core/test_signal.py +903 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_soft_signal_backend.py +24 -8
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_subset_enum.py +6 -6
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_table.py +25 -1
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_utils.py +7 -7
- ophyd_async-0.9.0/tests/epics/adandor/test_andor.py +123 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adaravis/test_aravis.py +35 -40
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adcore/test_drivers.py +31 -33
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adcore/test_scans.py +27 -18
- ophyd_async-0.9.0/tests/epics/adcore/test_single_trigger.py +60 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adcore/test_writers.py +49 -16
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adkinetix/test_kinetix.py +19 -18
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adpilatus/test_pilatus.py +47 -40
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adsimdetector/test_sim.py +67 -46
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/advimba/test_vimba.py +37 -33
- ophyd_async-0.9.0/tests/epics/conftest.py +69 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/eiger/test_eiger_controller.py +3 -5
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/eiger/test_eiger_detector.py +5 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/eiger/test_odin_io.py +3 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/pvi/test_pvi.py +2 -2
- ophyd_async-0.9.0/tests/epics/signal/test_signals.py +737 -0
- ophyd_async-0.9.0/tests/epics/signal/test_yaml_save_ca.yaml +23 -0
- ophyd_async-0.9.0/tests/epics/signal/test_yaml_save_pva.yaml +42 -0
- ophyd_async-0.8.0a6/tests/epics/demo/test_demo.py → ophyd_async-0.9.0/tests/epics/sim/test_epics_sim.py +51 -47
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/test_motor.py +56 -30
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_hdf_panda.py +9 -16
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_panda_connect.py +6 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_panda_control.py +6 -6
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_panda_utils.py +16 -14
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_seq_table.py +1 -2
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_trigger.py +4 -3
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_writer.py +5 -6
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/plan_stubs/test_fly.py +11 -9
- ophyd_async-0.9.0/tests/plan_stubs/test_settings.py +95 -0
- ophyd_async-0.9.0/tests/plan_stubs/test_setup.py +25 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/conftest.py +1 -1
- ophyd_async-0.9.0/tests/sim/test_pattern_generator.py +67 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/test_sim_detector.py +25 -12
- ophyd_async-0.9.0/tests/sim/test_sim_motor.py +93 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/test_sim_writer.py +3 -3
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/test_streaming_plan.py +5 -4
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/tango/test_base_device.py +11 -11
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/tango/test_tango_signals.py +214 -355
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/tango/test_tango_transport.py +4 -2
- ophyd_async-0.9.0/tests/test_data/test_yaml_save.yaml +119 -0
- ophyd_async-0.8.0a6/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -8
- ophyd_async-0.8.0a6/.mailmap +0 -18
- ophyd_async-0.8.0a6/docs/images/set_and_wait_for_other_value.svg +0 -10
- ophyd_async-0.8.0a6/src/ophyd_async/core/_device_save_loader.py +0 -274
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adaravis/_aravis.py +0 -61
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adcore/_core_logic.py +0 -108
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -44
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -54
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -58
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +0 -79
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adsimdetector/__init__.py +0 -7
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adsimdetector/_sim.py +0 -35
- ophyd_async-0.8.0a6/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -51
- ophyd_async-0.8.0a6/src/ophyd_async/epics/advimba/_vimba.py +0 -43
- ophyd_async-0.8.0a6/src/ophyd_async/epics/advimba/_vimba_controller.py +0 -66
- ophyd_async-0.8.0a6/src/ophyd_async/epics/testing/__init__.py +0 -24
- ophyd_async-0.8.0a6/src/ophyd_async/epics/testing/_example_ioc.py +0 -105
- ophyd_async-0.8.0a6/src/ophyd_async/epics/testing/_utils.py +0 -78
- ophyd_async-0.8.0a6/src/ophyd_async/fastcs/panda/_utils.py +0 -16
- ophyd_async-0.8.0a6/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -33
- ophyd_async-0.8.0a6/src/ophyd_async/tango/__init__.py +0 -0
- ophyd_async-0.8.0a6/src/ophyd_async.egg-info/entry_points.txt +0 -2
- ophyd_async-0.8.0a6/tests/core/test_device_save_loader.py +0 -317
- ophyd_async-0.8.0a6/tests/core/test_protocol.py +0 -33
- ophyd_async-0.8.0a6/tests/core/test_signal.py +0 -376
- ophyd_async-0.8.0a6/tests/epics/adcore/test_single_trigger.py +0 -52
- ophyd_async-0.8.0a6/tests/epics/conftest.py +0 -59
- ophyd_async-0.8.0a6/tests/epics/signal/test_signals.py +0 -934
- ophyd_async-0.8.0a6/tests/sim/__init__.py +0 -0
- ophyd_async-0.8.0a6/tests/sim/demo/__init__.py +0 -0
- ophyd_async-0.8.0a6/tests/sim/demo/test_sim_motor.py +0 -54
- ophyd_async-0.8.0a6/tests/sim/test_pattern_generator.py +0 -34
- ophyd_async-0.8.0a6/tests/test_data/test_yaml_save.yml +0 -40
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.codecov.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.git-blame-ignore-revs +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/actions/install_requirements/action.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/dependabot.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/pages/index.html +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_check.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_dist.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_docs.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_pypi.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_release.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_tox.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/periodic.yml +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/Dockerfile +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/LICENSE +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/README.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/_api.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/_templates/custom-module-template.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/conf.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/examples/foo_detector.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0008-signal-types.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/COPYME +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/design-goals.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/flyscanning.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/genindex.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/choose-interfaces-for-devices.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/contribute.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/make-a-standard-detector.rst +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/use_set_and_wait_for_other_value.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/images/ophyd-async-logo.svg +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/images/ophyd-favicon.svg +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/index.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/reference.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/tutorials/installation.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/tutorials.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/setup.cfg +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/__main__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_hdf_dataset.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_log.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_providers.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_status.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/advimba/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_epics_connector.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_epics_device.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_eiger.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_odin_io.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/signal.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/__init__.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/mover.db +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/sensor.db +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/testing/test_records_pva.db +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_writer.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/py.typed +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/__init__.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/__init__.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_detector.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_detector_writer.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim → ophyd_async-0.9.0/src/ophyd_async/tango}/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_base_device.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_tango_readable.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/__init__.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_counter.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_detector.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_tango/__init__.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_tango/_servers.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/system_tests/epics/eiger/README.md +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_log.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_providers.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_status.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_watchable_async_status.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/signal/test_common.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/test_areadetector_subclass_naming.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/db/panda.db +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/plan_stubs/test_ensure_connected.py +0 -0
- {ophyd_async-0.8.0a6/src/ophyd_async/sim/testing → ophyd_async-0.9.0/tests/sim}/__init__.py +0 -0
- {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/test_cli.py +0 -0
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
"features": {
|
|
40
|
-
//
|
|
41
|
-
"ghcr.io/
|
|
42
|
-
"upgradePackages": false
|
|
43
|
-
}
|
|
40
|
+
// add in eternal history and other bash features
|
|
41
|
+
"ghcr.io/diamondlightsource/devcontainer-features/bash-config:1.0.0": {}
|
|
44
42
|
},
|
|
43
|
+
// Create the config folder for the bash-config feature
|
|
44
|
+
"initializeCommand": "mkdir -p ${localEnv:HOME}/.config/bash-config",
|
|
45
45
|
"runArgs": [
|
|
46
46
|
// Allow the container to access the host X11 display and EPICS CA
|
|
47
47
|
"--net=host",
|
|
@@ -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.
|
|
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.6.0/how-to.html).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Fixes #ISSUE
|
|
2
|
+
|
|
3
|
+
### Instructions to reviewer on how to test:
|
|
4
|
+
1. Do thing x
|
|
5
|
+
2. Confirm thing y happens
|
|
6
|
+
|
|
7
|
+
### Checks for reviewer
|
|
8
|
+
- [ ] Would the PR title make sense to a user on a set of release notes
|
|
9
|
+
- [ ] If the change requires a bump in an IOC version, is that specified in a `##Changes` section in the body of the PR
|
|
10
|
+
- [ ] If the change requires a bump in the PandABlocks-ioc version, is the `ophyd_async.fastcs.panda._hdf_panda.MINIMUM_PANDA_IOC` variable updated to match
|
|
@@ -33,7 +33,7 @@ def get_versions(ref: str, add: str | None) -> list[str]:
|
|
|
33
33
|
builds = set(get_branch_contents(ref))
|
|
34
34
|
except CalledProcessError:
|
|
35
35
|
builds = set()
|
|
36
|
-
logging.warning(f"Cannot get {ref} contents")
|
|
36
|
+
logging.warning(f"Cannot get {ref} contents") # noqa: LOG015
|
|
37
37
|
|
|
38
38
|
# Add and remove from the list of builds
|
|
39
39
|
if add:
|
|
@@ -21,7 +21,7 @@ jobs:
|
|
|
21
21
|
strategy:
|
|
22
22
|
matrix:
|
|
23
23
|
runs-on: ["ubuntu-latest", "windows-latest"] # can add macos-latest
|
|
24
|
-
python-version: ["3.10","3.11"
|
|
24
|
+
python-version: ["3.10","3.11","3.12"]
|
|
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,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: ophyd-async
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.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
|
|
@@ -37,6 +37,7 @@ Classifier: Development Status :: 3 - Alpha
|
|
|
37
37
|
Classifier: License :: OSI Approved :: BSD License
|
|
38
38
|
Classifier: Programming Language :: Python :: 3.10
|
|
39
39
|
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
40
41
|
Requires-Python: >=3.10
|
|
41
42
|
Description-Content-Type: text/markdown
|
|
42
43
|
License-File: LICENSE
|
|
@@ -67,6 +68,7 @@ Requires-Dist: ophyd_async[tango]; extra == "dev"
|
|
|
67
68
|
Requires-Dist: inflection; extra == "dev"
|
|
68
69
|
Requires-Dist: ipython; extra == "dev"
|
|
69
70
|
Requires-Dist: ipywidgets; extra == "dev"
|
|
71
|
+
Requires-Dist: import-linter; extra == "dev"
|
|
70
72
|
Requires-Dist: matplotlib; extra == "dev"
|
|
71
73
|
Requires-Dist: myst-parser; extra == "dev"
|
|
72
74
|
Requires-Dist: numpydoc; extra == "dev"
|
|
@@ -7,8 +7,8 @@ from bluesky.plans import grid_scan # noqa
|
|
|
7
7
|
from bluesky.utils import ProgressBarManager, register_transform
|
|
8
8
|
from ophyd import Component, Device, EpicsSignal, EpicsSignalRO
|
|
9
9
|
|
|
10
|
-
from ophyd_async.core import
|
|
11
|
-
from ophyd_async.epics import
|
|
10
|
+
from ophyd_async.core import init_devices
|
|
11
|
+
from ophyd_async.epics import sim
|
|
12
12
|
|
|
13
13
|
# Create a run engine, with plotting, progressbar and transform
|
|
14
14
|
RE = RunEngine({}, call_returns_result=True)
|
|
@@ -19,7 +19,7 @@ plt.ion()
|
|
|
19
19
|
register_transform("RE", prefix="<")
|
|
20
20
|
|
|
21
21
|
# Start IOC with demo pvs in subprocess
|
|
22
|
-
pv_prefix =
|
|
22
|
+
pv_prefix = sim.start_ioc_subprocess()
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
# Create ophyd devices
|
|
@@ -31,7 +31,7 @@ class OldSensor(Device):
|
|
|
31
31
|
det_old = OldSensor(pv_prefix, name="det_old")
|
|
32
32
|
|
|
33
33
|
# Create ophyd-async devices
|
|
34
|
-
with
|
|
35
|
-
det =
|
|
36
|
-
det_group =
|
|
37
|
-
samp =
|
|
34
|
+
with init_devices():
|
|
35
|
+
det = sim.Sensor(pv_prefix)
|
|
36
|
+
det_group = sim.SensorGroup(pv_prefix)
|
|
37
|
+
samp = sim.SampleStage(pv_prefix)
|
|
@@ -4,7 +4,7 @@ import bluesky.plan_stubs as bps
|
|
|
4
4
|
import bluesky.plans as bp
|
|
5
5
|
from bluesky import RunEngine
|
|
6
6
|
|
|
7
|
-
from ophyd_async.tango.
|
|
7
|
+
from ophyd_async.tango.sim import (
|
|
8
8
|
DemoCounter,
|
|
9
9
|
DemoMover,
|
|
10
10
|
TangoDetector,
|
|
@@ -14,11 +14,11 @@ from tango.test_context import MultiDeviceTestContext
|
|
|
14
14
|
content = (
|
|
15
15
|
{
|
|
16
16
|
"class": DemoMover,
|
|
17
|
-
"devices": [{"name": "
|
|
17
|
+
"devices": [{"name": "sim/motor/1"}],
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
"class": DemoCounter,
|
|
21
|
-
"devices": [{"name": "
|
|
21
|
+
"devices": [{"name": "sim/counter/1"}, {"name": "sim/counter/2"}],
|
|
22
22
|
},
|
|
23
23
|
)
|
|
24
24
|
|
|
@@ -30,8 +30,8 @@ async def main():
|
|
|
30
30
|
detector = TangoDetector(
|
|
31
31
|
trl="",
|
|
32
32
|
name="detector",
|
|
33
|
-
counters_kwargs={"prefix": "
|
|
34
|
-
mover_kwargs={"trl": "
|
|
33
|
+
counters_kwargs={"prefix": "sim/counter/", "count": 2},
|
|
34
|
+
mover_kwargs={"trl": "sim/motor/1"},
|
|
35
35
|
)
|
|
36
36
|
await detector.connect()
|
|
37
37
|
|
|
@@ -62,7 +62,7 @@ The two approaches now look like:
|
|
|
62
62
|
|
|
63
63
|
```python
|
|
64
64
|
class Sensor(StandardReadable, EpicsDevice):
|
|
65
|
-
"""A
|
|
65
|
+
"""A sim sensor that produces a scalar value based on X and Y Movers"""
|
|
66
66
|
|
|
67
67
|
value: A[SignalR[float], PvSuffix("Value"), Format.HINTED_SIGNAL]
|
|
68
68
|
mode: A[SignalRW[EnergyMode], PvSuffix("Mode"), Format.CONFIG_SIGNAL]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Device Collector Event-Loop Choice
|
|
2
2
|
----------------------------------
|
|
3
3
|
|
|
4
|
-
In a sync context, the ophyd-async :python:`
|
|
4
|
+
In a sync context, the ophyd-async :python:`init_devices` requires the bluesky event-loop
|
|
5
5
|
to connect to devices. In an async context, it does not.
|
|
6
6
|
|
|
7
7
|
Sync Context
|
|
@@ -14,25 +14,25 @@ The following will fail if :python:`RE = RunEngine()` has not been called alread
|
|
|
14
14
|
|
|
15
15
|
.. code:: python
|
|
16
16
|
|
|
17
|
-
with
|
|
17
|
+
with init_devices():
|
|
18
18
|
device1 = Device1(prefix)
|
|
19
19
|
device2 = Device2(prefix)
|
|
20
20
|
device3 = Device3(prefix)
|
|
21
21
|
|
|
22
|
-
The :python:`
|
|
22
|
+
The :python:`init_devices` connects to devices in the event-loop created in the run-engine.
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
Async Context
|
|
26
26
|
=============
|
|
27
27
|
|
|
28
28
|
In an async context device connection is decoupled from the run-engine.
|
|
29
|
-
The following attempts connection to all the devices in the :python:`
|
|
29
|
+
The following attempts connection to all the devices in the :python:`init_devices`
|
|
30
30
|
before or after run-engine initialization.
|
|
31
31
|
|
|
32
32
|
.. code:: python
|
|
33
33
|
|
|
34
34
|
async def connection_function() :
|
|
35
|
-
async with
|
|
35
|
+
async with init_devices():
|
|
36
36
|
device1 = Device1(prefix)
|
|
37
37
|
device2 = Device2(prefix)
|
|
38
38
|
device3 = Device3(prefix)
|
|
@@ -43,8 +43,8 @@ The devices will be unable to be used in the run-engine unless they share the sa
|
|
|
43
43
|
When the run-engine is initialised it will create a new background event-loop to use if one
|
|
44
44
|
is not passed in with :python:`RunEngine(loop=loop)`.
|
|
45
45
|
|
|
46
|
-
If the user wants to use devices in the async :python:`
|
|
46
|
+
If the user wants to use devices in the async :python:`init_devices` within the run-engine
|
|
47
47
|
they can either:
|
|
48
48
|
|
|
49
|
-
* Run the :python:`
|
|
50
|
-
* Initialize the run-engine first and run the :python:`
|
|
49
|
+
* Run the :python:`init_devices` first and pass the event-loop into the run-engine.
|
|
50
|
+
* Initialize the run-engine first and run the :python:`init_devices` using the bluesky event-loop.
|
|
@@ -11,7 +11,7 @@ Assembly
|
|
|
11
11
|
|
|
12
12
|
Compound assemblies can be used to group Devices into larger logical Devices:
|
|
13
13
|
|
|
14
|
-
.. literalinclude:: ../../src/ophyd_async/epics/
|
|
14
|
+
.. literalinclude:: ../../src/ophyd_async/epics/sim/_mover.py
|
|
15
15
|
:pyobject: SampleStage
|
|
16
16
|
|
|
17
17
|
This applies prefixes on construction:
|
|
@@ -35,7 +35,7 @@ Grouping by Index
|
|
|
35
35
|
|
|
36
36
|
Sometimes, it makes sense to group devices by number, say an array of sensors:
|
|
37
37
|
|
|
38
|
-
.. literalinclude:: ../../src/ophyd_async/epics/
|
|
38
|
+
.. literalinclude:: ../../src/ophyd_async/epics/sim/_sensor.py
|
|
39
39
|
:pyobject: SensorGroup
|
|
40
40
|
|
|
41
41
|
:class:`~ophyd-async.core.DeviceVector` allows writing maintainable, arbitrary-length device groups instead of fixed classes for each possible grouping. A :class:`~ophyd-async.core.DeviceVector` can be accessed via indices, for example: ``my_sensor_group.sensors[2]``. Here ``sensors`` is a dictionary with integer indices rather than a list so that the most semantically sensible indices may be used, the sensor group above may be 1-indexed, for example, because the sensors' datasheet calls them "sensor 1", "sensor 2" etc.
|
|
@@ -13,7 +13,7 @@ To make a simple device, you need to subclass from the
|
|
|
13
13
|
other suitable Bluesky `Protocols <hardware_interface>` like
|
|
14
14
|
:external+bluesky:py:class:`bluesky.protocols.Movable`.
|
|
15
15
|
|
|
16
|
-
The rest of this guide will show examples from ``src/ophyd_async/epics/
|
|
16
|
+
The rest of this guide will show examples from ``src/ophyd_async/epics/sim/__init__.py``
|
|
17
17
|
|
|
18
18
|
Readable
|
|
19
19
|
--------
|
|
@@ -22,7 +22,7 @@ For a simple :external+bluesky:py:class:`bluesky.protocols.Readable` object like
|
|
|
22
22
|
define some signals, then tell the superclass which signals should contribute to
|
|
23
23
|
``read()`` and ``read_configuration()``:
|
|
24
24
|
|
|
25
|
-
.. literalinclude:: ../../src/ophyd_async/epics/
|
|
25
|
+
.. literalinclude:: ../../src/ophyd_async/epics/sim/_sensor.py
|
|
26
26
|
:pyobject: Sensor
|
|
27
27
|
|
|
28
28
|
First some Signals are constructed and stored on the Device. Each one is passed
|
|
@@ -54,7 +54,7 @@ Movable
|
|
|
54
54
|
For a more complicated device like a `Mover`, you can still use `StandardReadable`
|
|
55
55
|
and implement some addition protocols:
|
|
56
56
|
|
|
57
|
-
.. literalinclude:: ../../src/ophyd_async/epics/
|
|
57
|
+
.. literalinclude:: ../../src/ophyd_async/epics/sim/_mover.py
|
|
58
58
|
:pyobject: Mover
|
|
59
59
|
|
|
60
60
|
The ``set()`` method implements :external+bluesky:py:class:`bluesky.protocols.Movable`. This
|
|
@@ -71,7 +71,7 @@ Assembly
|
|
|
71
71
|
|
|
72
72
|
Compound assemblies can be used to group Devices into larger logical Devices:
|
|
73
73
|
|
|
74
|
-
.. literalinclude:: ../../src/ophyd_async/epics/
|
|
74
|
+
.. literalinclude:: ../../src/ophyd_async/epics/sim/_mover.py
|
|
75
75
|
:pyobject: SampleStage
|
|
76
76
|
|
|
77
77
|
This applies prefixes on construction:
|
|
@@ -24,9 +24,9 @@ Async Tests
|
|
|
24
24
|
Mock Backend
|
|
25
25
|
------------
|
|
26
26
|
|
|
27
|
-
Ophyd devices initialized with a mock backend behave in a similar way to mocks, without requiring you to mock out all the dependencies and internals. The `
|
|
27
|
+
Ophyd devices initialized with a mock backend behave in a similar way to mocks, without requiring you to mock out all the dependencies and internals. The `init_devices` can initialize any number of devices, and their signals and sub-devices (recursively), with a mock backend.
|
|
28
28
|
|
|
29
|
-
.. literalinclude:: ../../tests/epics/
|
|
29
|
+
.. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
|
|
30
30
|
:pyobject: mock_sensor
|
|
31
31
|
|
|
32
32
|
|
|
@@ -37,26 +37,26 @@ Mock signals behave as simply as possible, holding a sensible default value when
|
|
|
37
37
|
|
|
38
38
|
In addition this example also utilizes helper functions like ``assert_reading`` and ``assert_value`` to ensure the validity of device readings and values. For more information see: :doc:`API.core<../_api/ophyd_async.core>`
|
|
39
39
|
|
|
40
|
-
.. literalinclude:: ../../tests/epics/
|
|
40
|
+
.. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
|
|
41
41
|
:pyobject: test_sensor_reading_shows_value
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
Given that the mock signal holds a ``unittest.mock.Mock`` object you can retrieve this object and assert that the device has been set correctly using ``get_mock_put``. You are also free to use any other behaviour that ``unittest.mock.Mock`` provides, such as in this example which sets the parent of the mock to allow ordering across signals to be asserted:
|
|
45
45
|
|
|
46
|
-
.. literalinclude:: ../../tests/epics/
|
|
46
|
+
.. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
|
|
47
47
|
:pyobject: test_retrieve_mock_and_assert
|
|
48
48
|
|
|
49
49
|
There are several other test utility functions:
|
|
50
50
|
|
|
51
51
|
Use ``callback_on_mock_put``, for hooking in logic when a mock value changes (e.g. because someone puts to it). This can be called directly, or used as a context, with the callbacks ending after exit.
|
|
52
52
|
|
|
53
|
-
.. literalinclude:: ../../tests/epics/
|
|
53
|
+
.. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
|
|
54
54
|
:pyobject: test_mover_stopped
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
Testing a Device in a Plan with the RunEngine
|
|
58
58
|
---------------------------------------------
|
|
59
|
-
.. literalinclude:: ../../tests/epics/
|
|
59
|
+
.. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
|
|
60
60
|
:pyobject: test_sensor_in_plan
|
|
61
61
|
|
|
62
62
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1187.8240472771774 784.5838303364346" width="1187.8240472771774" height="784.5838303364346"><!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXGtT28hcdTAwMTL9nl/hYr+uZ6fnPVu1XHUwMDFmeL9cdGAg4LtblLBcdTAwMDU2yI/YMrbZyn+/PVwitmRLSkxQXHUwMDE1cK+VSlx1MDAwMlx1MDAxYUlcdTAwMWVPn3Ome7pH/34qlVbCcddf+bO04o9qXtCs97zhyu/u/KPf6zc7bWxi0e/9zqBXi65shGG3/+dcdTAwMWZ/xHeQWqf1fJdcdTAwMWb4Lb9cdTAwMWT28br/4O+l0r/Rv9jSrLt7d1x1MDAwZvbOzcBcdTAwMWLv8NP9w+1t9dS4236Kbo0umnQmaLb9+OzIdcIoorlQTEkqQVs9bVx1MDAxZLtWLVxilVSBppZyUHzaOmzWw4a7XHUwMDAyXGZRXHUwMDFjrNKUWrBcdTAwMTTiS1x1MDAxYX7zrlx1MDAxMeI1dHrKa99cdTAwMDX+zJl+2Os8+OudoNNzXHUwMDFk/FxyfPcn7uONV3u463VcdTAwMDbt+vSasOe1+12vh+NcdTAwMTFfd9tcZoJKOI6ejmOK47cy91x1MDAxOV8mPZ47n3dcdTAwMTd+6F2j7ffdmMP0bKfr1ZqhXHUwMDFiXHUwMDFioPG3cD3s7tYj8/xcdTAwMTP3qee1/F1nn/YgXGKmp5vtuu+GfsXTM5/Wrn//tIltY8Ox72e+xX33ffdg4NQoSpPDXHUwMDFlXHUwMDAzjKv5k0eddoQ10MBcdTAwMDAsmPiLNftcdTAwMWJcYrIweuqtXHUwMDE39P3YXHUwMDA0rmubXHRcdTAwMDDG33DQrXvPt4DmIC1cYnyskdN2xNvD/NdcdTAwMGY6tYeMT+l2mkl8uyP+qVx1MDAxNCMm+mX68z+/Z16dj8q52z/NPWYl8PrheqfVaob4vY5dn+b731x1MDAwZr1euIZGbLbv5tv8dj2nJbprtdfrXGZcdTAwMWK+l4JcdTAwMDTeN9/2KWHvObLLSnBTvX06OdLXltc26eZVfTRehOxIccKVkpZLXHUwMDEwXFxZk1wiO8LCNTFcdTAwMDaW2Vx1MDAxNNljwE+5XHJKXHUwMDEyI43mXHUwMDFjn1xu2sSQW3J9huvm9Vxcl4ZZq1xmj/lcdTAwMTVzXaZcdTAwMDRgwnWpQSpcdTAwMDGxNVx1MDAwYmK6NlrHXHUwMDAweiumz1xcXU6h8aMzfWdw3FxizvaHrcv7p4PLe749XHUwMDFhfVmM6UC0YtpcdTAwMWGqwf1cdTAwMTBj5lx1MDAxOc+SXGIhXHUwMDEwXHUwMDFhilx1MDAxYamVjFxyOeE6ylx1MDAwNEE7K2NcdTAwMTjKhqKxYzDlPidGUFx1MDAwMdxSfJax2i7Jn0P+1VeTX1xuLVx1MDAwNVozi/vI79yJnlkpuaE2lodi6C9cdTAwMTmjXHRn8a3on4tSd5TTXHUwMDAw/eB6cPxggro9XHUwMDFiqTXjs2FzNVx1MDAxOHVH54voXHUwMDAxgDJESKMkXHUwMDE4I4DyXHUwMDE4XHUwMDBmz1x1MDAxMOdcdTAwMDRcdTAwMDTljGNcdTAwMWNgqY6pM/XzXHSnglx0w1x1MDAwNVPKclx1MDAxNuMw4VxuUMLQXHUwMDAzxFx1MDAwYimCTibmqaVcdTAwMWPMyMHaq+VAS6lcZloq7mAsXHUwMDA3JtdcdTAwMTVcdTAwMDCjMYpcdTAwMDOdsF5BaiCYZuLN1SBcdTAwMTek7kjD84OLQf38er+744l9enmpz8Pg3JfVtVx1MDAwNcXAXHUwMDEyxpSL+5Wwls3FXHUwMDAxSlx1MDAxMMG1Rlx1MDAxOZBMK65jw07UXHUwMDAwuEY/XHUwMDBiXVx1MDAwN0mpQVx1MDAxN0PFT5jKwZwxTMy/pVx1MDAxYcyowfqr1UBYXHSIdpblXHUwMDFjWDF/cqJcdTAwMDZMSJxcdTAwMTk5LTIyYFx1MDAxNKzB2IDFY/VWYpCPUXeUU/D84GrgVeqNzVx1MDAxZF7/utX6Ut7YWq3fXHUwMDFjle/SauC5J87KXHUwMDAxt4pYjUrAmVx1MDAwNvRcdTAwMTBcdTAwMTLepEM4d45cdTAwMDNHt0BKQEmwad/ARVx1MDAxM+hcXEnqllx1MDAxNoRgiVx1MDAwN0zVQCmCkSsqXHUwMDBlSlxuM1bFoFuqwYxcdTAwMWFsvFpcclx1MDAxOLq8Ssgs14Dlilx1MDAwMXqA6FFgSF/0iiBOtWDffkUwXHUwMDFmo+5IofO9i8E8j/3gpjOMx/BcdTAwMDc6MVx1MDAxZdOy1aPu497J9vrZcFx1MDAxZvzbs520ToT+KJyTXHRQhFwiSrimimLIOatcdTAwMTJlMFx1MDAwNJ1LXHUwMDEzSYhCXHUwMDE3i6Z1wrr1xYzAgS1cdTAwMDOFXHUwMDFjMdjMXHUwMDE2g1ncfF8g4JapZJyfWFx1MDAxZmDzJ6cuXHUwMDAwMPbsvVx1MDAxN816zXVcIlx1MDAwZXlcdTAwMDHrI+C5wfbDUs1cdTAwMGJcdTAwMDI/MeK3nXZYaT5FPaczZ7e8VjNwgy5nXHUwMDFltFx1MDAxYTTv2pFcdTAwMTPs3yawgKNcdTAwMTA28eHT5rDTjVtr+DxcdTAwMGad5l7aMp1e867Z9oKzXHUwMDFmdNJcdTAwMWKEnVO//9zNsDfwk6Pg70yjZcLkXHUwMDBmaDqwNHzcqVx1MDAwZcfXm6u6vXNePeWrtYWmc4zvXHUwMDA0wUlcXIGlXHUwMDE2I0SYJSoznGgppKDAuaIssWI/4akhnEtcZlxyjLMkXlx1MDAxNcMnXvozgijGXHUwMDE4PohKXHUwMDA1XHUwMDE4ji4pnE3hrVfP5+iSXHUwMDE5UEon4TtcdPVzmVxyOJ9RKlx1MDAwNC903Vx1MDAxZnshXHUwMDExM1x0QXmr+TxcdTAwMTej7kij8393Pu96Z9XDrduB199f2zp73LjqXbTsXCLzOY5cdTAwMWHGQFx1MDAxYbVAXHUwMDAws5bPZv6VUYQroVxyM2Ckzcj8u9u1ZlK6RZWZ5Z+pSlxiQ5ihXHUwMDE2/0pEXHUwMDBmzlDxNUuVmFGJ7cUneuDIbGGtykxcdTAwMDWI1NlpXHUwMDFlMPJcdTAwMTCEKjrc10Zp9Utrf5OpvuJm0U6rXHUwMDFi9eXvduZ8XHUwMDBmlnBgXFyjw0KVXHUwMDE1kEhoveH8n9vzYpyAo3p1yK5cdTAwMGY2dqrdx4C1XHUwMDFiI713lOFcdTAwMDRkVfVcdTAwMTiiMPTSqJDS2WiG25IxYlx1MDAxMSnGXCKUXHUwMDE4+lx1MDAwYiluY1x1MDAwMInc5lxcUFxmmVDxM5b3MJxyy0fCKLfIQlx1MDAxNSyTfznc3nt95t9aXGZYXHUwMDE1miqD8jrlXHUwMDE4JHxcdTAwMDDDjVx1MDAwMVF0TK9cXFx1MDAxMVx0TUL6TXyAXFyUuqOcXHUwMDA26Ht3XHUwMDAyfrLCd2Iq/Vx1MDAwYk94Xs/SS3VVXHUwMDE5X9X8/lwiaqBd2Y8xLtBTVCZzyJFcdTAwMWHgKFpFlVx1MDAxMVx1MDAxMlx1MDAwNIbw6XhcdTAwMDDdXHUwMDA0dLMwnlx1MDAxMNrlXGIzKlx1MDAwMUBcdTAwMDGxXHUwMDAyXHUwMDAxylx1MDAwNOMozsvF/jwx2H+9XHUwMDE4oCGNq8bMXG5cYoDmJv9cdTAwMTjGgkZD4Vx1MDAwYnxugjGxU/FWYlDOQ2nUmFx1MDAwNuhcdTAwMDdcdTAwMTeDQ1j1/ftBZet2/CBcdTAwMWFhd9y+3G8uJlx1MDAwNpxQ6rxxXHSIoUSqP1rsl0CEwGGyoGmyPDSu96VEK8M4XHUwMDBlo1x1MDAwNMMzlvrnXGZcdTAwMDGJWoOlXHUwMDE4zIjBQVx1MDAwMTWBnDFU7zTtnanzV1x1MDAwNzCEwGis8GU/JTFcdTAwMWOMIfF25b85IHXHvFAgPj+4XHUwMDE2XFxcdTAwMDSNyv2Td7HfVMdcdTAwMWK1zZOt7mh0tYhcdTAwMTZYYERcdTAwMWFh0EkywpVcdTAwMDXPaoHQxChcdTAwMTffMWGpVlx1MDAxOYk/XHUwMDAy2IBcdTAwMTG+5qhcdTAwMTZuISDLNZBcdTAwMDRtgMDgQkhXdbBUg2w1OHy9XHUwMDFhXGJhjcb4ODNOyF1cdTAwMTkw6DpcdTAwMDNcdTAwMThWuGeguHhcdTAwMGapv1xclEatKXx+cDVYXHIvVoc4f1x1MDAxZldb7ZPH+/2d3aOb3mJqIDBcdTAwMTBwsZ3hjCo2XHUwMDFmJnBcdTAwMTdEoPPktlx1MDAwZliT3lx1MDAxZMBcciNMIPqYlFxiJpGxXHUwMDEzaCYm01bE61xuSy2Y0YKjXHUwMDAyqlx1MDAwMCTXWr20KFxiXWODs2PhXHUwMDFig1x1MDAxMFRKvP12gVxcjLqjnILnXHUwMDA3l4LDLjuiZ8NHM1TlXHUwMDAz8fBwerd7TVx1MDAxN0pcIlqQP4hcdTAwMTIkWIKDZLkrpnRZoZ94XHUwMDA2imeVXHUwMDBic0qsq2HVXHUwMDEw7VGIXHUwMDExt9SCXHUwMDE5Lfj8ei1cdTAwMDBw9W9orlxmLYD88lx1MDAwMFx1MDAxMCCURlx1MDAwYlx1MDAxNVx1MDAxOSe4nIFbwTfvoEQwXHUwMDBmpVHjPD7fu1x1MDAxOPx6XHUwMDBlsex/3Vx0t/nhnq7uhqbSPDg+5seL5Fx1MDAxMHF4XGJFOVx1MDAxNVpcdTAwMGLrXGY7I1x1MDAxM25zhpXMWpeyUZBcdTAwMTCBOIdo8VxuXHUwMDA0pmFCU02zXFyG5e7hXHUwMDFjXTjO1oXsnKFSVKNkZ1x1MDAwNVx1MDAwNkDz64NcXKJcdTAwMTGDP1WkO/A6XHUwMDAxmCRcck/XLkqHXlhr+PXS3+1TP1x1MDAxY/TapYbfS1j/3ZVcdTAwMGIt0OdiXHUwMDEyh1fbtfPxyf3t58HT7nrlZG90vN86XYTQTDJiLDpG0lx1MDAxNYdrSCR2o+IhjozmbkuAxjklWeg7rfGTRC1r/F5C45NcdTAwMTfQWGpKKfqlmTuA8/OA0lVwUFHs0r+rXHUwMDA1clx1MDAwNVx1MDAwNb9cdTAwMTTgJ1P/fWSVXHUwMDE3vGPaZnWyXHUwMDE4nm5Wx/edr5etQy5cdTAwMDJ2trq7a8MhLFa8XHUwMDAzjFxiJiRTOPtcbjNcdTAwMTesa0aJVKCY4NRcdTAwMWGTsZ+PU0OYXHUwMDBiyyZHxtS75GxcdTAwMWVnT1x1MDAxN+ese89cdTAwMDZcdTAwMDcqMzlcdTAwMGI/ekVHtIWN6lwi9+pF9Tr4n3xVae7Qa4bXt53edd9cdTAwMGavv5e/YM//Kp0hXHUwMDBm3jGPXHUwMDE37Hcx1D6RO/f65ubgofbF71x1MDAxZlxmap/LfP1sXHUwMDExamsliOZGaFx0XGJcdTAwMDCQaWZcdTAwMWKDs1x1MDAwMFx1MDAwN2FccqfpXHUwMDE5XHUwMDE4jUxQlVxyn1x1MDAxY0tiL07sylx1MDAwYiZj9GJccjPKZlx1MDAxMjtdrjslNqAuU5Pcu1uUT23Er7175yfELv1V2nLXfzxqp3teXGa5ny79yuOoelC+XHUwMDA3yldcdTAwMGZlY/vOW2jeZorjtK0toP8kuaSz62poPlwiqFx1MDAwMWMsl0InK3WmXHUwMDExM9jlJpqXcfpscU5LbaQrts8qrflBNl1cdTAwMWItXFw+udBt9Uqh/Vx1MDAxNee/lE6fMLrlos3372Fnd7NcdTAwMTiunrY3xGBXXHUwMDFl9PpP7HjfVPf2vcHJXCJcXFx1MDAwNUYp0e7tKVQyKsRcXIG8K6JcdTAwMTUou26/XHKIrFx1MDAwMnlJkMVoR9RlhyqawVrxXHUwMDEy1vo46XP4P2HtxVx1MDAwYmZiJpVcdTAwMDYtWSZt81lrXTWcVoVcdTAwMTbBIGst6OSuql9gLWRSNaFcdTAwMDRvSFUomp9b643zyvaVXHUwMDE4datcdTAwMDftXTa86lxmZMbG9TQ/LXcvp0RyWWqZoGxu8ZlaYo1CS3Anoybj1ZWSPMe/XHUwMDE0g2HDdXz/kp4/peeXxelpLUWFTL5cdTAwMTJcImanyk1EW4raKrgu8sVVxaw8s3fMTvZcbnZ++p7RWvG63UqIo7YySTKuPDb94VpcdTAwMWHOv91Gx8qn79x2UPaj3OS3T9/+XHUwMDBiP9Ji1SJ9<!-- payload-end --></metadata><defs><style class="style-fonts">
|
|
2
|
+
@font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }</style></defs><rect x="0" y="0" width="1187.8240472771774" height="784.5838303364346" fill="#ffffff"></rect><g stroke-linecap="round"><g transform="translate(43.84248105120804 302.75444427692025) rotate(0 109.31598350459507 0)"><path d="M-0.45 -0.7 C35.76 -0.86, 180.92 -1.39, 217.58 -1.19 M1.51 1.54 C38.06 1.51, 183.45 0.24, 219.75 -0.28" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(262.4744480603982 302.8253415087969) rotate(0 0 -82.9293667965893)"><path d="M0.64 0.3 C0.59 -27.08, -0.08 -137.51, -0.32 -165.29 M-0.48 -0.59 C-0.72 -28.23, -1.79 -139.66, -1.44 -167.12" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(258.8706526177911 134.14839879518058) rotate(0 332.5798441252804 -1.9202069522244898)"><path d="M-0.18 0.98 C110.67 0.28, 554.82 -2.97, 665.76 -3.76 M-1.73 0.45 C108.95 -0.07, 554.04 -1.71, 665.12 -2.18" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(925.5665064301318 131.8441504525112) rotate(0 1.1521241713346626 80.10711520276767)"><path d="M0.54 0.53 C0.98 27.16, 1.63 133.33, 2.07 159.95 M-0.63 -0.24 C-0.32 26.56, 0.42 134.38, 1 161.35" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(926.3345892110212 293.1415344393678) rotate(0 68.92542750440384 -1.152124171334691)"><path d="M1.09 -0.33 C24.12 -0.33, 115.62 -0.86, 138.29 -1.2 M0.21 -1.54 C23.1 -1.75, 114.33 -2.82, 137.57 -2.74" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(154.08449781789392 67.15748673767692) rotate(0 52.98975332972128 33.34186726364484)"><path d="M-1.06 0.7 C16.59 11.86, 88.97 56.89, 106.91 67.72 M0.58 0.03 C18.07 10.8, 88.85 55.06, 106.45 66.14" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(154.08449781789392 67.15748673767692) rotate(0 52.98975332972128 33.34186726364484)"><path d="M82 60.91 C92.6 64.68, 102.53 66.17, 106.45 66.14 M82 60.91 C86.56 61.38, 93.31 62.59, 106.45 66.14" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(154.08449781789392 67.15748673767692) rotate(0 52.98975332972128 33.34186726364484)"><path d="M91.08 46.42 C98.28 55.67, 104.73 62.72, 106.45 66.14 M91.08 46.42 C93.64 50.1, 98.42 54.45, 106.45 66.14" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(73.11139160618495 10) rotate(0 47.0625 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">set called</text></g><g stroke-linecap="round"><g transform="translate(931.6644736450401 312.4583673202069) rotate(0 4.167733407955666 192.31112725280877)"><path d="M-0.34 -0.98 C1.13 63.35, 6.73 321.09, 8.05 385.17 M1.68 1.12 C3.03 65.16, 5.56 319.49, 6.94 383.33" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(931.6644736450401 312.4583673202069) rotate(0 4.167733407955666 192.31112725280877)"><path d="M-1.96 359.97 C-1.66 365.01, 2.98 369.66, 6.94 383.33 M-1.96 359.97 C0.77 365.61, 2.46 369.39, 6.94 383.33" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(931.6644736450401 312.4583673202069) rotate(0 4.167733407955666 192.31112725280877)"><path d="M15.14 359.71 C11.41 364.76, 12.02 369.48, 6.94 383.33 M15.14 359.71 C14.41 365.37, 12.64 369.21, 6.94 383.33" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(889.4853986759654 715.0686100052003) rotate(0 66.3862760711362 24.140464025867686)"><text x="0" y="17.014199045431567" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="19.312371220694175px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Set completed</text><text x="0" y="41.15466307129928" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="19.312371220694175px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"></text></g><g stroke-linecap="round"><g transform="translate(45.723429211048085 551.6184165698157) rotate(0 208.3866703977804 -2.9769524342540308)"><path d="M1.15 -0.09 C70.36 -1.4, 346.52 -5.76, 415.96 -6.64 M0.29 -1.19 C69.83 -1.84, 348.7 -4.42, 418.24 -5.46" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(462.49677000660887 545.6645117013077) rotate(0 -1.190780973701635 -80.97310621170891)"><path d="M-0.62 -0.09 C-1.05 -26.87, -1.53 -134.53, -1.9 -161.39 M1.25 -1.18 C0.65 -28.26, -1.74 -136.22, -2.59 -163.22" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(460.1152080592056 380.14595635678495) rotate(0 105.3841161725918 -1.1907809737016066)"><path d="M0.98 -0.93 C36.1 -1.01, 176.54 -1, 211.51 -1.27 M0.04 1.2 C34.99 0.88, 175.96 -2.39, 210.95 -2.82" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(669.6926594306876 376.57361343568016) rotate(0 0.5953904868507607 82.75927767226133)"><path d="M-0.99 -0.41 C-0.54 27.2, 1.55 136.9, 1.72 164.64 M0.7 -1.68 C1.12 26.16, 0.78 138.12, 1.04 165.72" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(672.0742213780909 542.0921687802029) rotate(0 191.12034627910714 -2.976952434253974)"><path d="M0.95 0.4 C64.42 -0.86, 317.63 -5.42, 381.15 -6.62 M0 -0.44 C63.78 -1.63, 319.76 -4.51, 383.29 -5.43" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(672.1152080592055 548.1907594909206) rotate(0 0.5953904868508175 65.49295355358805)"><path d="M-0.92 1.14 C-0.95 23.33, -0.16 110.39, 0.31 131.92 M0.8 0.7 C1.09 22.66, 2.45 108.52, 2.56 130.29" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(672.1152080592055 548.1907594909206) rotate(0 0.5953904868508175 65.49295355358805)"><path d="M-6.25 106.9 C-1.55 113.53, 1.13 124.19, 2.56 130.29 M-6.25 106.9 C-4.64 113.13, -2.21 118.07, 2.56 130.29" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(672.1152080592055 548.1907594909206) rotate(0 0.5953904868508175 65.49295355358805)"><path d="M10.85 106.7 C9.68 113.27, 6.5 123.99, 2.56 130.29 M10.85 106.7 C8.22 113.14, 6.41 118.12, 2.56 130.29" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(616.1485022952302 694.6568192562175) rotate(0 69.97916412353516 25)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">RBV Matched </text><text x="0" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Return here</text></g><g transform="translate(10 264.6402019077296) rotate(0 47.8125 12.500000000000014)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Set signal</text></g><g transform="translate(869.5323806105109 749.2654514964912) rotate(0 154.14583333333326 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">wait_for_set_completion= True</text></g><g transform="translate(521.8463297153439 749.5838303364346) rotate(0 160.32291666666663 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">wait_for_set_completion = False</text></g><g transform="translate(20.535767711378583 514.1120161220821) rotate(0 59.5625 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">match signal</text></g><g transform="translate(957.8616550664754 651.6440183607504) rotate(0 7.677083492279053 22.5)"><text x="0" y="31.716" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="36px" fill="#e03131" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">1</text></g><g transform="translate(691.1677036384312 638.6901134922423) rotate(0 12.583333015441895 22.5)"><text x="0" y="31.716" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="36px" fill="#e03131" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">2</text></g></svg>
|
|
@@ -41,13 +41,13 @@ that you can mix Ophyd and Ophyd Async devices in the same RunEngine:
|
|
|
41
41
|
:start-after: # Create ophyd devices
|
|
42
42
|
:end-before: # Create ophyd-async devices
|
|
43
43
|
|
|
44
|
-
Finally we create the Ophyd Async devices imported from the `epics.
|
|
44
|
+
Finally we create the Ophyd Async devices imported from the `epics.sim` module:
|
|
45
45
|
|
|
46
46
|
.. literalinclude:: ../examples/epics_demo.py
|
|
47
47
|
:language: python
|
|
48
48
|
:start-after: # Create ophyd-async devices
|
|
49
49
|
|
|
50
|
-
The first thing to note is `with`. This uses
|
|
50
|
+
The first thing to note is `with`. This uses `init_devices` as a context
|
|
51
51
|
manager to collect up the top level `Device` instances created in the context,
|
|
52
52
|
and run the following:
|
|
53
53
|
|
|
@@ -9,6 +9,7 @@ classifiers = [
|
|
|
9
9
|
"License :: OSI Approved :: BSD License",
|
|
10
10
|
"Programming Language :: Python :: 3.10",
|
|
11
11
|
"Programming Language :: Python :: 3.11",
|
|
12
|
+
"Programming Language :: Python :: 3.12",
|
|
12
13
|
]
|
|
13
14
|
description = "Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango"
|
|
14
15
|
dependencies = [
|
|
@@ -42,6 +43,7 @@ dev = [
|
|
|
42
43
|
"inflection",
|
|
43
44
|
"ipython",
|
|
44
45
|
"ipywidgets",
|
|
46
|
+
"import-linter",
|
|
45
47
|
"matplotlib",
|
|
46
48
|
"myst-parser",
|
|
47
49
|
"numpydoc",
|
|
@@ -73,9 +75,6 @@ dev = [
|
|
|
73
75
|
"types-pyyaml",
|
|
74
76
|
]
|
|
75
77
|
|
|
76
|
-
[project.scripts]
|
|
77
|
-
ophyd-async = "ophyd_async.__main__:main"
|
|
78
|
-
|
|
79
78
|
[project.urls]
|
|
80
79
|
GitHub = "https://github.com/bluesky/ophyd-async"
|
|
81
80
|
|
|
@@ -156,6 +155,11 @@ lint.select = [
|
|
|
156
155
|
"UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up
|
|
157
156
|
"SLF", # self - https://docs.astral.sh/ruff/settings/#lintflake8-self
|
|
158
157
|
"PLC2701", # private import - https://docs.astral.sh/ruff/rules/import-private-name/
|
|
158
|
+
"LOG015", # root logger call - https://docs.astral.sh/ruff/rules/root-logger-call/
|
|
159
|
+
"S101", # assert = https://docs.astral.sh/ruff/rules/assert/
|
|
160
|
+
]
|
|
161
|
+
lint.ignore = [
|
|
162
|
+
"B901", # Return in a generator is needed for plans
|
|
159
163
|
]
|
|
160
164
|
lint.preview = true # so that preview mode PLC2701 is enabled
|
|
161
165
|
|
|
@@ -163,4 +167,30 @@ lint.preview = true # so that preview mode PLC2701 is enabled
|
|
|
163
167
|
# By default, private member access is allowed in tests
|
|
164
168
|
# See https://github.com/DiamondLightSource/python-copier-template/issues/154
|
|
165
169
|
# Remove this line to forbid private member access in tests
|
|
166
|
-
"tests/**/*" = ["SLF001"]
|
|
170
|
+
"tests/**/*" = ["SLF001", "S101"]
|
|
171
|
+
"src/ophyd_async/testing/**/*" = ["SLF001", "S101"]
|
|
172
|
+
"system_tests/**/*" = ["SLF001", "S101"]
|
|
173
|
+
"docs/examples/**/*" = ["SLF001", "S101"]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
[tool.importlinter]
|
|
177
|
+
root_package = "ophyd_async"
|
|
178
|
+
|
|
179
|
+
[[tool.importlinter.contracts]]
|
|
180
|
+
name = "All runtime modules are in layers"
|
|
181
|
+
type = "layers"
|
|
182
|
+
containers = ["ophyd_async"]
|
|
183
|
+
layers = ["plan_stubs", "fastcs", "epics | tango | sim", "core"]
|
|
184
|
+
exhaustive = true
|
|
185
|
+
exhaustive_ignores = ["testing", "_version", "__main__"]
|
|
186
|
+
|
|
187
|
+
[[tool.importlinter.contracts]]
|
|
188
|
+
name = "Testing and sim modules are not used at runtime"
|
|
189
|
+
type = "forbidden"
|
|
190
|
+
forbidden_modules = ["ophyd_async.testing", "ophyd_async.sim"]
|
|
191
|
+
source_modules = [
|
|
192
|
+
"ophyd_async.plan_stubs",
|
|
193
|
+
"ophyd_async.fast.*",
|
|
194
|
+
"ophyd_async.epics",
|
|
195
|
+
"ophyd_async.tango",
|
|
196
|
+
]
|