opentrons 8.6.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/__init__.py +150 -0
- opentrons/_version.py +34 -0
- opentrons/calibration_storage/__init__.py +54 -0
- opentrons/calibration_storage/deck_configuration.py +62 -0
- opentrons/calibration_storage/encoder_decoder.py +31 -0
- opentrons/calibration_storage/file_operators.py +142 -0
- opentrons/calibration_storage/helpers.py +103 -0
- opentrons/calibration_storage/ot2/__init__.py +34 -0
- opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
- opentrons/calibration_storage/ot2/models/__init__.py +0 -0
- opentrons/calibration_storage/ot2/models/v1.py +149 -0
- opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
- opentrons/calibration_storage/ot2/tip_length.py +281 -0
- opentrons/calibration_storage/ot3/__init__.py +31 -0
- opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
- opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
- opentrons/calibration_storage/ot3/models/__init__.py +0 -0
- opentrons/calibration_storage/ot3/models/v1.py +122 -0
- opentrons/calibration_storage/ot3/module_offset.py +138 -0
- opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
- opentrons/calibration_storage/types.py +45 -0
- opentrons/cli/__init__.py +21 -0
- opentrons/cli/__main__.py +5 -0
- opentrons/cli/analyze.py +501 -0
- opentrons/config/__init__.py +631 -0
- opentrons/config/advanced_settings.py +871 -0
- opentrons/config/defaults_ot2.py +214 -0
- opentrons/config/defaults_ot3.py +499 -0
- opentrons/config/feature_flags.py +86 -0
- opentrons/config/gripper_config.py +55 -0
- opentrons/config/reset.py +203 -0
- opentrons/config/robot_configs.py +187 -0
- opentrons/config/types.py +183 -0
- opentrons/drivers/__init__.py +0 -0
- opentrons/drivers/absorbance_reader/__init__.py +11 -0
- opentrons/drivers/absorbance_reader/abstract.py +72 -0
- opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
- opentrons/drivers/absorbance_reader/driver.py +81 -0
- opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
- opentrons/drivers/absorbance_reader/simulator.py +84 -0
- opentrons/drivers/asyncio/__init__.py +0 -0
- opentrons/drivers/asyncio/communication/__init__.py +22 -0
- opentrons/drivers/asyncio/communication/async_serial.py +183 -0
- opentrons/drivers/asyncio/communication/errors.py +88 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
- opentrons/drivers/command_builder.py +102 -0
- opentrons/drivers/flex_stacker/__init__.py +13 -0
- opentrons/drivers/flex_stacker/abstract.py +214 -0
- opentrons/drivers/flex_stacker/driver.py +768 -0
- opentrons/drivers/flex_stacker/errors.py +68 -0
- opentrons/drivers/flex_stacker/simulator.py +309 -0
- opentrons/drivers/flex_stacker/types.py +367 -0
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/drivers/heater_shaker/__init__.py +5 -0
- opentrons/drivers/heater_shaker/abstract.py +76 -0
- opentrons/drivers/heater_shaker/driver.py +204 -0
- opentrons/drivers/heater_shaker/simulator.py +94 -0
- opentrons/drivers/mag_deck/__init__.py +6 -0
- opentrons/drivers/mag_deck/abstract.py +44 -0
- opentrons/drivers/mag_deck/driver.py +208 -0
- opentrons/drivers/mag_deck/simulator.py +63 -0
- opentrons/drivers/rpi_drivers/__init__.py +33 -0
- opentrons/drivers/rpi_drivers/dev_types.py +94 -0
- opentrons/drivers/rpi_drivers/gpio.py +282 -0
- opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
- opentrons/drivers/rpi_drivers/interfaces.py +15 -0
- opentrons/drivers/rpi_drivers/types.py +364 -0
- opentrons/drivers/rpi_drivers/usb.py +102 -0
- opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
- opentrons/drivers/serial_communication.py +151 -0
- opentrons/drivers/smoothie_drivers/__init__.py +4 -0
- opentrons/drivers/smoothie_drivers/connection.py +51 -0
- opentrons/drivers/smoothie_drivers/constants.py +121 -0
- opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
- opentrons/drivers/smoothie_drivers/errors.py +49 -0
- opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
- opentrons/drivers/smoothie_drivers/simulator.py +99 -0
- opentrons/drivers/smoothie_drivers/types.py +16 -0
- opentrons/drivers/temp_deck/__init__.py +10 -0
- opentrons/drivers/temp_deck/abstract.py +54 -0
- opentrons/drivers/temp_deck/driver.py +197 -0
- opentrons/drivers/temp_deck/simulator.py +57 -0
- opentrons/drivers/thermocycler/__init__.py +12 -0
- opentrons/drivers/thermocycler/abstract.py +99 -0
- opentrons/drivers/thermocycler/driver.py +395 -0
- opentrons/drivers/thermocycler/simulator.py +126 -0
- opentrons/drivers/types.py +107 -0
- opentrons/drivers/utils.py +222 -0
- opentrons/execute.py +742 -0
- opentrons/hardware_control/__init__.py +65 -0
- opentrons/hardware_control/__main__.py +77 -0
- opentrons/hardware_control/adapters.py +98 -0
- opentrons/hardware_control/api.py +1347 -0
- opentrons/hardware_control/backends/__init__.py +7 -0
- opentrons/hardware_control/backends/controller.py +400 -0
- opentrons/hardware_control/backends/errors.py +9 -0
- opentrons/hardware_control/backends/estop_state.py +164 -0
- opentrons/hardware_control/backends/flex_protocol.py +497 -0
- opentrons/hardware_control/backends/ot3controller.py +1930 -0
- opentrons/hardware_control/backends/ot3simulator.py +900 -0
- opentrons/hardware_control/backends/ot3utils.py +664 -0
- opentrons/hardware_control/backends/simulator.py +442 -0
- opentrons/hardware_control/backends/status_bar_state.py +240 -0
- opentrons/hardware_control/backends/subsystem_manager.py +431 -0
- opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
- opentrons/hardware_control/backends/types.py +14 -0
- opentrons/hardware_control/constants.py +6 -0
- opentrons/hardware_control/dev_types.py +125 -0
- opentrons/hardware_control/emulation/__init__.py +0 -0
- opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
- opentrons/hardware_control/emulation/app.py +56 -0
- opentrons/hardware_control/emulation/connection_handler.py +38 -0
- opentrons/hardware_control/emulation/heater_shaker.py +150 -0
- opentrons/hardware_control/emulation/magdeck.py +60 -0
- opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
- opentrons/hardware_control/emulation/module_server/client.py +78 -0
- opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
- opentrons/hardware_control/emulation/module_server/models.py +31 -0
- opentrons/hardware_control/emulation/module_server/server.py +110 -0
- opentrons/hardware_control/emulation/parser.py +74 -0
- opentrons/hardware_control/emulation/proxy.py +241 -0
- opentrons/hardware_control/emulation/run_emulator.py +68 -0
- opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
- opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
- opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
- opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
- opentrons/hardware_control/emulation/settings.py +119 -0
- opentrons/hardware_control/emulation/simulations.py +133 -0
- opentrons/hardware_control/emulation/smoothie.py +192 -0
- opentrons/hardware_control/emulation/tempdeck.py +69 -0
- opentrons/hardware_control/emulation/thermocycler.py +128 -0
- opentrons/hardware_control/emulation/types.py +10 -0
- opentrons/hardware_control/emulation/util.py +38 -0
- opentrons/hardware_control/errors.py +43 -0
- opentrons/hardware_control/execution_manager.py +164 -0
- opentrons/hardware_control/instruments/__init__.py +5 -0
- opentrons/hardware_control/instruments/instrument_abc.py +39 -0
- opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
- opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
- opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
- opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
- opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
- opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
- opentrons/hardware_control/module_control.py +332 -0
- opentrons/hardware_control/modules/__init__.py +69 -0
- opentrons/hardware_control/modules/absorbance_reader.py +373 -0
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/flex_stacker.py +948 -0
- opentrons/hardware_control/modules/heater_shaker.py +426 -0
- opentrons/hardware_control/modules/lid_temp_status.py +35 -0
- opentrons/hardware_control/modules/magdeck.py +233 -0
- opentrons/hardware_control/modules/mod_abc.py +245 -0
- opentrons/hardware_control/modules/module_calibration.py +93 -0
- opentrons/hardware_control/modules/plate_temp_status.py +61 -0
- opentrons/hardware_control/modules/tempdeck.py +299 -0
- opentrons/hardware_control/modules/thermocycler.py +731 -0
- opentrons/hardware_control/modules/types.py +417 -0
- opentrons/hardware_control/modules/update.py +255 -0
- opentrons/hardware_control/modules/utils.py +73 -0
- opentrons/hardware_control/motion_utilities.py +318 -0
- opentrons/hardware_control/nozzle_manager.py +422 -0
- opentrons/hardware_control/ot3_calibration.py +1171 -0
- opentrons/hardware_control/ot3api.py +3227 -0
- opentrons/hardware_control/pause_manager.py +31 -0
- opentrons/hardware_control/poller.py +112 -0
- opentrons/hardware_control/protocols/__init__.py +106 -0
- opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
- opentrons/hardware_control/protocols/calibratable.py +45 -0
- opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
- opentrons/hardware_control/protocols/configurable.py +48 -0
- opentrons/hardware_control/protocols/event_sourcer.py +18 -0
- opentrons/hardware_control/protocols/execution_controllable.py +33 -0
- opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
- opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
- opentrons/hardware_control/protocols/gripper_controller.py +55 -0
- opentrons/hardware_control/protocols/hardware_manager.py +51 -0
- opentrons/hardware_control/protocols/identifiable.py +16 -0
- opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
- opentrons/hardware_control/protocols/liquid_handler.py +266 -0
- opentrons/hardware_control/protocols/module_provider.py +16 -0
- opentrons/hardware_control/protocols/motion_controller.py +243 -0
- opentrons/hardware_control/protocols/position_estimator.py +45 -0
- opentrons/hardware_control/protocols/simulatable.py +10 -0
- opentrons/hardware_control/protocols/stoppable.py +9 -0
- opentrons/hardware_control/protocols/types.py +27 -0
- opentrons/hardware_control/robot_calibration.py +224 -0
- opentrons/hardware_control/scripts/README.md +28 -0
- opentrons/hardware_control/scripts/__init__.py +1 -0
- opentrons/hardware_control/scripts/gripper_control.py +208 -0
- opentrons/hardware_control/scripts/ot3gripper +7 -0
- opentrons/hardware_control/scripts/ot3repl +7 -0
- opentrons/hardware_control/scripts/repl.py +187 -0
- opentrons/hardware_control/scripts/tc_control.py +97 -0
- opentrons/hardware_control/simulator_setup.py +260 -0
- opentrons/hardware_control/thread_manager.py +431 -0
- opentrons/hardware_control/threaded_async_lock.py +97 -0
- opentrons/hardware_control/types.py +792 -0
- opentrons/hardware_control/util.py +234 -0
- opentrons/legacy_broker.py +53 -0
- opentrons/legacy_commands/__init__.py +1 -0
- opentrons/legacy_commands/commands.py +483 -0
- opentrons/legacy_commands/helpers.py +153 -0
- opentrons/legacy_commands/module_commands.py +215 -0
- opentrons/legacy_commands/protocol_commands.py +54 -0
- opentrons/legacy_commands/publisher.py +155 -0
- opentrons/legacy_commands/robot_commands.py +51 -0
- opentrons/legacy_commands/types.py +1115 -0
- opentrons/motion_planning/__init__.py +32 -0
- opentrons/motion_planning/adjacent_slots_getters.py +168 -0
- opentrons/motion_planning/deck_conflict.py +396 -0
- opentrons/motion_planning/errors.py +35 -0
- opentrons/motion_planning/types.py +42 -0
- opentrons/motion_planning/waypoints.py +218 -0
- opentrons/ordered_set.py +138 -0
- opentrons/protocol_api/__init__.py +105 -0
- opentrons/protocol_api/_liquid.py +157 -0
- opentrons/protocol_api/_liquid_properties.py +814 -0
- opentrons/protocol_api/_nozzle_layout.py +31 -0
- opentrons/protocol_api/_parameter_context.py +300 -0
- opentrons/protocol_api/_parameters.py +31 -0
- opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
- opentrons/protocol_api/_types.py +43 -0
- opentrons/protocol_api/config.py +23 -0
- opentrons/protocol_api/core/__init__.py +23 -0
- opentrons/protocol_api/core/common.py +33 -0
- opentrons/protocol_api/core/core_map.py +74 -0
- opentrons/protocol_api/core/engine/__init__.py +22 -0
- opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
- opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
- opentrons/protocol_api/core/engine/exceptions.py +19 -0
- opentrons/protocol_api/core/engine/instrument.py +2391 -0
- opentrons/protocol_api/core/engine/labware.py +238 -0
- opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
- opentrons/protocol_api/core/engine/module_core.py +1025 -0
- opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
- opentrons/protocol_api/core/engine/point_calculations.py +64 -0
- opentrons/protocol_api/core/engine/protocol.py +1153 -0
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/stringify.py +74 -0
- opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
- opentrons/protocol_api/core/engine/well.py +241 -0
- opentrons/protocol_api/core/instrument.py +459 -0
- opentrons/protocol_api/core/labware.py +151 -0
- opentrons/protocol_api/core/legacy/__init__.py +11 -0
- opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
- opentrons/protocol_api/core/legacy/deck.py +369 -0
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
- opentrons/protocol_api/core/legacy/load_info.py +67 -0
- opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
- opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
- opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
- opentrons/protocol_api/core/module.py +484 -0
- opentrons/protocol_api/core/protocol.py +311 -0
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/core/well.py +116 -0
- opentrons/protocol_api/core/well_grid.py +45 -0
- opentrons/protocol_api/create_protocol_context.py +177 -0
- opentrons/protocol_api/deck.py +223 -0
- opentrons/protocol_api/disposal_locations.py +244 -0
- opentrons/protocol_api/instrument_context.py +3212 -0
- opentrons/protocol_api/labware.py +1579 -0
- opentrons/protocol_api/module_contexts.py +1425 -0
- opentrons/protocol_api/module_validation_and_errors.py +61 -0
- opentrons/protocol_api/protocol_context.py +1688 -0
- opentrons/protocol_api/robot_context.py +303 -0
- opentrons/protocol_api/validation.py +761 -0
- opentrons/protocol_engine/__init__.py +155 -0
- opentrons/protocol_engine/actions/__init__.py +65 -0
- opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
- opentrons/protocol_engine/actions/action_handler.py +13 -0
- opentrons/protocol_engine/actions/actions.py +302 -0
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/__init__.py +5 -0
- opentrons/protocol_engine/clients/sync_client.py +174 -0
- opentrons/protocol_engine/clients/transports.py +197 -0
- opentrons/protocol_engine/commands/__init__.py +757 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
- opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
- opentrons/protocol_engine/commands/aspirate.py +244 -0
- opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
- opentrons/protocol_engine/commands/blow_out.py +146 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
- opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
- opentrons/protocol_engine/commands/command.py +308 -0
- opentrons/protocol_engine/commands/command_unions.py +974 -0
- opentrons/protocol_engine/commands/comment.py +57 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
- opentrons/protocol_engine/commands/custom.py +67 -0
- opentrons/protocol_engine/commands/dispense.py +194 -0
- opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +232 -0
- opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
- opentrons/protocol_engine/commands/hash_command_params.py +38 -0
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
- opentrons/protocol_engine/commands/home.py +100 -0
- opentrons/protocol_engine/commands/identify_module.py +86 -0
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +464 -0
- opentrons/protocol_engine/commands/load_labware.py +210 -0
- opentrons/protocol_engine/commands/load_lid.py +154 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
- opentrons/protocol_engine/commands/load_liquid.py +95 -0
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +223 -0
- opentrons/protocol_engine/commands/load_pipette.py +167 -0
- opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
- opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
- opentrons/protocol_engine/commands/move_labware.py +546 -0
- opentrons/protocol_engine/commands/move_relative.py +102 -0
- opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
- opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
- opentrons/protocol_engine/commands/move_to_well.py +119 -0
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
- opentrons/protocol_engine/commands/pipetting_common.py +443 -0
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
- opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
- opentrons/protocol_engine/commands/reload_labware.py +90 -0
- opentrons/protocol_engine/commands/retract_axis.py +75 -0
- opentrons/protocol_engine/commands/robot/__init__.py +70 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/save_position.py +109 -0
- opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
- opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
- opentrons/protocol_engine/commands/set_status_bar.py +89 -0
- opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
- opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
- opentrons/protocol_engine/commands/touch_tip.py +189 -0
- opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
- opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
- opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
- opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
- opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
- opentrons/protocol_engine/create_protocol_engine.py +193 -0
- opentrons/protocol_engine/engine_support.py +28 -0
- opentrons/protocol_engine/error_recovery_policy.py +81 -0
- opentrons/protocol_engine/errors/__init__.py +191 -0
- opentrons/protocol_engine/errors/error_occurrence.py +182 -0
- opentrons/protocol_engine/errors/exceptions.py +1308 -0
- opentrons/protocol_engine/execution/__init__.py +50 -0
- opentrons/protocol_engine/execution/command_executor.py +216 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
- opentrons/protocol_engine/execution/door_watcher.py +119 -0
- opentrons/protocol_engine/execution/equipment.py +819 -0
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +686 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
- opentrons/protocol_engine/execution/labware_movement.py +297 -0
- opentrons/protocol_engine/execution/movement.py +349 -0
- opentrons/protocol_engine/execution/pipetting.py +607 -0
- opentrons/protocol_engine/execution/queue_worker.py +86 -0
- opentrons/protocol_engine/execution/rail_lights.py +25 -0
- opentrons/protocol_engine/execution/run_control.py +33 -0
- opentrons/protocol_engine/execution/status_bar.py +34 -0
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
- opentrons/protocol_engine/execution/tip_handler.py +550 -0
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/notes/__init__.py +17 -0
- opentrons/protocol_engine/notes/notes.py +59 -0
- opentrons/protocol_engine/plugins.py +104 -0
- opentrons/protocol_engine/protocol_engine.py +683 -0
- opentrons/protocol_engine/resources/__init__.py +26 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +58 -0
- opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
- opentrons/protocol_engine/resources/labware_validation.py +73 -0
- opentrons/protocol_engine/resources/model_utils.py +32 -0
- opentrons/protocol_engine/resources/module_data_provider.py +44 -0
- opentrons/protocol_engine/resources/ot3_validation.py +21 -0
- opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
- opentrons/protocol_engine/slot_standardization.py +128 -0
- opentrons/protocol_engine/state/__init__.py +1 -0
- opentrons/protocol_engine/state/_abstract_store.py +27 -0
- opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
- opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
- opentrons/protocol_engine/state/_move_types.py +83 -0
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +699 -0
- opentrons/protocol_engine/state/command_history.py +309 -0
- opentrons/protocol_engine/state/commands.py +1158 -0
- opentrons/protocol_engine/state/config.py +39 -0
- opentrons/protocol_engine/state/files.py +57 -0
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/geometry.py +2359 -0
- opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
- opentrons/protocol_engine/state/labware.py +1459 -0
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +73 -0
- opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
- opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
- opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
- opentrons/protocol_engine/state/modules.py +1500 -0
- opentrons/protocol_engine/state/motion.py +373 -0
- opentrons/protocol_engine/state/pipettes.py +905 -0
- opentrons/protocol_engine/state/state.py +421 -0
- opentrons/protocol_engine/state/state_summary.py +36 -0
- opentrons/protocol_engine/state/tips.py +420 -0
- opentrons/protocol_engine/state/update_types.py +904 -0
- opentrons/protocol_engine/state/wells.py +290 -0
- opentrons/protocol_engine/types/__init__.py +308 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +81 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +131 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +303 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/__init__.py +37 -0
- opentrons/protocol_reader/extract_labware_definitions.py +66 -0
- opentrons/protocol_reader/file_format_validator.py +152 -0
- opentrons/protocol_reader/file_hasher.py +27 -0
- opentrons/protocol_reader/file_identifier.py +284 -0
- opentrons/protocol_reader/file_reader_writer.py +90 -0
- opentrons/protocol_reader/input_file.py +16 -0
- opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
- opentrons/protocol_reader/protocol_reader.py +188 -0
- opentrons/protocol_reader/protocol_source.py +124 -0
- opentrons/protocol_reader/role_analyzer.py +86 -0
- opentrons/protocol_runner/__init__.py +26 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
- opentrons/protocol_runner/json_file_reader.py +55 -0
- opentrons/protocol_runner/json_translator.py +314 -0
- opentrons/protocol_runner/legacy_command_mapper.py +848 -0
- opentrons/protocol_runner/legacy_context_plugin.py +116 -0
- opentrons/protocol_runner/protocol_runner.py +530 -0
- opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
- opentrons/protocol_runner/run_orchestrator.py +496 -0
- opentrons/protocol_runner/task_queue.py +95 -0
- opentrons/protocols/__init__.py +6 -0
- opentrons/protocols/advanced_control/__init__.py +0 -0
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +60 -0
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +180 -0
- opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
- opentrons/protocols/api_support/__init__.py +0 -0
- opentrons/protocols/api_support/constants.py +8 -0
- opentrons/protocols/api_support/deck_type.py +110 -0
- opentrons/protocols/api_support/definitions.py +18 -0
- opentrons/protocols/api_support/instrument.py +151 -0
- opentrons/protocols/api_support/labware_like.py +233 -0
- opentrons/protocols/api_support/tip_tracker.py +175 -0
- opentrons/protocols/api_support/types.py +32 -0
- opentrons/protocols/api_support/util.py +403 -0
- opentrons/protocols/bundle.py +89 -0
- opentrons/protocols/duration/__init__.py +4 -0
- opentrons/protocols/duration/errors.py +5 -0
- opentrons/protocols/duration/estimator.py +628 -0
- opentrons/protocols/execution/__init__.py +0 -0
- opentrons/protocols/execution/dev_types.py +181 -0
- opentrons/protocols/execution/errors.py +40 -0
- opentrons/protocols/execution/execute.py +84 -0
- opentrons/protocols/execution/execute_json_v3.py +275 -0
- opentrons/protocols/execution/execute_json_v4.py +359 -0
- opentrons/protocols/execution/execute_json_v5.py +28 -0
- opentrons/protocols/execution/execute_python.py +169 -0
- opentrons/protocols/execution/json_dispatchers.py +87 -0
- opentrons/protocols/execution/types.py +7 -0
- opentrons/protocols/geometry/__init__.py +0 -0
- opentrons/protocols/geometry/planning.py +297 -0
- opentrons/protocols/labware.py +312 -0
- opentrons/protocols/models/__init__.py +0 -0
- opentrons/protocols/models/json_protocol.py +679 -0
- opentrons/protocols/parameters/__init__.py +0 -0
- opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
- opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
- opentrons/protocols/parameters/exceptions.py +34 -0
- opentrons/protocols/parameters/parameter_definition.py +272 -0
- opentrons/protocols/parameters/types.py +17 -0
- opentrons/protocols/parameters/validation.py +267 -0
- opentrons/protocols/parse.py +671 -0
- opentrons/protocols/types.py +159 -0
- opentrons/py.typed +0 -0
- opentrons/resources/scripts/lpc21isp +0 -0
- opentrons/resources/smoothie-edge-8414642.hex +23010 -0
- opentrons/simulate.py +1065 -0
- opentrons/system/__init__.py +6 -0
- opentrons/system/camera.py +51 -0
- opentrons/system/log_control.py +59 -0
- opentrons/system/nmcli.py +856 -0
- opentrons/system/resin.py +24 -0
- opentrons/system/smoothie_update.py +15 -0
- opentrons/system/wifi.py +204 -0
- opentrons/tools/__init__.py +0 -0
- opentrons/tools/args_handler.py +22 -0
- opentrons/tools/write_pipette_memory.py +157 -0
- opentrons/types.py +618 -0
- opentrons/util/__init__.py +1 -0
- opentrons/util/async_helpers.py +166 -0
- opentrons/util/broker.py +84 -0
- opentrons/util/change_notifier.py +47 -0
- opentrons/util/entrypoint_util.py +278 -0
- opentrons/util/get_union_elements.py +26 -0
- opentrons/util/helpers.py +6 -0
- opentrons/util/linal.py +178 -0
- opentrons/util/logging_config.py +265 -0
- opentrons/util/logging_queue_handler.py +61 -0
- opentrons/util/performance_helpers.py +157 -0
- opentrons-8.6.0a1.dist-info/METADATA +37 -0
- opentrons-8.6.0a1.dist-info/RECORD +600 -0
- opentrons-8.6.0a1.dist-info/WHEEL +4 -0
- opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
- opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from opentrons.util.helpers import utc_now
|
|
4
|
+
|
|
5
|
+
from .. import types as local_types
|
|
6
|
+
|
|
7
|
+
from .models import v1
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
CalibrationType = typing.TypeVar(
|
|
11
|
+
"CalibrationType",
|
|
12
|
+
v1.PipetteOffsetCalibration,
|
|
13
|
+
v1.InstrumentOffsetModel,
|
|
14
|
+
v1.TipLengthCalibration,
|
|
15
|
+
v1.TipLengthModel,
|
|
16
|
+
v1.DeckCalibrationModel,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def mark_bad(
|
|
21
|
+
calibration: CalibrationType,
|
|
22
|
+
source_marked_bad: local_types.SourceType,
|
|
23
|
+
) -> CalibrationType:
|
|
24
|
+
calibration.status = v1.CalibrationStatus(
|
|
25
|
+
markedBad=True, source=source_marked_bad, markedAt=utc_now()
|
|
26
|
+
)
|
|
27
|
+
return calibration
|
|
File without changes
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from typing_extensions import Literal
|
|
4
|
+
from pydantic import field_validator, BaseModel, Field, PlainSerializer
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from opentrons_shared_data.pipette.types import LabwareUri
|
|
8
|
+
|
|
9
|
+
from opentrons.types import Point
|
|
10
|
+
from opentrons.calibration_storage import types
|
|
11
|
+
|
|
12
|
+
DatetimeType = typing.Annotated[
|
|
13
|
+
datetime,
|
|
14
|
+
PlainSerializer(lambda x: x.isoformat(), when_used="json"),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CalibrationStatus(BaseModel):
|
|
19
|
+
markedBad: bool = False
|
|
20
|
+
source: typing.Optional[types.SourceType] = None
|
|
21
|
+
markedAt: typing.Optional[DatetimeType] = None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Schemas used to store the data types
|
|
25
|
+
# TODO(lc 09-01-2022) We should ensure that all pydantic models are
|
|
26
|
+
# in camel case, but for now, the schemas are following the format
|
|
27
|
+
# they are currently saved in on the OT-2 to avoid a large migration.
|
|
28
|
+
class TipLengthModel(BaseModel):
|
|
29
|
+
tipLength: float = Field(..., description="Tip length data found from calibration.")
|
|
30
|
+
lastModified: DatetimeType = Field(
|
|
31
|
+
..., description="The last time this tip length was calibrated."
|
|
32
|
+
)
|
|
33
|
+
source: types.SourceType = Field(
|
|
34
|
+
default=types.SourceType.factory, description="The source of calibration."
|
|
35
|
+
)
|
|
36
|
+
status: CalibrationStatus = Field(
|
|
37
|
+
default_factory=CalibrationStatus,
|
|
38
|
+
description="The status of the calibration data.",
|
|
39
|
+
)
|
|
40
|
+
# Old data may have a `uri` field, replaced later by `definitionHash`.
|
|
41
|
+
# uri: typing.Union[LabwareUri, Literal[""]] = Field(
|
|
42
|
+
# ..., description="The tiprack URI associated with the tip length data."
|
|
43
|
+
# )
|
|
44
|
+
definitionHash: str = Field(
|
|
45
|
+
..., description="The tiprack hash associated with the tip length data."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
@field_validator("tipLength")
|
|
49
|
+
@classmethod
|
|
50
|
+
def ensure_tip_length_positive(cls, tipLength: float) -> float:
|
|
51
|
+
if tipLength < 0.0:
|
|
52
|
+
raise ValueError("Tip Length must be a positive number")
|
|
53
|
+
return tipLength
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class DeckCalibrationModel(BaseModel):
|
|
57
|
+
attitude: types.AttitudeMatrix = Field(
|
|
58
|
+
..., description="Attitude matrix for deck found from calibration."
|
|
59
|
+
)
|
|
60
|
+
last_modified: typing.Optional[DatetimeType] = Field(
|
|
61
|
+
default=None, description="The last time this deck was calibrated."
|
|
62
|
+
)
|
|
63
|
+
source: types.SourceType = Field(
|
|
64
|
+
default=types.SourceType.factory, description="The source of calibration."
|
|
65
|
+
)
|
|
66
|
+
pipette_calibrated_with: typing.Optional[str] = Field(
|
|
67
|
+
default=None, description="The pipette id used to calibrate the deck."
|
|
68
|
+
)
|
|
69
|
+
tiprack: typing.Optional[str] = Field(
|
|
70
|
+
default=None, description="The tiprack id used to calibrate the deck."
|
|
71
|
+
)
|
|
72
|
+
status: CalibrationStatus = Field(
|
|
73
|
+
default_factory=CalibrationStatus,
|
|
74
|
+
description="The status of the calibration data.",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class InstrumentOffsetModel(BaseModel):
|
|
79
|
+
offset: Point = Field(..., description="Instrument offset found from calibration.")
|
|
80
|
+
tiprack: str = Field(..., description="Tiprack used to calibrate this offset")
|
|
81
|
+
uri: str = Field(
|
|
82
|
+
..., description="The URI of the labware used for instrument offset"
|
|
83
|
+
)
|
|
84
|
+
last_modified: DatetimeType = Field(
|
|
85
|
+
..., description="The last time this instrument was calibrated."
|
|
86
|
+
)
|
|
87
|
+
source: types.SourceType = Field(
|
|
88
|
+
default=types.SourceType.factory, description="The source of calibration."
|
|
89
|
+
)
|
|
90
|
+
status: CalibrationStatus = Field(
|
|
91
|
+
default_factory=CalibrationStatus,
|
|
92
|
+
description="The status of the calibration data.",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# TODO(lc 09-19-2022) We need to refactor the calibration endpoints
|
|
97
|
+
# so that we only need to use one data model schema. This model is a
|
|
98
|
+
# temporary workaround to match with current behavior.
|
|
99
|
+
class PipetteOffsetCalibration(BaseModel):
|
|
100
|
+
pipette: str = Field(..., description="Pipette id associated with calibration.")
|
|
101
|
+
mount: str = Field(
|
|
102
|
+
..., description="The mount that this pipette was calibrated with."
|
|
103
|
+
)
|
|
104
|
+
offset: Point = Field(..., description="Instrument offset found from calibration.")
|
|
105
|
+
tiprack: str = Field(..., description="Tiprack used to calibrate this offset")
|
|
106
|
+
uri: str = Field(
|
|
107
|
+
..., description="The URI of the labware used for instrument offset"
|
|
108
|
+
)
|
|
109
|
+
last_modified: DatetimeType = Field(
|
|
110
|
+
..., description="The last time this instrument was calibrated."
|
|
111
|
+
)
|
|
112
|
+
source: types.SourceType = Field(
|
|
113
|
+
default=types.SourceType.factory, description="The source of calibration."
|
|
114
|
+
)
|
|
115
|
+
status: CalibrationStatus = Field(
|
|
116
|
+
default_factory=CalibrationStatus,
|
|
117
|
+
description="The status of the calibration data.",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# TODO(lc 09-19-2022) We need to refactor the calibration endpoints
|
|
122
|
+
# so that we only need to use one data model schema. This model is a
|
|
123
|
+
# temporary workaround to match with current behavior.
|
|
124
|
+
class TipLengthCalibration(BaseModel):
|
|
125
|
+
pipette: str = Field(..., description="Pipette id associated with calibration.")
|
|
126
|
+
tiprack: str = Field(
|
|
127
|
+
..., description="The tiprack hash associated with this tip length data."
|
|
128
|
+
)
|
|
129
|
+
tipLength: float = Field(..., description="Tip length data found from calibration.")
|
|
130
|
+
lastModified: DatetimeType = Field(
|
|
131
|
+
..., description="The last time this tip length was calibrated."
|
|
132
|
+
)
|
|
133
|
+
source: types.SourceType = Field(
|
|
134
|
+
default=types.SourceType.factory, description="The source of calibration."
|
|
135
|
+
)
|
|
136
|
+
status: CalibrationStatus = Field(
|
|
137
|
+
default_factory=CalibrationStatus,
|
|
138
|
+
description="The status of the calibration data.",
|
|
139
|
+
)
|
|
140
|
+
uri: typing.Union[LabwareUri, Literal[""]] = Field(
|
|
141
|
+
..., description="The tiprack URI associated with the tip length data."
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
@field_validator("tipLength")
|
|
145
|
+
@classmethod
|
|
146
|
+
def ensure_tip_length_positive(cls, tipLength: float) -> float:
|
|
147
|
+
if tipLength < 0.0:
|
|
148
|
+
raise ValueError("Tip Length must be a positive number")
|
|
149
|
+
return tipLength
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typing
|
|
3
|
+
import logging
|
|
4
|
+
from pydantic import ValidationError
|
|
5
|
+
from dataclasses import asdict
|
|
6
|
+
|
|
7
|
+
from opentrons import config, types
|
|
8
|
+
|
|
9
|
+
from .. import file_operators as io, types as local_types
|
|
10
|
+
|
|
11
|
+
from .models import v1
|
|
12
|
+
|
|
13
|
+
from opentrons.types import Mount, Point
|
|
14
|
+
from opentrons.util.helpers import utc_now
|
|
15
|
+
|
|
16
|
+
log = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
# Delete Pipette Offset Calibrations
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def delete_pipette_offset_file(pipette: str, mount: Mount) -> None:
|
|
22
|
+
"""
|
|
23
|
+
Delete pipette offset file based on mount and pipette serial number
|
|
24
|
+
|
|
25
|
+
:param pipette: pipette serial number
|
|
26
|
+
:param mount: pipette mount
|
|
27
|
+
"""
|
|
28
|
+
offset_dir = config.get_opentrons_path("pipette_calibration_dir")
|
|
29
|
+
offset_path = offset_dir / mount.name.lower() / f"{pipette}.json"
|
|
30
|
+
io.delete_file(offset_path)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def clear_pipette_offset_calibrations() -> None:
|
|
34
|
+
"""
|
|
35
|
+
Delete all pipette offset calibration files.
|
|
36
|
+
"""
|
|
37
|
+
io._remove_json_files_in_directories(
|
|
38
|
+
config.get_opentrons_path("pipette_calibration_dir")
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Save Pipette Offset Calibrations
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def save_pipette_calibration(
|
|
46
|
+
offset: Point,
|
|
47
|
+
pip_id: str,
|
|
48
|
+
mount: Mount,
|
|
49
|
+
tiprack_hash: str,
|
|
50
|
+
tiprack_uri: str,
|
|
51
|
+
cal_status: typing.Optional[
|
|
52
|
+
typing.Union[local_types.CalibrationStatus, v1.CalibrationStatus]
|
|
53
|
+
] = None,
|
|
54
|
+
) -> None:
|
|
55
|
+
pip_dir = config.get_opentrons_path("pipette_calibration_dir") / mount.name.lower()
|
|
56
|
+
|
|
57
|
+
if isinstance(cal_status, local_types.CalibrationStatus):
|
|
58
|
+
cal_status_model = v1.CalibrationStatus(**asdict(cal_status))
|
|
59
|
+
elif isinstance(cal_status, v1.CalibrationStatus):
|
|
60
|
+
cal_status_model = cal_status
|
|
61
|
+
else:
|
|
62
|
+
cal_status_model = v1.CalibrationStatus()
|
|
63
|
+
|
|
64
|
+
pipette_calibration = v1.InstrumentOffsetModel(
|
|
65
|
+
offset=offset,
|
|
66
|
+
tiprack=tiprack_hash,
|
|
67
|
+
uri=tiprack_uri,
|
|
68
|
+
last_modified=utc_now(),
|
|
69
|
+
source=local_types.SourceType.user,
|
|
70
|
+
status=cal_status_model,
|
|
71
|
+
)
|
|
72
|
+
io.save_to_file(pip_dir, pip_id, pipette_calibration)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# Get Pipette Offset Calibrations
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_pipette_offset(
|
|
79
|
+
pipette_id: str, mount: Mount
|
|
80
|
+
) -> typing.Optional[v1.InstrumentOffsetModel]:
|
|
81
|
+
try:
|
|
82
|
+
pipette_calibration_filepath = (
|
|
83
|
+
config.get_opentrons_path("pipette_calibration_dir")
|
|
84
|
+
/ mount.name.lower()
|
|
85
|
+
/ f"{pipette_id}.json"
|
|
86
|
+
)
|
|
87
|
+
return v1.InstrumentOffsetModel(
|
|
88
|
+
**io.read_cal_file(pipette_calibration_filepath)
|
|
89
|
+
)
|
|
90
|
+
except FileNotFoundError:
|
|
91
|
+
log.debug(f"Calibrations for {pipette_id} on {mount} does not exist.")
|
|
92
|
+
return None
|
|
93
|
+
except (json.JSONDecodeError, ValidationError):
|
|
94
|
+
log.warning(
|
|
95
|
+
f"Malformed calibrations for {pipette_id} on {mount}. Please factory reset your calibrations.",
|
|
96
|
+
exc_info=True,
|
|
97
|
+
)
|
|
98
|
+
# TODO: Delete the bad calibration here maybe?
|
|
99
|
+
return None
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_all_pipette_offset_calibrations() -> typing.List[v1.PipetteOffsetCalibration]:
|
|
103
|
+
"""
|
|
104
|
+
A helper function that will list all of the pipette offset
|
|
105
|
+
calibrations.
|
|
106
|
+
|
|
107
|
+
:return: A list of dictionary objects representing all of the
|
|
108
|
+
pipette offset calibration files found on the robot.
|
|
109
|
+
"""
|
|
110
|
+
pipette_calibration_dir = config.get_opentrons_path("pipette_calibration_dir")
|
|
111
|
+
pipette_calibration_list = []
|
|
112
|
+
for filepath in pipette_calibration_dir.glob("**/*.json"):
|
|
113
|
+
pipette_id = filepath.stem
|
|
114
|
+
mount = Mount.string_to_mount(filepath.parent.stem)
|
|
115
|
+
calibration = get_pipette_offset(pipette_id, mount)
|
|
116
|
+
if calibration:
|
|
117
|
+
pipette_calibration_list.append(
|
|
118
|
+
v1.PipetteOffsetCalibration(
|
|
119
|
+
pipette=pipette_id,
|
|
120
|
+
mount=mount.name.lower(),
|
|
121
|
+
offset=types.Point(*calibration.offset),
|
|
122
|
+
tiprack=calibration.tiprack,
|
|
123
|
+
uri=calibration.uri,
|
|
124
|
+
last_modified=calibration.last_modified,
|
|
125
|
+
source=calibration.source,
|
|
126
|
+
status=calibration.status,
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
return pipette_calibration_list
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typing
|
|
3
|
+
import logging
|
|
4
|
+
from pydantic import ValidationError
|
|
5
|
+
from dataclasses import asdict
|
|
6
|
+
|
|
7
|
+
from opentrons import config
|
|
8
|
+
|
|
9
|
+
from .. import file_operators as io, helpers, types as local_types
|
|
10
|
+
from opentrons_shared_data.pipette.types import LabwareUri
|
|
11
|
+
|
|
12
|
+
from opentrons.protocols.api_support.constants import OPENTRONS_NAMESPACE
|
|
13
|
+
from opentrons.util.helpers import utc_now
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from .models import v1
|
|
17
|
+
|
|
18
|
+
if typing.TYPE_CHECKING:
|
|
19
|
+
from opentrons_shared_data.labware.types import LabwareDefinition2
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
log = logging.getLogger(__name__)
|
|
23
|
+
# Get Tip Length Calibration
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _convert_tip_length_model_to_dict(
|
|
27
|
+
to_dict: typing.Dict[LabwareUri, v1.TipLengthModel],
|
|
28
|
+
) -> typing.Dict[LabwareUri, typing.Any]:
|
|
29
|
+
# TODO[pydantic]: supported in Pydantic V2
|
|
30
|
+
# This is a workaround since pydantic doesn't have a nice way to
|
|
31
|
+
# add encoders when converting to a dict.
|
|
32
|
+
dict_of_tip_lengths = {}
|
|
33
|
+
for key, item in to_dict.items():
|
|
34
|
+
dict_of_tip_lengths[key] = json.loads(item.model_dump_json())
|
|
35
|
+
return dict_of_tip_lengths
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def tip_lengths_for_pipette(
|
|
39
|
+
pipette_id: str,
|
|
40
|
+
) -> typing.Dict[LabwareUri, v1.TipLengthModel]:
|
|
41
|
+
try:
|
|
42
|
+
tip_length_filepath = config.get_tip_length_cal_path() / f"{pipette_id}.json"
|
|
43
|
+
all_tip_lengths_for_pipette = io.read_cal_file(tip_length_filepath)
|
|
44
|
+
except FileNotFoundError:
|
|
45
|
+
log.debug(f"Tip length calibrations not found for {pipette_id}")
|
|
46
|
+
return {}
|
|
47
|
+
except json.JSONDecodeError:
|
|
48
|
+
log.warning(
|
|
49
|
+
f"Tip length calibration is malformed for {pipette_id}", exc_info=True
|
|
50
|
+
)
|
|
51
|
+
return {}
|
|
52
|
+
|
|
53
|
+
tip_lengths: typing.Dict[LabwareUri, v1.TipLengthModel] = {}
|
|
54
|
+
|
|
55
|
+
for tiprack_identifier, data in all_tip_lengths_for_pipette.items():
|
|
56
|
+
# We normally key these calibrations by their tip rack URI,
|
|
57
|
+
# but older software had them keyed by their tip rack hash.
|
|
58
|
+
# Migrate from the old format, if necessary.
|
|
59
|
+
tiprack_identifier_is_uri = "/" in tiprack_identifier
|
|
60
|
+
if not tiprack_identifier_is_uri:
|
|
61
|
+
data["definitionHash"] = tiprack_identifier
|
|
62
|
+
uri = data.pop("uri", None)
|
|
63
|
+
if uri is None:
|
|
64
|
+
# We don't have a way to migrate old records without a URI,
|
|
65
|
+
# so skip over them.
|
|
66
|
+
continue
|
|
67
|
+
else:
|
|
68
|
+
tiprack_identifier = uri
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
tip_lengths[LabwareUri(tiprack_identifier)] = v1.TipLengthModel(**data)
|
|
72
|
+
except ValidationError:
|
|
73
|
+
log.warning(
|
|
74
|
+
f"Tip length calibration is malformed for {tiprack_identifier} on {pipette_id}",
|
|
75
|
+
exc_info=True,
|
|
76
|
+
)
|
|
77
|
+
return tip_lengths
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def load_tip_length_calibration(
|
|
81
|
+
pip_id: str, definition: "LabwareDefinition2"
|
|
82
|
+
) -> v1.TipLengthModel:
|
|
83
|
+
"""
|
|
84
|
+
Function used to grab the current tip length associated
|
|
85
|
+
with a particular tiprack.
|
|
86
|
+
|
|
87
|
+
:param pip_id: pipette you are using
|
|
88
|
+
:param definition: full definition of the tiprack
|
|
89
|
+
"""
|
|
90
|
+
labware_uri = helpers.uri_from_definition(definition)
|
|
91
|
+
load_name = definition["parameters"]["loadName"]
|
|
92
|
+
try:
|
|
93
|
+
return tip_lengths_for_pipette(pip_id)[labware_uri]
|
|
94
|
+
except KeyError as e:
|
|
95
|
+
raise local_types.TipLengthCalNotFound(
|
|
96
|
+
f"Tip length of {load_name} has not been "
|
|
97
|
+
f"calibrated for this pipette: {pip_id} and cannot"
|
|
98
|
+
"be loaded"
|
|
99
|
+
) from e
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_all_tip_length_calibrations() -> typing.List[v1.TipLengthCalibration]:
|
|
103
|
+
"""
|
|
104
|
+
A helper function that will list all of the tip length calibrations.
|
|
105
|
+
|
|
106
|
+
:return: A list of dictionary objects representing all of the
|
|
107
|
+
tip length calibration files found on the robot.
|
|
108
|
+
"""
|
|
109
|
+
all_tip_lengths_available = []
|
|
110
|
+
tip_length_dir_path = config.get_tip_length_cal_path()
|
|
111
|
+
for filepath in tip_length_dir_path.glob("**/*.json"):
|
|
112
|
+
if filepath.stem == "index":
|
|
113
|
+
continue
|
|
114
|
+
tip_lengths = tip_lengths_for_pipette(filepath.stem)
|
|
115
|
+
for tiprack_uri, tip_length in tip_lengths.items():
|
|
116
|
+
all_tip_lengths_available.append(
|
|
117
|
+
v1.TipLengthCalibration(
|
|
118
|
+
pipette=filepath.stem,
|
|
119
|
+
tiprack=tip_length.definitionHash,
|
|
120
|
+
tipLength=tip_length.tipLength,
|
|
121
|
+
lastModified=tip_length.lastModified,
|
|
122
|
+
source=tip_length.source,
|
|
123
|
+
status=tip_length.status,
|
|
124
|
+
uri=tiprack_uri,
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
return all_tip_lengths_available
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def get_custom_tiprack_definition_for_tlc(labware_uri: str) -> "LabwareDefinition2":
|
|
131
|
+
"""
|
|
132
|
+
Return the custom tiprack definition saved in the custom tiprack directory
|
|
133
|
+
during tip length calibration
|
|
134
|
+
"""
|
|
135
|
+
custom_tiprack_dir = config.get_custom_tiprack_def_path()
|
|
136
|
+
custom_tiprack_path = custom_tiprack_dir / f"{labware_uri}.json"
|
|
137
|
+
try:
|
|
138
|
+
with open(custom_tiprack_path, "rb") as f:
|
|
139
|
+
return typing.cast(
|
|
140
|
+
"LabwareDefinition2",
|
|
141
|
+
json.loads(f.read().decode("utf-8")),
|
|
142
|
+
)
|
|
143
|
+
except FileNotFoundError:
|
|
144
|
+
raise FileNotFoundError(
|
|
145
|
+
f"Custom tiprack {labware_uri} not found in the custom tiprack"
|
|
146
|
+
"directory on the robot. Please recalibrate tip length and "
|
|
147
|
+
"pipette offset with this tiprack before performing calibration "
|
|
148
|
+
"health check."
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# Delete Tip Length Calibration
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def delete_tip_length_calibration(
|
|
156
|
+
pipette_id: str,
|
|
157
|
+
tiprack_uri: typing.Optional[LabwareUri] = None,
|
|
158
|
+
tiprack_hash: typing.Optional[str] = None,
|
|
159
|
+
) -> None:
|
|
160
|
+
"""
|
|
161
|
+
Delete tip length calibration based on an optional tiprack uri or
|
|
162
|
+
tiprack hash and pipette serial number.
|
|
163
|
+
|
|
164
|
+
:param tiprack_uri: tiprack uri
|
|
165
|
+
:param tiprack_hash: tiprack uri
|
|
166
|
+
:param pipette: pipette serial number
|
|
167
|
+
"""
|
|
168
|
+
tip_lengths = tip_lengths_for_pipette(pipette_id)
|
|
169
|
+
tip_length_dir = config.get_tip_length_cal_path()
|
|
170
|
+
if tiprack_uri in tip_lengths:
|
|
171
|
+
# maybe make modify and delete same file?
|
|
172
|
+
del tip_lengths[tiprack_uri]
|
|
173
|
+
|
|
174
|
+
if tip_lengths:
|
|
175
|
+
dict_of_tip_lengths = _convert_tip_length_model_to_dict(tip_lengths)
|
|
176
|
+
io.save_to_file(tip_length_dir, pipette_id, dict_of_tip_lengths)
|
|
177
|
+
else:
|
|
178
|
+
io.delete_file(tip_length_dir / f"{pipette_id}.json")
|
|
179
|
+
elif tiprack_hash and any(
|
|
180
|
+
tiprack_hash in v.model_dump() for v in tip_lengths.values()
|
|
181
|
+
):
|
|
182
|
+
# NOTE this is for backwards compatibilty only
|
|
183
|
+
# TODO delete this check once the tip_length DELETE router
|
|
184
|
+
# no longer depends on a tiprack hash
|
|
185
|
+
for k, v in tip_lengths.items():
|
|
186
|
+
if tiprack_hash in v.model_dump():
|
|
187
|
+
tip_lengths.pop(k)
|
|
188
|
+
if tip_lengths:
|
|
189
|
+
dict_of_tip_lengths = _convert_tip_length_model_to_dict(tip_lengths)
|
|
190
|
+
io.save_to_file(tip_length_dir, pipette_id, dict_of_tip_lengths)
|
|
191
|
+
else:
|
|
192
|
+
io.delete_file(tip_length_dir / f"{pipette_id}.json")
|
|
193
|
+
else:
|
|
194
|
+
raise local_types.TipLengthCalNotFound(
|
|
195
|
+
f"Tip length for uri {tiprack_uri} and hash {tiprack_hash} has not been "
|
|
196
|
+
f"calibrated for this pipette: {pipette_id} and cannot"
|
|
197
|
+
"be loaded"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def clear_tip_length_calibration() -> None:
|
|
202
|
+
"""
|
|
203
|
+
Delete all tip length calibration files.
|
|
204
|
+
"""
|
|
205
|
+
offset_dir = config.get_tip_length_cal_path()
|
|
206
|
+
try:
|
|
207
|
+
io._remove_json_files_in_directories(offset_dir)
|
|
208
|
+
except FileNotFoundError:
|
|
209
|
+
pass
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# Save Tip Length Calibration
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def create_tip_length_data(
|
|
216
|
+
definition: "LabwareDefinition2",
|
|
217
|
+
length: float,
|
|
218
|
+
cal_status: typing.Optional[
|
|
219
|
+
typing.Union[local_types.CalibrationStatus, v1.CalibrationStatus]
|
|
220
|
+
] = None,
|
|
221
|
+
) -> typing.Dict[LabwareUri, v1.TipLengthModel]:
|
|
222
|
+
"""
|
|
223
|
+
Function to correctly format tip length data.
|
|
224
|
+
|
|
225
|
+
:param definition: full labware definition
|
|
226
|
+
:param length: the tip length to save
|
|
227
|
+
"""
|
|
228
|
+
labware_hash = helpers.hash_labware_def(definition)
|
|
229
|
+
labware_uri = helpers.uri_from_definition(definition)
|
|
230
|
+
|
|
231
|
+
if isinstance(cal_status, local_types.CalibrationStatus):
|
|
232
|
+
cal_status_model = v1.CalibrationStatus(**asdict(cal_status))
|
|
233
|
+
elif isinstance(cal_status, v1.CalibrationStatus):
|
|
234
|
+
cal_status_model = cal_status
|
|
235
|
+
else:
|
|
236
|
+
cal_status_model = v1.CalibrationStatus()
|
|
237
|
+
tip_length_data = v1.TipLengthModel(
|
|
238
|
+
tipLength=length,
|
|
239
|
+
lastModified=utc_now(),
|
|
240
|
+
source=local_types.SourceType.user,
|
|
241
|
+
status=cal_status_model,
|
|
242
|
+
definitionHash=labware_hash,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
if not definition.get("namespace") == OPENTRONS_NAMESPACE:
|
|
246
|
+
_save_custom_tiprack_definition(labware_uri, definition)
|
|
247
|
+
|
|
248
|
+
data = {labware_uri: tip_length_data}
|
|
249
|
+
return data
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _save_custom_tiprack_definition(
|
|
253
|
+
labware_uri: str,
|
|
254
|
+
definition: "LabwareDefinition2",
|
|
255
|
+
) -> None:
|
|
256
|
+
namespace, load_name, version = labware_uri.split("/")
|
|
257
|
+
custom_tr_dir_path = config.get_custom_tiprack_def_path()
|
|
258
|
+
custom_namespace_dir = custom_tr_dir_path / f"{namespace}/{load_name}"
|
|
259
|
+
|
|
260
|
+
io.save_to_file(custom_namespace_dir, version, definition)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def save_tip_length_calibration(
|
|
264
|
+
pip_id: str,
|
|
265
|
+
tip_length_cal: typing.Dict[LabwareUri, v1.TipLengthModel],
|
|
266
|
+
) -> None:
|
|
267
|
+
"""
|
|
268
|
+
Function used to save tip length calibration to file.
|
|
269
|
+
|
|
270
|
+
:param pip_id: pipette id to associate with this tip length
|
|
271
|
+
:param tip_length_cal: results of the data created using
|
|
272
|
+
:meth:`create_tip_length_data`
|
|
273
|
+
"""
|
|
274
|
+
tip_length_dir_path = config.get_tip_length_cal_path()
|
|
275
|
+
|
|
276
|
+
all_tip_lengths = tip_lengths_for_pipette(pip_id)
|
|
277
|
+
|
|
278
|
+
all_tip_lengths.update(tip_length_cal)
|
|
279
|
+
|
|
280
|
+
dict_of_tip_lengths = _convert_tip_length_model_to_dict(all_tip_lengths)
|
|
281
|
+
io.save_to_file(tip_length_dir_path, pip_id, dict_of_tip_lengths)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from . import (
|
|
2
|
+
models,
|
|
3
|
+
gripper_offset as gripper_offset,
|
|
4
|
+
)
|
|
5
|
+
from .pipette_offset import (
|
|
6
|
+
save_pipette_calibration,
|
|
7
|
+
clear_pipette_offset_calibrations,
|
|
8
|
+
get_pipette_offset,
|
|
9
|
+
delete_pipette_offset_file,
|
|
10
|
+
)
|
|
11
|
+
from .module_offset import (
|
|
12
|
+
save_module_calibration,
|
|
13
|
+
clear_module_offset_calibrations,
|
|
14
|
+
get_module_offset,
|
|
15
|
+
delete_module_offset_file,
|
|
16
|
+
load_all_module_offsets,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"models",
|
|
21
|
+
"gripper_offset",
|
|
22
|
+
"save_pipette_calibration",
|
|
23
|
+
"clear_pipette_offset_calibrations",
|
|
24
|
+
"get_pipette_offset",
|
|
25
|
+
"delete_pipette_offset_file",
|
|
26
|
+
"save_module_calibration",
|
|
27
|
+
"clear_module_offset_calibrations",
|
|
28
|
+
"get_module_offset",
|
|
29
|
+
"delete_module_offset_file",
|
|
30
|
+
"load_all_module_offsets",
|
|
31
|
+
]
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from pydantic import ValidationError
|
|
4
|
+
from typing import Optional, Union, no_type_check
|
|
5
|
+
from dataclasses import asdict
|
|
6
|
+
|
|
7
|
+
from opentrons import config
|
|
8
|
+
from opentrons.util.helpers import utc_now
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from .. import file_operators as io, types as local_types
|
|
12
|
+
|
|
13
|
+
from .models import v1
|
|
14
|
+
|
|
15
|
+
log = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Delete Belt Calibration
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@no_type_check
|
|
22
|
+
def delete_robot_belt_attitude() -> None:
|
|
23
|
+
"""
|
|
24
|
+
Delete the robot belt attitude calibration.
|
|
25
|
+
"""
|
|
26
|
+
gantry_path = (
|
|
27
|
+
config.get_opentrons_path("robot_calibration_dir") / "belt_calibration.json"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
io.delete_file(gantry_path)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Save Belt Calibration
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@no_type_check
|
|
37
|
+
def save_robot_belt_attitude(
|
|
38
|
+
transform: local_types.AttitudeMatrix,
|
|
39
|
+
pip_id: Optional[str],
|
|
40
|
+
source: Optional[local_types.SourceType] = None,
|
|
41
|
+
cal_status: Optional[
|
|
42
|
+
Union[local_types.CalibrationStatus, local_types.CalibrationStatus]
|
|
43
|
+
] = None,
|
|
44
|
+
) -> None:
|
|
45
|
+
robot_dir = config.get_opentrons_path("robot_calibration_dir")
|
|
46
|
+
|
|
47
|
+
if isinstance(cal_status, local_types.CalibrationStatus):
|
|
48
|
+
cal_status_model = v1.CalibrationStatus(**asdict(cal_status))
|
|
49
|
+
elif isinstance(cal_status, v1.CalibrationStatus):
|
|
50
|
+
cal_status_model = cal_status
|
|
51
|
+
else:
|
|
52
|
+
cal_status_model = v1.CalibrationStatus()
|
|
53
|
+
|
|
54
|
+
gantry_calibration = v1.BeltCalibrationModel(
|
|
55
|
+
attitude=transform,
|
|
56
|
+
pipetteCalibratedWith=pip_id,
|
|
57
|
+
lastModified=utc_now(),
|
|
58
|
+
source=source or local_types.SourceType.user,
|
|
59
|
+
status=cal_status_model,
|
|
60
|
+
)
|
|
61
|
+
# convert to schema + validate json conversion
|
|
62
|
+
io.save_to_file(robot_dir, "belt_calibration", gantry_calibration)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# Get Belt Calibration
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@no_type_check
|
|
69
|
+
def get_robot_belt_attitude() -> Optional[v1.BeltCalibrationModel]:
|
|
70
|
+
belt_calibration_path = (
|
|
71
|
+
config.get_opentrons_path("robot_calibration_dir") / "belt_calibration.json"
|
|
72
|
+
)
|
|
73
|
+
try:
|
|
74
|
+
return v1.BeltCalibrationModel(**io.read_cal_file(belt_calibration_path))
|
|
75
|
+
except FileNotFoundError:
|
|
76
|
+
log.warning("Belt calibration not found.")
|
|
77
|
+
pass
|
|
78
|
+
except (json.JSONDecodeError, ValidationError):
|
|
79
|
+
log.warning(
|
|
80
|
+
"Belt calibration is malformed. Please factory reset your calibrations.",
|
|
81
|
+
exc_info=True,
|
|
82
|
+
)
|
|
83
|
+
return None
|