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,628 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, Optional, List, cast
|
|
3
|
+
from typing_extensions import Final
|
|
4
|
+
import math
|
|
5
|
+
import functools
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from opentrons.legacy_commands import types
|
|
10
|
+
from opentrons.protocols.api_support.deck_type import (
|
|
11
|
+
guess_from_global_config as guess_deck_type_from_global_config,
|
|
12
|
+
)
|
|
13
|
+
from opentrons.protocols.api_support.labware_like import LabwareLike
|
|
14
|
+
from opentrons.protocols.duration.errors import DurationEstimatorException
|
|
15
|
+
from opentrons.protocol_api.core.legacy.deck import Deck
|
|
16
|
+
from opentrons.types import Location
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# We refer to page 3 of the GEN2 Temperature Module White-Paper
|
|
20
|
+
# https://blog.opentrons.com/opentrons-technical-documentation/
|
|
21
|
+
# Through the data we notice that there are different
|
|
22
|
+
# rates of Celsius/second depending on temperature range.
|
|
23
|
+
# These were all tested to be ~95% consistent with the data
|
|
24
|
+
TEMP_MOD_RATE_HIGH_AND_ABOVE: Final = 0.3611111111
|
|
25
|
+
TEMP_MOD_RATE_LOW_TO_HIGH: Final = 0.2
|
|
26
|
+
TEMP_MOD_RATE_ZERO_TO_LOW: Final = 0.0875
|
|
27
|
+
TEMP_MOD_LOW_THRESH: Final = 25.0
|
|
28
|
+
TEMP_MOD_HIGH_THRESH: Final = 37.0
|
|
29
|
+
|
|
30
|
+
THERMO_LOW_THRESH: Final = 23.0
|
|
31
|
+
THERMO_HIGH_THRESH: Final = 70.0
|
|
32
|
+
|
|
33
|
+
START_MODULE_TEMPERATURE: Final = 25.0
|
|
34
|
+
|
|
35
|
+
STARTING_SLOT: Final[str] = "12"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
logger = logging.getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class TimerEntry:
|
|
43
|
+
command: types.CommandMessage
|
|
44
|
+
duration: float
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# TODO (al, 2021-09-09): Write doc strings for each method detailing how the
|
|
48
|
+
# duration is computed.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class DurationEstimator:
|
|
52
|
+
"""
|
|
53
|
+
Broker listener that calculates the duration of protocol steps.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(self) -> None:
|
|
57
|
+
# Which slot the last command was in.
|
|
58
|
+
self._last_deckslot = STARTING_SLOT
|
|
59
|
+
# todo(mm, 2021-09-08): Support protocols with more than one
|
|
60
|
+
# Temperature or Thermocycler Module.
|
|
61
|
+
self._last_temperature_module_temperature = START_MODULE_TEMPERATURE
|
|
62
|
+
self._last_thermocycler_module_temperature = START_MODULE_TEMPERATURE
|
|
63
|
+
# Per step time estimate.
|
|
64
|
+
self._increments: List[TimerEntry] = []
|
|
65
|
+
|
|
66
|
+
# TODO(mm, 2022-12-01): Allow the caller to configure the deck type.
|
|
67
|
+
self._deck = Deck(deck_type=guess_deck_type_from_global_config())
|
|
68
|
+
|
|
69
|
+
def get_total_duration(self) -> float:
|
|
70
|
+
"""Return the total duration"""
|
|
71
|
+
return functools.reduce(
|
|
72
|
+
lambda acc, val: acc + val.duration, self._increments, 0.0
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def on_message(self, message: types.CommandMessage) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Message handler for Broker events.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
message: A protocol message
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
None
|
|
84
|
+
"""
|
|
85
|
+
# Whether this message comes before or after the command is being executed..
|
|
86
|
+
if message["$"] != "after":
|
|
87
|
+
# We only want to process the afters.
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
# Extract the message name
|
|
91
|
+
message_name = message["name"]
|
|
92
|
+
# The actual payload of the command that varies by message.
|
|
93
|
+
payload = message["payload"]
|
|
94
|
+
|
|
95
|
+
location = payload.get("location")
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
duration = self.handle_message(message_name, payload)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise DurationEstimatorException(str(e))
|
|
101
|
+
|
|
102
|
+
if location:
|
|
103
|
+
slot = self.get_slot(location)
|
|
104
|
+
self._last_deckslot = slot if slot else self._last_deckslot
|
|
105
|
+
|
|
106
|
+
self._increments.append(
|
|
107
|
+
TimerEntry(
|
|
108
|
+
command=message,
|
|
109
|
+
duration=duration,
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def handle_message( # noqa: C901
|
|
114
|
+
self, message_name: str, payload: types.CommandPayload
|
|
115
|
+
) -> float:
|
|
116
|
+
"""
|
|
117
|
+
Handle the message payload
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
message_name: Name of message
|
|
121
|
+
payload: The command payload
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
The duration in seconds
|
|
125
|
+
"""
|
|
126
|
+
duration = 0.0
|
|
127
|
+
# TODO (al, 2021-09-09):
|
|
128
|
+
# - Make this into a map
|
|
129
|
+
# - Remove "noqa: C901"
|
|
130
|
+
if message_name == types.PICK_UP_TIP:
|
|
131
|
+
payload = cast(types.PickUpTipCommandPayload, payload)
|
|
132
|
+
duration = self.on_pick_up_tip(payload=payload)
|
|
133
|
+
elif message_name == types.DROP_TIP:
|
|
134
|
+
payload = cast(types.DropTipCommandPayload, payload)
|
|
135
|
+
duration = self.on_drop_tip(payload=payload)
|
|
136
|
+
elif message_name == types.ASPIRATE:
|
|
137
|
+
payload = cast(types.AspirateDispenseCommandPayload, payload)
|
|
138
|
+
duration = self.on_aspirate(payload=payload)
|
|
139
|
+
elif message_name == types.DISPENSE:
|
|
140
|
+
payload = cast(types.AspirateDispenseCommandPayload, payload)
|
|
141
|
+
duration = self.on_dispense(payload=payload)
|
|
142
|
+
elif message_name == types.BLOW_OUT:
|
|
143
|
+
payload = cast(types.BlowOutCommandPayload, payload)
|
|
144
|
+
duration = self.on_blow_out(payload=payload)
|
|
145
|
+
elif message_name == types.TOUCH_TIP:
|
|
146
|
+
payload = cast(types.TouchTipCommandPayload, payload)
|
|
147
|
+
duration = self.on_touch_tip()
|
|
148
|
+
elif message_name == types.DELAY:
|
|
149
|
+
payload = cast(types.DelayCommandPayload, payload)
|
|
150
|
+
duration = self.on_delay(payload=payload)
|
|
151
|
+
elif message_name == types.TEMPDECK_SET_TEMP:
|
|
152
|
+
payload = cast(types.TempdeckSetTempCommandPayload, payload)
|
|
153
|
+
duration = self.on_tempdeck_set_temp(payload=payload)
|
|
154
|
+
elif message_name == types.TEMPDECK_DEACTIVATE:
|
|
155
|
+
payload = cast(types.TempdeckDeactivateCommandPayload, payload)
|
|
156
|
+
duration = self.on_tempdeck_deactivate()
|
|
157
|
+
elif message_name == types.TEMPDECK_AWAIT_TEMP:
|
|
158
|
+
payload = cast(types.TempdeckAwaitTempCommandPayload, payload)
|
|
159
|
+
duration = self.on_tempdeck_await_temp()
|
|
160
|
+
elif message_name == types.THERMOCYCLER_SET_BLOCK_TEMP:
|
|
161
|
+
payload = cast(types.ThermocyclerSetBlockTempCommandPayload, payload)
|
|
162
|
+
duration = self.on_thermocycler_block_temp(payload=payload)
|
|
163
|
+
elif message_name == types.THERMOCYCLER_EXECUTE_PROFILE:
|
|
164
|
+
payload = cast(types.ThermocyclerExecuteProfileCommandPayload, payload)
|
|
165
|
+
duration = self.on_execute_profile(payload=payload)
|
|
166
|
+
elif message_name == types.THERMOCYCLER_SET_LID_TEMP:
|
|
167
|
+
duration = self.on_thermocycler_set_lid_temp()
|
|
168
|
+
elif message_name == types.THERMOCYCLER_CLOSE:
|
|
169
|
+
duration = self.on_thermocycler_lid_close()
|
|
170
|
+
elif message_name == types.THERMOCYCLER_DEACTIVATE_LID:
|
|
171
|
+
duration = self.on_thermocycler_deactivate_lid()
|
|
172
|
+
elif message_name == types.THERMOCYCLER_OPEN:
|
|
173
|
+
duration = self.on_thermocycler_lid_open()
|
|
174
|
+
elif message_name == types.TRANSFER:
|
|
175
|
+
# Already accounted for in other steps
|
|
176
|
+
pass
|
|
177
|
+
elif message_name == types.DISTRIBUTE:
|
|
178
|
+
pass
|
|
179
|
+
elif message_name == types.CONSOLIDATE:
|
|
180
|
+
pass
|
|
181
|
+
elif message_name == types.COMMENT:
|
|
182
|
+
pass
|
|
183
|
+
else:
|
|
184
|
+
logger.warning(
|
|
185
|
+
f"Command type '{message_name}' is not yet supported by the "
|
|
186
|
+
f"duration estimator."
|
|
187
|
+
)
|
|
188
|
+
return duration
|
|
189
|
+
|
|
190
|
+
def on_pick_up_tip(self, payload: types.PickUpTipCommandPayload) -> float:
|
|
191
|
+
"""Handle a pick up tip event"""
|
|
192
|
+
|
|
193
|
+
instrument = payload["instrument"]
|
|
194
|
+
location = payload["location"]
|
|
195
|
+
prev_slot = self._last_deckslot
|
|
196
|
+
curr_slot = self.get_slot(location)
|
|
197
|
+
|
|
198
|
+
gantry_speed = instrument.default_speed
|
|
199
|
+
|
|
200
|
+
deck_travel_time = self.calc_deck_movement_time(
|
|
201
|
+
self._deck, curr_slot, prev_slot, gantry_speed
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# The time to pick up tip is 4 seconds. Determined by testing on hardware.
|
|
205
|
+
duration = deck_travel_time + 4
|
|
206
|
+
|
|
207
|
+
logger.info(
|
|
208
|
+
f"{instrument.name} picked up tip from slot "
|
|
209
|
+
f"{curr_slot} the duration is {duration}"
|
|
210
|
+
)
|
|
211
|
+
return duration
|
|
212
|
+
|
|
213
|
+
def on_drop_tip(self, payload: types.DropTipCommandPayload) -> float:
|
|
214
|
+
|
|
215
|
+
instrument = payload["instrument"]
|
|
216
|
+
# We are going to once again use our "deck movement" set up. This should
|
|
217
|
+
# be in pickup, drop tip, aspirate, dispense
|
|
218
|
+
location = payload["location"]
|
|
219
|
+
curr_slot = self.get_slot(location)
|
|
220
|
+
# this one disagrees with me.
|
|
221
|
+
prev_slot = self._last_deckslot
|
|
222
|
+
gantry_speed = instrument.default_speed
|
|
223
|
+
deck_travel_time = self.calc_deck_movement_time(
|
|
224
|
+
self._deck, curr_slot, prev_slot, gantry_speed
|
|
225
|
+
)
|
|
226
|
+
# TODO (al, 2021-09-08): Should we be checking for drop tip home_after = False?
|
|
227
|
+
|
|
228
|
+
# The time to drop up tip is 10 seconds. Determined by testing on hardware.
|
|
229
|
+
duration = deck_travel_time + 10
|
|
230
|
+
|
|
231
|
+
# let's only log the message after the pick up tip is done.
|
|
232
|
+
logger.info(f"{instrument.name}, drop tip duration is {duration}")
|
|
233
|
+
return duration
|
|
234
|
+
|
|
235
|
+
def on_aspirate(self, payload: types.AspirateDispenseCommandPayload) -> float:
|
|
236
|
+
# General aspiration code
|
|
237
|
+
instrument = payload["instrument"]
|
|
238
|
+
volume = payload["volume"]
|
|
239
|
+
rate = payload["rate"] * instrument.flow_rate.aspirate
|
|
240
|
+
|
|
241
|
+
aspiration_time = volume / rate
|
|
242
|
+
|
|
243
|
+
# now lets handle the aspiration z-axis code.
|
|
244
|
+
location = payload["location"]
|
|
245
|
+
slot = self.get_slot(location)
|
|
246
|
+
|
|
247
|
+
gantry_speed = instrument.default_speed
|
|
248
|
+
z_total_time = self.z_time(
|
|
249
|
+
location.labware.parent.parent.is_module, gantry_speed
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# We are going to once again use our "deck movement" set up.
|
|
253
|
+
# Might be changed in future PR if our travel
|
|
254
|
+
# calculations adjust
|
|
255
|
+
# This should be in pickup, drop tip, aspirate, dispense
|
|
256
|
+
location = payload["location"]
|
|
257
|
+
prev_slot = self._last_deckslot
|
|
258
|
+
curr_slot = self.get_slot(location)
|
|
259
|
+
|
|
260
|
+
gantry_speed = instrument.default_speed
|
|
261
|
+
deck_travel_time = self.calc_deck_movement_time(
|
|
262
|
+
self._deck, curr_slot, prev_slot, gantry_speed
|
|
263
|
+
)
|
|
264
|
+
assert isinstance(aspiration_time, float)
|
|
265
|
+
duration = deck_travel_time + z_total_time + aspiration_time
|
|
266
|
+
logger.info(
|
|
267
|
+
f"{instrument.name} aspirate from {slot}, " f"the duration is {duration}"
|
|
268
|
+
)
|
|
269
|
+
return duration
|
|
270
|
+
|
|
271
|
+
def on_dispense(self, payload: types.AspirateDispenseCommandPayload) -> float:
|
|
272
|
+
# General code for aspiration/dispense
|
|
273
|
+
instrument = payload["instrument"]
|
|
274
|
+
volume = payload["volume"]
|
|
275
|
+
rate = payload["rate"] * instrument.flow_rate.dispense
|
|
276
|
+
dispense_time = volume / rate
|
|
277
|
+
|
|
278
|
+
# define variables
|
|
279
|
+
location = payload["location"]
|
|
280
|
+
slot = self.get_slot(location)
|
|
281
|
+
gantry_speed = instrument.default_speed
|
|
282
|
+
|
|
283
|
+
z_total_time = self.z_time(
|
|
284
|
+
location.labware.parent.parent.is_module, gantry_speed
|
|
285
|
+
)
|
|
286
|
+
# We are going to once again use our "deck movement" set up.
|
|
287
|
+
# This should be in pickup, drop tip, aspirate, dispense
|
|
288
|
+
location = payload["location"]
|
|
289
|
+
prev_slot = self._last_deckslot
|
|
290
|
+
curr_slot = self.get_slot(location)
|
|
291
|
+
|
|
292
|
+
gantry_speed = instrument.default_speed
|
|
293
|
+
deck_travel_time = self.calc_deck_movement_time(
|
|
294
|
+
self._deck, curr_slot, prev_slot, gantry_speed
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
assert isinstance(dispense_time, float)
|
|
298
|
+
duration = deck_travel_time + z_total_time + dispense_time
|
|
299
|
+
|
|
300
|
+
logger.info(
|
|
301
|
+
f"{instrument.name} dispensed from {slot}, the duration is {duration}"
|
|
302
|
+
)
|
|
303
|
+
return duration
|
|
304
|
+
|
|
305
|
+
def on_blow_out(self, payload: types.BlowOutCommandPayload) -> float:
|
|
306
|
+
location = payload["location"]
|
|
307
|
+
curr_slot = self.get_slot(location)
|
|
308
|
+
# In theory, we could use instrument.flow_rate.blow_out, but we don't
|
|
309
|
+
# know how much is in the tip left to blow out
|
|
310
|
+
# So we are defaulting to 0.5 seconds
|
|
311
|
+
duration = 0.5
|
|
312
|
+
logger.info(f"blowing_out_for {duration} seconds, in slot {curr_slot}")
|
|
313
|
+
return duration
|
|
314
|
+
|
|
315
|
+
def on_touch_tip(self) -> float:
|
|
316
|
+
# base assumption. Touch_tip takes 0.5 seconds This is consistent with a
|
|
317
|
+
# ~7.5mm diameter (default 60mm/s, 4 sides)
|
|
318
|
+
# plate = protocol.load_labware('corning_96_wellplate_360ul_flat', '1')
|
|
319
|
+
# depth = plate['A1'].diameter
|
|
320
|
+
# Then use the speed of the touch tip
|
|
321
|
+
# ( plate = protocol.load_labware('corning_96_wellplate_360ul_flat', '1')
|
|
322
|
+
# depth = plate['A1'].diameter
|
|
323
|
+
duration = 0.5
|
|
324
|
+
logger.info(f"touch_tip for {duration} seconds")
|
|
325
|
+
return duration
|
|
326
|
+
|
|
327
|
+
def on_delay(self, payload: types.DelayCommandPayload) -> float:
|
|
328
|
+
# Explanation: we are gathering seconds and minutes here
|
|
329
|
+
seconds_delay = payload["seconds"]
|
|
330
|
+
minutes_delay = payload["minutes"]
|
|
331
|
+
duration = seconds_delay + minutes_delay * 60
|
|
332
|
+
duration = float(duration)
|
|
333
|
+
# Note will need to multiply minutes by 60
|
|
334
|
+
logger.info(f"delay for {seconds_delay} seconds and {minutes_delay} minutes")
|
|
335
|
+
|
|
336
|
+
return duration
|
|
337
|
+
|
|
338
|
+
def on_thermocycler_block_temp(
|
|
339
|
+
self, payload: types.ThermocyclerSetBlockTempCommandPayload
|
|
340
|
+
) -> float:
|
|
341
|
+
temperature = payload["temperature"]
|
|
342
|
+
hold_time = payload["hold_time"]
|
|
343
|
+
temp0 = self._last_thermocycler_module_temperature
|
|
344
|
+
temp1 = temperature
|
|
345
|
+
# we are referring to a thermocycler_handler(temp0, temp1) function.
|
|
346
|
+
# Magic numbers come from testing and have been consistent
|
|
347
|
+
temperature_changing_time = self.thermocycler_handler(temp0, temp1)
|
|
348
|
+
if hold_time is None:
|
|
349
|
+
hold_time = 0
|
|
350
|
+
else:
|
|
351
|
+
hold_time = float(hold_time)
|
|
352
|
+
|
|
353
|
+
duration = temperature_changing_time + hold_time
|
|
354
|
+
# Note will need to multiply minutes by 60
|
|
355
|
+
logger.info(
|
|
356
|
+
f"hold for {hold_time} seconds and set temp for {temperature}"
|
|
357
|
+
f" C total duration {duration}"
|
|
358
|
+
)
|
|
359
|
+
duration = float(duration)
|
|
360
|
+
|
|
361
|
+
return duration
|
|
362
|
+
|
|
363
|
+
def on_execute_profile(
|
|
364
|
+
self, payload: types.ThermocyclerExecuteProfileCommandPayload
|
|
365
|
+
) -> float:
|
|
366
|
+
# Overview We need to run each time a temperature change happens
|
|
367
|
+
# through thermocycler_handler and multiply
|
|
368
|
+
# By the cycle count. Then we also (in parallel) do the same with delays
|
|
369
|
+
|
|
370
|
+
profile_total_steps = payload["steps"]
|
|
371
|
+
thermocycler_temperatures = [self._last_thermocycler_module_temperature]
|
|
372
|
+
thermocycler_hold_times = []
|
|
373
|
+
cycle_count = float(payload["text"].split(" ")[2])
|
|
374
|
+
|
|
375
|
+
# We are going to need to treat this theromcycler part a bit differently
|
|
376
|
+
# for a bit and just send out total times
|
|
377
|
+
for step in profile_total_steps:
|
|
378
|
+
thermocycler_temperatures.append(float(step["temperature"]))
|
|
379
|
+
thermocycler_hold_times.append(float(step["hold_time_seconds"]))
|
|
380
|
+
# Initializing variable
|
|
381
|
+
total_hold_time = float(cycle_count) * float(sum(thermocycler_hold_times))
|
|
382
|
+
# This takes care of the cumulative hold time
|
|
383
|
+
# WE DON't Have a way to deal with this currently in the way we
|
|
384
|
+
# have things set up.
|
|
385
|
+
cycling_counter = []
|
|
386
|
+
thermocycler_temperatures.pop(0)
|
|
387
|
+
for thermocycler_counter in range(0, len(thermocycler_temperatures)):
|
|
388
|
+
cycling_counter.append(
|
|
389
|
+
self.thermocycler_handler(
|
|
390
|
+
float(thermocycler_temperatures[thermocycler_counter - 1]),
|
|
391
|
+
float(thermocycler_temperatures[thermocycler_counter]),
|
|
392
|
+
)
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Sum hold time and cycling temp time
|
|
396
|
+
duration = float(sum(cycling_counter) + total_hold_time)
|
|
397
|
+
self._last_thermocycler_module_temperature = thermocycler_temperatures[-1]
|
|
398
|
+
|
|
399
|
+
cycling_counter = []
|
|
400
|
+
# Note will need to multiply minutes by 60
|
|
401
|
+
logger.info(
|
|
402
|
+
f"temperatures {sum(cycling_counter)}, "
|
|
403
|
+
f"hold_times {total_hold_time} , cycles are {cycle_count}, "
|
|
404
|
+
f"{duration}"
|
|
405
|
+
)
|
|
406
|
+
return duration
|
|
407
|
+
|
|
408
|
+
def on_thermocycler_set_lid_temp(self) -> float:
|
|
409
|
+
# Hardware said ~1 minute
|
|
410
|
+
duration = 60
|
|
411
|
+
thermoaction = "set lid temperature"
|
|
412
|
+
logger.info(f"thermocation = {thermoaction}")
|
|
413
|
+
return duration
|
|
414
|
+
|
|
415
|
+
def on_thermocycler_lid_close(self) -> float:
|
|
416
|
+
# Hardware said ~24 seconds
|
|
417
|
+
duration = 24
|
|
418
|
+
thermoaction = "closing"
|
|
419
|
+
logger.info(f"thermocation = {thermoaction}")
|
|
420
|
+
return duration
|
|
421
|
+
|
|
422
|
+
def on_thermocycler_lid_open(self) -> float:
|
|
423
|
+
# Hardware said ~24 seconds
|
|
424
|
+
duration = 24
|
|
425
|
+
thermoaction = "opening"
|
|
426
|
+
logger.info(f"thermocation = {thermoaction}")
|
|
427
|
+
return duration
|
|
428
|
+
|
|
429
|
+
def on_thermocycler_deactivate_lid(self) -> float:
|
|
430
|
+
# Hardware said ~23 seconds
|
|
431
|
+
duration = 23
|
|
432
|
+
thermoaction = "Deactivating"
|
|
433
|
+
logger.info(f"thermocation = {thermoaction}")
|
|
434
|
+
return duration
|
|
435
|
+
|
|
436
|
+
def on_tempdeck_set_temp(
|
|
437
|
+
self, payload: types.TempdeckSetTempCommandPayload
|
|
438
|
+
) -> float:
|
|
439
|
+
temperature_tempdeck = payload["celsius"]
|
|
440
|
+
temp0 = self._last_temperature_module_temperature
|
|
441
|
+
temp1 = float(temperature_tempdeck)
|
|
442
|
+
duration = self.temperature_module(temp0, temp1)
|
|
443
|
+
self._last_temperature_module_temperature = temp0
|
|
444
|
+
logger.info(f"tempdeck {duration} ")
|
|
445
|
+
return duration
|
|
446
|
+
|
|
447
|
+
def thermocycler_handler(self, temp0: float, temp1: float) -> float:
|
|
448
|
+
total = 0.0
|
|
449
|
+
if temp1 - temp0 > 0:
|
|
450
|
+
# heating up!
|
|
451
|
+
if temp1 > THERMO_HIGH_THRESH:
|
|
452
|
+
# the temp1 part that's over 70 is
|
|
453
|
+
total = abs(temp1 - THERMO_HIGH_THRESH) / 2
|
|
454
|
+
# the temp1 part that's under 70 is:
|
|
455
|
+
total += abs(THERMO_HIGH_THRESH - temp0) / 4
|
|
456
|
+
else:
|
|
457
|
+
total = abs(temp1 - temp0) / 4
|
|
458
|
+
# This is where the error is. if it's 10 and 94 this would not
|
|
459
|
+
# @Matt please look into this
|
|
460
|
+
elif temp1 - temp0 < 0:
|
|
461
|
+
if temp1 >= THERMO_HIGH_THRESH:
|
|
462
|
+
total = abs(temp1 - temp0) / 2
|
|
463
|
+
elif temp1 >= THERMO_LOW_THRESH:
|
|
464
|
+
total = abs(temp1 - temp0) / 1
|
|
465
|
+
else:
|
|
466
|
+
# 70 to 23 2 C/s
|
|
467
|
+
total = abs(temp0 - THERMO_LOW_THRESH) / 0.5
|
|
468
|
+
# 23 to temp1 0.1 C/s
|
|
469
|
+
total += abs(temp1 - THERMO_LOW_THRESH) / 0.1
|
|
470
|
+
|
|
471
|
+
return total
|
|
472
|
+
|
|
473
|
+
def temperature_module(self, temp0: float, temp1: float) -> float:
|
|
474
|
+
duration = 0.0
|
|
475
|
+
if temp1 != temp0:
|
|
476
|
+
if temp1 > TEMP_MOD_HIGH_THRESH:
|
|
477
|
+
duration = self.rate_high(temp0, temp1)
|
|
478
|
+
elif TEMP_MOD_LOW_THRESH <= temp1 <= TEMP_MOD_HIGH_THRESH:
|
|
479
|
+
duration = self.rate_mid(temp0, temp1)
|
|
480
|
+
elif temp1 < TEMP_MOD_LOW_THRESH:
|
|
481
|
+
duration = self.rate_low(temp0, temp1)
|
|
482
|
+
return duration
|
|
483
|
+
|
|
484
|
+
def on_tempdeck_deactivate(self) -> float:
|
|
485
|
+
# TODO (al, 2021-09-08: Find an answer for this value.
|
|
486
|
+
duration = 0.0
|
|
487
|
+
logger.info("tempdeck deactivating")
|
|
488
|
+
return duration
|
|
489
|
+
|
|
490
|
+
def on_tempdeck_await_temp(self) -> float:
|
|
491
|
+
# The duration is accounted for in set temperature
|
|
492
|
+
duration = 0.0
|
|
493
|
+
logger.info("tempdeck awaiting temperature")
|
|
494
|
+
return duration
|
|
495
|
+
|
|
496
|
+
@staticmethod
|
|
497
|
+
def get_slot(location: Any) -> Optional[str]:
|
|
498
|
+
"""A utility function to extract the slot number from the location."""
|
|
499
|
+
if isinstance(location, Location):
|
|
500
|
+
return location.labware.first_parent()
|
|
501
|
+
else:
|
|
502
|
+
return LabwareLike(location).first_parent()
|
|
503
|
+
|
|
504
|
+
@staticmethod
|
|
505
|
+
def calc_deck_movement_time(
|
|
506
|
+
deck: Deck, current_slot: Optional[str], previous_slot: str, gantry_speed: float
|
|
507
|
+
) -> float:
|
|
508
|
+
# Quick summary we set coordinates for each deck slot and found ways
|
|
509
|
+
# to move between deck slots.
|
|
510
|
+
# Each deck slot is a key for a coordinate value
|
|
511
|
+
# Moving between coordinate values
|
|
512
|
+
if not current_slot:
|
|
513
|
+
raise DurationEstimatorException(
|
|
514
|
+
f"Current slot '{current_slot}' is not valid."
|
|
515
|
+
)
|
|
516
|
+
|
|
517
|
+
previous_deck_center = deck.position_for(previous_slot)
|
|
518
|
+
if not previous_deck_center:
|
|
519
|
+
raise DurationEstimatorException(
|
|
520
|
+
f"Previous slot '{current_slot}' is not valid."
|
|
521
|
+
)
|
|
522
|
+
current_deck_center = deck.position_for(current_slot)
|
|
523
|
+
|
|
524
|
+
x_difference = abs(current_deck_center.point.x - previous_deck_center.point.x)
|
|
525
|
+
y_difference = abs(current_deck_center.point.y - previous_deck_center.point.y)
|
|
526
|
+
|
|
527
|
+
if x_difference == 0 and y_difference == 0:
|
|
528
|
+
# Inter slot movement defaults to half a second.
|
|
529
|
+
deck_movement_time = 0.5
|
|
530
|
+
else:
|
|
531
|
+
deck_distance = math.sqrt((x_difference**2) + (y_difference**2))
|
|
532
|
+
deck_movement_time = deck_distance / gantry_speed
|
|
533
|
+
return deck_movement_time
|
|
534
|
+
|
|
535
|
+
@staticmethod
|
|
536
|
+
def z_time(is_module: bool, gantry_speed: float) -> float:
|
|
537
|
+
# TODO (al, 2021-09-08): Use definitions from protocol context objects.
|
|
538
|
+
z_default_labware_height = 177.8
|
|
539
|
+
z_default_module_height = 95.25
|
|
540
|
+
# 177.8 - 82.55 Where did we get 177.8 from?
|
|
541
|
+
# Would it be better to just use
|
|
542
|
+
# protocol_api.labware.Well.top
|
|
543
|
+
# labware.top() ?
|
|
544
|
+
|
|
545
|
+
if is_module:
|
|
546
|
+
z_time = z_default_module_height / gantry_speed
|
|
547
|
+
else:
|
|
548
|
+
z_time = z_default_labware_height / gantry_speed
|
|
549
|
+
|
|
550
|
+
return z_time
|
|
551
|
+
|
|
552
|
+
@staticmethod
|
|
553
|
+
def rate_high(temp0: float, temp1: float) -> float:
|
|
554
|
+
"""
|
|
555
|
+
Calculate temp deck temperature change to a high temperature.
|
|
556
|
+
|
|
557
|
+
Args:
|
|
558
|
+
temp0: Current
|
|
559
|
+
temp1: Target
|
|
560
|
+
|
|
561
|
+
Returns:
|
|
562
|
+
Duration in seconds.
|
|
563
|
+
"""
|
|
564
|
+
val = 0.0
|
|
565
|
+
if temp0 >= TEMP_MOD_HIGH_THRESH:
|
|
566
|
+
val = abs(temp1 - temp0) / TEMP_MOD_RATE_HIGH_AND_ABOVE
|
|
567
|
+
elif TEMP_MOD_LOW_THRESH < temp0 < TEMP_MOD_HIGH_THRESH:
|
|
568
|
+
val = abs(temp0 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
|
|
569
|
+
val += abs(temp1 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_HIGH_AND_ABOVE
|
|
570
|
+
elif temp0 <= TEMP_MOD_LOW_THRESH:
|
|
571
|
+
# the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
|
|
572
|
+
val = abs(TEMP_MOD_LOW_THRESH - temp0) / TEMP_MOD_RATE_ZERO_TO_LOW
|
|
573
|
+
val += abs(TEMP_MOD_LOW_THRESH - temp1) / TEMP_MOD_RATE_HIGH_AND_ABOVE
|
|
574
|
+
|
|
575
|
+
return val
|
|
576
|
+
|
|
577
|
+
@staticmethod
|
|
578
|
+
def rate_mid(temp0: float, temp1: float) -> float:
|
|
579
|
+
"""
|
|
580
|
+
Calculate temp deck temperature change to a medium temperature.
|
|
581
|
+
|
|
582
|
+
Args:
|
|
583
|
+
temp0: Current
|
|
584
|
+
temp1: Target
|
|
585
|
+
|
|
586
|
+
Returns:
|
|
587
|
+
Duration in seconds.
|
|
588
|
+
"""
|
|
589
|
+
val = 0.0
|
|
590
|
+
if TEMP_MOD_LOW_THRESH <= temp0 <= TEMP_MOD_HIGH_THRESH:
|
|
591
|
+
val = abs(temp1 - temp0) / TEMP_MOD_RATE_LOW_TO_HIGH
|
|
592
|
+
elif temp0 < TEMP_MOD_LOW_THRESH:
|
|
593
|
+
# the temp1 part that's over TEMP_MOD_HIGH_THRESH is
|
|
594
|
+
val = abs(temp1 - TEMP_MOD_LOW_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
|
|
595
|
+
# the temp0 part that's under TEMP_MOD_HIGH_THRESH is:
|
|
596
|
+
val += abs(TEMP_MOD_LOW_THRESH - temp0) / TEMP_MOD_RATE_ZERO_TO_LOW
|
|
597
|
+
elif temp0 > TEMP_MOD_HIGH_THRESH:
|
|
598
|
+
val = abs(temp0 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_HIGH_AND_ABOVE
|
|
599
|
+
# the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
|
|
600
|
+
val += abs(TEMP_MOD_HIGH_THRESH - temp1) / TEMP_MOD_RATE_ZERO_TO_LOW
|
|
601
|
+
return val
|
|
602
|
+
|
|
603
|
+
# How to handle temperatures where one of them is low temp
|
|
604
|
+
@staticmethod
|
|
605
|
+
def rate_low(temp0: float, temp1: float) -> float:
|
|
606
|
+
"""
|
|
607
|
+
Calculate temp deck temperature change to a low temperature.
|
|
608
|
+
|
|
609
|
+
Args:
|
|
610
|
+
temp0: Current
|
|
611
|
+
temp1: Target
|
|
612
|
+
|
|
613
|
+
Returns:
|
|
614
|
+
Duration in seconds.
|
|
615
|
+
"""
|
|
616
|
+
val = 0.0
|
|
617
|
+
if temp0 <= TEMP_MOD_LOW_THRESH:
|
|
618
|
+
val = abs(temp1 - temp0) / TEMP_MOD_RATE_ZERO_TO_LOW
|
|
619
|
+
elif TEMP_MOD_LOW_THRESH < temp0 < TEMP_MOD_HIGH_THRESH:
|
|
620
|
+
# the temp0 part that's over TEMP_MOD_HIGH_THRESH is
|
|
621
|
+
val = abs(temp0 - TEMP_MOD_LOW_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
|
|
622
|
+
# the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
|
|
623
|
+
val += abs(TEMP_MOD_LOW_THRESH - temp1) / TEMP_MOD_RATE_ZERO_TO_LOW
|
|
624
|
+
elif temp0 >= TEMP_MOD_HIGH_THRESH:
|
|
625
|
+
val = abs(temp0 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
|
|
626
|
+
# the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
|
|
627
|
+
val += abs(TEMP_MOD_HIGH_THRESH - temp1) / TEMP_MOD_RATE_ZERO_TO_LOW
|
|
628
|
+
return val
|
|
File without changes
|