ophyd-async 0.7.0a1__tar.gz → 0.8.0a3__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.7.0a1 → ophyd_async-0.8.0a3}/.copier-answers.yml +1 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/CONTRIBUTING.md +1 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_pypi.yml +2 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/ci.yml +1 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/Dockerfile +1 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/PKG-INFO +8 -12
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/README.md +3 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/conf.py +2 -5
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/examples/foo_detector.py +1 -1
- ophyd_async-0.8.0a3/docs/explanations/decisions/0008-signal-types.md +159 -0
- ophyd_async-0.8.0a3/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +140 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to/make-a-simple-device.rst +4 -4
- ophyd_async-0.8.0a3/docs/images/ophyd-async-logo.svg +358 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/pyproject.toml +16 -17
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/_version.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/__init__.py +30 -9
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_detector.py +5 -10
- ophyd_async-0.8.0a3/src/ophyd_async/core/_device.py +315 -0
- ophyd_async-0.8.0a3/src/ophyd_async/core/_device_filler.py +269 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_device_save_loader.py +6 -7
- ophyd_async-0.8.0a3/src/ophyd_async/core/_mock_signal_backend.py +76 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_mock_signal_utils.py +22 -16
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_protocol.py +28 -8
- ophyd_async-0.8.0a3/src/ophyd_async/core/_readable.py +260 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_signal.py +140 -152
- ophyd_async-0.8.0a3/src/ophyd_async/core/_signal_backend.py +164 -0
- ophyd_async-0.8.0a3/src/ophyd_async/core/_soft_signal_backend.py +175 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_status.py +22 -6
- ophyd_async-0.8.0a3/src/ophyd_async/core/_table.py +143 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_utils.py +79 -18
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adaravis/_aravis_controller.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adaravis/_aravis_io.py +8 -6
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adcore/_core_io.py +5 -7
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adcore/_hdf_writer.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adcore/_single_trigger.py +4 -9
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adcore/_utils.py +15 -10
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adkinetix/__init__.py +2 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +6 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +4 -5
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +3 -4
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adsimdetector/_sim_controller.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/advimba/__init__.py +4 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/advimba/_vimba_controller.py +6 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/advimba/_vimba_io.py +8 -9
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/__init__.py +26 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_aioca.py +323 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_epics_connector.py +53 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_epics_device.py +13 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_p4p.py +382 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_pvi_connector.py +92 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_signal.py +171 -0
- ophyd_async-0.8.0a3/src/ophyd_async/epics/core/_util.py +61 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/demo/_mover.py +4 -5
- ophyd_async-0.8.0a3/src/ophyd_async/epics/demo/_sensor.py +37 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/eiger/_eiger.py +1 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/eiger/_eiger_controller.py +1 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/eiger/_eiger_io.py +3 -5
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/eiger/_odin_io.py +5 -5
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/motor.py +4 -5
- ophyd_async-0.8.0a3/src/ophyd_async/epics/signal.py +11 -0
- ophyd_async-0.8.0a3/src/ophyd_async/fastcs/core.py +9 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/__init__.py +4 -4
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/_block.py +23 -11
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/_control.py +3 -5
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/_hdf_panda.py +5 -19
- ophyd_async-0.8.0a3/src/ophyd_async/fastcs/panda/_table.py +87 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/_trigger.py +8 -8
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/_writer.py +4 -7
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/plan_stubs/_ensure_connected.py +3 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/plan_stubs/_fly.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/plan_stubs/_nd_attributes.py +5 -4
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector_controller.py +1 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/_sim_motor.py +3 -4
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/__init__.py +2 -4
- ophyd_async-0.8.0a3/src/ophyd_async/tango/base_devices/_base_device.py +157 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/demo/_counter.py +8 -18
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/demo/_mover.py +5 -6
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/signal/__init__.py +2 -4
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/signal/_signal.py +29 -50
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/signal/_tango_transport.py +38 -40
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async.egg-info/PKG-INFO +8 -12
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async.egg-info/SOURCES.txt +18 -12
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async.egg-info/requires.txt +4 -8
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/system_tests/epics/eiger/test_eiger_system.py +1 -1
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_device.py +55 -91
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_device_collector.py +16 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_device_save_loader.py +121 -94
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_flyer.py +8 -4
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_log.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_mock_signal_backend.py +68 -70
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_readable.py +83 -68
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_signal.py +25 -98
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_soft_signal_backend.py +64 -60
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_status.py +15 -6
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_subset_enum.py +23 -31
- ophyd_async-0.8.0a3/tests/core/test_table.py +53 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_utils.py +7 -6
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_watchable_async_status.py +19 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adaravis/test_aravis.py +5 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adcore/test_single_trigger.py +6 -10
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adcore/test_writers.py +11 -8
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adkinetix/test_kinetix.py +9 -6
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adsimdetector/test_sim.py +13 -9
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/advimba/test_vimba.py +7 -5
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/conftest.py +6 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/demo/test_demo.py +49 -13
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/eiger/test_eiger_controller.py +7 -8
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/eiger/test_eiger_detector.py +1 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/eiger/test_odin_io.py +9 -22
- ophyd_async-0.8.0a3/tests/epics/pvi/test_pvi.py +173 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/signal/test_common.py +5 -16
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/signal/test_records.db +1 -25
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/signal/test_signals.py +217 -199
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/test_motor.py +22 -16
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/db/panda.db +39 -46
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/test_hdf_panda.py +9 -24
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/test_panda_connect.py +21 -26
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/test_panda_control.py +5 -13
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/test_panda_utils.py +6 -14
- ophyd_async-0.7.0a1/tests/fastcs/panda/test_table.py → ophyd_async-0.8.0a3/tests/fastcs/panda/test_seq_table.py +45 -73
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/test_trigger.py +12 -18
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/fastcs/panda/test_writer.py +22 -43
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/plan_stubs/test_ensure_connected.py +3 -3
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/plan_stubs/test_fly.py +4 -11
- ophyd_async-0.8.0a3/tests/sim/demo/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/sim/demo/test_sim_motor.py +2 -2
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/sim/test_sim_detector.py +3 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/tango/test_base_device.py +11 -29
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/tango/test_tango_signals.py +21 -24
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/tango/test_tango_transport.py +33 -31
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/test_data/test_yaml_save.yml +31 -10
- ophyd_async-0.7.0a1/docs/images/bluesky_ophyd_epics_devices_logo.svg +0 -389
- ophyd_async-0.7.0a1/docs/images/bluesky_ophyd_logo.svg +0 -323
- ophyd_async-0.7.0a1/src/ophyd_async/core/_device.py +0 -236
- ophyd_async-0.7.0a1/src/ophyd_async/core/_mock_signal_backend.py +0 -84
- ophyd_async-0.7.0a1/src/ophyd_async/core/_readable.py +0 -261
- ophyd_async-0.7.0a1/src/ophyd_async/core/_signal_backend.py +0 -97
- ophyd_async-0.7.0a1/src/ophyd_async/core/_soft_signal_backend.py +0 -244
- ophyd_async-0.7.0a1/src/ophyd_async/core/_table.py +0 -146
- ophyd_async-0.7.0a1/src/ophyd_async/epics/demo/_sensor.py +0 -36
- ophyd_async-0.7.0a1/src/ophyd_async/epics/pvi/__init__.py +0 -3
- ophyd_async-0.7.0a1/src/ophyd_async/epics/pvi/_pvi.py +0 -338
- ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/__init__.py +0 -21
- ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_aioca.py +0 -378
- ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_common.py +0 -57
- ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_epics_transport.py +0 -34
- ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_p4p.py +0 -518
- ophyd_async-0.7.0a1/src/ophyd_async/epics/signal/_signal.py +0 -114
- ophyd_async-0.7.0a1/src/ophyd_async/fastcs/panda/_table.py +0 -109
- ophyd_async-0.7.0a1/src/ophyd_async/tango/base_devices/_base_device.py +0 -225
- ophyd_async-0.7.0a1/tests/epics/pvi/test_pvi.py +0 -202
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.codecov.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.devcontainer/devcontainer.json +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.git-blame-ignore-revs +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/ISSUE_TEMPLATE/issue.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/actions/install_requirements/action.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/dependabot.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/pages/index.html +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/pages/make_switcher.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_check.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_dist.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_docs.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_release.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_test.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/_tox.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.github/workflows/periodic.yml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.gitignore +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.mailmap +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/.pre-commit-config.yaml +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/LICENSE +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/_api.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/_templates/custom-module-template.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/examples/epics_demo.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/examples/tango_demo.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions/COPYME +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/decisions.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/design-goals.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/event-loop-choice.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations/flyscanning.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/explanations.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/genindex.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to/choose-interfaces-for-devices.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to/compound-devices.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to/contribute.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to/make-a-standard-detector.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to/write-tests-for-devices.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/how-to.md +0 -0
- /ophyd_async-0.7.0a1/docs/images/ophyd_favicon.svg → /ophyd_async-0.8.0a3/docs/images/ophyd-favicon.svg +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/index.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/reference.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/tutorials/installation.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/tutorials/using-existing-devices.rst +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/docs/tutorials.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/setup.cfg +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/__main__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_flyer.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_hdf_dataset.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_log.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/core/_providers.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adaravis/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adaravis/_aravis.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adcore/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adcore/_core_logic.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adpilatus/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adsimdetector/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/adsimdetector/_sim.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/advimba/_vimba.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/demo/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/demo/mover.db +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/demo/sensor.db +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/epics/eiger/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/fastcs/panda/_utils.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/plan_stubs/__init__.py +0 -0
- /ophyd_async-0.7.0a1/src/ophyd_async/sim/__init__.py → /ophyd_async-0.8.0a3/src/ophyd_async/py.typed +0 -0
- {ophyd_async-0.7.0a1/src/ophyd_async/sim/testing → ophyd_async-0.8.0a3/src/ophyd_async/sim}/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/_pattern_detector/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_detector_writer.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/sim/demo/_pattern_detector/_pattern_generator.py +0 -0
- {ophyd_async-0.7.0a1/tests/sim → ophyd_async-0.8.0a3/src/ophyd_async/sim/testing}/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/base_devices/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/base_devices/_tango_readable.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/demo/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/demo/_detector.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/demo/_tango/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async/tango/demo/_tango/_servers.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async.egg-info/entry_points.txt +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/src/ophyd_async.egg-info/top_level.txt +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/system_tests/epics/eiger/README.md +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/conftest.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_protocol.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/core/test_providers.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adcore/test_drivers.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adcore/test_scans.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/adpilatus/test_pilatus.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/epics/test_areadetector_subclass_naming.py +0 -0
- {ophyd_async-0.7.0a1/tests/sim/demo → ophyd_async-0.8.0a3/tests/sim}/__init__.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/sim/conftest.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/sim/test_pattern_generator.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/sim/test_sim_writer.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/sim/test_streaming_plan.py +0 -0
- {ophyd_async-0.7.0a1 → ophyd_async-0.8.0a3}/tests/test_cli.py +0 -0
|
@@ -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.4.0/how-to.html).
|
|
@@ -20,7 +20,7 @@ jobs:
|
|
|
20
20
|
if: needs.check.outputs.branch-pr == ''
|
|
21
21
|
strategy:
|
|
22
22
|
matrix:
|
|
23
|
-
runs-on: ["ubuntu-latest"] # can add
|
|
23
|
+
runs-on: ["ubuntu-latest", "windows-latest"] # can add macos-latest
|
|
24
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
|
|
@@ -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}
|
|
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.
|
|
3
|
+
Version: 0.8.0a3
|
|
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
|
|
44
|
+
Requires-Dist: numpy
|
|
45
45
|
Requires-Dist: packaging
|
|
46
46
|
Requires-Dist: pint
|
|
47
|
-
Requires-Dist: bluesky>=1.13
|
|
48
|
-
Requires-Dist:
|
|
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,10 +64,6 @@ 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"
|
|
@@ -104,9 +100,9 @@ Requires-Dist: types-pyyaml; extra == "dev"
|
|
|
104
100
|
[](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml)
|
|
105
101
|
[](https://codecov.io/gh/bluesky/ophyd-async)
|
|
106
102
|
[](https://pypi.org/project/ophyd-async)
|
|
107
|
-
[](https://
|
|
103
|
+
[](https://choosealicense.com/licenses/bsd-3-clause)
|
|
108
104
|
|
|
109
|
-
# ophyd-async
|
|
105
|
+
# 
|
|
110
106
|
|
|
111
107
|
Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango.
|
|
112
108
|
|
|
@@ -116,7 +112,7 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
|
|
|
116
112
|
| Documentation | <https://bluesky.github.io/ophyd-async> |
|
|
117
113
|
| Releases | <https://github.com/bluesky/ophyd-async/releases> |
|
|
118
114
|
|
|
119
|
-
Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
|
|
115
|
+
Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
|
|
120
116
|
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
117
|
systems.
|
|
122
118
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
[](https://github.com/bluesky/ophyd-async/actions/workflows/ci.yml)
|
|
2
2
|
[](https://codecov.io/gh/bluesky/ophyd-async)
|
|
3
3
|
[](https://pypi.org/project/ophyd-async)
|
|
4
|
-
[](https://
|
|
4
|
+
[](https://choosealicense.com/licenses/bsd-3-clause)
|
|
5
5
|
|
|
6
|
-
# ophyd-async
|
|
6
|
+
# 
|
|
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/
|
|
234
|
-
html_favicon = "images/
|
|
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
|
|
@@ -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(
|
|
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
|
--------
|