opentrons 8.6.0__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 +557 -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 +187 -0
- opentrons/drivers/asyncio/communication/errors.py +88 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +557 -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/scripts/update_module_fw.py +274 -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 +276 -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 +1186 -0
- opentrons/motion_planning/__init__.py +32 -0
- opentrons/motion_planning/adjacent_slots_getters.py +168 -0
- opentrons/motion_planning/deck_conflict.py +501 -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 +400 -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 +1027 -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 +1006 -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 +3272 -0
- opentrons/protocol_api/labware.py +1579 -0
- opentrons/protocol_api/module_contexts.py +1447 -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 +339 -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 +350 -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 +68 -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 +1164 -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 +2408 -0
- opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
- opentrons/protocol_engine/state/labware.py +1432 -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 +1515 -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 +310 -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 +310 -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 +852 -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.0.dist-info/METADATA +37 -0
- opentrons-8.6.0.dist-info/RECORD +601 -0
- opentrons-8.6.0.dist-info/WHEEL +4 -0
- opentrons-8.6.0.dist-info/entry_points.txt +3 -0
- opentrons-8.6.0.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
"""Models and implementation for the ``moveLabware`` command."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Any, List
|
|
5
|
+
from typing_extensions import (
|
|
6
|
+
TypedDict,
|
|
7
|
+
assert_type,
|
|
8
|
+
) # note: need this instead of typing for py<3.12
|
|
9
|
+
|
|
10
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
11
|
+
from pydantic import BaseModel, Field
|
|
12
|
+
from typing_extensions import Literal
|
|
13
|
+
|
|
14
|
+
from opentrons_shared_data.labware.labware_definition import (
|
|
15
|
+
LabwareDefinition,
|
|
16
|
+
LabwareDefinition2,
|
|
17
|
+
LabwareDefinition3,
|
|
18
|
+
)
|
|
19
|
+
from opentrons_shared_data.errors.exceptions import (
|
|
20
|
+
FailedGripperPickupError,
|
|
21
|
+
LabwareDroppedError,
|
|
22
|
+
StallOrCollisionDetectedError,
|
|
23
|
+
)
|
|
24
|
+
from opentrons_shared_data.gripper.constants import GRIPPER_PADDLE_WIDTH
|
|
25
|
+
|
|
26
|
+
from opentrons.protocol_engine.resources.model_utils import ModelUtils
|
|
27
|
+
from opentrons.types import Point
|
|
28
|
+
from ..types import (
|
|
29
|
+
ModuleModel,
|
|
30
|
+
CurrentWell,
|
|
31
|
+
LoadableLabwareLocation,
|
|
32
|
+
DeckSlotLocation,
|
|
33
|
+
ModuleLocation,
|
|
34
|
+
OnLabwareLocation,
|
|
35
|
+
AddressableAreaLocation,
|
|
36
|
+
LabwareMovementStrategy,
|
|
37
|
+
LabwareOffsetVector,
|
|
38
|
+
LabwareLocationSequence,
|
|
39
|
+
NotOnDeckLocationSequenceComponent,
|
|
40
|
+
OFF_DECK_LOCATION,
|
|
41
|
+
)
|
|
42
|
+
from ..errors import (
|
|
43
|
+
LabwareMovementNotAllowedError,
|
|
44
|
+
NotSupportedOnRobotType,
|
|
45
|
+
LabwareOffsetDoesNotExistError,
|
|
46
|
+
)
|
|
47
|
+
from ..resources import labware_validation, fixture_validation
|
|
48
|
+
from .command import (
|
|
49
|
+
AbstractCommandImpl,
|
|
50
|
+
BaseCommand,
|
|
51
|
+
BaseCommandCreate,
|
|
52
|
+
DefinedErrorData,
|
|
53
|
+
SuccessData,
|
|
54
|
+
)
|
|
55
|
+
from ..errors.error_occurrence import ErrorOccurrence
|
|
56
|
+
from ..state.update_types import StateUpdate
|
|
57
|
+
|
|
58
|
+
if TYPE_CHECKING:
|
|
59
|
+
from ..execution import EquipmentHandler, RunControlHandler, LabwareMovementHandler
|
|
60
|
+
from ..state.state import StateView
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
MoveLabwareCommandType = Literal["moveLabware"]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
67
|
+
s.pop("default", None)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Extra buffer on top of minimum distance to move to the right
|
|
71
|
+
_TRASH_CHUTE_DROP_BUFFER_MM = 8
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class MoveLabwareParams(BaseModel):
|
|
75
|
+
"""Input parameters for a ``moveLabware`` command."""
|
|
76
|
+
|
|
77
|
+
labwareId: str = Field(..., description="The ID of the labware to move.")
|
|
78
|
+
newLocation: LoadableLabwareLocation = Field(
|
|
79
|
+
..., description="Where to move the labware."
|
|
80
|
+
)
|
|
81
|
+
strategy: LabwareMovementStrategy = Field(
|
|
82
|
+
...,
|
|
83
|
+
description="Whether to use the gripper to perform the labware movement"
|
|
84
|
+
" or to perform a manual movement with an option to pause.",
|
|
85
|
+
)
|
|
86
|
+
pickUpOffset: LabwareOffsetVector | SkipJsonSchema[None] = Field(
|
|
87
|
+
None,
|
|
88
|
+
description="Offset to use when picking up labware. "
|
|
89
|
+
"Experimental param, subject to change",
|
|
90
|
+
json_schema_extra=_remove_default,
|
|
91
|
+
)
|
|
92
|
+
dropOffset: LabwareOffsetVector | SkipJsonSchema[None] = Field(
|
|
93
|
+
None,
|
|
94
|
+
description="Offset to use when dropping off labware. "
|
|
95
|
+
"Experimental param, subject to change",
|
|
96
|
+
json_schema_extra=_remove_default,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MoveLabwareResult(BaseModel):
|
|
101
|
+
"""The output of a successful ``moveLabware`` command."""
|
|
102
|
+
|
|
103
|
+
offsetId: Optional[str] = Field(
|
|
104
|
+
# Default `None` instead of `...` so this field shows up as non-required in
|
|
105
|
+
# OpenAPI. The server is allowed to omit it or make it null.
|
|
106
|
+
None,
|
|
107
|
+
description=(
|
|
108
|
+
"An ID referencing the labware offset that will apply to this labware"
|
|
109
|
+
" now that it's in the new location."
|
|
110
|
+
" This offset will be in effect until the labware is moved"
|
|
111
|
+
" with another `moveLabware` command."
|
|
112
|
+
" Null or undefined means no offset applies,"
|
|
113
|
+
" so the default of (0, 0, 0) will be used."
|
|
114
|
+
),
|
|
115
|
+
)
|
|
116
|
+
eventualDestinationLocationSequence: LabwareLocationSequence | None = Field(
|
|
117
|
+
None,
|
|
118
|
+
description=(
|
|
119
|
+
"The full location in which this labware will eventually reside. This will typically be the same as its "
|
|
120
|
+
"immediate destination, but if this labware is going to the trash then this field will be off deck."
|
|
121
|
+
),
|
|
122
|
+
)
|
|
123
|
+
immediateDestinationLocationSequence: LabwareLocationSequence | None = Field(
|
|
124
|
+
None,
|
|
125
|
+
description=(
|
|
126
|
+
"The full location to which this labware is being moved, right now."
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
originLocationSequence: LabwareLocationSequence | None = Field(
|
|
130
|
+
None,
|
|
131
|
+
description="The full location down to the deck of the labware before this command.",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class ErrorDetails(TypedDict):
|
|
136
|
+
"""Location details for a failed gripper move."""
|
|
137
|
+
|
|
138
|
+
originLocationSequence: LabwareLocationSequence
|
|
139
|
+
immediateDestinationLocationSequence: LabwareLocationSequence
|
|
140
|
+
eventualDestinationLocationSequence: LabwareLocationSequence
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class GripperMovementError(ErrorOccurrence):
|
|
144
|
+
"""Returned when something physically goes wrong when the gripper moves labware.
|
|
145
|
+
|
|
146
|
+
When this error happens, the engine will leave the labware in its original place.
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
isDefined: bool = True
|
|
150
|
+
|
|
151
|
+
errorType: Literal["gripperMovement"] = "gripperMovement"
|
|
152
|
+
|
|
153
|
+
errorInfo: ErrorDetails
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
_ExecuteReturn = SuccessData[MoveLabwareResult] | DefinedErrorData[GripperMovementError]
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class MoveLabwareImplementation(AbstractCommandImpl[MoveLabwareParams, _ExecuteReturn]):
|
|
160
|
+
"""The execution implementation for ``moveLabware`` commands."""
|
|
161
|
+
|
|
162
|
+
def __init__(
|
|
163
|
+
self,
|
|
164
|
+
model_utils: ModelUtils,
|
|
165
|
+
state_view: StateView,
|
|
166
|
+
equipment: EquipmentHandler,
|
|
167
|
+
labware_movement: LabwareMovementHandler,
|
|
168
|
+
run_control: RunControlHandler,
|
|
169
|
+
**kwargs: object,
|
|
170
|
+
) -> None:
|
|
171
|
+
self._model_utils = model_utils
|
|
172
|
+
self._state_view = state_view
|
|
173
|
+
self._equipment = equipment
|
|
174
|
+
self._labware_movement = labware_movement
|
|
175
|
+
self._run_control = run_control
|
|
176
|
+
|
|
177
|
+
async def execute(self, params: MoveLabwareParams) -> _ExecuteReturn: # noqa: C901
|
|
178
|
+
"""Move a loaded labware to a new location."""
|
|
179
|
+
state_update = StateUpdate()
|
|
180
|
+
|
|
181
|
+
# Allow propagation of LabwareNotLoadedError.
|
|
182
|
+
current_labware = self._state_view.labware.get(labware_id=params.labwareId)
|
|
183
|
+
current_labware_definition = self._state_view.labware.get_definition(
|
|
184
|
+
labware_id=params.labwareId
|
|
185
|
+
)
|
|
186
|
+
definition_uri = current_labware.definitionUri
|
|
187
|
+
post_drop_slide_offset: Optional[Point] = None
|
|
188
|
+
trash_lid_drop_offset: Optional[Point] = None
|
|
189
|
+
|
|
190
|
+
if self._state_view.labware.is_fixed_trash(params.labwareId):
|
|
191
|
+
raise LabwareMovementNotAllowedError(
|
|
192
|
+
f"Cannot move fixed trash labware '{current_labware_definition.parameters.loadName}'."
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
origin_location_sequence = self._state_view.geometry.get_location_sequence(
|
|
196
|
+
params.labwareId
|
|
197
|
+
)
|
|
198
|
+
eventual_destination_location_sequence: LabwareLocationSequence | None = None
|
|
199
|
+
|
|
200
|
+
if isinstance(params.newLocation, AddressableAreaLocation):
|
|
201
|
+
area_name = params.newLocation.addressableAreaName
|
|
202
|
+
if (
|
|
203
|
+
not fixture_validation.is_gripper_waste_chute(area_name)
|
|
204
|
+
and not fixture_validation.is_deck_slot(area_name)
|
|
205
|
+
and not fixture_validation.is_trash(area_name)
|
|
206
|
+
):
|
|
207
|
+
raise LabwareMovementNotAllowedError(
|
|
208
|
+
f"Cannot move {current_labware.loadName} to addressable area {area_name}"
|
|
209
|
+
)
|
|
210
|
+
self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
|
|
211
|
+
area_name
|
|
212
|
+
)
|
|
213
|
+
state_update.set_addressable_area_used(addressable_area_name=area_name)
|
|
214
|
+
|
|
215
|
+
if fixture_validation.is_gripper_waste_chute(area_name):
|
|
216
|
+
# When dropping off labware in the waste chute, some bigger pieces
|
|
217
|
+
# of labware (namely tipracks) can get stuck between a gripper
|
|
218
|
+
# paddle and the bottom of the waste chute, even after the gripper
|
|
219
|
+
# has homed all the way to the top of its travel. We add a "post-drop
|
|
220
|
+
# slide" to dropoffs in the waste chute in order to guarantee that the
|
|
221
|
+
# labware can drop fully through the chute before the gripper jaws close.
|
|
222
|
+
post_drop_slide_offset = Point(
|
|
223
|
+
x=(_labware_x_dimension(current_labware_definition) / 2.0)
|
|
224
|
+
+ (GRIPPER_PADDLE_WIDTH / 2.0)
|
|
225
|
+
+ _TRASH_CHUTE_DROP_BUFFER_MM,
|
|
226
|
+
y=0,
|
|
227
|
+
z=0,
|
|
228
|
+
)
|
|
229
|
+
eventual_destination_location_sequence = [
|
|
230
|
+
NotOnDeckLocationSequenceComponent(
|
|
231
|
+
logicalLocationName=OFF_DECK_LOCATION
|
|
232
|
+
)
|
|
233
|
+
]
|
|
234
|
+
elif fixture_validation.is_trash(area_name):
|
|
235
|
+
# When dropping labware in the trash bins we want to ensure they are lids
|
|
236
|
+
# and enforce a y-axis drop offset to ensure they fall within the trash bin
|
|
237
|
+
eventual_destination_location_sequence = [
|
|
238
|
+
NotOnDeckLocationSequenceComponent(
|
|
239
|
+
logicalLocationName=OFF_DECK_LOCATION
|
|
240
|
+
)
|
|
241
|
+
]
|
|
242
|
+
if labware_validation.validate_definition_is_lid(
|
|
243
|
+
self._state_view.labware.get_definition(params.labwareId)
|
|
244
|
+
):
|
|
245
|
+
lid_disposable_offsets = (
|
|
246
|
+
current_labware_definition.gripperOffsets.get(
|
|
247
|
+
"lidDisposalOffsets"
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
if lid_disposable_offsets is not None:
|
|
251
|
+
trash_lid_drop_offset = Point.from_xyz_attrs(
|
|
252
|
+
lid_disposable_offsets.dropOffset
|
|
253
|
+
)
|
|
254
|
+
else:
|
|
255
|
+
raise LabwareOffsetDoesNotExistError(
|
|
256
|
+
f"Labware Definition {current_labware.loadName} does not contain required field 'lidDisposalOffsets' of 'gripperOffsets'."
|
|
257
|
+
)
|
|
258
|
+
else:
|
|
259
|
+
raise LabwareMovementNotAllowedError(
|
|
260
|
+
"Can only move labware with allowed role 'Lid' to a Trash Bin."
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
elif isinstance(params.newLocation, DeckSlotLocation):
|
|
264
|
+
self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
|
|
265
|
+
params.newLocation.slotName.id
|
|
266
|
+
)
|
|
267
|
+
state_update.set_addressable_area_used(
|
|
268
|
+
addressable_area_name=params.newLocation.slotName.id
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
available_new_location = self._state_view.geometry.ensure_location_not_occupied(
|
|
272
|
+
location=params.newLocation
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Check that labware and destination do not have labware on top
|
|
276
|
+
self._state_view.labware.raise_if_labware_has_non_lid_labware_on_top(
|
|
277
|
+
labware_id=params.labwareId
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
if isinstance(available_new_location, DeckSlotLocation):
|
|
281
|
+
self._state_view.labware.raise_if_labware_cannot_be_ondeck(
|
|
282
|
+
location=available_new_location,
|
|
283
|
+
labware_definition=self._state_view.labware.get_definition(
|
|
284
|
+
params.labwareId
|
|
285
|
+
),
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
module_location_error = None
|
|
289
|
+
if isinstance(available_new_location, OnLabwareLocation):
|
|
290
|
+
self._state_view.labware.raise_if_labware_has_labware_on_top(
|
|
291
|
+
available_new_location.labwareId
|
|
292
|
+
)
|
|
293
|
+
# Ensure that labware can be placed on requested labware
|
|
294
|
+
self._state_view.labware.raise_if_labware_cannot_be_stacked(
|
|
295
|
+
top_labware_definition=current_labware_definition,
|
|
296
|
+
bottom_labware_id=available_new_location.labwareId,
|
|
297
|
+
)
|
|
298
|
+
if params.labwareId == available_new_location.labwareId:
|
|
299
|
+
raise LabwareMovementNotAllowedError(
|
|
300
|
+
"Cannot move a labware onto itself."
|
|
301
|
+
)
|
|
302
|
+
# Validate labware for the module placement
|
|
303
|
+
elif isinstance(available_new_location, ModuleLocation):
|
|
304
|
+
module = self._state_view.modules.get(available_new_location.moduleId)
|
|
305
|
+
if module is not None and module.model == ModuleModel.ABSORBANCE_READER_V1:
|
|
306
|
+
self._state_view.labware.raise_if_labware_incompatible_with_plate_reader(
|
|
307
|
+
current_labware_definition
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
# Allow propagation of ModuleNotLoadedError.
|
|
311
|
+
new_offset_id = self._equipment.find_applicable_labware_offset_id(
|
|
312
|
+
labware_definition_uri=definition_uri,
|
|
313
|
+
labware_location=available_new_location,
|
|
314
|
+
)
|
|
315
|
+
await self._labware_movement.ensure_movement_not_obstructed_by_module(
|
|
316
|
+
labware_id=params.labwareId, new_location=available_new_location
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
if params.strategy == LabwareMovementStrategy.USING_GRIPPER:
|
|
320
|
+
if self._state_view.config.robot_type == "OT-2 Standard":
|
|
321
|
+
raise NotSupportedOnRobotType(
|
|
322
|
+
message="Labware movement using a gripper is not supported on the OT-2",
|
|
323
|
+
details={"strategy": params.strategy},
|
|
324
|
+
)
|
|
325
|
+
if not labware_validation.validate_gripper_compatible(
|
|
326
|
+
current_labware_definition
|
|
327
|
+
):
|
|
328
|
+
raise LabwareMovementNotAllowedError(
|
|
329
|
+
f"Cannot move labware '{current_labware_definition.parameters.loadName}' with gripper."
|
|
330
|
+
f" If trying to move a labware on an adapter, load the adapter separately to allow"
|
|
331
|
+
f" gripper movement."
|
|
332
|
+
)
|
|
333
|
+
if labware_validation.validate_definition_is_adapter(
|
|
334
|
+
current_labware_definition
|
|
335
|
+
):
|
|
336
|
+
raise LabwareMovementNotAllowedError(
|
|
337
|
+
f"Cannot move adapter '{current_labware_definition.parameters.loadName}' with gripper."
|
|
338
|
+
)
|
|
339
|
+
validated_current_loc = (
|
|
340
|
+
self._state_view.geometry.ensure_valid_gripper_location(
|
|
341
|
+
current_labware.location
|
|
342
|
+
)
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
if module_location_error:
|
|
346
|
+
return DefinedErrorData(
|
|
347
|
+
public=module_location_error,
|
|
348
|
+
state_update=state_update,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
validated_new_loc = self._state_view.geometry.ensure_valid_gripper_location(
|
|
352
|
+
available_new_location,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
user_pick_up_offset = (
|
|
356
|
+
Point.from_xyz_attrs(params.pickUpOffset)
|
|
357
|
+
if params.pickUpOffset is not None
|
|
358
|
+
else Point()
|
|
359
|
+
)
|
|
360
|
+
user_drop_offset = (
|
|
361
|
+
Point.from_xyz_attrs(params.dropOffset)
|
|
362
|
+
if params.dropOffset is not None
|
|
363
|
+
else Point()
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
if trash_lid_drop_offset:
|
|
367
|
+
user_drop_offset += trash_lid_drop_offset
|
|
368
|
+
|
|
369
|
+
immediate_destination_location_sequence = (
|
|
370
|
+
self._state_view.geometry.get_predicted_location_sequence(
|
|
371
|
+
validated_new_loc
|
|
372
|
+
)
|
|
373
|
+
)
|
|
374
|
+
if eventual_destination_location_sequence is None:
|
|
375
|
+
eventual_destination_location_sequence = (
|
|
376
|
+
immediate_destination_location_sequence
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
try:
|
|
380
|
+
# Skips gripper moves when using virtual gripper
|
|
381
|
+
await self._labware_movement.move_labware_with_gripper(
|
|
382
|
+
labware_id=params.labwareId,
|
|
383
|
+
current_location=validated_current_loc,
|
|
384
|
+
new_location=validated_new_loc,
|
|
385
|
+
user_pick_up_offset=user_pick_up_offset,
|
|
386
|
+
user_drop_offset=user_drop_offset,
|
|
387
|
+
post_drop_slide_offset=post_drop_slide_offset,
|
|
388
|
+
)
|
|
389
|
+
except (
|
|
390
|
+
FailedGripperPickupError,
|
|
391
|
+
LabwareDroppedError,
|
|
392
|
+
StallOrCollisionDetectedError,
|
|
393
|
+
# todo(mm, 2024-09-26): Catch LabwareNotPickedUpError when that exists and
|
|
394
|
+
# move_labware_with_gripper() raises it.
|
|
395
|
+
) as exception:
|
|
396
|
+
gripper_movement_error: GripperMovementError | None = GripperMovementError(
|
|
397
|
+
id=self._model_utils.generate_id(),
|
|
398
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
399
|
+
errorCode=exception.code.value.code,
|
|
400
|
+
detail=exception.code.value.detail,
|
|
401
|
+
errorInfo={
|
|
402
|
+
"originLocationSequence": origin_location_sequence,
|
|
403
|
+
"immediateDestinationLocationSequence": immediate_destination_location_sequence,
|
|
404
|
+
"eventualDestinationLocationSequence": eventual_destination_location_sequence,
|
|
405
|
+
},
|
|
406
|
+
wrappedErrors=[
|
|
407
|
+
ErrorOccurrence.from_failed(
|
|
408
|
+
id=self._model_utils.generate_id(),
|
|
409
|
+
createdAt=self._model_utils.get_timestamp(),
|
|
410
|
+
error=exception,
|
|
411
|
+
)
|
|
412
|
+
],
|
|
413
|
+
)
|
|
414
|
+
else:
|
|
415
|
+
gripper_movement_error = None
|
|
416
|
+
|
|
417
|
+
# All mounts will have been retracted as part of the gripper move.
|
|
418
|
+
state_update.clear_all_pipette_locations()
|
|
419
|
+
|
|
420
|
+
if gripper_movement_error:
|
|
421
|
+
return DefinedErrorData(
|
|
422
|
+
public=gripper_movement_error,
|
|
423
|
+
state_update=state_update,
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
elif params.strategy == LabwareMovementStrategy.MANUAL_MOVE_WITH_PAUSE:
|
|
427
|
+
# Pause to allow for manual labware movement
|
|
428
|
+
immediate_destination_location_sequence = (
|
|
429
|
+
self._state_view.geometry.get_predicted_location_sequence(
|
|
430
|
+
params.newLocation
|
|
431
|
+
)
|
|
432
|
+
)
|
|
433
|
+
if eventual_destination_location_sequence is None:
|
|
434
|
+
eventual_destination_location_sequence = (
|
|
435
|
+
immediate_destination_location_sequence
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
await self._run_control.wait_for_resume()
|
|
439
|
+
else:
|
|
440
|
+
immediate_destination_location_sequence = (
|
|
441
|
+
self._state_view.geometry.get_predicted_location_sequence(
|
|
442
|
+
params.newLocation
|
|
443
|
+
)
|
|
444
|
+
)
|
|
445
|
+
if eventual_destination_location_sequence is None:
|
|
446
|
+
eventual_destination_location_sequence = (
|
|
447
|
+
immediate_destination_location_sequence
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# We may have just moved the labware that contains the current well out from
|
|
451
|
+
# under the pipette. Clear the current location to reflect the fact that the
|
|
452
|
+
# pipette is no longer over any labware. This is necessary for safe path
|
|
453
|
+
# planning in case the next movement goes to the same labware (now in a new
|
|
454
|
+
# place).
|
|
455
|
+
pipette_location = self._state_view.pipettes.get_current_location()
|
|
456
|
+
if (
|
|
457
|
+
isinstance(pipette_location, CurrentWell)
|
|
458
|
+
and pipette_location.labware_id == params.labwareId
|
|
459
|
+
):
|
|
460
|
+
state_update.clear_all_pipette_locations()
|
|
461
|
+
|
|
462
|
+
state_update.set_labware_location(
|
|
463
|
+
labware_id=params.labwareId,
|
|
464
|
+
new_location=available_new_location,
|
|
465
|
+
new_offset_id=new_offset_id,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
if labware_validation.validate_definition_is_lid(
|
|
469
|
+
definition=self._state_view.labware.get_definition(params.labwareId)
|
|
470
|
+
):
|
|
471
|
+
parent_updates: List[str] = []
|
|
472
|
+
lid_updates: List[str | None] = []
|
|
473
|
+
# when moving a lid between locations we need to:
|
|
474
|
+
if (
|
|
475
|
+
isinstance(current_labware.location, OnLabwareLocation)
|
|
476
|
+
and self._state_view.labware.get_lid_by_labware_id(
|
|
477
|
+
current_labware.location.labwareId
|
|
478
|
+
)
|
|
479
|
+
is not None
|
|
480
|
+
):
|
|
481
|
+
# if the source location was a parent labware and not a lid stack or lid, update the parent labware lid ID to None (no more lid)
|
|
482
|
+
parent_updates.append(current_labware.location.labwareId)
|
|
483
|
+
lid_updates.append(None)
|
|
484
|
+
|
|
485
|
+
# If we're moving to a non lid object, add to the setlids list of things to do
|
|
486
|
+
if isinstance(
|
|
487
|
+
available_new_location, OnLabwareLocation
|
|
488
|
+
) and not labware_validation.validate_definition_is_lid(
|
|
489
|
+
self._state_view.labware.get_definition(
|
|
490
|
+
available_new_location.labwareId
|
|
491
|
+
)
|
|
492
|
+
):
|
|
493
|
+
parent_updates.append(available_new_location.labwareId)
|
|
494
|
+
lid_updates.append(params.labwareId)
|
|
495
|
+
# Add to setlids
|
|
496
|
+
if len(parent_updates) > 0:
|
|
497
|
+
state_update.set_lids(
|
|
498
|
+
parent_labware_ids=parent_updates,
|
|
499
|
+
lid_ids=lid_updates,
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
return SuccessData(
|
|
503
|
+
public=MoveLabwareResult(
|
|
504
|
+
offsetId=new_offset_id,
|
|
505
|
+
originLocationSequence=origin_location_sequence,
|
|
506
|
+
immediateDestinationLocationSequence=immediate_destination_location_sequence,
|
|
507
|
+
eventualDestinationLocationSequence=eventual_destination_location_sequence,
|
|
508
|
+
),
|
|
509
|
+
state_update=state_update,
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
class MoveLabware(
|
|
514
|
+
BaseCommand[
|
|
515
|
+
MoveLabwareParams,
|
|
516
|
+
MoveLabwareResult,
|
|
517
|
+
GripperMovementError,
|
|
518
|
+
]
|
|
519
|
+
):
|
|
520
|
+
"""A ``moveLabware`` command."""
|
|
521
|
+
|
|
522
|
+
commandType: MoveLabwareCommandType = "moveLabware"
|
|
523
|
+
params: MoveLabwareParams
|
|
524
|
+
result: Optional[MoveLabwareResult] = None
|
|
525
|
+
|
|
526
|
+
_ImplementationCls: Type[MoveLabwareImplementation] = MoveLabwareImplementation
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
class MoveLabwareCreate(BaseCommandCreate[MoveLabwareParams]):
|
|
530
|
+
"""A request to create a ``moveLabware`` command."""
|
|
531
|
+
|
|
532
|
+
commandType: MoveLabwareCommandType = "moveLabware"
|
|
533
|
+
params: MoveLabwareParams
|
|
534
|
+
|
|
535
|
+
_CommandCls: Type[MoveLabware] = MoveLabware
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def _labware_x_dimension(labware_definition: LabwareDefinition) -> float:
|
|
539
|
+
if isinstance(labware_definition, LabwareDefinition2):
|
|
540
|
+
return labware_definition.dimensions.xDimension
|
|
541
|
+
else:
|
|
542
|
+
assert_type(labware_definition, LabwareDefinition3)
|
|
543
|
+
return (
|
|
544
|
+
labware_definition.extents.total.frontRightTop.x
|
|
545
|
+
- labware_definition.extents.total.backLeftBottom.x
|
|
546
|
+
)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Move relative (jog) command payload, result, and implementation models."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type
|
|
5
|
+
from typing_extensions import Literal
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from ..types import MovementAxis
|
|
9
|
+
from .command import (
|
|
10
|
+
AbstractCommandImpl,
|
|
11
|
+
BaseCommand,
|
|
12
|
+
BaseCommandCreate,
|
|
13
|
+
SuccessData,
|
|
14
|
+
DefinedErrorData,
|
|
15
|
+
)
|
|
16
|
+
from .movement_common import (
|
|
17
|
+
DestinationPositionResult,
|
|
18
|
+
move_relative,
|
|
19
|
+
StallOrCollisionError,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from ..execution import MovementHandler
|
|
24
|
+
from ..resources.model_utils import ModelUtils
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
MoveRelativeCommandType = Literal["moveRelative"]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MoveRelativeParams(BaseModel):
|
|
31
|
+
"""Payload required for a MoveRelative command."""
|
|
32
|
+
|
|
33
|
+
pipetteId: str = Field(..., description="Pipette to move.")
|
|
34
|
+
axis: MovementAxis = Field(..., description="Axis along which to move.")
|
|
35
|
+
distance: float = Field(
|
|
36
|
+
...,
|
|
37
|
+
description=(
|
|
38
|
+
"Distance to move in millimeters. A positive number will move"
|
|
39
|
+
" towards the right (x), back (y), top (z) of the deck."
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class MoveRelativeResult(DestinationPositionResult):
|
|
45
|
+
"""Result data from the execution of a MoveRelative command."""
|
|
46
|
+
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class MoveRelativeImplementation(
|
|
51
|
+
AbstractCommandImpl[
|
|
52
|
+
MoveRelativeParams,
|
|
53
|
+
SuccessData[MoveRelativeResult] | DefinedErrorData[StallOrCollisionError],
|
|
54
|
+
]
|
|
55
|
+
):
|
|
56
|
+
"""Move relative command implementation."""
|
|
57
|
+
|
|
58
|
+
def __init__(
|
|
59
|
+
self, movement: MovementHandler, model_utils: ModelUtils, **kwargs: object
|
|
60
|
+
) -> None:
|
|
61
|
+
self._movement = movement
|
|
62
|
+
self._model_utils = model_utils
|
|
63
|
+
|
|
64
|
+
async def execute(
|
|
65
|
+
self, params: MoveRelativeParams
|
|
66
|
+
) -> SuccessData[MoveRelativeResult] | DefinedErrorData[StallOrCollisionError]:
|
|
67
|
+
"""Move (jog) a given pipette a relative distance."""
|
|
68
|
+
result = await move_relative(
|
|
69
|
+
movement=self._movement,
|
|
70
|
+
model_utils=self._model_utils,
|
|
71
|
+
pipette_id=params.pipetteId,
|
|
72
|
+
axis=params.axis,
|
|
73
|
+
distance=params.distance,
|
|
74
|
+
)
|
|
75
|
+
if isinstance(result, DefinedErrorData):
|
|
76
|
+
return result
|
|
77
|
+
else:
|
|
78
|
+
return SuccessData(
|
|
79
|
+
public=MoveRelativeResult(position=result.public.position),
|
|
80
|
+
state_update=result.state_update,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class MoveRelative(
|
|
85
|
+
BaseCommand[MoveRelativeParams, MoveRelativeResult, StallOrCollisionError]
|
|
86
|
+
):
|
|
87
|
+
"""Command to move (jog) a given pipette a relative distance."""
|
|
88
|
+
|
|
89
|
+
commandType: MoveRelativeCommandType = "moveRelative"
|
|
90
|
+
params: MoveRelativeParams
|
|
91
|
+
result: Optional[MoveRelativeResult] = None
|
|
92
|
+
|
|
93
|
+
_ImplementationCls: Type[MoveRelativeImplementation] = MoveRelativeImplementation
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class MoveRelativeCreate(BaseCommandCreate[MoveRelativeParams]):
|
|
97
|
+
"""Data to create a MoveRelative command."""
|
|
98
|
+
|
|
99
|
+
commandType: MoveRelativeCommandType = "moveRelative"
|
|
100
|
+
params: MoveRelativeParams
|
|
101
|
+
|
|
102
|
+
_CommandCls: Type[MoveRelative] = MoveRelative
|