opentrons 8.6.0a1__py3-none-any.whl
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.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/__init__.py +150 -0
- opentrons/_version.py +34 -0
- opentrons/calibration_storage/__init__.py +54 -0
- opentrons/calibration_storage/deck_configuration.py +62 -0
- opentrons/calibration_storage/encoder_decoder.py +31 -0
- opentrons/calibration_storage/file_operators.py +142 -0
- opentrons/calibration_storage/helpers.py +103 -0
- opentrons/calibration_storage/ot2/__init__.py +34 -0
- opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
- opentrons/calibration_storage/ot2/models/__init__.py +0 -0
- opentrons/calibration_storage/ot2/models/v1.py +149 -0
- opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
- opentrons/calibration_storage/ot2/tip_length.py +281 -0
- opentrons/calibration_storage/ot3/__init__.py +31 -0
- opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
- opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
- opentrons/calibration_storage/ot3/models/__init__.py +0 -0
- opentrons/calibration_storage/ot3/models/v1.py +122 -0
- opentrons/calibration_storage/ot3/module_offset.py +138 -0
- opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
- opentrons/calibration_storage/types.py +45 -0
- opentrons/cli/__init__.py +21 -0
- opentrons/cli/__main__.py +5 -0
- opentrons/cli/analyze.py +501 -0
- opentrons/config/__init__.py +631 -0
- opentrons/config/advanced_settings.py +871 -0
- opentrons/config/defaults_ot2.py +214 -0
- opentrons/config/defaults_ot3.py +499 -0
- opentrons/config/feature_flags.py +86 -0
- opentrons/config/gripper_config.py +55 -0
- opentrons/config/reset.py +203 -0
- opentrons/config/robot_configs.py +187 -0
- opentrons/config/types.py +183 -0
- opentrons/drivers/__init__.py +0 -0
- opentrons/drivers/absorbance_reader/__init__.py +11 -0
- opentrons/drivers/absorbance_reader/abstract.py +72 -0
- opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
- opentrons/drivers/absorbance_reader/driver.py +81 -0
- opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
- opentrons/drivers/absorbance_reader/simulator.py +84 -0
- opentrons/drivers/asyncio/__init__.py +0 -0
- opentrons/drivers/asyncio/communication/__init__.py +22 -0
- opentrons/drivers/asyncio/communication/async_serial.py +183 -0
- opentrons/drivers/asyncio/communication/errors.py +88 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
- opentrons/drivers/command_builder.py +102 -0
- opentrons/drivers/flex_stacker/__init__.py +13 -0
- opentrons/drivers/flex_stacker/abstract.py +214 -0
- opentrons/drivers/flex_stacker/driver.py +768 -0
- opentrons/drivers/flex_stacker/errors.py +68 -0
- opentrons/drivers/flex_stacker/simulator.py +309 -0
- opentrons/drivers/flex_stacker/types.py +367 -0
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/drivers/heater_shaker/__init__.py +5 -0
- opentrons/drivers/heater_shaker/abstract.py +76 -0
- opentrons/drivers/heater_shaker/driver.py +204 -0
- opentrons/drivers/heater_shaker/simulator.py +94 -0
- opentrons/drivers/mag_deck/__init__.py +6 -0
- opentrons/drivers/mag_deck/abstract.py +44 -0
- opentrons/drivers/mag_deck/driver.py +208 -0
- opentrons/drivers/mag_deck/simulator.py +63 -0
- opentrons/drivers/rpi_drivers/__init__.py +33 -0
- opentrons/drivers/rpi_drivers/dev_types.py +94 -0
- opentrons/drivers/rpi_drivers/gpio.py +282 -0
- opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
- opentrons/drivers/rpi_drivers/interfaces.py +15 -0
- opentrons/drivers/rpi_drivers/types.py +364 -0
- opentrons/drivers/rpi_drivers/usb.py +102 -0
- opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
- opentrons/drivers/serial_communication.py +151 -0
- opentrons/drivers/smoothie_drivers/__init__.py +4 -0
- opentrons/drivers/smoothie_drivers/connection.py +51 -0
- opentrons/drivers/smoothie_drivers/constants.py +121 -0
- opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
- opentrons/drivers/smoothie_drivers/errors.py +49 -0
- opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
- opentrons/drivers/smoothie_drivers/simulator.py +99 -0
- opentrons/drivers/smoothie_drivers/types.py +16 -0
- opentrons/drivers/temp_deck/__init__.py +10 -0
- opentrons/drivers/temp_deck/abstract.py +54 -0
- opentrons/drivers/temp_deck/driver.py +197 -0
- opentrons/drivers/temp_deck/simulator.py +57 -0
- opentrons/drivers/thermocycler/__init__.py +12 -0
- opentrons/drivers/thermocycler/abstract.py +99 -0
- opentrons/drivers/thermocycler/driver.py +395 -0
- opentrons/drivers/thermocycler/simulator.py +126 -0
- opentrons/drivers/types.py +107 -0
- opentrons/drivers/utils.py +222 -0
- opentrons/execute.py +742 -0
- opentrons/hardware_control/__init__.py +65 -0
- opentrons/hardware_control/__main__.py +77 -0
- opentrons/hardware_control/adapters.py +98 -0
- opentrons/hardware_control/api.py +1347 -0
- opentrons/hardware_control/backends/__init__.py +7 -0
- opentrons/hardware_control/backends/controller.py +400 -0
- opentrons/hardware_control/backends/errors.py +9 -0
- opentrons/hardware_control/backends/estop_state.py +164 -0
- opentrons/hardware_control/backends/flex_protocol.py +497 -0
- opentrons/hardware_control/backends/ot3controller.py +1930 -0
- opentrons/hardware_control/backends/ot3simulator.py +900 -0
- opentrons/hardware_control/backends/ot3utils.py +664 -0
- opentrons/hardware_control/backends/simulator.py +442 -0
- opentrons/hardware_control/backends/status_bar_state.py +240 -0
- opentrons/hardware_control/backends/subsystem_manager.py +431 -0
- opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
- opentrons/hardware_control/backends/types.py +14 -0
- opentrons/hardware_control/constants.py +6 -0
- opentrons/hardware_control/dev_types.py +125 -0
- opentrons/hardware_control/emulation/__init__.py +0 -0
- opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
- opentrons/hardware_control/emulation/app.py +56 -0
- opentrons/hardware_control/emulation/connection_handler.py +38 -0
- opentrons/hardware_control/emulation/heater_shaker.py +150 -0
- opentrons/hardware_control/emulation/magdeck.py +60 -0
- opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
- opentrons/hardware_control/emulation/module_server/client.py +78 -0
- opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
- opentrons/hardware_control/emulation/module_server/models.py +31 -0
- opentrons/hardware_control/emulation/module_server/server.py +110 -0
- opentrons/hardware_control/emulation/parser.py +74 -0
- opentrons/hardware_control/emulation/proxy.py +241 -0
- opentrons/hardware_control/emulation/run_emulator.py +68 -0
- opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
- opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
- opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
- opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
- opentrons/hardware_control/emulation/settings.py +119 -0
- opentrons/hardware_control/emulation/simulations.py +133 -0
- opentrons/hardware_control/emulation/smoothie.py +192 -0
- opentrons/hardware_control/emulation/tempdeck.py +69 -0
- opentrons/hardware_control/emulation/thermocycler.py +128 -0
- opentrons/hardware_control/emulation/types.py +10 -0
- opentrons/hardware_control/emulation/util.py +38 -0
- opentrons/hardware_control/errors.py +43 -0
- opentrons/hardware_control/execution_manager.py +164 -0
- opentrons/hardware_control/instruments/__init__.py +5 -0
- opentrons/hardware_control/instruments/instrument_abc.py +39 -0
- opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
- opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
- opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
- opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
- opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
- opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
- opentrons/hardware_control/module_control.py +332 -0
- opentrons/hardware_control/modules/__init__.py +69 -0
- opentrons/hardware_control/modules/absorbance_reader.py +373 -0
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/flex_stacker.py +948 -0
- opentrons/hardware_control/modules/heater_shaker.py +426 -0
- opentrons/hardware_control/modules/lid_temp_status.py +35 -0
- opentrons/hardware_control/modules/magdeck.py +233 -0
- opentrons/hardware_control/modules/mod_abc.py +245 -0
- opentrons/hardware_control/modules/module_calibration.py +93 -0
- opentrons/hardware_control/modules/plate_temp_status.py +61 -0
- opentrons/hardware_control/modules/tempdeck.py +299 -0
- opentrons/hardware_control/modules/thermocycler.py +731 -0
- opentrons/hardware_control/modules/types.py +417 -0
- opentrons/hardware_control/modules/update.py +255 -0
- opentrons/hardware_control/modules/utils.py +73 -0
- opentrons/hardware_control/motion_utilities.py +318 -0
- opentrons/hardware_control/nozzle_manager.py +422 -0
- opentrons/hardware_control/ot3_calibration.py +1171 -0
- opentrons/hardware_control/ot3api.py +3227 -0
- opentrons/hardware_control/pause_manager.py +31 -0
- opentrons/hardware_control/poller.py +112 -0
- opentrons/hardware_control/protocols/__init__.py +106 -0
- opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
- opentrons/hardware_control/protocols/calibratable.py +45 -0
- opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
- opentrons/hardware_control/protocols/configurable.py +48 -0
- opentrons/hardware_control/protocols/event_sourcer.py +18 -0
- opentrons/hardware_control/protocols/execution_controllable.py +33 -0
- opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
- opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
- opentrons/hardware_control/protocols/gripper_controller.py +55 -0
- opentrons/hardware_control/protocols/hardware_manager.py +51 -0
- opentrons/hardware_control/protocols/identifiable.py +16 -0
- opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
- opentrons/hardware_control/protocols/liquid_handler.py +266 -0
- opentrons/hardware_control/protocols/module_provider.py +16 -0
- opentrons/hardware_control/protocols/motion_controller.py +243 -0
- opentrons/hardware_control/protocols/position_estimator.py +45 -0
- opentrons/hardware_control/protocols/simulatable.py +10 -0
- opentrons/hardware_control/protocols/stoppable.py +9 -0
- opentrons/hardware_control/protocols/types.py +27 -0
- opentrons/hardware_control/robot_calibration.py +224 -0
- opentrons/hardware_control/scripts/README.md +28 -0
- opentrons/hardware_control/scripts/__init__.py +1 -0
- opentrons/hardware_control/scripts/gripper_control.py +208 -0
- opentrons/hardware_control/scripts/ot3gripper +7 -0
- opentrons/hardware_control/scripts/ot3repl +7 -0
- opentrons/hardware_control/scripts/repl.py +187 -0
- opentrons/hardware_control/scripts/tc_control.py +97 -0
- opentrons/hardware_control/simulator_setup.py +260 -0
- opentrons/hardware_control/thread_manager.py +431 -0
- opentrons/hardware_control/threaded_async_lock.py +97 -0
- opentrons/hardware_control/types.py +792 -0
- opentrons/hardware_control/util.py +234 -0
- opentrons/legacy_broker.py +53 -0
- opentrons/legacy_commands/__init__.py +1 -0
- opentrons/legacy_commands/commands.py +483 -0
- opentrons/legacy_commands/helpers.py +153 -0
- opentrons/legacy_commands/module_commands.py +215 -0
- opentrons/legacy_commands/protocol_commands.py +54 -0
- opentrons/legacy_commands/publisher.py +155 -0
- opentrons/legacy_commands/robot_commands.py +51 -0
- opentrons/legacy_commands/types.py +1115 -0
- opentrons/motion_planning/__init__.py +32 -0
- opentrons/motion_planning/adjacent_slots_getters.py +168 -0
- opentrons/motion_planning/deck_conflict.py +396 -0
- opentrons/motion_planning/errors.py +35 -0
- opentrons/motion_planning/types.py +42 -0
- opentrons/motion_planning/waypoints.py +218 -0
- opentrons/ordered_set.py +138 -0
- opentrons/protocol_api/__init__.py +105 -0
- opentrons/protocol_api/_liquid.py +157 -0
- opentrons/protocol_api/_liquid_properties.py +814 -0
- opentrons/protocol_api/_nozzle_layout.py +31 -0
- opentrons/protocol_api/_parameter_context.py +300 -0
- opentrons/protocol_api/_parameters.py +31 -0
- opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
- opentrons/protocol_api/_types.py +43 -0
- opentrons/protocol_api/config.py +23 -0
- opentrons/protocol_api/core/__init__.py +23 -0
- opentrons/protocol_api/core/common.py +33 -0
- opentrons/protocol_api/core/core_map.py +74 -0
- opentrons/protocol_api/core/engine/__init__.py +22 -0
- opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
- opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
- opentrons/protocol_api/core/engine/exceptions.py +19 -0
- opentrons/protocol_api/core/engine/instrument.py +2391 -0
- opentrons/protocol_api/core/engine/labware.py +238 -0
- opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
- opentrons/protocol_api/core/engine/module_core.py +1025 -0
- opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
- opentrons/protocol_api/core/engine/point_calculations.py +64 -0
- opentrons/protocol_api/core/engine/protocol.py +1153 -0
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/stringify.py +74 -0
- opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
- opentrons/protocol_api/core/engine/well.py +241 -0
- opentrons/protocol_api/core/instrument.py +459 -0
- opentrons/protocol_api/core/labware.py +151 -0
- opentrons/protocol_api/core/legacy/__init__.py +11 -0
- opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
- opentrons/protocol_api/core/legacy/deck.py +369 -0
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
- opentrons/protocol_api/core/legacy/load_info.py +67 -0
- opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
- opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
- opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
- opentrons/protocol_api/core/module.py +484 -0
- opentrons/protocol_api/core/protocol.py +311 -0
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/core/well.py +116 -0
- opentrons/protocol_api/core/well_grid.py +45 -0
- opentrons/protocol_api/create_protocol_context.py +177 -0
- opentrons/protocol_api/deck.py +223 -0
- opentrons/protocol_api/disposal_locations.py +244 -0
- opentrons/protocol_api/instrument_context.py +3212 -0
- opentrons/protocol_api/labware.py +1579 -0
- opentrons/protocol_api/module_contexts.py +1425 -0
- opentrons/protocol_api/module_validation_and_errors.py +61 -0
- opentrons/protocol_api/protocol_context.py +1688 -0
- opentrons/protocol_api/robot_context.py +303 -0
- opentrons/protocol_api/validation.py +761 -0
- opentrons/protocol_engine/__init__.py +155 -0
- opentrons/protocol_engine/actions/__init__.py +65 -0
- opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
- opentrons/protocol_engine/actions/action_handler.py +13 -0
- opentrons/protocol_engine/actions/actions.py +302 -0
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/__init__.py +5 -0
- opentrons/protocol_engine/clients/sync_client.py +174 -0
- opentrons/protocol_engine/clients/transports.py +197 -0
- opentrons/protocol_engine/commands/__init__.py +757 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
- opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
- opentrons/protocol_engine/commands/aspirate.py +244 -0
- opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
- opentrons/protocol_engine/commands/blow_out.py +146 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
- opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
- opentrons/protocol_engine/commands/command.py +308 -0
- opentrons/protocol_engine/commands/command_unions.py +974 -0
- opentrons/protocol_engine/commands/comment.py +57 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
- opentrons/protocol_engine/commands/custom.py +67 -0
- opentrons/protocol_engine/commands/dispense.py +194 -0
- opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +232 -0
- opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
- opentrons/protocol_engine/commands/hash_command_params.py +38 -0
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
- opentrons/protocol_engine/commands/home.py +100 -0
- opentrons/protocol_engine/commands/identify_module.py +86 -0
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +464 -0
- opentrons/protocol_engine/commands/load_labware.py +210 -0
- opentrons/protocol_engine/commands/load_lid.py +154 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
- opentrons/protocol_engine/commands/load_liquid.py +95 -0
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +223 -0
- opentrons/protocol_engine/commands/load_pipette.py +167 -0
- opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
- opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
- opentrons/protocol_engine/commands/move_labware.py +546 -0
- opentrons/protocol_engine/commands/move_relative.py +102 -0
- opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
- opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
- opentrons/protocol_engine/commands/move_to_well.py +119 -0
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
- opentrons/protocol_engine/commands/pipetting_common.py +443 -0
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
- opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
- opentrons/protocol_engine/commands/reload_labware.py +90 -0
- opentrons/protocol_engine/commands/retract_axis.py +75 -0
- opentrons/protocol_engine/commands/robot/__init__.py +70 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/save_position.py +109 -0
- opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
- opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
- opentrons/protocol_engine/commands/set_status_bar.py +89 -0
- opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
- opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
- opentrons/protocol_engine/commands/touch_tip.py +189 -0
- opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
- opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
- opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
- opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
- opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
- opentrons/protocol_engine/create_protocol_engine.py +193 -0
- opentrons/protocol_engine/engine_support.py +28 -0
- opentrons/protocol_engine/error_recovery_policy.py +81 -0
- opentrons/protocol_engine/errors/__init__.py +191 -0
- opentrons/protocol_engine/errors/error_occurrence.py +182 -0
- opentrons/protocol_engine/errors/exceptions.py +1308 -0
- opentrons/protocol_engine/execution/__init__.py +50 -0
- opentrons/protocol_engine/execution/command_executor.py +216 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
- opentrons/protocol_engine/execution/door_watcher.py +119 -0
- opentrons/protocol_engine/execution/equipment.py +819 -0
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +686 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
- opentrons/protocol_engine/execution/labware_movement.py +297 -0
- opentrons/protocol_engine/execution/movement.py +349 -0
- opentrons/protocol_engine/execution/pipetting.py +607 -0
- opentrons/protocol_engine/execution/queue_worker.py +86 -0
- opentrons/protocol_engine/execution/rail_lights.py +25 -0
- opentrons/protocol_engine/execution/run_control.py +33 -0
- opentrons/protocol_engine/execution/status_bar.py +34 -0
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
- opentrons/protocol_engine/execution/tip_handler.py +550 -0
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/notes/__init__.py +17 -0
- opentrons/protocol_engine/notes/notes.py +59 -0
- opentrons/protocol_engine/plugins.py +104 -0
- opentrons/protocol_engine/protocol_engine.py +683 -0
- opentrons/protocol_engine/resources/__init__.py +26 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +58 -0
- opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
- opentrons/protocol_engine/resources/labware_validation.py +73 -0
- opentrons/protocol_engine/resources/model_utils.py +32 -0
- opentrons/protocol_engine/resources/module_data_provider.py +44 -0
- opentrons/protocol_engine/resources/ot3_validation.py +21 -0
- opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
- opentrons/protocol_engine/slot_standardization.py +128 -0
- opentrons/protocol_engine/state/__init__.py +1 -0
- opentrons/protocol_engine/state/_abstract_store.py +27 -0
- opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
- opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
- opentrons/protocol_engine/state/_move_types.py +83 -0
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +699 -0
- opentrons/protocol_engine/state/command_history.py +309 -0
- opentrons/protocol_engine/state/commands.py +1158 -0
- opentrons/protocol_engine/state/config.py +39 -0
- opentrons/protocol_engine/state/files.py +57 -0
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/geometry.py +2359 -0
- opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
- opentrons/protocol_engine/state/labware.py +1459 -0
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +73 -0
- opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
- opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
- opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
- opentrons/protocol_engine/state/modules.py +1500 -0
- opentrons/protocol_engine/state/motion.py +373 -0
- opentrons/protocol_engine/state/pipettes.py +905 -0
- opentrons/protocol_engine/state/state.py +421 -0
- opentrons/protocol_engine/state/state_summary.py +36 -0
- opentrons/protocol_engine/state/tips.py +420 -0
- opentrons/protocol_engine/state/update_types.py +904 -0
- opentrons/protocol_engine/state/wells.py +290 -0
- opentrons/protocol_engine/types/__init__.py +308 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +81 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +131 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +303 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/__init__.py +37 -0
- opentrons/protocol_reader/extract_labware_definitions.py +66 -0
- opentrons/protocol_reader/file_format_validator.py +152 -0
- opentrons/protocol_reader/file_hasher.py +27 -0
- opentrons/protocol_reader/file_identifier.py +284 -0
- opentrons/protocol_reader/file_reader_writer.py +90 -0
- opentrons/protocol_reader/input_file.py +16 -0
- opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
- opentrons/protocol_reader/protocol_reader.py +188 -0
- opentrons/protocol_reader/protocol_source.py +124 -0
- opentrons/protocol_reader/role_analyzer.py +86 -0
- opentrons/protocol_runner/__init__.py +26 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
- opentrons/protocol_runner/json_file_reader.py +55 -0
- opentrons/protocol_runner/json_translator.py +314 -0
- opentrons/protocol_runner/legacy_command_mapper.py +848 -0
- opentrons/protocol_runner/legacy_context_plugin.py +116 -0
- opentrons/protocol_runner/protocol_runner.py +530 -0
- opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
- opentrons/protocol_runner/run_orchestrator.py +496 -0
- opentrons/protocol_runner/task_queue.py +95 -0
- opentrons/protocols/__init__.py +6 -0
- opentrons/protocols/advanced_control/__init__.py +0 -0
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +60 -0
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +180 -0
- opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
- opentrons/protocols/api_support/__init__.py +0 -0
- opentrons/protocols/api_support/constants.py +8 -0
- opentrons/protocols/api_support/deck_type.py +110 -0
- opentrons/protocols/api_support/definitions.py +18 -0
- opentrons/protocols/api_support/instrument.py +151 -0
- opentrons/protocols/api_support/labware_like.py +233 -0
- opentrons/protocols/api_support/tip_tracker.py +175 -0
- opentrons/protocols/api_support/types.py +32 -0
- opentrons/protocols/api_support/util.py +403 -0
- opentrons/protocols/bundle.py +89 -0
- opentrons/protocols/duration/__init__.py +4 -0
- opentrons/protocols/duration/errors.py +5 -0
- opentrons/protocols/duration/estimator.py +628 -0
- opentrons/protocols/execution/__init__.py +0 -0
- opentrons/protocols/execution/dev_types.py +181 -0
- opentrons/protocols/execution/errors.py +40 -0
- opentrons/protocols/execution/execute.py +84 -0
- opentrons/protocols/execution/execute_json_v3.py +275 -0
- opentrons/protocols/execution/execute_json_v4.py +359 -0
- opentrons/protocols/execution/execute_json_v5.py +28 -0
- opentrons/protocols/execution/execute_python.py +169 -0
- opentrons/protocols/execution/json_dispatchers.py +87 -0
- opentrons/protocols/execution/types.py +7 -0
- opentrons/protocols/geometry/__init__.py +0 -0
- opentrons/protocols/geometry/planning.py +297 -0
- opentrons/protocols/labware.py +312 -0
- opentrons/protocols/models/__init__.py +0 -0
- opentrons/protocols/models/json_protocol.py +679 -0
- opentrons/protocols/parameters/__init__.py +0 -0
- opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
- opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
- opentrons/protocols/parameters/exceptions.py +34 -0
- opentrons/protocols/parameters/parameter_definition.py +272 -0
- opentrons/protocols/parameters/types.py +17 -0
- opentrons/protocols/parameters/validation.py +267 -0
- opentrons/protocols/parse.py +671 -0
- opentrons/protocols/types.py +159 -0
- opentrons/py.typed +0 -0
- opentrons/resources/scripts/lpc21isp +0 -0
- opentrons/resources/smoothie-edge-8414642.hex +23010 -0
- opentrons/simulate.py +1065 -0
- opentrons/system/__init__.py +6 -0
- opentrons/system/camera.py +51 -0
- opentrons/system/log_control.py +59 -0
- opentrons/system/nmcli.py +856 -0
- opentrons/system/resin.py +24 -0
- opentrons/system/smoothie_update.py +15 -0
- opentrons/system/wifi.py +204 -0
- opentrons/tools/__init__.py +0 -0
- opentrons/tools/args_handler.py +22 -0
- opentrons/tools/write_pipette_memory.py +157 -0
- opentrons/types.py +618 -0
- opentrons/util/__init__.py +1 -0
- opentrons/util/async_helpers.py +166 -0
- opentrons/util/broker.py +84 -0
- opentrons/util/change_notifier.py +47 -0
- opentrons/util/entrypoint_util.py +278 -0
- opentrons/util/get_union_elements.py +26 -0
- opentrons/util/helpers.py +6 -0
- opentrons/util/linal.py +178 -0
- opentrons/util/logging_config.py +265 -0
- opentrons/util/logging_queue_handler.py +61 -0
- opentrons/util/performance_helpers.py +157 -0
- opentrons-8.6.0a1.dist-info/METADATA +37 -0
- opentrons-8.6.0a1.dist-info/RECORD +600 -0
- opentrons-8.6.0a1.dist-info/WHEEL +4 -0
- opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
- opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""Command models to read absorbance."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Optional, Dict, TYPE_CHECKING, List, Any
|
|
5
|
+
|
|
6
|
+
from typing_extensions import Literal, Type
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
9
|
+
|
|
10
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
11
|
+
from ...errors import CannotPerformModuleAction, StorageLimitReachedError
|
|
12
|
+
from ...errors.error_occurrence import ErrorOccurrence
|
|
13
|
+
|
|
14
|
+
from ...resources.file_provider import (
|
|
15
|
+
PlateReaderData,
|
|
16
|
+
ReadData,
|
|
17
|
+
MAXIMUM_CSV_FILE_LIMIT,
|
|
18
|
+
)
|
|
19
|
+
from ...resources import FileProvider
|
|
20
|
+
from ...state import update_types
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
24
|
+
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
28
|
+
s.pop("default", None)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
ReadAbsorbanceCommandType = Literal["absorbanceReader/read"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ReadAbsorbanceParams(BaseModel):
|
|
35
|
+
"""Input parameters for an absorbance reading."""
|
|
36
|
+
|
|
37
|
+
moduleId: str = Field(..., description="Unique ID of the Absorbance Reader.")
|
|
38
|
+
fileName: str | SkipJsonSchema[None] = Field(
|
|
39
|
+
None,
|
|
40
|
+
description="Optional file name to use when storing the results of a measurement.",
|
|
41
|
+
json_schema_extra=_remove_default,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ReadAbsorbanceResult(BaseModel):
|
|
46
|
+
"""Result data from running an aborbance reading, returned as a dictionary map of wavelengths containing a map of values by well name (eg. {450: {"A1": 0.0, ...}})."""
|
|
47
|
+
|
|
48
|
+
data: Optional[Dict[int, Dict[str, float]]] = Field(
|
|
49
|
+
..., description="Absorbance data points per wavelength."
|
|
50
|
+
)
|
|
51
|
+
fileIds: Optional[List[str]] = Field(
|
|
52
|
+
...,
|
|
53
|
+
description="List of file IDs for files output as a result of a Read action.",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ReadAbsorbanceImpl(
|
|
58
|
+
AbstractCommandImpl[ReadAbsorbanceParams, SuccessData[ReadAbsorbanceResult]]
|
|
59
|
+
):
|
|
60
|
+
"""Execution implementation of an Absorbance Reader measurement."""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
state_view: StateView,
|
|
65
|
+
equipment: EquipmentHandler,
|
|
66
|
+
file_provider: FileProvider,
|
|
67
|
+
**unused_dependencies: object,
|
|
68
|
+
) -> None:
|
|
69
|
+
self._state_view = state_view
|
|
70
|
+
self._equipment = equipment
|
|
71
|
+
self._file_provider = file_provider
|
|
72
|
+
|
|
73
|
+
async def execute( # noqa: C901
|
|
74
|
+
self, params: ReadAbsorbanceParams
|
|
75
|
+
) -> SuccessData[ReadAbsorbanceResult]:
|
|
76
|
+
"""Initiate an absorbance measurement."""
|
|
77
|
+
state_update = update_types.StateUpdate()
|
|
78
|
+
abs_reader_substate = self._state_view.modules.get_absorbance_reader_substate(
|
|
79
|
+
module_id=params.moduleId
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Allow propagation of ModuleNotAttachedError.
|
|
83
|
+
abs_reader = self._equipment.get_module_hardware_api(
|
|
84
|
+
abs_reader_substate.module_id
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if abs_reader_substate.configured is False:
|
|
88
|
+
raise CannotPerformModuleAction(
|
|
89
|
+
"Cannot perform Read action on Absorbance Reader without calling `.initialize(...)` first."
|
|
90
|
+
)
|
|
91
|
+
if abs_reader_substate.is_lid_on is False:
|
|
92
|
+
raise CannotPerformModuleAction(
|
|
93
|
+
"Absorbance Plate Reader can't read a plate with the lid open. Call `close_lid()` first."
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# TODO: we need to return a file ID and increase the file count even when a moduel is not attached
|
|
97
|
+
if (
|
|
98
|
+
params.fileName is not None
|
|
99
|
+
and abs_reader_substate.configured_wavelengths is not None
|
|
100
|
+
):
|
|
101
|
+
# Validate that the amount of files we are about to generate does not put us higher than the limit
|
|
102
|
+
if (
|
|
103
|
+
self._state_view.files.get_filecount()
|
|
104
|
+
+ len(abs_reader_substate.configured_wavelengths)
|
|
105
|
+
> MAXIMUM_CSV_FILE_LIMIT
|
|
106
|
+
):
|
|
107
|
+
raise StorageLimitReachedError(
|
|
108
|
+
message=f"Attempt to write file {params.fileName} exceeds file creation limit of {MAXIMUM_CSV_FILE_LIMIT} files."
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
asbsorbance_result: Dict[int, Dict[str, float]] = {}
|
|
112
|
+
transform_results = []
|
|
113
|
+
# Handle the measurement and begin building data for return
|
|
114
|
+
if abs_reader is not None:
|
|
115
|
+
start_time = datetime.now()
|
|
116
|
+
results = await abs_reader.start_measure()
|
|
117
|
+
finish_time = datetime.now()
|
|
118
|
+
if abs_reader._measurement_config is not None:
|
|
119
|
+
sample_wavelengths = abs_reader._measurement_config.sample_wavelengths
|
|
120
|
+
for wavelength, result in zip(sample_wavelengths, results):
|
|
121
|
+
converted_values = (
|
|
122
|
+
self._state_view.modules.convert_absorbance_reader_data_points(
|
|
123
|
+
data=result
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
asbsorbance_result[wavelength] = converted_values
|
|
127
|
+
transform_results.append(
|
|
128
|
+
ReadData.model_construct(
|
|
129
|
+
wavelength=wavelength, data=converted_values
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
# Handle the virtual module case for data creation (all zeroes)
|
|
133
|
+
elif self._state_view.config.use_virtual_modules:
|
|
134
|
+
start_time = finish_time = datetime.now()
|
|
135
|
+
if abs_reader_substate.configured_wavelengths is not None:
|
|
136
|
+
for wavelength in abs_reader_substate.configured_wavelengths:
|
|
137
|
+
converted_values = (
|
|
138
|
+
self._state_view.modules.convert_absorbance_reader_data_points(
|
|
139
|
+
data=[0] * 96
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
asbsorbance_result[wavelength] = converted_values
|
|
143
|
+
transform_results.append(
|
|
144
|
+
ReadData.model_construct(
|
|
145
|
+
wavelength=wavelength, data=converted_values
|
|
146
|
+
)
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
raise CannotPerformModuleAction(
|
|
150
|
+
"Plate Reader data cannot be requested with a module that has not been initialized."
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
state_update.set_absorbance_reader_data(
|
|
154
|
+
module_id=abs_reader_substate.module_id, read_result=asbsorbance_result
|
|
155
|
+
)
|
|
156
|
+
# TODO (cb, 10-17-2024): FILE PROVIDER - Some day we may want to break the file provider behavior into a seperate API function.
|
|
157
|
+
# When this happens, we probably will to have the change the command results handler we utilize to track file IDs in engine.
|
|
158
|
+
# Today, the action handler for the FileStore looks for a ReadAbsorbanceResult command action, this will need to be delinked.
|
|
159
|
+
|
|
160
|
+
# Begin interfacing with the file provider if the user provided a filename
|
|
161
|
+
file_ids: list[str] = []
|
|
162
|
+
if params.fileName is not None:
|
|
163
|
+
# Create the Plate Reader Transform
|
|
164
|
+
plate_read_result = PlateReaderData.model_construct(
|
|
165
|
+
read_results=transform_results,
|
|
166
|
+
reference_wavelength=abs_reader_substate.reference_wavelength,
|
|
167
|
+
start_time=start_time,
|
|
168
|
+
finish_time=finish_time,
|
|
169
|
+
serial_number=abs_reader.serial_number
|
|
170
|
+
if (abs_reader is not None and abs_reader.serial_number is not None)
|
|
171
|
+
else "VIRTUAL_SERIAL",
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if isinstance(plate_read_result, PlateReaderData):
|
|
175
|
+
# Write a CSV file for each of the measurements taken
|
|
176
|
+
for measurement in plate_read_result.read_results:
|
|
177
|
+
file_id = await self._file_provider.write_csv(
|
|
178
|
+
write_data=plate_read_result.build_generic_csv(
|
|
179
|
+
filename=params.fileName,
|
|
180
|
+
measurement=measurement,
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
file_ids.append(file_id)
|
|
184
|
+
|
|
185
|
+
state_update.files_added = update_types.FilesAddedUpdate(
|
|
186
|
+
file_ids=file_ids
|
|
187
|
+
)
|
|
188
|
+
# Return success data to api
|
|
189
|
+
return SuccessData(
|
|
190
|
+
public=ReadAbsorbanceResult(
|
|
191
|
+
data=asbsorbance_result,
|
|
192
|
+
fileIds=file_ids,
|
|
193
|
+
),
|
|
194
|
+
state_update=state_update,
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
state_update.files_added = update_types.FilesAddedUpdate(file_ids=file_ids)
|
|
198
|
+
|
|
199
|
+
return SuccessData(
|
|
200
|
+
public=ReadAbsorbanceResult(
|
|
201
|
+
data=asbsorbance_result,
|
|
202
|
+
fileIds=file_ids,
|
|
203
|
+
),
|
|
204
|
+
state_update=state_update,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class ReadAbsorbance(
|
|
209
|
+
BaseCommand[ReadAbsorbanceParams, ReadAbsorbanceResult, ErrorOccurrence]
|
|
210
|
+
):
|
|
211
|
+
"""A command to execute an Absorbance Reader measurement."""
|
|
212
|
+
|
|
213
|
+
commandType: ReadAbsorbanceCommandType = "absorbanceReader/read"
|
|
214
|
+
params: ReadAbsorbanceParams
|
|
215
|
+
result: Optional[ReadAbsorbanceResult] = None
|
|
216
|
+
|
|
217
|
+
_ImplementationCls: Type[ReadAbsorbanceImpl] = ReadAbsorbanceImpl
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class ReadAbsorbanceCreate(BaseCommandCreate[ReadAbsorbanceParams]):
|
|
221
|
+
"""A request to execute an Absorbance Reader measurement."""
|
|
222
|
+
|
|
223
|
+
commandType: ReadAbsorbanceCommandType = "absorbanceReader/read"
|
|
224
|
+
params: ReadAbsorbanceParams
|
|
225
|
+
|
|
226
|
+
_CommandCls: Type[ReadAbsorbance] = ReadAbsorbance
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""AirGap in place command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
|
+
from typing_extensions import Literal
|
|
6
|
+
|
|
7
|
+
from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
|
|
8
|
+
|
|
9
|
+
from opentrons.hardware_control import HardwareControlAPI
|
|
10
|
+
|
|
11
|
+
from .pipetting_common import (
|
|
12
|
+
PipetteIdMixin,
|
|
13
|
+
AspirateVolumeMixin,
|
|
14
|
+
FlowRateMixin,
|
|
15
|
+
BaseLiquidHandlingResult,
|
|
16
|
+
OverpressureError,
|
|
17
|
+
DEFAULT_CORRECTION_VOLUME,
|
|
18
|
+
)
|
|
19
|
+
from .command import (
|
|
20
|
+
AbstractCommandImpl,
|
|
21
|
+
BaseCommand,
|
|
22
|
+
BaseCommandCreate,
|
|
23
|
+
SuccessData,
|
|
24
|
+
DefinedErrorData,
|
|
25
|
+
)
|
|
26
|
+
from ..errors.error_occurrence import ErrorOccurrence
|
|
27
|
+
from ..errors.exceptions import PipetteNotReadyToAspirateError
|
|
28
|
+
from ..state.update_types import StateUpdate
|
|
29
|
+
from ..types import AspiratedFluid, FluidKind
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from ..execution import PipettingHandler, GantryMover
|
|
33
|
+
from ..resources import ModelUtils
|
|
34
|
+
from ..state.state import StateView
|
|
35
|
+
from ..notes import CommandNoteAdder
|
|
36
|
+
|
|
37
|
+
AirGapInPlaceCommandType = Literal["airGapInPlace"]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class AirGapInPlaceParams(PipetteIdMixin, AspirateVolumeMixin, FlowRateMixin):
|
|
41
|
+
"""Payload required to air gap in place."""
|
|
42
|
+
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class AirGapInPlaceResult(BaseLiquidHandlingResult):
|
|
47
|
+
"""Result data from the execution of a AirGapInPlace command."""
|
|
48
|
+
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
_ExecuteReturn = Union[
|
|
53
|
+
SuccessData[AirGapInPlaceResult],
|
|
54
|
+
DefinedErrorData[OverpressureError],
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class AirGapInPlaceImplementation(
|
|
59
|
+
AbstractCommandImpl[AirGapInPlaceParams, _ExecuteReturn]
|
|
60
|
+
):
|
|
61
|
+
"""AirGapInPlace command implementation."""
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
pipetting: PipettingHandler,
|
|
66
|
+
hardware_api: HardwareControlAPI,
|
|
67
|
+
state_view: StateView,
|
|
68
|
+
command_note_adder: CommandNoteAdder,
|
|
69
|
+
model_utils: ModelUtils,
|
|
70
|
+
gantry_mover: GantryMover,
|
|
71
|
+
**kwargs: object,
|
|
72
|
+
) -> None:
|
|
73
|
+
self._pipetting = pipetting
|
|
74
|
+
self._state_view = state_view
|
|
75
|
+
self._hardware_api = hardware_api
|
|
76
|
+
self._command_note_adder = command_note_adder
|
|
77
|
+
self._model_utils = model_utils
|
|
78
|
+
self._gantry_mover = gantry_mover
|
|
79
|
+
|
|
80
|
+
async def execute(self, params: AirGapInPlaceParams) -> _ExecuteReturn:
|
|
81
|
+
"""Air gap without moving the pipette.
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
TipNotAttachedError: if no tip is attached to the pipette.
|
|
85
|
+
PipetteNotReadyToAirGapError: pipette plunger is not ready.
|
|
86
|
+
"""
|
|
87
|
+
ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
|
|
88
|
+
pipette_id=params.pipetteId
|
|
89
|
+
)
|
|
90
|
+
if not ready_to_aspirate:
|
|
91
|
+
raise PipetteNotReadyToAspirateError(
|
|
92
|
+
"Pipette cannot air gap in place because a previous dispense or blowout"
|
|
93
|
+
" pushed the plunger beyond the bottom position."
|
|
94
|
+
" The subsequent aspirate must be from a specific well so the plunger"
|
|
95
|
+
" can be reset in a known safe position."
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
state_update = StateUpdate()
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
102
|
+
volume = await self._pipetting.aspirate_in_place(
|
|
103
|
+
pipette_id=params.pipetteId,
|
|
104
|
+
volume=params.volume,
|
|
105
|
+
flow_rate=params.flowRate,
|
|
106
|
+
command_note_adder=self._command_note_adder,
|
|
107
|
+
correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
|
|
108
|
+
)
|
|
109
|
+
except PipetteOverpressureError as e:
|
|
110
|
+
return DefinedErrorData(
|
|
111
|
+
public=OverpressureError(
|
|
112
|
+
id=self._model_utils.generate_id(),
|
|
113
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
114
|
+
wrappedErrors=[
|
|
115
|
+
ErrorOccurrence.from_failed(
|
|
116
|
+
id=self._model_utils.generate_id(),
|
|
117
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
118
|
+
error=e,
|
|
119
|
+
)
|
|
120
|
+
],
|
|
121
|
+
errorInfo=(
|
|
122
|
+
{
|
|
123
|
+
"retryLocation": (
|
|
124
|
+
current_position.x,
|
|
125
|
+
current_position.y,
|
|
126
|
+
current_position.z,
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
),
|
|
130
|
+
),
|
|
131
|
+
state_update=state_update,
|
|
132
|
+
)
|
|
133
|
+
else:
|
|
134
|
+
state_update.set_fluid_aspirated(
|
|
135
|
+
pipette_id=params.pipetteId,
|
|
136
|
+
fluid=AspiratedFluid(kind=FluidKind.AIR, volume=volume),
|
|
137
|
+
)
|
|
138
|
+
return SuccessData(
|
|
139
|
+
public=AirGapInPlaceResult(volume=volume),
|
|
140
|
+
state_update=state_update,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class AirGapInPlace(
|
|
145
|
+
BaseCommand[AirGapInPlaceParams, AirGapInPlaceResult, OverpressureError]
|
|
146
|
+
):
|
|
147
|
+
"""AirGapInPlace command model."""
|
|
148
|
+
|
|
149
|
+
commandType: AirGapInPlaceCommandType = "airGapInPlace"
|
|
150
|
+
params: AirGapInPlaceParams
|
|
151
|
+
result: Optional[AirGapInPlaceResult] = None
|
|
152
|
+
|
|
153
|
+
_ImplementationCls: Type[AirGapInPlaceImplementation] = AirGapInPlaceImplementation
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class AirGapInPlaceCreate(BaseCommandCreate[AirGapInPlaceParams]):
|
|
157
|
+
"""AirGapInPlace command request model."""
|
|
158
|
+
|
|
159
|
+
commandType: AirGapInPlaceCommandType = "airGapInPlace"
|
|
160
|
+
params: AirGapInPlaceParams
|
|
161
|
+
|
|
162
|
+
_CommandCls: Type[AirGapInPlace] = AirGapInPlace
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"""Aspirate command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
|
+
from typing_extensions import Literal
|
|
6
|
+
|
|
7
|
+
from .pipetting_common import (
|
|
8
|
+
OverpressureError,
|
|
9
|
+
PipetteIdMixin,
|
|
10
|
+
AspirateVolumeMixin,
|
|
11
|
+
FlowRateMixin,
|
|
12
|
+
BaseLiquidHandlingResult,
|
|
13
|
+
aspirate_in_place,
|
|
14
|
+
prepare_for_aspirate,
|
|
15
|
+
DEFAULT_CORRECTION_VOLUME,
|
|
16
|
+
)
|
|
17
|
+
from .movement_common import (
|
|
18
|
+
LiquidHandlingWellLocationMixin,
|
|
19
|
+
DestinationPositionResult,
|
|
20
|
+
StallOrCollisionError,
|
|
21
|
+
move_to_well,
|
|
22
|
+
)
|
|
23
|
+
from .command import (
|
|
24
|
+
AbstractCommandImpl,
|
|
25
|
+
BaseCommand,
|
|
26
|
+
BaseCommandCreate,
|
|
27
|
+
DefinedErrorData,
|
|
28
|
+
SuccessData,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
from opentrons.hardware_control import HardwareControlAPI
|
|
32
|
+
|
|
33
|
+
from ..state.update_types import StateUpdate, CLEAR
|
|
34
|
+
from ..types import (
|
|
35
|
+
WellLocation,
|
|
36
|
+
WellOrigin,
|
|
37
|
+
CurrentWell,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if TYPE_CHECKING:
|
|
41
|
+
from ..execution import MovementHandler, PipettingHandler
|
|
42
|
+
from ..resources import ModelUtils
|
|
43
|
+
from ..state.state import StateView
|
|
44
|
+
from ..notes import CommandNoteAdder
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
AspirateCommandType = Literal["aspirate"]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AspirateParams(
|
|
51
|
+
PipetteIdMixin,
|
|
52
|
+
AspirateVolumeMixin,
|
|
53
|
+
FlowRateMixin,
|
|
54
|
+
LiquidHandlingWellLocationMixin,
|
|
55
|
+
):
|
|
56
|
+
"""Parameters required to aspirate from a specific well."""
|
|
57
|
+
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class AspirateResult(BaseLiquidHandlingResult, DestinationPositionResult):
|
|
62
|
+
"""Result data from execution of an Aspirate command."""
|
|
63
|
+
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
_ExecuteReturn = Union[
|
|
68
|
+
SuccessData[AspirateResult],
|
|
69
|
+
DefinedErrorData[OverpressureError] | DefinedErrorData[StallOrCollisionError],
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]):
|
|
74
|
+
"""Aspirate command implementation."""
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
pipetting: PipettingHandler,
|
|
79
|
+
state_view: StateView,
|
|
80
|
+
hardware_api: HardwareControlAPI,
|
|
81
|
+
movement: MovementHandler,
|
|
82
|
+
command_note_adder: CommandNoteAdder,
|
|
83
|
+
model_utils: ModelUtils,
|
|
84
|
+
**kwargs: object,
|
|
85
|
+
) -> None:
|
|
86
|
+
self._pipetting = pipetting
|
|
87
|
+
self._state_view = state_view
|
|
88
|
+
self._hardware_api = hardware_api
|
|
89
|
+
self._movement = movement
|
|
90
|
+
self._command_note_adder = command_note_adder
|
|
91
|
+
self._model_utils = model_utils
|
|
92
|
+
|
|
93
|
+
async def execute(self, params: AspirateParams) -> _ExecuteReturn:
|
|
94
|
+
"""Move to and aspirate from the requested well.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
TipNotAttachedError: if no tip is attached to the pipette.
|
|
98
|
+
"""
|
|
99
|
+
pipette_id = params.pipetteId
|
|
100
|
+
labware_id = params.labwareId
|
|
101
|
+
well_name = params.wellName
|
|
102
|
+
well_location = params.wellLocation
|
|
103
|
+
|
|
104
|
+
state_update = StateUpdate()
|
|
105
|
+
|
|
106
|
+
final_location = self._state_view.geometry.get_well_position(
|
|
107
|
+
labware_id=labware_id,
|
|
108
|
+
well_name=well_name,
|
|
109
|
+
well_location=well_location,
|
|
110
|
+
operation_volume=-params.volume,
|
|
111
|
+
pipette_id=pipette_id,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
|
|
115
|
+
pipette_id=pipette_id
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
current_well = None
|
|
119
|
+
|
|
120
|
+
if not ready_to_aspirate:
|
|
121
|
+
move_result = await move_to_well(
|
|
122
|
+
movement=self._movement,
|
|
123
|
+
model_utils=self._model_utils,
|
|
124
|
+
pipette_id=pipette_id,
|
|
125
|
+
labware_id=labware_id,
|
|
126
|
+
well_name=well_name,
|
|
127
|
+
well_location=WellLocation(origin=WellOrigin.TOP),
|
|
128
|
+
)
|
|
129
|
+
state_update.append(move_result.state_update)
|
|
130
|
+
if isinstance(move_result, DefinedErrorData):
|
|
131
|
+
return DefinedErrorData(move_result.public, state_update=state_update)
|
|
132
|
+
|
|
133
|
+
prepare_result = await prepare_for_aspirate(
|
|
134
|
+
pipette_id=pipette_id,
|
|
135
|
+
pipetting=self._pipetting,
|
|
136
|
+
model_utils=self._model_utils,
|
|
137
|
+
# Note that the retryLocation is the final location, inside the liquid,
|
|
138
|
+
# because that's where we'd want the client to try re-aspirating if this
|
|
139
|
+
# command fails and the run enters error recovery.
|
|
140
|
+
location_if_error={"retryLocation": final_location},
|
|
141
|
+
)
|
|
142
|
+
state_update.append(prepare_result.state_update)
|
|
143
|
+
if isinstance(prepare_result, DefinedErrorData):
|
|
144
|
+
return DefinedErrorData(
|
|
145
|
+
public=prepare_result.public, state_update=state_update
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# set our current deck location to the well now that we've made
|
|
149
|
+
# an intermediate move for the "prepare for aspirate" step
|
|
150
|
+
current_well = CurrentWell(
|
|
151
|
+
pipette_id=pipette_id,
|
|
152
|
+
labware_id=labware_id,
|
|
153
|
+
well_name=well_name,
|
|
154
|
+
)
|
|
155
|
+
move_result = await move_to_well(
|
|
156
|
+
movement=self._movement,
|
|
157
|
+
model_utils=self._model_utils,
|
|
158
|
+
pipette_id=pipette_id,
|
|
159
|
+
labware_id=labware_id,
|
|
160
|
+
well_name=well_name,
|
|
161
|
+
well_location=well_location,
|
|
162
|
+
current_well=current_well,
|
|
163
|
+
operation_volume=-params.volume,
|
|
164
|
+
)
|
|
165
|
+
state_update.append(move_result.state_update)
|
|
166
|
+
if isinstance(move_result, DefinedErrorData):
|
|
167
|
+
return DefinedErrorData(
|
|
168
|
+
public=move_result.public, state_update=state_update
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
aspirate_result = await aspirate_in_place(
|
|
172
|
+
pipette_id=pipette_id,
|
|
173
|
+
volume=params.volume,
|
|
174
|
+
flow_rate=params.flowRate,
|
|
175
|
+
location_if_error={
|
|
176
|
+
"retryLocation": (
|
|
177
|
+
move_result.public.position.x,
|
|
178
|
+
move_result.public.position.y,
|
|
179
|
+
move_result.public.position.z,
|
|
180
|
+
)
|
|
181
|
+
},
|
|
182
|
+
command_note_adder=self._command_note_adder,
|
|
183
|
+
pipetting=self._pipetting,
|
|
184
|
+
model_utils=self._model_utils,
|
|
185
|
+
correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
|
|
186
|
+
)
|
|
187
|
+
state_update.append(aspirate_result.state_update)
|
|
188
|
+
if isinstance(aspirate_result, DefinedErrorData):
|
|
189
|
+
state_update.set_liquid_operated(
|
|
190
|
+
labware_id=labware_id,
|
|
191
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
192
|
+
labware_id,
|
|
193
|
+
well_name,
|
|
194
|
+
params.pipetteId,
|
|
195
|
+
),
|
|
196
|
+
volume_added=CLEAR,
|
|
197
|
+
)
|
|
198
|
+
return DefinedErrorData(
|
|
199
|
+
public=aspirate_result.public, state_update=state_update
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
state_update.set_liquid_operated(
|
|
203
|
+
labware_id=labware_id,
|
|
204
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
205
|
+
labware_id, well_name, pipette_id
|
|
206
|
+
),
|
|
207
|
+
volume_added=-aspirate_result.public.volume
|
|
208
|
+
* self._state_view.geometry.get_nozzles_per_well(
|
|
209
|
+
labware_id,
|
|
210
|
+
well_name,
|
|
211
|
+
params.pipetteId,
|
|
212
|
+
),
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
return SuccessData(
|
|
216
|
+
public=AspirateResult(
|
|
217
|
+
volume=aspirate_result.public.volume,
|
|
218
|
+
position=move_result.public.position,
|
|
219
|
+
),
|
|
220
|
+
state_update=state_update,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class Aspirate(
|
|
225
|
+
BaseCommand[
|
|
226
|
+
AspirateParams, AspirateResult, OverpressureError | StallOrCollisionError
|
|
227
|
+
]
|
|
228
|
+
):
|
|
229
|
+
"""Aspirate command model."""
|
|
230
|
+
|
|
231
|
+
commandType: AspirateCommandType = "aspirate"
|
|
232
|
+
params: AspirateParams
|
|
233
|
+
result: Optional[AspirateResult] = None
|
|
234
|
+
|
|
235
|
+
_ImplementationCls: Type[AspirateImplementation] = AspirateImplementation
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class AspirateCreate(BaseCommandCreate[AspirateParams]):
|
|
239
|
+
"""Create aspirate command request model."""
|
|
240
|
+
|
|
241
|
+
commandType: AspirateCommandType = "aspirate"
|
|
242
|
+
params: AspirateParams
|
|
243
|
+
|
|
244
|
+
_CommandCls: Type[Aspirate] = Aspirate
|