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,223 @@
|
|
|
1
|
+
"""Implementation, request models, and response models for the load module command."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
4
|
+
from typing_extensions import Literal
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
7
|
+
|
|
8
|
+
from opentrons.protocol_engine.state.update_types import StateUpdate
|
|
9
|
+
|
|
10
|
+
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
11
|
+
from ..errors.error_occurrence import ErrorOccurrence
|
|
12
|
+
from ..types import (
|
|
13
|
+
DeckSlotLocation,
|
|
14
|
+
AddressableAreaLocation,
|
|
15
|
+
ModuleType,
|
|
16
|
+
ModuleModel,
|
|
17
|
+
)
|
|
18
|
+
from opentrons.types import DeckSlotName
|
|
19
|
+
|
|
20
|
+
from opentrons.protocol_engine.resources import deck_configuration_provider
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from ..state.state import StateView
|
|
25
|
+
from ..execution import EquipmentHandler
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
LoadModuleCommandType = Literal["loadModule"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
32
|
+
s.pop("default", None)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class LoadModuleParams(BaseModel):
|
|
36
|
+
"""Payload required to load a module."""
|
|
37
|
+
|
|
38
|
+
model: ModuleModel = Field(
|
|
39
|
+
...,
|
|
40
|
+
description=(
|
|
41
|
+
"The model name of the module to load."
|
|
42
|
+
"\n\n"
|
|
43
|
+
"Protocol Engine will look for a connected module that either"
|
|
44
|
+
" exactly matches this one, or is compatible."
|
|
45
|
+
"\n\n"
|
|
46
|
+
" For example, if you request a `temperatureModuleV1` here,"
|
|
47
|
+
" Protocol Engine might load a `temperatureModuleV1` or a `temperatureModuleV2`."
|
|
48
|
+
"\n\n"
|
|
49
|
+
" The model that it finds connected will be available through `result.model`."
|
|
50
|
+
),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Note: Our assumption here that a module's position can be boiled down to a
|
|
54
|
+
# single deck slot precludes loading a Thermocycler in its special "shifted slightly
|
|
55
|
+
# to the left" position. This is okay for now because neither the Python Protocol
|
|
56
|
+
# API nor Protocol Designer attempt to support it, either.
|
|
57
|
+
location: DeckSlotLocation = Field(
|
|
58
|
+
...,
|
|
59
|
+
description=(
|
|
60
|
+
"The location into which this module should be loaded."
|
|
61
|
+
"\n\n"
|
|
62
|
+
"For the Thermocycler Module, which occupies multiple deck slots,"
|
|
63
|
+
" this should be the front-most occupied slot (normally slot 7)."
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
moduleId: str | SkipJsonSchema[None] = Field(
|
|
68
|
+
None,
|
|
69
|
+
description=(
|
|
70
|
+
"An optional ID to assign to this module."
|
|
71
|
+
" If None, an ID will be generated."
|
|
72
|
+
),
|
|
73
|
+
json_schema_extra=_remove_default,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class LoadModuleResult(BaseModel):
|
|
78
|
+
"""The results of loading a module."""
|
|
79
|
+
|
|
80
|
+
# The `definition` used to exist here, but we intentionally removed it. See #18639.
|
|
81
|
+
|
|
82
|
+
moduleId: str = Field(
|
|
83
|
+
description="An ID to reference this module in subsequent commands."
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
model: ModuleModel = Field(
|
|
87
|
+
...,
|
|
88
|
+
description=(
|
|
89
|
+
"The hardware model of the connected module."
|
|
90
|
+
" This can be different from the exact model that this command requested."
|
|
91
|
+
" See `params.model`."
|
|
92
|
+
"\n\n"
|
|
93
|
+
"This field is only meaningful in the run's actual execution,"
|
|
94
|
+
" not in the protocol's analysis."
|
|
95
|
+
" In analysis, it will be an arbitrary placeholder."
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
serialNumber: Optional[str] = Field(
|
|
100
|
+
None,
|
|
101
|
+
description="Hardware serial number of the connected module. "
|
|
102
|
+
"Will be `None` if a module is not electrically connected to the robot (like the Magnetic Block).",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class LoadModuleImplementation(
|
|
107
|
+
AbstractCommandImpl[LoadModuleParams, SuccessData[LoadModuleResult]]
|
|
108
|
+
):
|
|
109
|
+
"""The implementation of the load module command."""
|
|
110
|
+
|
|
111
|
+
def __init__(
|
|
112
|
+
self, equipment: EquipmentHandler, state_view: StateView, **kwargs: object
|
|
113
|
+
) -> None:
|
|
114
|
+
self._equipment = equipment
|
|
115
|
+
self._state_view = state_view
|
|
116
|
+
|
|
117
|
+
async def execute(self, params: LoadModuleParams) -> SuccessData[LoadModuleResult]:
|
|
118
|
+
"""Check that the requested module is attached and assign its identifier."""
|
|
119
|
+
state_update = StateUpdate()
|
|
120
|
+
|
|
121
|
+
module_type = params.model.as_type()
|
|
122
|
+
self._ensure_module_location(params.location.slotName, module_type)
|
|
123
|
+
|
|
124
|
+
if self._state_view.modules.get_deck_supports_module_fixtures():
|
|
125
|
+
addressable_area_module_reference = (
|
|
126
|
+
self._state_view.modules.ensure_and_convert_module_fixture_location(
|
|
127
|
+
deck_slot=params.location.slotName,
|
|
128
|
+
model=params.model,
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
else:
|
|
132
|
+
addressable_area_module_reference = params.location.slotName.id
|
|
133
|
+
state_update.set_addressable_area_used(
|
|
134
|
+
addressable_area_name=addressable_area_module_reference
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
|
|
138
|
+
addressable_area_module_reference
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
self._state_view.geometry.ensure_location_not_occupied(
|
|
142
|
+
params.location, addressable_area_module_reference
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if params.model == ModuleModel.MAGNETIC_BLOCK_V1:
|
|
146
|
+
loaded_module = await self._equipment.load_magnetic_block(
|
|
147
|
+
model=params.model,
|
|
148
|
+
location=AddressableAreaLocation(
|
|
149
|
+
addressableAreaName=addressable_area_module_reference
|
|
150
|
+
),
|
|
151
|
+
module_id=params.moduleId,
|
|
152
|
+
)
|
|
153
|
+
else:
|
|
154
|
+
loaded_module = await self._equipment.load_module(
|
|
155
|
+
model=params.model,
|
|
156
|
+
location=AddressableAreaLocation(
|
|
157
|
+
addressableAreaName=addressable_area_module_reference
|
|
158
|
+
),
|
|
159
|
+
module_id=params.moduleId,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
state_update.set_load_module(
|
|
163
|
+
module_id=loaded_module.module_id,
|
|
164
|
+
definition=loaded_module.definition,
|
|
165
|
+
requested_model=params.model,
|
|
166
|
+
serial_number=loaded_module.serial_number,
|
|
167
|
+
slot_name=params.location.slotName,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return SuccessData(
|
|
171
|
+
public=LoadModuleResult(
|
|
172
|
+
moduleId=loaded_module.module_id,
|
|
173
|
+
serialNumber=loaded_module.serial_number,
|
|
174
|
+
model=loaded_module.definition.model,
|
|
175
|
+
),
|
|
176
|
+
state_update=state_update,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def _ensure_module_location(
|
|
180
|
+
self, slot: DeckSlotName, module_type: ModuleType
|
|
181
|
+
) -> None:
|
|
182
|
+
# todo(mm, 2024-12-03): Theoretically, we should be able to deal with
|
|
183
|
+
# addressable areas and deck configurations the same way between OT-2 and Flex.
|
|
184
|
+
# Can this be simplified?
|
|
185
|
+
if self._state_view.config.robot_type == "OT-2 Standard":
|
|
186
|
+
slot_def = self._state_view.addressable_areas.get_slot_definition(slot.id)
|
|
187
|
+
compatible_modules = slot_def["compatibleModuleTypes"]
|
|
188
|
+
if module_type.value not in compatible_modules:
|
|
189
|
+
raise ValueError(
|
|
190
|
+
f"A {module_type.value} cannot be loaded into slot {slot}"
|
|
191
|
+
)
|
|
192
|
+
else:
|
|
193
|
+
cutout_fixture_id = ModuleType.to_module_fixture_id(module_type)
|
|
194
|
+
module_fixture = deck_configuration_provider.get_cutout_fixture(
|
|
195
|
+
cutout_fixture_id,
|
|
196
|
+
self._state_view.labware.get_deck_definition(),
|
|
197
|
+
)
|
|
198
|
+
cutout_id = (
|
|
199
|
+
self._state_view.addressable_areas.get_cutout_id_by_deck_slot_name(slot)
|
|
200
|
+
)
|
|
201
|
+
if cutout_id not in module_fixture["mayMountTo"]:
|
|
202
|
+
raise ValueError(
|
|
203
|
+
f"A {module_type.value} cannot be loaded into slot {slot}"
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class LoadModule(BaseCommand[LoadModuleParams, LoadModuleResult, ErrorOccurrence]):
|
|
208
|
+
"""The model for a load module command."""
|
|
209
|
+
|
|
210
|
+
commandType: LoadModuleCommandType = "loadModule"
|
|
211
|
+
params: LoadModuleParams
|
|
212
|
+
result: Optional[LoadModuleResult] = None
|
|
213
|
+
|
|
214
|
+
_ImplementationCls: Type[LoadModuleImplementation] = LoadModuleImplementation
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class LoadModuleCreate(BaseCommandCreate[LoadModuleParams]):
|
|
218
|
+
"""The model for a creation request for a load module command."""
|
|
219
|
+
|
|
220
|
+
commandType: LoadModuleCommandType = "loadModule"
|
|
221
|
+
params: LoadModuleParams
|
|
222
|
+
|
|
223
|
+
_CommandCls: Type[LoadModule] = LoadModule
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"""Load pipette command request, result, and implementation models."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type, Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
7
|
+
from typing_extensions import Literal
|
|
8
|
+
|
|
9
|
+
from opentrons_shared_data.pipette.pipette_load_name_conversions import (
|
|
10
|
+
convert_to_pipette_name_type,
|
|
11
|
+
)
|
|
12
|
+
from opentrons_shared_data.pipette.types import PipetteGenerationType
|
|
13
|
+
from opentrons_shared_data.robot import user_facing_robot_type
|
|
14
|
+
from opentrons_shared_data.robot.types import RobotTypeEnum
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
from opentrons_shared_data.pipette.types import PipetteNameType
|
|
18
|
+
from opentrons.types import MountType
|
|
19
|
+
|
|
20
|
+
from opentrons.protocol_engine.state.update_types import StateUpdate
|
|
21
|
+
from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
22
|
+
from ..errors.error_occurrence import ErrorOccurrence
|
|
23
|
+
from ..errors import InvalidSpecificationForRobotTypeError, InvalidLoadPipetteSpecsError
|
|
24
|
+
|
|
25
|
+
if TYPE_CHECKING:
|
|
26
|
+
from ..execution import EquipmentHandler
|
|
27
|
+
from ..state.state import StateView
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
LoadPipetteCommandType = Literal["loadPipette"]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
34
|
+
s.pop("default", None)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class LoadPipetteParams(BaseModel):
|
|
38
|
+
"""Payload needed to load a pipette on to a mount."""
|
|
39
|
+
|
|
40
|
+
pipetteName: PipetteNameType = Field(
|
|
41
|
+
...,
|
|
42
|
+
description="The load name of the pipette to be required.",
|
|
43
|
+
)
|
|
44
|
+
mount: MountType = Field(
|
|
45
|
+
...,
|
|
46
|
+
description="The mount the pipette should be present on.",
|
|
47
|
+
)
|
|
48
|
+
pipetteId: str | SkipJsonSchema[None] = Field(
|
|
49
|
+
None,
|
|
50
|
+
description="An optional ID to assign to this pipette. If None, an ID "
|
|
51
|
+
"will be generated.",
|
|
52
|
+
json_schema_extra=_remove_default,
|
|
53
|
+
)
|
|
54
|
+
tipOverlapNotAfterVersion: str | SkipJsonSchema[None] = Field(
|
|
55
|
+
None,
|
|
56
|
+
description="A version of tip overlap data to not exceed. The highest-versioned "
|
|
57
|
+
"tip overlap data that does not exceed this version will be used. Versions are "
|
|
58
|
+
"expressed as vN where N is an integer, counting up from v0. If None, the current "
|
|
59
|
+
"highest version will be used.",
|
|
60
|
+
json_schema_extra=_remove_default,
|
|
61
|
+
)
|
|
62
|
+
liquidPresenceDetection: bool | SkipJsonSchema[None] = Field(
|
|
63
|
+
None,
|
|
64
|
+
description="Enable liquid presence detection for this pipette. Defaults to False.",
|
|
65
|
+
json_schema_extra=_remove_default,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class LoadPipetteResult(BaseModel):
|
|
70
|
+
"""Result data for executing a LoadPipette."""
|
|
71
|
+
|
|
72
|
+
pipetteId: str = Field(
|
|
73
|
+
...,
|
|
74
|
+
description="An ID to reference this pipette in subsequent commands.",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class LoadPipetteImplementation(
|
|
79
|
+
AbstractCommandImpl[LoadPipetteParams, SuccessData[LoadPipetteResult]]
|
|
80
|
+
):
|
|
81
|
+
"""Load pipette command implementation."""
|
|
82
|
+
|
|
83
|
+
def __init__(
|
|
84
|
+
self, equipment: EquipmentHandler, state_view: StateView, **kwargs: object
|
|
85
|
+
) -> None:
|
|
86
|
+
self._equipment = equipment
|
|
87
|
+
self._state_view = state_view
|
|
88
|
+
|
|
89
|
+
async def execute(
|
|
90
|
+
self, params: LoadPipetteParams
|
|
91
|
+
) -> SuccessData[LoadPipetteResult]:
|
|
92
|
+
"""Check that requested pipette is attached and assign its identifier."""
|
|
93
|
+
pipette_generation = convert_to_pipette_name_type(
|
|
94
|
+
params.pipetteName.value
|
|
95
|
+
).pipette_generation
|
|
96
|
+
robot_type = RobotTypeEnum.robot_literal_to_enum(
|
|
97
|
+
self._state_view.config.robot_type
|
|
98
|
+
)
|
|
99
|
+
if (
|
|
100
|
+
(
|
|
101
|
+
robot_type == RobotTypeEnum.FLEX
|
|
102
|
+
and pipette_generation != PipetteGenerationType.FLEX
|
|
103
|
+
)
|
|
104
|
+
) or (
|
|
105
|
+
(
|
|
106
|
+
robot_type == RobotTypeEnum.OT2
|
|
107
|
+
and pipette_generation
|
|
108
|
+
not in [PipetteGenerationType.GEN1, PipetteGenerationType.GEN2]
|
|
109
|
+
)
|
|
110
|
+
):
|
|
111
|
+
raise InvalidSpecificationForRobotTypeError(
|
|
112
|
+
f"Cannot load a {pipette_generation.value.capitalize()} pipette on "
|
|
113
|
+
f"{user_facing_robot_type(robot_type=self._state_view.config.robot_type, include_article=True)}."
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if params.mount == MountType.EXTENSION:
|
|
117
|
+
raise InvalidLoadPipetteSpecsError(
|
|
118
|
+
"Cannot load a pipette on the EXTENSION mount. Use mount LEFT or RIGHT."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
loaded_pipette = await self._equipment.load_pipette(
|
|
122
|
+
pipette_name=params.pipetteName,
|
|
123
|
+
mount=params.mount,
|
|
124
|
+
pipette_id=params.pipetteId,
|
|
125
|
+
tip_overlap_version=params.tipOverlapNotAfterVersion,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
state_update = StateUpdate()
|
|
129
|
+
state_update.set_load_pipette(
|
|
130
|
+
pipette_id=loaded_pipette.pipette_id,
|
|
131
|
+
pipette_name=params.pipetteName,
|
|
132
|
+
mount=params.mount,
|
|
133
|
+
liquid_presence_detection=params.liquidPresenceDetection,
|
|
134
|
+
)
|
|
135
|
+
state_update.update_pipette_config(
|
|
136
|
+
pipette_id=loaded_pipette.pipette_id,
|
|
137
|
+
serial_number=loaded_pipette.serial_number,
|
|
138
|
+
config=loaded_pipette.static_config,
|
|
139
|
+
)
|
|
140
|
+
state_update.set_fluid_unknown(pipette_id=loaded_pipette.pipette_id)
|
|
141
|
+
state_update.set_pipette_ready_to_aspirate(
|
|
142
|
+
pipette_id=loaded_pipette.pipette_id, ready_to_aspirate=False
|
|
143
|
+
),
|
|
144
|
+
|
|
145
|
+
return SuccessData(
|
|
146
|
+
public=LoadPipetteResult(pipetteId=loaded_pipette.pipette_id),
|
|
147
|
+
state_update=state_update,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class LoadPipette(BaseCommand[LoadPipetteParams, LoadPipetteResult, ErrorOccurrence]):
|
|
152
|
+
"""Load pipette command model."""
|
|
153
|
+
|
|
154
|
+
commandType: LoadPipetteCommandType = "loadPipette"
|
|
155
|
+
params: LoadPipetteParams
|
|
156
|
+
result: Optional[LoadPipetteResult] = None
|
|
157
|
+
|
|
158
|
+
_ImplementationCls: Type[LoadPipetteImplementation] = LoadPipetteImplementation
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class LoadPipetteCreate(BaseCommandCreate[LoadPipetteParams]):
|
|
162
|
+
"""Load pipette command creation request model."""
|
|
163
|
+
|
|
164
|
+
commandType: LoadPipetteCommandType = "loadPipette"
|
|
165
|
+
params: LoadPipetteParams
|
|
166
|
+
|
|
167
|
+
_CommandCls: Type[LoadPipette] = LoadPipette
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Magnetic Module protocol commands."""
|
|
2
|
+
|
|
3
|
+
from .disengage import (
|
|
4
|
+
Disengage,
|
|
5
|
+
DisengageCreate,
|
|
6
|
+
DisengageParams,
|
|
7
|
+
DisengageResult,
|
|
8
|
+
DisengageCommandType,
|
|
9
|
+
)
|
|
10
|
+
from .engage import (
|
|
11
|
+
Engage,
|
|
12
|
+
EngageCreate,
|
|
13
|
+
EngageParams,
|
|
14
|
+
EngageResult,
|
|
15
|
+
EngageCommandType,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
# magneticModule/disengageMagnet
|
|
21
|
+
"Disengage",
|
|
22
|
+
"DisengageCreate",
|
|
23
|
+
"DisengageParams",
|
|
24
|
+
"DisengageResult",
|
|
25
|
+
"DisengageCommandType",
|
|
26
|
+
# magneticModule/engageMagnet
|
|
27
|
+
"Engage",
|
|
28
|
+
"EngageCreate",
|
|
29
|
+
"EngageParams",
|
|
30
|
+
"EngageResult",
|
|
31
|
+
"EngageCommandType",
|
|
32
|
+
]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Magnetic Module disengage command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from typing import Optional, TYPE_CHECKING
|
|
7
|
+
from typing_extensions import Literal, Type
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
12
|
+
from ...errors.error_occurrence import ErrorOccurrence
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
16
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
DisengageCommandType = Literal["magneticModule/disengage"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DisengageParams(BaseModel):
|
|
23
|
+
"""Input data to disengage a Magnetic Module's magnets."""
|
|
24
|
+
|
|
25
|
+
moduleId: str = Field(
|
|
26
|
+
...,
|
|
27
|
+
description=(
|
|
28
|
+
"The ID of the Magnetic Module whose magnets you want to disengage,"
|
|
29
|
+
" from a prior `loadModule` command."
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DisengageResult(BaseModel):
|
|
35
|
+
"""The result of a Magnetic Module disengage command."""
|
|
36
|
+
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DisengageImplementation(
|
|
41
|
+
AbstractCommandImpl[DisengageParams, SuccessData[DisengageResult]]
|
|
42
|
+
):
|
|
43
|
+
"""The implementation of a Magnetic Module disengage command."""
|
|
44
|
+
|
|
45
|
+
def __init__(
|
|
46
|
+
self,
|
|
47
|
+
state_view: StateView,
|
|
48
|
+
equipment: EquipmentHandler,
|
|
49
|
+
**unused_dependencies: object,
|
|
50
|
+
) -> None:
|
|
51
|
+
self._state_view = state_view
|
|
52
|
+
self._equipment = equipment
|
|
53
|
+
|
|
54
|
+
async def execute(self, params: DisengageParams) -> SuccessData[DisengageResult]:
|
|
55
|
+
"""Execute a Magnetic Module disengage command.
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
ModuleNotLoadedError: If the given module ID has not been loaded.
|
|
59
|
+
WrongModuleTypeError: If the given module ID has been loaded,
|
|
60
|
+
but it's not a Magnetic Module.
|
|
61
|
+
ModuleNotAttachedError: If the given module ID points to a valid loaded
|
|
62
|
+
Magnetic Module, but that module's hardware wasn't found attached.
|
|
63
|
+
"""
|
|
64
|
+
# Allow propagation of ModuleNotLoadedError and WrongModuleTypeError.
|
|
65
|
+
mag_module_substate = self._state_view.modules.get_magnetic_module_substate(
|
|
66
|
+
module_id=params.moduleId
|
|
67
|
+
)
|
|
68
|
+
# Allow propagation of ModuleNotAttachedError.
|
|
69
|
+
hardware_module = self._equipment.get_module_hardware_api(
|
|
70
|
+
mag_module_substate.module_id
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
if hardware_module is not None: # Not virtualizing modules.
|
|
74
|
+
await hardware_module.deactivate()
|
|
75
|
+
|
|
76
|
+
return SuccessData(
|
|
77
|
+
public=DisengageResult(),
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Disengage(BaseCommand[DisengageParams, DisengageResult, ErrorOccurrence]):
|
|
82
|
+
"""A command to disengage a Magnetic Module's magnets."""
|
|
83
|
+
|
|
84
|
+
commandType: DisengageCommandType = "magneticModule/disengage"
|
|
85
|
+
params: DisengageParams
|
|
86
|
+
result: Optional[DisengageResult] = None
|
|
87
|
+
|
|
88
|
+
_ImplementationCls: Type[DisengageImplementation] = DisengageImplementation
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class DisengageCreate(BaseCommandCreate[DisengageParams]):
|
|
92
|
+
"""A request to create a Magnetic Module disengage command."""
|
|
93
|
+
|
|
94
|
+
commandType: DisengageCommandType = "magneticModule/disengage"
|
|
95
|
+
params: DisengageParams
|
|
96
|
+
|
|
97
|
+
_CommandCls: Type[Disengage] = Disengage
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Magnetic Module engage command request, result, and implementation models."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import Optional, TYPE_CHECKING
|
|
4
|
+
from typing_extensions import Literal, Type
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
|
|
9
|
+
from ...errors.error_occurrence import ErrorOccurrence
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from opentrons.protocol_engine.execution import EquipmentHandler
|
|
13
|
+
from opentrons.protocol_engine.state.state import StateView
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
EngageCommandType = Literal["magneticModule/engage"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class EngageParams(BaseModel):
|
|
20
|
+
"""Input data to engage a Magnetic Module."""
|
|
21
|
+
|
|
22
|
+
moduleId: str = Field(
|
|
23
|
+
...,
|
|
24
|
+
description=(
|
|
25
|
+
"The ID of the Magnetic Module whose magnets you want to raise,"
|
|
26
|
+
" from a prior `loadModule` command."
|
|
27
|
+
),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
height: float = Field(
|
|
31
|
+
...,
|
|
32
|
+
description=(
|
|
33
|
+
"How high, in millimeters, to raise the magnets."
|
|
34
|
+
"\n\n"
|
|
35
|
+
"Zero means the tops of the magnets are level with the ledge"
|
|
36
|
+
" that the labware rests on."
|
|
37
|
+
" This will be slightly above the magnets' minimum height,"
|
|
38
|
+
" the hardware home position."
|
|
39
|
+
" Negative values are allowed, to put the magnets below the ledge."
|
|
40
|
+
"\n\n"
|
|
41
|
+
"Units are always true millimeters."
|
|
42
|
+
" This is unlike certain labware definitions,"
|
|
43
|
+
" engage commands in the Python Protocol API,"
|
|
44
|
+
" and engage commands in older versions of the JSON protocol schema."
|
|
45
|
+
" Take care to convert properly."
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class EngageResult(BaseModel):
|
|
51
|
+
"""The result of a Magnetic Module engage command."""
|
|
52
|
+
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class EngageImplementation(
|
|
57
|
+
AbstractCommandImpl[EngageParams, SuccessData[EngageResult]]
|
|
58
|
+
):
|
|
59
|
+
"""The implementation of a Magnetic Module engage command."""
|
|
60
|
+
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
state_view: StateView,
|
|
64
|
+
equipment: EquipmentHandler,
|
|
65
|
+
**unused_dependencies: object,
|
|
66
|
+
) -> None:
|
|
67
|
+
self._state_view = state_view
|
|
68
|
+
self._equipment = equipment
|
|
69
|
+
|
|
70
|
+
async def execute(self, params: EngageParams) -> SuccessData[EngageResult]:
|
|
71
|
+
"""Execute a Magnetic Module engage command.
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
ModuleNotLoadedError: If the given module ID doesn't point to a
|
|
75
|
+
module that's already been loaded.
|
|
76
|
+
WrongModuleTypeError: If the given module ID points to a non-Magnetic
|
|
77
|
+
module.
|
|
78
|
+
ModuleNotAttachedError: If the given module ID points to a valid loaded
|
|
79
|
+
Magnetic Module, but that module's hardware wasn't found attached.
|
|
80
|
+
EngageHeightOutOfRangeError: If the given height is unreachable.
|
|
81
|
+
"""
|
|
82
|
+
# Allow propagation of ModuleNotLoadedError and WrongModuleTypeError.
|
|
83
|
+
mag_module_substate = self._state_view.modules.get_magnetic_module_substate(
|
|
84
|
+
module_id=params.moduleId
|
|
85
|
+
)
|
|
86
|
+
# Allow propagation of EngageHeightOutOfRangeError.
|
|
87
|
+
hardware_height = mag_module_substate.calculate_magnet_hardware_height(
|
|
88
|
+
mm_from_base=params.height,
|
|
89
|
+
)
|
|
90
|
+
# Allow propagation of ModuleNotAttachedError.
|
|
91
|
+
hardware_module = self._equipment.get_module_hardware_api(
|
|
92
|
+
mag_module_substate.module_id
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if hardware_module is not None: # Not virtualizing modules.
|
|
96
|
+
await hardware_module.engage(height=hardware_height)
|
|
97
|
+
|
|
98
|
+
return SuccessData(
|
|
99
|
+
public=EngageResult(),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class Engage(BaseCommand[EngageParams, EngageResult, ErrorOccurrence]):
|
|
104
|
+
"""A command to engage a Magnetic Module's magnets."""
|
|
105
|
+
|
|
106
|
+
commandType: EngageCommandType = "magneticModule/engage"
|
|
107
|
+
params: EngageParams
|
|
108
|
+
result: Optional[EngageResult] = None
|
|
109
|
+
|
|
110
|
+
_ImplementationCls: Type[EngageImplementation] = EngageImplementation
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class EngageCreate(BaseCommandCreate[EngageParams]):
|
|
114
|
+
"""A request to create a Magnetic Module engage command."""
|
|
115
|
+
|
|
116
|
+
commandType: EngageCommandType = "magneticModule/engage"
|
|
117
|
+
params: EngageParams
|
|
118
|
+
|
|
119
|
+
_CommandCls: Type[Engage] = Engage
|