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,631 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module handles configuration management. It keeps track of where the
|
|
3
|
+
configuration data is found in the robot, and is able to search for data to
|
|
4
|
+
construct an index if an existing index is not found. All other modules that
|
|
5
|
+
use persistent configuration data should use this module to read and write it.
|
|
6
|
+
|
|
7
|
+
The settings file defined here is opentrons.json. This file should be located
|
|
8
|
+
|
|
9
|
+
- On the robot, in /data
|
|
10
|
+
- Not on the robot, either in
|
|
11
|
+
- the directory from which the python importing this module was launched
|
|
12
|
+
- ~/.opentrons for the current user (where it will be written if nothing is
|
|
13
|
+
found)
|
|
14
|
+
|
|
15
|
+
The keys in opentrons.json are defined by the CONFIG_ELEMENTS tuple below.
|
|
16
|
+
The keys in the file are the name elements of the CONFIG_ELEMENTS. They can
|
|
17
|
+
also be specified via environment variables, the names of which are
|
|
18
|
+
OT_API_${UPPERCASED_NAME_ELEMENT}. For instance, to override the
|
|
19
|
+
robot_settings_file option from an environment variable, you would set the
|
|
20
|
+
OT_API_ROBOT_CONFIG_FILE variable.
|
|
21
|
+
|
|
22
|
+
This module's interface to the rest of the system are the IS_* attributes and
|
|
23
|
+
the CONFIG attribute.
|
|
24
|
+
"""
|
|
25
|
+
import enum
|
|
26
|
+
import os
|
|
27
|
+
import json
|
|
28
|
+
import logging
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
import re
|
|
31
|
+
import shutil
|
|
32
|
+
import subprocess
|
|
33
|
+
import sys
|
|
34
|
+
from enum import Enum, auto
|
|
35
|
+
from typing import Dict, NamedTuple, Optional, cast
|
|
36
|
+
|
|
37
|
+
_CONFIG_FILENAME = "config.json"
|
|
38
|
+
_LEGACY_INDICES = (
|
|
39
|
+
Path("/mnt") / "usbdrive" / "config" / "index.json",
|
|
40
|
+
Path("/data") / "index.json",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
log = logging.getLogger(__file__)
|
|
44
|
+
|
|
45
|
+
IS_WIN = sys.platform.startswith("win")
|
|
46
|
+
IS_OSX = sys.platform == "darwin"
|
|
47
|
+
IS_LINUX = sys.platform.startswith("linux")
|
|
48
|
+
IS_ROBOT = bool(
|
|
49
|
+
IS_LINUX
|
|
50
|
+
and (os.environ.get("RUNNING_ON_PI") or os.environ.get("RUNNING_ON_VERDIN"))
|
|
51
|
+
)
|
|
52
|
+
#: This is the correct thing to check to see if we’re running on a robot
|
|
53
|
+
IS_VIRTUAL = bool(os.environ.get("ENABLE_VIRTUAL_SMOOTHIE"))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class SystemArchitecture(Enum):
|
|
57
|
+
HOST = auto()
|
|
58
|
+
BUILDROOT = auto()
|
|
59
|
+
YOCTO = auto()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
ROBOT_FIRMWARE_DIR: Optional[Path] = None
|
|
63
|
+
#: The path to firmware files for modules
|
|
64
|
+
|
|
65
|
+
ARCHITECTURE: SystemArchitecture = SystemArchitecture.HOST
|
|
66
|
+
#: The system architecture running
|
|
67
|
+
|
|
68
|
+
JUPYTER_NOTEBOOK_ROOT_DIR: Optional[Path] = None
|
|
69
|
+
#: The path to the root dir for Jupyter
|
|
70
|
+
|
|
71
|
+
JUPYTER_NOTEBOOK_LABWARE_DIR: Optional[Path] = None
|
|
72
|
+
#: The path to labware installs for jupyter
|
|
73
|
+
|
|
74
|
+
OT_SYSTEM_VERSION = "0.0.0"
|
|
75
|
+
#: The semver string of the system
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if IS_ROBOT:
|
|
79
|
+
if "OT_SYSTEM_VERSION" in os.environ:
|
|
80
|
+
OT_SYSTEM_VERSION = os.environ["OT_SYSTEM_VERSION"]
|
|
81
|
+
ARCHITECTURE = SystemArchitecture.YOCTO
|
|
82
|
+
else:
|
|
83
|
+
try:
|
|
84
|
+
with open("/etc/VERSION.json") as vj:
|
|
85
|
+
contents = json.load(vj)
|
|
86
|
+
OT_SYSTEM_VERSION = contents["buildroot_version"]
|
|
87
|
+
ARCHITECTURE = SystemArchitecture.BUILDROOT
|
|
88
|
+
except Exception:
|
|
89
|
+
log.exception("Could not find version file in /etc/VERSION.json")
|
|
90
|
+
ROBOT_FIRMWARE_DIR = Path("/usr/lib/firmware/")
|
|
91
|
+
JUPYTER_NOTEBOOK_ROOT_DIR = Path("/var/lib/jupyter/notebooks/")
|
|
92
|
+
JUPYTER_NOTEBOOK_LABWARE_DIR = JUPYTER_NOTEBOOK_ROOT_DIR / "labware"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def name() -> str:
|
|
96
|
+
if IS_ROBOT and ARCHITECTURE in (
|
|
97
|
+
SystemArchitecture.BUILDROOT,
|
|
98
|
+
SystemArchitecture.YOCTO,
|
|
99
|
+
):
|
|
100
|
+
# Read the name from the machine's pretty hostname, which is maintained
|
|
101
|
+
# by update-server. This retrieval logic needs to be kept in sync with
|
|
102
|
+
# update-server.
|
|
103
|
+
|
|
104
|
+
# NOTE: This call to hostnamectl can fail momentarily if it runs
|
|
105
|
+
# at the same time as a systemd-hostnamed restart.
|
|
106
|
+
# update-server triggers such restarts regularly, any time the name changes.
|
|
107
|
+
#
|
|
108
|
+
# We let the exception propagate so the caller (probably an HTTP client
|
|
109
|
+
# polling /health) can retry later.
|
|
110
|
+
result = subprocess.check_output(["hostnamectl", "--pretty", "status"]).decode(
|
|
111
|
+
"utf-8"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Strip the trailing newline, since it's not part of the actual name value.
|
|
115
|
+
# TODO(mm, 2022-07-18): When we upgrade to systemd 249, use
|
|
116
|
+
# `hostnamectl --json` for CLI output that we can parse more robustly.
|
|
117
|
+
assert len(result) >= 1 and result[-1] == "\n"
|
|
118
|
+
return result[:-1]
|
|
119
|
+
|
|
120
|
+
else:
|
|
121
|
+
robot_name = "opentrons-dev"
|
|
122
|
+
if "DEV_ROBOT_NAME" in os.environ.keys():
|
|
123
|
+
robot_name = os.environ["DEV_ROBOT_NAME"]
|
|
124
|
+
return robot_name
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class ConfigElementType(enum.Enum):
|
|
128
|
+
FILE = enum.auto()
|
|
129
|
+
DIR = enum.auto()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ConfigElement(NamedTuple):
|
|
133
|
+
name: str
|
|
134
|
+
display_name: str
|
|
135
|
+
default: Path
|
|
136
|
+
kind: ConfigElementType
|
|
137
|
+
help: str
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
CONFIG_ELEMENTS = (
|
|
141
|
+
ConfigElement(
|
|
142
|
+
"labware_database_file",
|
|
143
|
+
"API V1 Labware Database",
|
|
144
|
+
Path("opentrons.db"),
|
|
145
|
+
ConfigElementType.FILE,
|
|
146
|
+
(
|
|
147
|
+
"A SQLite database where labware definitions and offsets were stored."
|
|
148
|
+
" No longer used as of v4."
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
ConfigElement(
|
|
152
|
+
"labware_calibration_offsets_dir_v2",
|
|
153
|
+
"API V2 Calibration Offsets Directory",
|
|
154
|
+
Path("labware") / "v2" / "offsets",
|
|
155
|
+
ConfigElementType.DIR,
|
|
156
|
+
"A location where labware offsets were stored. No longer used as of v5.",
|
|
157
|
+
),
|
|
158
|
+
ConfigElement(
|
|
159
|
+
"labware_user_definitions_dir_v2",
|
|
160
|
+
"API V2 Custom Labware Directory",
|
|
161
|
+
Path("labware") / "v2" / "custom_definitions",
|
|
162
|
+
ConfigElementType.DIR,
|
|
163
|
+
(
|
|
164
|
+
"A location where custom labware definitions may be stored."
|
|
165
|
+
" Usage not recommended."
|
|
166
|
+
),
|
|
167
|
+
),
|
|
168
|
+
ConfigElement(
|
|
169
|
+
"feature_flags_file",
|
|
170
|
+
"Feature Flags",
|
|
171
|
+
Path("feature_flags.json"),
|
|
172
|
+
ConfigElementType.FILE,
|
|
173
|
+
"The file storing the advanced feature flags.",
|
|
174
|
+
),
|
|
175
|
+
ConfigElement(
|
|
176
|
+
"robot_settings_file",
|
|
177
|
+
"Robot Settings",
|
|
178
|
+
Path("robot_settings.json"),
|
|
179
|
+
ConfigElementType.FILE,
|
|
180
|
+
"The file storing settings relevant to motion",
|
|
181
|
+
),
|
|
182
|
+
ConfigElement(
|
|
183
|
+
"deck_calibration_file",
|
|
184
|
+
"Deck Calibration",
|
|
185
|
+
Path("deck_calibration.json"),
|
|
186
|
+
ConfigElementType.FILE,
|
|
187
|
+
"The file storing the deck calibration. Superseded in v4 by robot_calibration_dir.",
|
|
188
|
+
),
|
|
189
|
+
ConfigElement(
|
|
190
|
+
"log_dir",
|
|
191
|
+
"Log Directory",
|
|
192
|
+
Path("logs"),
|
|
193
|
+
ConfigElementType.FILE,
|
|
194
|
+
"The location for saving log files",
|
|
195
|
+
),
|
|
196
|
+
ConfigElement(
|
|
197
|
+
"api_log_file",
|
|
198
|
+
"API Log File",
|
|
199
|
+
Path("logs") / "api.log",
|
|
200
|
+
ConfigElementType.FILE,
|
|
201
|
+
"The location of the file to save API logs to. If this is an"
|
|
202
|
+
" absolute path, it will be used directly. If it is a "
|
|
203
|
+
"relative path it will be relative to log_dir",
|
|
204
|
+
),
|
|
205
|
+
ConfigElement(
|
|
206
|
+
"sensor_log_file",
|
|
207
|
+
"Sensor Log File",
|
|
208
|
+
Path("logs") / "sensor.log",
|
|
209
|
+
ConfigElementType.FILE,
|
|
210
|
+
"The location of the file to save sensor logs to. If this is an"
|
|
211
|
+
" absolute path, it will be used directly. If it is a "
|
|
212
|
+
"relative path it will be relative to log_dir",
|
|
213
|
+
),
|
|
214
|
+
ConfigElement(
|
|
215
|
+
"serial_log_file",
|
|
216
|
+
"Serial Log File",
|
|
217
|
+
Path("logs") / "serial.log",
|
|
218
|
+
ConfigElementType.FILE,
|
|
219
|
+
"The location of the file to save serial logs to. If this is"
|
|
220
|
+
" an absolute path, it will be used directly. If it is a "
|
|
221
|
+
"relative path it will be relative to log_dir"
|
|
222
|
+
"The location of the file to save serial logs to",
|
|
223
|
+
),
|
|
224
|
+
# Unlike other config elements, the wifi keys dir is still in
|
|
225
|
+
# /data/user_storage/opentrons_data because these paths are fed directly to
|
|
226
|
+
# NetworkManager and stored in connections files there. To change this
|
|
227
|
+
# directory, we would have to modify those connections files, presumably on
|
|
228
|
+
# boot, which is a level of complexity that makes it worth having an
|
|
229
|
+
# annoying path.
|
|
230
|
+
ConfigElement(
|
|
231
|
+
"wifi_keys_dir",
|
|
232
|
+
"Wifi Keys Dir",
|
|
233
|
+
Path("user_storage/opentrons_data/network_keys"),
|
|
234
|
+
ConfigElementType.DIR,
|
|
235
|
+
"The directory in which to save any key material for wifi"
|
|
236
|
+
" auth. Not relevant outside of a robot.",
|
|
237
|
+
),
|
|
238
|
+
ConfigElement(
|
|
239
|
+
"hardware_controller_lockfile",
|
|
240
|
+
"Hardware Controller Lockfile",
|
|
241
|
+
Path("hardware.lock"),
|
|
242
|
+
ConfigElementType.FILE,
|
|
243
|
+
"The file to use for a hardware controller lockfile.",
|
|
244
|
+
),
|
|
245
|
+
ConfigElement(
|
|
246
|
+
"pipette_config_overrides_dir",
|
|
247
|
+
"Pipette Config User Overrides",
|
|
248
|
+
Path("pipettes"),
|
|
249
|
+
ConfigElementType.DIR,
|
|
250
|
+
"The dir where settings overrides for pipettes are stored",
|
|
251
|
+
),
|
|
252
|
+
ConfigElement(
|
|
253
|
+
"tip_length_calibration_dir",
|
|
254
|
+
"Tip Length Calibration Directory",
|
|
255
|
+
Path("tip_lengths"),
|
|
256
|
+
ConfigElementType.DIR,
|
|
257
|
+
"The dir where tip length calibration of each tiprack for "
|
|
258
|
+
"each unique pipette is stored",
|
|
259
|
+
),
|
|
260
|
+
ConfigElement(
|
|
261
|
+
"robot_calibration_dir",
|
|
262
|
+
"Robot Calibration Directory",
|
|
263
|
+
Path("robot"),
|
|
264
|
+
ConfigElementType.DIR,
|
|
265
|
+
"The dir where robot calibration is stored",
|
|
266
|
+
),
|
|
267
|
+
ConfigElement(
|
|
268
|
+
"pipette_calibration_dir",
|
|
269
|
+
"Pipette Calibration Directory",
|
|
270
|
+
Path("robot") / "pipettes",
|
|
271
|
+
ConfigElementType.DIR,
|
|
272
|
+
"The dir where pipette calibration is stored",
|
|
273
|
+
),
|
|
274
|
+
ConfigElement(
|
|
275
|
+
"custom_tiprack_dir",
|
|
276
|
+
"Custom Tiprack Directory",
|
|
277
|
+
Path("tip_lengths") / "custom_tiprack_definitions",
|
|
278
|
+
ConfigElementType.DIR,
|
|
279
|
+
"The dir where custom tiprack definitions for tip length "
|
|
280
|
+
"calibration are stored",
|
|
281
|
+
),
|
|
282
|
+
ConfigElement(
|
|
283
|
+
"gripper_calibration_dir",
|
|
284
|
+
"Gripper Calibration Directory",
|
|
285
|
+
Path("robot") / "gripper",
|
|
286
|
+
ConfigElementType.DIR,
|
|
287
|
+
"The dir where gripper calibration is stored",
|
|
288
|
+
),
|
|
289
|
+
ConfigElement(
|
|
290
|
+
"gripper_jaw_width_dir",
|
|
291
|
+
"Gripper Jaw Width Directory",
|
|
292
|
+
Path("robot") / "gripper_jaw_width_data",
|
|
293
|
+
ConfigElementType.DIR,
|
|
294
|
+
"The dir where gripper jaw width data is stored",
|
|
295
|
+
),
|
|
296
|
+
ConfigElement(
|
|
297
|
+
"module_calibration_dir",
|
|
298
|
+
"Module Calibration Directory",
|
|
299
|
+
Path("robot") / "modules",
|
|
300
|
+
ConfigElementType.DIR,
|
|
301
|
+
"The dir where module calibration is stored",
|
|
302
|
+
),
|
|
303
|
+
ConfigElement(
|
|
304
|
+
"performance_metrics_dir",
|
|
305
|
+
"Performance Metrics Directory",
|
|
306
|
+
Path("performance_metrics_data"),
|
|
307
|
+
ConfigElementType.DIR,
|
|
308
|
+
"The dir where performance metrics are stored",
|
|
309
|
+
),
|
|
310
|
+
)
|
|
311
|
+
#: The available configuration file elements to modify. All of these can be
|
|
312
|
+
#: changed by editing opentrons.json, where the keys are the name elements,
|
|
313
|
+
#: or by specifying as environment variables, where the keys are uppercase
|
|
314
|
+
#: versions of the name elements.
|
|
315
|
+
#: In addition to these flags, the OT_API_CONFIG_DIR env var (if present)
|
|
316
|
+
#: will change where the API looks for these settings by prepending it to the
|
|
317
|
+
#: normal search path.
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def infer_config_base_dir() -> Path:
|
|
321
|
+
"""Return the directory to store data in.
|
|
322
|
+
|
|
323
|
+
Defaults are ~/.opentrons if not on a pi; OT_API_CONFIG_DIR is
|
|
324
|
+
respected here.
|
|
325
|
+
|
|
326
|
+
When this module is imported, this function is called automatically
|
|
327
|
+
and the result stored in :py:attr:`APP_DATA_DIR`.
|
|
328
|
+
|
|
329
|
+
This directory may not exist when the module is imported. Even if it
|
|
330
|
+
does exist, it may not contain data, or may require data to be moved
|
|
331
|
+
to it.
|
|
332
|
+
|
|
333
|
+
:return pathlib.Path: The path to the desired root settings dir.
|
|
334
|
+
"""
|
|
335
|
+
if "OT_API_CONFIG_DIR" in os.environ:
|
|
336
|
+
return Path(os.environ["OT_API_CONFIG_DIR"])
|
|
337
|
+
elif IS_ROBOT:
|
|
338
|
+
return Path("/data")
|
|
339
|
+
else:
|
|
340
|
+
search = (Path.cwd(), Path.home() / ".opentrons")
|
|
341
|
+
for path in search:
|
|
342
|
+
if (path / _CONFIG_FILENAME).exists():
|
|
343
|
+
return path
|
|
344
|
+
else:
|
|
345
|
+
return search[-1]
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def load_and_migrate() -> Dict[str, Path]:
|
|
349
|
+
"""Ensure the settings directory tree is properly configured.
|
|
350
|
+
|
|
351
|
+
This function does most of its work on the actual robot. It will move
|
|
352
|
+
all settings files from wherever they happen to be to the proper
|
|
353
|
+
place. On non-robots, this mostly just loads. In addition, it writes
|
|
354
|
+
a default config and makes sure all directories required exist (though
|
|
355
|
+
the files in them may not).
|
|
356
|
+
"""
|
|
357
|
+
if IS_ROBOT and ARCHITECTURE != SystemArchitecture.YOCTO:
|
|
358
|
+
_migrate_robot()
|
|
359
|
+
base = infer_config_base_dir()
|
|
360
|
+
base.mkdir(parents=True, exist_ok=True)
|
|
361
|
+
index = _load_with_overrides(base)
|
|
362
|
+
return _ensure_paths_and_types(index)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def _load_with_overrides(base: Path) -> Dict[str, str]:
|
|
366
|
+
"""Load an config or write its defaults"""
|
|
367
|
+
should_write = False
|
|
368
|
+
overrides = _get_environ_overrides()
|
|
369
|
+
try:
|
|
370
|
+
with (base / _CONFIG_FILENAME).open() as file:
|
|
371
|
+
index = json.load(file)
|
|
372
|
+
except (OSError, json.JSONDecodeError):
|
|
373
|
+
should_write = True
|
|
374
|
+
index = generate_config_index(overrides)
|
|
375
|
+
|
|
376
|
+
for key in CONFIG_ELEMENTS:
|
|
377
|
+
if key.name not in index:
|
|
378
|
+
if key.kind in (ConfigElementType.DIR, ConfigElementType.FILE):
|
|
379
|
+
index[key.name] = base / key.default
|
|
380
|
+
else:
|
|
381
|
+
index[key.name] = key.default
|
|
382
|
+
should_write = True
|
|
383
|
+
|
|
384
|
+
if should_write:
|
|
385
|
+
try:
|
|
386
|
+
write_config(index, path=base)
|
|
387
|
+
except Exception as e:
|
|
388
|
+
sys.stderr.write(
|
|
389
|
+
"Error writing config to {}: {}\nProceeding memory-only\n".format(
|
|
390
|
+
str(base), e
|
|
391
|
+
)
|
|
392
|
+
)
|
|
393
|
+
index.update(overrides)
|
|
394
|
+
return cast(Dict[str, str], index)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _ensure_paths_and_types(index: Dict[str, str]) -> Dict[str, Path]:
|
|
398
|
+
"""Take the direct results of loading the config and make sure
|
|
399
|
+
the filesystem reflects them.
|
|
400
|
+
"""
|
|
401
|
+
configs_by_name = {ce.name: ce for ce in CONFIG_ELEMENTS}
|
|
402
|
+
correct_types: Dict[str, Path] = {}
|
|
403
|
+
for key, item in index.items():
|
|
404
|
+
if key not in configs_by_name: # old config, ignore
|
|
405
|
+
continue
|
|
406
|
+
if configs_by_name[key].kind == ConfigElementType.FILE:
|
|
407
|
+
it = Path(item)
|
|
408
|
+
it.parent.mkdir(parents=True, exist_ok=True)
|
|
409
|
+
correct_types[key] = it
|
|
410
|
+
elif configs_by_name[key].kind == ConfigElementType.DIR:
|
|
411
|
+
it = Path(item)
|
|
412
|
+
it.mkdir(parents=True, exist_ok=True)
|
|
413
|
+
correct_types[key] = it
|
|
414
|
+
else:
|
|
415
|
+
raise RuntimeError(
|
|
416
|
+
f"unhandled kind in ConfigElements: {key}: "
|
|
417
|
+
f"{configs_by_name[key].kind}"
|
|
418
|
+
)
|
|
419
|
+
return correct_types
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def _get_environ_overrides() -> Dict[str, str]:
|
|
423
|
+
"""Pull any overrides for the config elements from the environ and return
|
|
424
|
+
a mapping from the names to the values (as strings). Config elements that
|
|
425
|
+
are not overridden will not be in the mapping.
|
|
426
|
+
"""
|
|
427
|
+
return {
|
|
428
|
+
ce.name: os.environ["OT_API_" + ce.name.upper()]
|
|
429
|
+
for ce in CONFIG_ELEMENTS
|
|
430
|
+
if "OT_API_" + ce.name.upper() in os.environ
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def _legacy_index() -> Optional[Dict[str, str]]:
|
|
435
|
+
"""Try and load an index file from the various places it might exist.
|
|
436
|
+
|
|
437
|
+
If the legacy file cannot be found or cannot be parsed, return None.
|
|
438
|
+
|
|
439
|
+
This method should only be called on a robot.
|
|
440
|
+
"""
|
|
441
|
+
for index in _LEGACY_INDICES:
|
|
442
|
+
if index.exists():
|
|
443
|
+
try:
|
|
444
|
+
with open(index) as file:
|
|
445
|
+
return cast(Dict[str, str], json.load(file))
|
|
446
|
+
except (OSError, json.JSONDecodeError):
|
|
447
|
+
return None
|
|
448
|
+
return None
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def _erase_old_indices() -> None:
|
|
452
|
+
"""Remove old index files so they don't pollute future loads.
|
|
453
|
+
|
|
454
|
+
This method should only be called on a robot.
|
|
455
|
+
"""
|
|
456
|
+
for index in _LEGACY_INDICES:
|
|
457
|
+
if index.exists():
|
|
458
|
+
index.unlink()
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def _find_most_recent_backup(normal_path: Optional[str]) -> Optional[str]:
|
|
462
|
+
"""Find the most recent old settings to migrate.
|
|
463
|
+
|
|
464
|
+
The input is the path to an unqualified settings file - e.g.
|
|
465
|
+
/mnt/usbdrive/config/robotSettings.json
|
|
466
|
+
|
|
467
|
+
This will return
|
|
468
|
+
- None if the input is None (to support chaining from dict.get())
|
|
469
|
+
- The input if it exists, or
|
|
470
|
+
- The file named normal_path-TIMESTAMP.json with the highest timestamp
|
|
471
|
+
if one can be found, or
|
|
472
|
+
- None
|
|
473
|
+
"""
|
|
474
|
+
if normal_path is None:
|
|
475
|
+
return None
|
|
476
|
+
|
|
477
|
+
if os.path.exists(normal_path):
|
|
478
|
+
return normal_path
|
|
479
|
+
|
|
480
|
+
dirname, basename = os.path.split(normal_path)
|
|
481
|
+
root, ext = os.path.splitext(basename)
|
|
482
|
+
backups = [
|
|
483
|
+
fi for fi in os.listdir(dirname) if fi.startswith(root) and fi.endswith(ext)
|
|
484
|
+
]
|
|
485
|
+
ts_re = re.compile(r".*-([0-9]+)" + ext + "$")
|
|
486
|
+
|
|
487
|
+
def ts_compare(filename: str) -> int:
|
|
488
|
+
match = ts_re.match(filename)
|
|
489
|
+
if not match:
|
|
490
|
+
return -1
|
|
491
|
+
else:
|
|
492
|
+
return int(match.group(1))
|
|
493
|
+
|
|
494
|
+
backups_sorted = sorted(backups, key=ts_compare)
|
|
495
|
+
if not backups_sorted:
|
|
496
|
+
return None
|
|
497
|
+
return os.path.join(dirname, backups_sorted[-1])
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def _do_migrate(index: Dict[str, str]) -> None:
|
|
501
|
+
base = infer_config_base_dir()
|
|
502
|
+
new_index = generate_config_index(_get_environ_overrides(), base)
|
|
503
|
+
moves = (
|
|
504
|
+
(
|
|
505
|
+
"/data/user_storage/opentrons_data/opentrons.db",
|
|
506
|
+
new_index["labware_database_file"],
|
|
507
|
+
),
|
|
508
|
+
(
|
|
509
|
+
_find_most_recent_backup(index.get("robotSettingsFile")),
|
|
510
|
+
new_index["robot_settings_file"],
|
|
511
|
+
),
|
|
512
|
+
(index.get("deckCalibrationFile"), new_index["deck_calibration_file"]),
|
|
513
|
+
(index.get("featureFlagFile"), new_index["feature_flags_file"]),
|
|
514
|
+
)
|
|
515
|
+
sys.stdout.write(f"config migration: new base {base}\n")
|
|
516
|
+
for old, new in moves:
|
|
517
|
+
if not old:
|
|
518
|
+
continue
|
|
519
|
+
old_path = Path(old)
|
|
520
|
+
new_path = Path(new)
|
|
521
|
+
if old_path.exists() and not old_path.is_symlink():
|
|
522
|
+
sys.stdout.write(f"config migration: {old}->{new}\n")
|
|
523
|
+
if new_path.is_dir():
|
|
524
|
+
shutil.rmtree(new_path)
|
|
525
|
+
shutil.move(str(old_path), str(new_path))
|
|
526
|
+
else:
|
|
527
|
+
sys.stdout.write(f"config migration: not moving {old}:")
|
|
528
|
+
sys.stdout.write(f" exists={old_path.exists()}")
|
|
529
|
+
sys.stdout.write(f" symlink={old_path.is_symlink()}\n")
|
|
530
|
+
|
|
531
|
+
write_config(new_index, base)
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
def _migrate_robot() -> None:
|
|
535
|
+
old_index = _legacy_index()
|
|
536
|
+
if old_index:
|
|
537
|
+
_do_migrate(old_index)
|
|
538
|
+
_erase_old_indices()
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def generate_config_index(
|
|
542
|
+
defaults: Dict[str, str], base_dir: Optional[Path] = None
|
|
543
|
+
) -> Dict[str, Path]:
|
|
544
|
+
"""
|
|
545
|
+
Determines where existing info can be found in the system, and creates a
|
|
546
|
+
corresponding data dict that can be written to index.json in the
|
|
547
|
+
baseDataDir.
|
|
548
|
+
|
|
549
|
+
The information in the files defined by the config index is information
|
|
550
|
+
required by the API itself and nothing else - labware definitions, feature
|
|
551
|
+
flags, robot configurations. It does not include configuration files that
|
|
552
|
+
relate to the rest of the system, such as network description file
|
|
553
|
+
definitions.
|
|
554
|
+
|
|
555
|
+
:param defaults: A dict of defaults to write, useful for specifying part
|
|
556
|
+
(but not all) of the index succinctly. This is used both
|
|
557
|
+
when loading a configuration file from disk and when
|
|
558
|
+
generating a new one.
|
|
559
|
+
:param base_dir: If specified, a base path used if this function has to
|
|
560
|
+
generate defaults. If not specified, falls back to
|
|
561
|
+
:py:attr:`CONFIG_BASE_DIR`
|
|
562
|
+
:returns: The config object
|
|
563
|
+
"""
|
|
564
|
+
base = Path(base_dir) if base_dir else infer_config_base_dir()
|
|
565
|
+
|
|
566
|
+
def parse_or_default(ce: ConfigElement, val: Optional[str]) -> Path:
|
|
567
|
+
if not val:
|
|
568
|
+
return base / ce.default
|
|
569
|
+
else:
|
|
570
|
+
return Path(val)
|
|
571
|
+
|
|
572
|
+
return {
|
|
573
|
+
ce.name: parse_or_default(ce, defaults.get(ce.name)) for ce in CONFIG_ELEMENTS
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
def write_config(config_data: Dict[str, Path], path: Optional[Path] = None) -> None:
|
|
578
|
+
"""Save the config file.
|
|
579
|
+
|
|
580
|
+
:param config_data: The index to save
|
|
581
|
+
:param base_dir: The place to save the file. If ``None``,
|
|
582
|
+
:py:meth:`infer_config_base_dir()` will be used
|
|
583
|
+
|
|
584
|
+
Only keys that are in the config elements will be saved.
|
|
585
|
+
"""
|
|
586
|
+
path = Path(path) if path else infer_config_base_dir()
|
|
587
|
+
valid_names = [ce.name for ce in CONFIG_ELEMENTS]
|
|
588
|
+
try:
|
|
589
|
+
os.makedirs(path, exist_ok=True)
|
|
590
|
+
with (path / _CONFIG_FILENAME).open("w") as base_f:
|
|
591
|
+
json.dump(
|
|
592
|
+
{k: str(v) for k, v in config_data.items() if k in valid_names},
|
|
593
|
+
base_f,
|
|
594
|
+
indent=2,
|
|
595
|
+
)
|
|
596
|
+
except OSError as e:
|
|
597
|
+
sys.stderr.write(
|
|
598
|
+
"Config index write to {} failed: {}\n".format(path / _CONFIG_FILENAME, e)
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def reload() -> None:
|
|
603
|
+
global CONFIG
|
|
604
|
+
CONFIG.clear()
|
|
605
|
+
CONFIG.update(load_and_migrate())
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
def get_opentrons_path(path_name: str) -> Path:
|
|
609
|
+
# Helper function to look-up the path
|
|
610
|
+
# to specific configuration files for
|
|
611
|
+
# the Opentrons system
|
|
612
|
+
global CONFIG
|
|
613
|
+
return CONFIG[path_name]
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
CONFIG = load_and_migrate()
|
|
617
|
+
#: The currently loaded config. This should not change for the lifetime
|
|
618
|
+
#: of the program. This is a dict much like os.environ() where the keys
|
|
619
|
+
#: are config element names
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
def get_tip_length_cal_path() -> Path:
|
|
623
|
+
return get_opentrons_path("tip_length_calibration_dir")
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
def get_custom_tiprack_def_path() -> Path:
|
|
627
|
+
return get_opentrons_path("custom_tiprack_dir")
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
def get_performance_metrics_data_dir() -> Path:
|
|
631
|
+
return get_opentrons_path("performance_metrics_dir")
|