opentrons 8.6.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/__init__.py +150 -0
- opentrons/_version.py +34 -0
- opentrons/calibration_storage/__init__.py +54 -0
- opentrons/calibration_storage/deck_configuration.py +62 -0
- opentrons/calibration_storage/encoder_decoder.py +31 -0
- opentrons/calibration_storage/file_operators.py +142 -0
- opentrons/calibration_storage/helpers.py +103 -0
- opentrons/calibration_storage/ot2/__init__.py +34 -0
- opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
- opentrons/calibration_storage/ot2/models/__init__.py +0 -0
- opentrons/calibration_storage/ot2/models/v1.py +149 -0
- opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
- opentrons/calibration_storage/ot2/tip_length.py +281 -0
- opentrons/calibration_storage/ot3/__init__.py +31 -0
- opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
- opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
- opentrons/calibration_storage/ot3/models/__init__.py +0 -0
- opentrons/calibration_storage/ot3/models/v1.py +122 -0
- opentrons/calibration_storage/ot3/module_offset.py +138 -0
- opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
- opentrons/calibration_storage/types.py +45 -0
- opentrons/cli/__init__.py +21 -0
- opentrons/cli/__main__.py +5 -0
- opentrons/cli/analyze.py +501 -0
- opentrons/config/__init__.py +631 -0
- opentrons/config/advanced_settings.py +871 -0
- opentrons/config/defaults_ot2.py +214 -0
- opentrons/config/defaults_ot3.py +499 -0
- opentrons/config/feature_flags.py +86 -0
- opentrons/config/gripper_config.py +55 -0
- opentrons/config/reset.py +203 -0
- opentrons/config/robot_configs.py +187 -0
- opentrons/config/types.py +183 -0
- opentrons/drivers/__init__.py +0 -0
- opentrons/drivers/absorbance_reader/__init__.py +11 -0
- opentrons/drivers/absorbance_reader/abstract.py +72 -0
- opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
- opentrons/drivers/absorbance_reader/driver.py +81 -0
- opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
- opentrons/drivers/absorbance_reader/simulator.py +84 -0
- opentrons/drivers/asyncio/__init__.py +0 -0
- opentrons/drivers/asyncio/communication/__init__.py +22 -0
- opentrons/drivers/asyncio/communication/async_serial.py +183 -0
- opentrons/drivers/asyncio/communication/errors.py +88 -0
- opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
- opentrons/drivers/command_builder.py +102 -0
- opentrons/drivers/flex_stacker/__init__.py +13 -0
- opentrons/drivers/flex_stacker/abstract.py +214 -0
- opentrons/drivers/flex_stacker/driver.py +768 -0
- opentrons/drivers/flex_stacker/errors.py +68 -0
- opentrons/drivers/flex_stacker/simulator.py +309 -0
- opentrons/drivers/flex_stacker/types.py +367 -0
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/drivers/heater_shaker/__init__.py +5 -0
- opentrons/drivers/heater_shaker/abstract.py +76 -0
- opentrons/drivers/heater_shaker/driver.py +204 -0
- opentrons/drivers/heater_shaker/simulator.py +94 -0
- opentrons/drivers/mag_deck/__init__.py +6 -0
- opentrons/drivers/mag_deck/abstract.py +44 -0
- opentrons/drivers/mag_deck/driver.py +208 -0
- opentrons/drivers/mag_deck/simulator.py +63 -0
- opentrons/drivers/rpi_drivers/__init__.py +33 -0
- opentrons/drivers/rpi_drivers/dev_types.py +94 -0
- opentrons/drivers/rpi_drivers/gpio.py +282 -0
- opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
- opentrons/drivers/rpi_drivers/interfaces.py +15 -0
- opentrons/drivers/rpi_drivers/types.py +364 -0
- opentrons/drivers/rpi_drivers/usb.py +102 -0
- opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
- opentrons/drivers/serial_communication.py +151 -0
- opentrons/drivers/smoothie_drivers/__init__.py +4 -0
- opentrons/drivers/smoothie_drivers/connection.py +51 -0
- opentrons/drivers/smoothie_drivers/constants.py +121 -0
- opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
- opentrons/drivers/smoothie_drivers/errors.py +49 -0
- opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
- opentrons/drivers/smoothie_drivers/simulator.py +99 -0
- opentrons/drivers/smoothie_drivers/types.py +16 -0
- opentrons/drivers/temp_deck/__init__.py +10 -0
- opentrons/drivers/temp_deck/abstract.py +54 -0
- opentrons/drivers/temp_deck/driver.py +197 -0
- opentrons/drivers/temp_deck/simulator.py +57 -0
- opentrons/drivers/thermocycler/__init__.py +12 -0
- opentrons/drivers/thermocycler/abstract.py +99 -0
- opentrons/drivers/thermocycler/driver.py +395 -0
- opentrons/drivers/thermocycler/simulator.py +126 -0
- opentrons/drivers/types.py +107 -0
- opentrons/drivers/utils.py +222 -0
- opentrons/execute.py +742 -0
- opentrons/hardware_control/__init__.py +65 -0
- opentrons/hardware_control/__main__.py +77 -0
- opentrons/hardware_control/adapters.py +98 -0
- opentrons/hardware_control/api.py +1347 -0
- opentrons/hardware_control/backends/__init__.py +7 -0
- opentrons/hardware_control/backends/controller.py +400 -0
- opentrons/hardware_control/backends/errors.py +9 -0
- opentrons/hardware_control/backends/estop_state.py +164 -0
- opentrons/hardware_control/backends/flex_protocol.py +497 -0
- opentrons/hardware_control/backends/ot3controller.py +1930 -0
- opentrons/hardware_control/backends/ot3simulator.py +900 -0
- opentrons/hardware_control/backends/ot3utils.py +664 -0
- opentrons/hardware_control/backends/simulator.py +442 -0
- opentrons/hardware_control/backends/status_bar_state.py +240 -0
- opentrons/hardware_control/backends/subsystem_manager.py +431 -0
- opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
- opentrons/hardware_control/backends/types.py +14 -0
- opentrons/hardware_control/constants.py +6 -0
- opentrons/hardware_control/dev_types.py +125 -0
- opentrons/hardware_control/emulation/__init__.py +0 -0
- opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
- opentrons/hardware_control/emulation/app.py +56 -0
- opentrons/hardware_control/emulation/connection_handler.py +38 -0
- opentrons/hardware_control/emulation/heater_shaker.py +150 -0
- opentrons/hardware_control/emulation/magdeck.py +60 -0
- opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
- opentrons/hardware_control/emulation/module_server/client.py +78 -0
- opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
- opentrons/hardware_control/emulation/module_server/models.py +31 -0
- opentrons/hardware_control/emulation/module_server/server.py +110 -0
- opentrons/hardware_control/emulation/parser.py +74 -0
- opentrons/hardware_control/emulation/proxy.py +241 -0
- opentrons/hardware_control/emulation/run_emulator.py +68 -0
- opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
- opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
- opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
- opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
- opentrons/hardware_control/emulation/settings.py +119 -0
- opentrons/hardware_control/emulation/simulations.py +133 -0
- opentrons/hardware_control/emulation/smoothie.py +192 -0
- opentrons/hardware_control/emulation/tempdeck.py +69 -0
- opentrons/hardware_control/emulation/thermocycler.py +128 -0
- opentrons/hardware_control/emulation/types.py +10 -0
- opentrons/hardware_control/emulation/util.py +38 -0
- opentrons/hardware_control/errors.py +43 -0
- opentrons/hardware_control/execution_manager.py +164 -0
- opentrons/hardware_control/instruments/__init__.py +5 -0
- opentrons/hardware_control/instruments/instrument_abc.py +39 -0
- opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
- opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
- opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
- opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
- opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
- opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
- opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
- opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
- opentrons/hardware_control/module_control.py +332 -0
- opentrons/hardware_control/modules/__init__.py +69 -0
- opentrons/hardware_control/modules/absorbance_reader.py +373 -0
- opentrons/hardware_control/modules/errors.py +7 -0
- opentrons/hardware_control/modules/flex_stacker.py +948 -0
- opentrons/hardware_control/modules/heater_shaker.py +426 -0
- opentrons/hardware_control/modules/lid_temp_status.py +35 -0
- opentrons/hardware_control/modules/magdeck.py +233 -0
- opentrons/hardware_control/modules/mod_abc.py +245 -0
- opentrons/hardware_control/modules/module_calibration.py +93 -0
- opentrons/hardware_control/modules/plate_temp_status.py +61 -0
- opentrons/hardware_control/modules/tempdeck.py +299 -0
- opentrons/hardware_control/modules/thermocycler.py +731 -0
- opentrons/hardware_control/modules/types.py +417 -0
- opentrons/hardware_control/modules/update.py +255 -0
- opentrons/hardware_control/modules/utils.py +73 -0
- opentrons/hardware_control/motion_utilities.py +318 -0
- opentrons/hardware_control/nozzle_manager.py +422 -0
- opentrons/hardware_control/ot3_calibration.py +1171 -0
- opentrons/hardware_control/ot3api.py +3227 -0
- opentrons/hardware_control/pause_manager.py +31 -0
- opentrons/hardware_control/poller.py +112 -0
- opentrons/hardware_control/protocols/__init__.py +106 -0
- opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
- opentrons/hardware_control/protocols/calibratable.py +45 -0
- opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
- opentrons/hardware_control/protocols/configurable.py +48 -0
- opentrons/hardware_control/protocols/event_sourcer.py +18 -0
- opentrons/hardware_control/protocols/execution_controllable.py +33 -0
- opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
- opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
- opentrons/hardware_control/protocols/gripper_controller.py +55 -0
- opentrons/hardware_control/protocols/hardware_manager.py +51 -0
- opentrons/hardware_control/protocols/identifiable.py +16 -0
- opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
- opentrons/hardware_control/protocols/liquid_handler.py +266 -0
- opentrons/hardware_control/protocols/module_provider.py +16 -0
- opentrons/hardware_control/protocols/motion_controller.py +243 -0
- opentrons/hardware_control/protocols/position_estimator.py +45 -0
- opentrons/hardware_control/protocols/simulatable.py +10 -0
- opentrons/hardware_control/protocols/stoppable.py +9 -0
- opentrons/hardware_control/protocols/types.py +27 -0
- opentrons/hardware_control/robot_calibration.py +224 -0
- opentrons/hardware_control/scripts/README.md +28 -0
- opentrons/hardware_control/scripts/__init__.py +1 -0
- opentrons/hardware_control/scripts/gripper_control.py +208 -0
- opentrons/hardware_control/scripts/ot3gripper +7 -0
- opentrons/hardware_control/scripts/ot3repl +7 -0
- opentrons/hardware_control/scripts/repl.py +187 -0
- opentrons/hardware_control/scripts/tc_control.py +97 -0
- opentrons/hardware_control/simulator_setup.py +260 -0
- opentrons/hardware_control/thread_manager.py +431 -0
- opentrons/hardware_control/threaded_async_lock.py +97 -0
- opentrons/hardware_control/types.py +792 -0
- opentrons/hardware_control/util.py +234 -0
- opentrons/legacy_broker.py +53 -0
- opentrons/legacy_commands/__init__.py +1 -0
- opentrons/legacy_commands/commands.py +483 -0
- opentrons/legacy_commands/helpers.py +153 -0
- opentrons/legacy_commands/module_commands.py +215 -0
- opentrons/legacy_commands/protocol_commands.py +54 -0
- opentrons/legacy_commands/publisher.py +155 -0
- opentrons/legacy_commands/robot_commands.py +51 -0
- opentrons/legacy_commands/types.py +1115 -0
- opentrons/motion_planning/__init__.py +32 -0
- opentrons/motion_planning/adjacent_slots_getters.py +168 -0
- opentrons/motion_planning/deck_conflict.py +396 -0
- opentrons/motion_planning/errors.py +35 -0
- opentrons/motion_planning/types.py +42 -0
- opentrons/motion_planning/waypoints.py +218 -0
- opentrons/ordered_set.py +138 -0
- opentrons/protocol_api/__init__.py +105 -0
- opentrons/protocol_api/_liquid.py +157 -0
- opentrons/protocol_api/_liquid_properties.py +814 -0
- opentrons/protocol_api/_nozzle_layout.py +31 -0
- opentrons/protocol_api/_parameter_context.py +300 -0
- opentrons/protocol_api/_parameters.py +31 -0
- opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
- opentrons/protocol_api/_types.py +43 -0
- opentrons/protocol_api/config.py +23 -0
- opentrons/protocol_api/core/__init__.py +23 -0
- opentrons/protocol_api/core/common.py +33 -0
- opentrons/protocol_api/core/core_map.py +74 -0
- opentrons/protocol_api/core/engine/__init__.py +22 -0
- opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
- opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
- opentrons/protocol_api/core/engine/exceptions.py +19 -0
- opentrons/protocol_api/core/engine/instrument.py +2391 -0
- opentrons/protocol_api/core/engine/labware.py +238 -0
- opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
- opentrons/protocol_api/core/engine/module_core.py +1025 -0
- opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
- opentrons/protocol_api/core/engine/point_calculations.py +64 -0
- opentrons/protocol_api/core/engine/protocol.py +1153 -0
- opentrons/protocol_api/core/engine/robot.py +139 -0
- opentrons/protocol_api/core/engine/stringify.py +74 -0
- opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
- opentrons/protocol_api/core/engine/well.py +241 -0
- opentrons/protocol_api/core/instrument.py +459 -0
- opentrons/protocol_api/core/labware.py +151 -0
- opentrons/protocol_api/core/legacy/__init__.py +11 -0
- opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
- opentrons/protocol_api/core/legacy/deck.py +369 -0
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
- opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
- opentrons/protocol_api/core/legacy/load_info.py +67 -0
- opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
- opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
- opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
- opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
- opentrons/protocol_api/core/module.py +484 -0
- opentrons/protocol_api/core/protocol.py +311 -0
- opentrons/protocol_api/core/robot.py +51 -0
- opentrons/protocol_api/core/well.py +116 -0
- opentrons/protocol_api/core/well_grid.py +45 -0
- opentrons/protocol_api/create_protocol_context.py +177 -0
- opentrons/protocol_api/deck.py +223 -0
- opentrons/protocol_api/disposal_locations.py +244 -0
- opentrons/protocol_api/instrument_context.py +3212 -0
- opentrons/protocol_api/labware.py +1579 -0
- opentrons/protocol_api/module_contexts.py +1425 -0
- opentrons/protocol_api/module_validation_and_errors.py +61 -0
- opentrons/protocol_api/protocol_context.py +1688 -0
- opentrons/protocol_api/robot_context.py +303 -0
- opentrons/protocol_api/validation.py +761 -0
- opentrons/protocol_engine/__init__.py +155 -0
- opentrons/protocol_engine/actions/__init__.py +65 -0
- opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
- opentrons/protocol_engine/actions/action_handler.py +13 -0
- opentrons/protocol_engine/actions/actions.py +302 -0
- opentrons/protocol_engine/actions/get_state_update.py +38 -0
- opentrons/protocol_engine/clients/__init__.py +5 -0
- opentrons/protocol_engine/clients/sync_client.py +174 -0
- opentrons/protocol_engine/clients/transports.py +197 -0
- opentrons/protocol_engine/commands/__init__.py +757 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
- opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
- opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
- opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
- opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
- opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
- opentrons/protocol_engine/commands/aspirate.py +244 -0
- opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
- opentrons/protocol_engine/commands/blow_out.py +146 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
- opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
- opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
- opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
- opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
- opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
- opentrons/protocol_engine/commands/command.py +308 -0
- opentrons/protocol_engine/commands/command_unions.py +974 -0
- opentrons/protocol_engine/commands/comment.py +57 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
- opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
- opentrons/protocol_engine/commands/custom.py +67 -0
- opentrons/protocol_engine/commands/dispense.py +194 -0
- opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +232 -0
- opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
- opentrons/protocol_engine/commands/get_next_tip.py +134 -0
- opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
- opentrons/protocol_engine/commands/hash_command_params.py +38 -0
- opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
- opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
- opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
- opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
- opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
- opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
- opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
- opentrons/protocol_engine/commands/home.py +100 -0
- opentrons/protocol_engine/commands/identify_module.py +86 -0
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +464 -0
- opentrons/protocol_engine/commands/load_labware.py +210 -0
- opentrons/protocol_engine/commands/load_lid.py +154 -0
- opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
- opentrons/protocol_engine/commands/load_liquid.py +95 -0
- opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
- opentrons/protocol_engine/commands/load_module.py +223 -0
- opentrons/protocol_engine/commands/load_pipette.py +167 -0
- opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
- opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
- opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
- opentrons/protocol_engine/commands/move_labware.py +546 -0
- opentrons/protocol_engine/commands/move_relative.py +102 -0
- opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
- opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
- opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
- opentrons/protocol_engine/commands/move_to_well.py +119 -0
- opentrons/protocol_engine/commands/movement_common.py +338 -0
- opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
- opentrons/protocol_engine/commands/pipetting_common.py +443 -0
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
- opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
- opentrons/protocol_engine/commands/reload_labware.py +90 -0
- opentrons/protocol_engine/commands/retract_axis.py +75 -0
- opentrons/protocol_engine/commands/robot/__init__.py +70 -0
- opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
- opentrons/protocol_engine/commands/robot/common.py +18 -0
- opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
- opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
- opentrons/protocol_engine/commands/robot/move_to.py +94 -0
- opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
- opentrons/protocol_engine/commands/save_position.py +109 -0
- opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
- opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
- opentrons/protocol_engine/commands/set_status_bar.py +89 -0
- opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
- opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
- opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
- opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
- opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
- opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
- opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
- opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
- opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
- opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
- opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
- opentrons/protocol_engine/commands/touch_tip.py +189 -0
- opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
- opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
- opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
- opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
- opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
- opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
- opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
- opentrons/protocol_engine/create_protocol_engine.py +193 -0
- opentrons/protocol_engine/engine_support.py +28 -0
- opentrons/protocol_engine/error_recovery_policy.py +81 -0
- opentrons/protocol_engine/errors/__init__.py +191 -0
- opentrons/protocol_engine/errors/error_occurrence.py +182 -0
- opentrons/protocol_engine/errors/exceptions.py +1308 -0
- opentrons/protocol_engine/execution/__init__.py +50 -0
- opentrons/protocol_engine/execution/command_executor.py +216 -0
- opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
- opentrons/protocol_engine/execution/door_watcher.py +119 -0
- opentrons/protocol_engine/execution/equipment.py +819 -0
- opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
- opentrons/protocol_engine/execution/gantry_mover.py +686 -0
- opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
- opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
- opentrons/protocol_engine/execution/labware_movement.py +297 -0
- opentrons/protocol_engine/execution/movement.py +349 -0
- opentrons/protocol_engine/execution/pipetting.py +607 -0
- opentrons/protocol_engine/execution/queue_worker.py +86 -0
- opentrons/protocol_engine/execution/rail_lights.py +25 -0
- opentrons/protocol_engine/execution/run_control.py +33 -0
- opentrons/protocol_engine/execution/status_bar.py +34 -0
- opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
- opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
- opentrons/protocol_engine/execution/tip_handler.py +550 -0
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/notes/__init__.py +17 -0
- opentrons/protocol_engine/notes/notes.py +59 -0
- opentrons/protocol_engine/plugins.py +104 -0
- opentrons/protocol_engine/protocol_engine.py +683 -0
- opentrons/protocol_engine/resources/__init__.py +26 -0
- opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
- opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
- opentrons/protocol_engine/resources/file_provider.py +161 -0
- opentrons/protocol_engine/resources/fixture_validation.py +58 -0
- opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
- opentrons/protocol_engine/resources/labware_validation.py +73 -0
- opentrons/protocol_engine/resources/model_utils.py +32 -0
- opentrons/protocol_engine/resources/module_data_provider.py +44 -0
- opentrons/protocol_engine/resources/ot3_validation.py +21 -0
- opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
- opentrons/protocol_engine/slot_standardization.py +128 -0
- opentrons/protocol_engine/state/__init__.py +1 -0
- opentrons/protocol_engine/state/_abstract_store.py +27 -0
- opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
- opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
- opentrons/protocol_engine/state/_move_types.py +83 -0
- opentrons/protocol_engine/state/_well_math.py +193 -0
- opentrons/protocol_engine/state/addressable_areas.py +699 -0
- opentrons/protocol_engine/state/command_history.py +309 -0
- opentrons/protocol_engine/state/commands.py +1158 -0
- opentrons/protocol_engine/state/config.py +39 -0
- opentrons/protocol_engine/state/files.py +57 -0
- opentrons/protocol_engine/state/fluid_stack.py +138 -0
- opentrons/protocol_engine/state/geometry.py +2359 -0
- opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
- opentrons/protocol_engine/state/labware.py +1459 -0
- opentrons/protocol_engine/state/liquid_classes.py +82 -0
- opentrons/protocol_engine/state/liquids.py +73 -0
- opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
- opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
- opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
- opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
- opentrons/protocol_engine/state/modules.py +1500 -0
- opentrons/protocol_engine/state/motion.py +373 -0
- opentrons/protocol_engine/state/pipettes.py +905 -0
- opentrons/protocol_engine/state/state.py +421 -0
- opentrons/protocol_engine/state/state_summary.py +36 -0
- opentrons/protocol_engine/state/tips.py +420 -0
- opentrons/protocol_engine/state/update_types.py +904 -0
- opentrons/protocol_engine/state/wells.py +290 -0
- opentrons/protocol_engine/types/__init__.py +308 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +81 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +131 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +303 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/__init__.py +37 -0
- opentrons/protocol_reader/extract_labware_definitions.py +66 -0
- opentrons/protocol_reader/file_format_validator.py +152 -0
- opentrons/protocol_reader/file_hasher.py +27 -0
- opentrons/protocol_reader/file_identifier.py +284 -0
- opentrons/protocol_reader/file_reader_writer.py +90 -0
- opentrons/protocol_reader/input_file.py +16 -0
- opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
- opentrons/protocol_reader/protocol_reader.py +188 -0
- opentrons/protocol_reader/protocol_source.py +124 -0
- opentrons/protocol_reader/role_analyzer.py +86 -0
- opentrons/protocol_runner/__init__.py +26 -0
- opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
- opentrons/protocol_runner/json_file_reader.py +55 -0
- opentrons/protocol_runner/json_translator.py +314 -0
- opentrons/protocol_runner/legacy_command_mapper.py +848 -0
- opentrons/protocol_runner/legacy_context_plugin.py +116 -0
- opentrons/protocol_runner/protocol_runner.py +530 -0
- opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
- opentrons/protocol_runner/run_orchestrator.py +496 -0
- opentrons/protocol_runner/task_queue.py +95 -0
- opentrons/protocols/__init__.py +6 -0
- opentrons/protocols/advanced_control/__init__.py +0 -0
- opentrons/protocols/advanced_control/common.py +38 -0
- opentrons/protocols/advanced_control/mix.py +60 -0
- opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
- opentrons/protocols/advanced_control/transfers/common.py +180 -0
- opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
- opentrons/protocols/api_support/__init__.py +0 -0
- opentrons/protocols/api_support/constants.py +8 -0
- opentrons/protocols/api_support/deck_type.py +110 -0
- opentrons/protocols/api_support/definitions.py +18 -0
- opentrons/protocols/api_support/instrument.py +151 -0
- opentrons/protocols/api_support/labware_like.py +233 -0
- opentrons/protocols/api_support/tip_tracker.py +175 -0
- opentrons/protocols/api_support/types.py +32 -0
- opentrons/protocols/api_support/util.py +403 -0
- opentrons/protocols/bundle.py +89 -0
- opentrons/protocols/duration/__init__.py +4 -0
- opentrons/protocols/duration/errors.py +5 -0
- opentrons/protocols/duration/estimator.py +628 -0
- opentrons/protocols/execution/__init__.py +0 -0
- opentrons/protocols/execution/dev_types.py +181 -0
- opentrons/protocols/execution/errors.py +40 -0
- opentrons/protocols/execution/execute.py +84 -0
- opentrons/protocols/execution/execute_json_v3.py +275 -0
- opentrons/protocols/execution/execute_json_v4.py +359 -0
- opentrons/protocols/execution/execute_json_v5.py +28 -0
- opentrons/protocols/execution/execute_python.py +169 -0
- opentrons/protocols/execution/json_dispatchers.py +87 -0
- opentrons/protocols/execution/types.py +7 -0
- opentrons/protocols/geometry/__init__.py +0 -0
- opentrons/protocols/geometry/planning.py +297 -0
- opentrons/protocols/labware.py +312 -0
- opentrons/protocols/models/__init__.py +0 -0
- opentrons/protocols/models/json_protocol.py +679 -0
- opentrons/protocols/parameters/__init__.py +0 -0
- opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
- opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
- opentrons/protocols/parameters/exceptions.py +34 -0
- opentrons/protocols/parameters/parameter_definition.py +272 -0
- opentrons/protocols/parameters/types.py +17 -0
- opentrons/protocols/parameters/validation.py +267 -0
- opentrons/protocols/parse.py +671 -0
- opentrons/protocols/types.py +159 -0
- opentrons/py.typed +0 -0
- opentrons/resources/scripts/lpc21isp +0 -0
- opentrons/resources/smoothie-edge-8414642.hex +23010 -0
- opentrons/simulate.py +1065 -0
- opentrons/system/__init__.py +6 -0
- opentrons/system/camera.py +51 -0
- opentrons/system/log_control.py +59 -0
- opentrons/system/nmcli.py +856 -0
- opentrons/system/resin.py +24 -0
- opentrons/system/smoothie_update.py +15 -0
- opentrons/system/wifi.py +204 -0
- opentrons/tools/__init__.py +0 -0
- opentrons/tools/args_handler.py +22 -0
- opentrons/tools/write_pipette_memory.py +157 -0
- opentrons/types.py +618 -0
- opentrons/util/__init__.py +1 -0
- opentrons/util/async_helpers.py +166 -0
- opentrons/util/broker.py +84 -0
- opentrons/util/change_notifier.py +47 -0
- opentrons/util/entrypoint_util.py +278 -0
- opentrons/util/get_union_elements.py +26 -0
- opentrons/util/helpers.py +6 -0
- opentrons/util/linal.py +178 -0
- opentrons/util/logging_config.py +265 -0
- opentrons/util/logging_queue_handler.py +61 -0
- opentrons/util/performance_helpers.py +157 -0
- opentrons-8.6.0a1.dist-info/METADATA +37 -0
- opentrons-8.6.0a1.dist-info/RECORD +600 -0
- opentrons-8.6.0a1.dist-info/WHEEL +4 -0
- opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
- opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import logging
|
|
5
|
+
from typing import Optional, List, Type
|
|
6
|
+
|
|
7
|
+
from opentrons.drivers.command_builder import CommandBuilder
|
|
8
|
+
|
|
9
|
+
from .errors import (
|
|
10
|
+
NoResponse,
|
|
11
|
+
AlarmResponse,
|
|
12
|
+
ErrorResponse,
|
|
13
|
+
BaseErrorCode,
|
|
14
|
+
DefaultErrorCodes,
|
|
15
|
+
)
|
|
16
|
+
from .async_serial import AsyncSerial
|
|
17
|
+
|
|
18
|
+
log = logging.getLogger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SerialConnection:
|
|
22
|
+
@classmethod
|
|
23
|
+
async def _build_serial(
|
|
24
|
+
cls,
|
|
25
|
+
port: str,
|
|
26
|
+
baud_rate: int,
|
|
27
|
+
timeout: float,
|
|
28
|
+
loop: Optional[asyncio.AbstractEventLoop],
|
|
29
|
+
reset_buffer_before_write: bool,
|
|
30
|
+
) -> AsyncSerial:
|
|
31
|
+
return await AsyncSerial.create(
|
|
32
|
+
port=port,
|
|
33
|
+
baud_rate=baud_rate,
|
|
34
|
+
timeout=timeout,
|
|
35
|
+
loop=loop,
|
|
36
|
+
reset_buffer_before_write=reset_buffer_before_write,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
async def create(
|
|
41
|
+
cls,
|
|
42
|
+
port: str,
|
|
43
|
+
baud_rate: int,
|
|
44
|
+
timeout: float,
|
|
45
|
+
ack: str,
|
|
46
|
+
name: Optional[str] = None,
|
|
47
|
+
retry_wait_time_seconds: float = 0.1,
|
|
48
|
+
loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
49
|
+
error_keyword: Optional[str] = None,
|
|
50
|
+
alarm_keyword: Optional[str] = None,
|
|
51
|
+
reset_buffer_before_write: bool = False,
|
|
52
|
+
error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
|
|
53
|
+
) -> "SerialConnection":
|
|
54
|
+
"""
|
|
55
|
+
Create a connection.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
port: url or port to connect to
|
|
59
|
+
baud_rate: baud rate
|
|
60
|
+
timeout: timeout in seconds
|
|
61
|
+
ack: the command response ack
|
|
62
|
+
name: the connection name
|
|
63
|
+
retry_wait_time_seconds: how long to wait between retries.
|
|
64
|
+
loop: optional event loop.
|
|
65
|
+
error_keyword: optional string that will cause an
|
|
66
|
+
ErrorResponse exception when detected
|
|
67
|
+
(default: error)
|
|
68
|
+
alarm_keyword: optional string that will cause an
|
|
69
|
+
AlarmResponse exception when detected
|
|
70
|
+
(default: alarm)
|
|
71
|
+
reset_buffer_before_write: whether to reset the read buffer before
|
|
72
|
+
every write
|
|
73
|
+
error_codes: Enum class for error codes
|
|
74
|
+
(default: DefaultErrorCodes)
|
|
75
|
+
|
|
76
|
+
Returns: SerialConnection
|
|
77
|
+
"""
|
|
78
|
+
serial = await cls._build_serial(
|
|
79
|
+
port=port,
|
|
80
|
+
baud_rate=baud_rate,
|
|
81
|
+
timeout=timeout,
|
|
82
|
+
loop=loop,
|
|
83
|
+
reset_buffer_before_write=reset_buffer_before_write,
|
|
84
|
+
)
|
|
85
|
+
name = name or port
|
|
86
|
+
obj = cls(
|
|
87
|
+
serial=serial,
|
|
88
|
+
port=port,
|
|
89
|
+
name=name,
|
|
90
|
+
ack=ack,
|
|
91
|
+
retry_wait_time_seconds=retry_wait_time_seconds,
|
|
92
|
+
error_keyword=error_keyword or "error",
|
|
93
|
+
alarm_keyword=alarm_keyword or "alarm",
|
|
94
|
+
error_codes=error_codes,
|
|
95
|
+
)
|
|
96
|
+
await obj.flush_input()
|
|
97
|
+
return obj
|
|
98
|
+
|
|
99
|
+
def __init__(
|
|
100
|
+
self,
|
|
101
|
+
serial: AsyncSerial,
|
|
102
|
+
port: str,
|
|
103
|
+
name: str,
|
|
104
|
+
ack: str,
|
|
105
|
+
retry_wait_time_seconds: float,
|
|
106
|
+
error_keyword: str,
|
|
107
|
+
alarm_keyword: str,
|
|
108
|
+
error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""
|
|
111
|
+
Constructor
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
serial: AsyncSerial object
|
|
115
|
+
port: url or port to connect to
|
|
116
|
+
ack: the command response ack
|
|
117
|
+
name: the connection name
|
|
118
|
+
retry_wait_time_seconds: how long to wait between retries.
|
|
119
|
+
error_keyword: string that will cause an ErrorResponse
|
|
120
|
+
exception when detected
|
|
121
|
+
alarm_keyword: string that will cause an AlarmResponse
|
|
122
|
+
exception when detected
|
|
123
|
+
error_codes: Enum class for error codes
|
|
124
|
+
"""
|
|
125
|
+
self._serial = serial
|
|
126
|
+
self._port = port
|
|
127
|
+
self._name = name
|
|
128
|
+
self._ack = ack.encode()
|
|
129
|
+
self._retry_wait_time_seconds = retry_wait_time_seconds
|
|
130
|
+
self._send_data_lock = asyncio.Lock()
|
|
131
|
+
self._error_keyword = error_keyword.lower()
|
|
132
|
+
self._alarm_keyword = alarm_keyword.lower()
|
|
133
|
+
self._error_codes = error_codes
|
|
134
|
+
|
|
135
|
+
async def send_command(
|
|
136
|
+
self, command: CommandBuilder, retries: int = 0, timeout: Optional[float] = None
|
|
137
|
+
) -> str:
|
|
138
|
+
"""
|
|
139
|
+
Send a command and return the response.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
command: A command builder.
|
|
143
|
+
retries: number of times to retry in case of timeout
|
|
144
|
+
timeout: optional override of default timeout in seconds
|
|
145
|
+
|
|
146
|
+
Returns: The command response
|
|
147
|
+
|
|
148
|
+
Raises: SerialException
|
|
149
|
+
"""
|
|
150
|
+
return await self.send_data(
|
|
151
|
+
data=command.build(), retries=retries, timeout=timeout
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
async def send_dfu_command(self, command: CommandBuilder) -> None:
|
|
155
|
+
"""
|
|
156
|
+
Send a dfu command to enter device bootloader.
|
|
157
|
+
|
|
158
|
+
This method doesn't wait for a response after sending the command since the
|
|
159
|
+
module port gets disconnected once it enters its bootloader.
|
|
160
|
+
"""
|
|
161
|
+
encoded_command = command.build().encode()
|
|
162
|
+
|
|
163
|
+
async with self._send_data_lock:
|
|
164
|
+
log.debug(f"{self.name}: Write -> {encoded_command!r}")
|
|
165
|
+
await self._serial.write(data=encoded_command)
|
|
166
|
+
|
|
167
|
+
async def send_data(
|
|
168
|
+
self, data: str, retries: int = 0, timeout: Optional[float] = None
|
|
169
|
+
) -> str:
|
|
170
|
+
"""
|
|
171
|
+
Send data and return the response.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
data: The data to send.
|
|
175
|
+
retries: number of times to retry in case of timeout
|
|
176
|
+
timeout: optional override of default timeout in seconds
|
|
177
|
+
|
|
178
|
+
Returns: The command response
|
|
179
|
+
|
|
180
|
+
Raises: SerialException
|
|
181
|
+
"""
|
|
182
|
+
async with self._send_data_lock, self._serial.timeout_override(
|
|
183
|
+
"timeout", timeout
|
|
184
|
+
):
|
|
185
|
+
return await self._send_data(data=data, retries=retries)
|
|
186
|
+
|
|
187
|
+
async def _send_data(self, data: str, retries: int = 0) -> str:
|
|
188
|
+
"""
|
|
189
|
+
Send data and return the response.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
data: The data to send.
|
|
193
|
+
retries: number of times to retry in case of timeout
|
|
194
|
+
|
|
195
|
+
Returns: The command response
|
|
196
|
+
|
|
197
|
+
Raises: SerialException
|
|
198
|
+
"""
|
|
199
|
+
data_encode = data.encode()
|
|
200
|
+
|
|
201
|
+
for retry in range(retries + 1):
|
|
202
|
+
log.debug(f"{self.name}: Write -> {data_encode!r}")
|
|
203
|
+
await self._serial.write(data=data_encode)
|
|
204
|
+
|
|
205
|
+
response = await self._serial.read_until(match=self._ack)
|
|
206
|
+
log.debug(f"{self.name}: Read <- {response!r}")
|
|
207
|
+
|
|
208
|
+
if (
|
|
209
|
+
self._ack in response
|
|
210
|
+
or self._error_keyword.encode() in response.lower()
|
|
211
|
+
):
|
|
212
|
+
# Remove ack from response
|
|
213
|
+
response = response.replace(self._ack, b"")
|
|
214
|
+
str_response = self.process_raw_response(
|
|
215
|
+
command=data, response=response.decode()
|
|
216
|
+
)
|
|
217
|
+
self.raise_on_error(response=str_response, request=data)
|
|
218
|
+
return str_response
|
|
219
|
+
|
|
220
|
+
log.info(f"{self.name}: retry number {retry}/{retries}")
|
|
221
|
+
|
|
222
|
+
await self.on_retry()
|
|
223
|
+
|
|
224
|
+
raise NoResponse(port=self._port, command=data)
|
|
225
|
+
|
|
226
|
+
async def open(self) -> None:
|
|
227
|
+
"""Open the connection."""
|
|
228
|
+
await self._serial.open()
|
|
229
|
+
|
|
230
|
+
async def close(self) -> None:
|
|
231
|
+
"""Close the connection."""
|
|
232
|
+
await self._serial.close()
|
|
233
|
+
|
|
234
|
+
async def is_open(self) -> bool:
|
|
235
|
+
"""Check if connection is open."""
|
|
236
|
+
return await self._serial.is_open()
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def port(self) -> str:
|
|
240
|
+
return self._port
|
|
241
|
+
|
|
242
|
+
@property
|
|
243
|
+
def name(self) -> str:
|
|
244
|
+
return self._name
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def send_data_lock(self) -> asyncio.Lock:
|
|
248
|
+
return self._send_data_lock
|
|
249
|
+
|
|
250
|
+
def raise_on_error(self, response: str, request: str) -> None:
|
|
251
|
+
"""
|
|
252
|
+
Raise an error if the response contains an error
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
response: response
|
|
256
|
+
request: the requesting command
|
|
257
|
+
|
|
258
|
+
Returns: None
|
|
259
|
+
|
|
260
|
+
Raises: SerialException
|
|
261
|
+
"""
|
|
262
|
+
if not response or not request:
|
|
263
|
+
return
|
|
264
|
+
|
|
265
|
+
lower = response.lower()
|
|
266
|
+
res_gcode = response.split()[0]
|
|
267
|
+
req_gcode = request.split()[0]
|
|
268
|
+
|
|
269
|
+
# Make sure this is not just a normal response that happens to contain the
|
|
270
|
+
# `err` or `alarm` keyword in the message body by checking the gcode values
|
|
271
|
+
# for both the request and response. If the gcodes are the same then this
|
|
272
|
+
# is not an error response.
|
|
273
|
+
if res_gcode == req_gcode:
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
if self._alarm_keyword in lower:
|
|
277
|
+
raise AlarmResponse(port=self._port, response=response)
|
|
278
|
+
|
|
279
|
+
if self._error_keyword.lower() in lower:
|
|
280
|
+
# Check for specific error codes
|
|
281
|
+
error_codes_dict = self._error_codes.get_error_codes()
|
|
282
|
+
for code, error_code in error_codes_dict.items():
|
|
283
|
+
if code in lower:
|
|
284
|
+
error_code.raise_exception(
|
|
285
|
+
port=self._port, response=response, command=request
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# If no specific error code was found, raise a generic ErrorResponse
|
|
289
|
+
raise ErrorResponse(port=self._port, response=response)
|
|
290
|
+
|
|
291
|
+
async def on_retry(self) -> None:
|
|
292
|
+
"""
|
|
293
|
+
Opportunity for derived classes to perform action between retries. Default
|
|
294
|
+
behaviour is to wait then re-open the connection.
|
|
295
|
+
|
|
296
|
+
Returns: None
|
|
297
|
+
"""
|
|
298
|
+
await asyncio.sleep(self._retry_wait_time_seconds)
|
|
299
|
+
await self._serial.close()
|
|
300
|
+
await self._serial.open()
|
|
301
|
+
|
|
302
|
+
def process_raw_response(self, command: str, response: str) -> str:
|
|
303
|
+
"""
|
|
304
|
+
Opportunity for derived classes to process the raw response. Default
|
|
305
|
+
strips white space.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
command: The sent command.
|
|
309
|
+
response: The raw read response minus ack.
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
processed response.
|
|
313
|
+
"""
|
|
314
|
+
return response.strip()
|
|
315
|
+
|
|
316
|
+
async def flush_input(self) -> None:
|
|
317
|
+
"""Empty the input buffer.
|
|
318
|
+
|
|
319
|
+
This is a pretty gross utility that may take a while and is intended to consume
|
|
320
|
+
blocks of text printed by the other side, for instance on boot.
|
|
321
|
+
"""
|
|
322
|
+
self._serial.reset_input_buffer()
|
|
323
|
+
log.info("flushing input")
|
|
324
|
+
consecutive_empties = 0
|
|
325
|
+
async with self._serial.timeout_override("timeout", 0.1):
|
|
326
|
+
while True:
|
|
327
|
+
try:
|
|
328
|
+
inp = await self._serial.read_until(b"\r\n")
|
|
329
|
+
log.info(f"flush_input read: {inp!r}")
|
|
330
|
+
if not inp:
|
|
331
|
+
consecutive_empties += 1
|
|
332
|
+
if consecutive_empties >= 5:
|
|
333
|
+
return
|
|
334
|
+
else:
|
|
335
|
+
consecutive_empties = 0
|
|
336
|
+
except Exception:
|
|
337
|
+
log.exception("timeout exception is")
|
|
338
|
+
return
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
class AsyncResponseSerialConnection(SerialConnection):
|
|
342
|
+
@classmethod
|
|
343
|
+
async def create(
|
|
344
|
+
cls,
|
|
345
|
+
port: str,
|
|
346
|
+
baud_rate: int,
|
|
347
|
+
timeout: float,
|
|
348
|
+
ack: str,
|
|
349
|
+
name: Optional[str] = None,
|
|
350
|
+
retry_wait_time_seconds: float = 0.1,
|
|
351
|
+
loop: Optional[asyncio.AbstractEventLoop] = None,
|
|
352
|
+
error_keyword: Optional[str] = None,
|
|
353
|
+
alarm_keyword: Optional[str] = None,
|
|
354
|
+
reset_buffer_before_write: bool = False,
|
|
355
|
+
error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
|
|
356
|
+
async_error_ack: Optional[str] = None,
|
|
357
|
+
number_of_retries: int = 0,
|
|
358
|
+
) -> AsyncResponseSerialConnection:
|
|
359
|
+
"""
|
|
360
|
+
Create a connection.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
port: url or port to connect to
|
|
364
|
+
baud_rate: baud rate
|
|
365
|
+
timeout: timeout in seconds
|
|
366
|
+
ack: the command response ack
|
|
367
|
+
name: the connection name
|
|
368
|
+
retry_wait_time_seconds: how long to wait between retries.
|
|
369
|
+
loop: optional event loop.
|
|
370
|
+
error_keyword: optional string that will cause an
|
|
371
|
+
ErrorResponse exception when detected
|
|
372
|
+
(default: error)
|
|
373
|
+
alarm_keyword: optional string that will cause an
|
|
374
|
+
AlarmResponse exception when detected
|
|
375
|
+
(default: alarm)
|
|
376
|
+
reset_buffer_before_write: whether to reset the read buffer before
|
|
377
|
+
every write
|
|
378
|
+
async_error_ack: optional string that will indicate an asynchronous
|
|
379
|
+
error when detected (default: async)
|
|
380
|
+
number_of_retries: default number of retries
|
|
381
|
+
error_codes: Enum class for error codes
|
|
382
|
+
(default: DefaultErrorCodes)
|
|
383
|
+
|
|
384
|
+
Returns: AsyncResponseSerialConnection
|
|
385
|
+
"""
|
|
386
|
+
serial = await super()._build_serial(
|
|
387
|
+
port=port,
|
|
388
|
+
baud_rate=baud_rate,
|
|
389
|
+
timeout=timeout,
|
|
390
|
+
loop=loop,
|
|
391
|
+
reset_buffer_before_write=reset_buffer_before_write,
|
|
392
|
+
)
|
|
393
|
+
name = name or port
|
|
394
|
+
obj = cls(
|
|
395
|
+
serial=serial,
|
|
396
|
+
port=port,
|
|
397
|
+
name=name,
|
|
398
|
+
ack=ack,
|
|
399
|
+
retry_wait_time_seconds=retry_wait_time_seconds,
|
|
400
|
+
error_keyword=error_keyword or "err",
|
|
401
|
+
alarm_keyword=alarm_keyword or "alarm",
|
|
402
|
+
async_error_ack=async_error_ack or "async",
|
|
403
|
+
number_of_retries=number_of_retries,
|
|
404
|
+
error_codes=error_codes,
|
|
405
|
+
)
|
|
406
|
+
return obj
|
|
407
|
+
|
|
408
|
+
def __init__(
|
|
409
|
+
self,
|
|
410
|
+
serial: AsyncSerial,
|
|
411
|
+
port: str,
|
|
412
|
+
name: str,
|
|
413
|
+
ack: str,
|
|
414
|
+
retry_wait_time_seconds: float,
|
|
415
|
+
error_keyword: str,
|
|
416
|
+
alarm_keyword: str,
|
|
417
|
+
async_error_ack: str,
|
|
418
|
+
number_of_retries: int = 0,
|
|
419
|
+
error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
|
|
420
|
+
) -> None:
|
|
421
|
+
"""
|
|
422
|
+
Constructor
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
serial: AsyncSerial object
|
|
426
|
+
port: url or port to connect to
|
|
427
|
+
ack: the command response ack
|
|
428
|
+
name: the connection name
|
|
429
|
+
retry_wait_time_seconds: how long to wait between retries.
|
|
430
|
+
error_keyword: string that will cause an ErrorResponse
|
|
431
|
+
exception when detected
|
|
432
|
+
alarm_keyword: string that will cause an AlarmResponse
|
|
433
|
+
exception when detected
|
|
434
|
+
async_error_ack: string that will indicate an asynchronous
|
|
435
|
+
error when detected
|
|
436
|
+
number_of_retries: default number of retries
|
|
437
|
+
error_codes: Enum class for error codes
|
|
438
|
+
"""
|
|
439
|
+
super().__init__(
|
|
440
|
+
serial=serial,
|
|
441
|
+
port=port,
|
|
442
|
+
name=name,
|
|
443
|
+
ack=ack,
|
|
444
|
+
retry_wait_time_seconds=retry_wait_time_seconds,
|
|
445
|
+
error_keyword=error_keyword,
|
|
446
|
+
alarm_keyword=alarm_keyword,
|
|
447
|
+
error_codes=error_codes,
|
|
448
|
+
)
|
|
449
|
+
self._serial = serial
|
|
450
|
+
self._port = port
|
|
451
|
+
self._name = name
|
|
452
|
+
self._ack = ack.encode()
|
|
453
|
+
self._retry_wait_time_seconds = retry_wait_time_seconds
|
|
454
|
+
self._number_of_retries = number_of_retries
|
|
455
|
+
self._error_keyword = error_keyword.lower()
|
|
456
|
+
self._alarm_keyword = alarm_keyword.lower()
|
|
457
|
+
self._async_error_ack = async_error_ack.lower()
|
|
458
|
+
|
|
459
|
+
async def send_command(
|
|
460
|
+
self, command: CommandBuilder, retries: int = 0, timeout: Optional[float] = None
|
|
461
|
+
) -> str:
|
|
462
|
+
"""
|
|
463
|
+
Send a command and return the response.
|
|
464
|
+
|
|
465
|
+
Args:
|
|
466
|
+
command: A command builder.
|
|
467
|
+
retries: number of times to retry in case of timeout
|
|
468
|
+
timeout: optional override of default timeout in seconds
|
|
469
|
+
|
|
470
|
+
Returns: The command response
|
|
471
|
+
|
|
472
|
+
Raises: SerialException
|
|
473
|
+
"""
|
|
474
|
+
return await self.send_data(
|
|
475
|
+
data=command.build(),
|
|
476
|
+
retries=retries or self._number_of_retries,
|
|
477
|
+
timeout=timeout,
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
async def send_data(
|
|
481
|
+
self, data: str, retries: int = 0, timeout: Optional[float] = None
|
|
482
|
+
) -> str:
|
|
483
|
+
"""
|
|
484
|
+
Send data and return the response.
|
|
485
|
+
|
|
486
|
+
Args:
|
|
487
|
+
data: The data to send.
|
|
488
|
+
retries: number of times to retry in case of timeout
|
|
489
|
+
timeout: optional override of default timeout in seconds
|
|
490
|
+
|
|
491
|
+
Returns: The command response
|
|
492
|
+
|
|
493
|
+
Raises: SerialException
|
|
494
|
+
"""
|
|
495
|
+
async with super().send_data_lock, self._serial.timeout_override(
|
|
496
|
+
"timeout", timeout
|
|
497
|
+
):
|
|
498
|
+
return await self._send_data(
|
|
499
|
+
data=data, retries=retries or self._number_of_retries
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
async def _send_data(self, data: str, retries: int = 0) -> str:
|
|
503
|
+
"""
|
|
504
|
+
Send data and return the response.
|
|
505
|
+
|
|
506
|
+
Args:
|
|
507
|
+
data: The data to send.
|
|
508
|
+
retries: number of times to retry in case of timeout
|
|
509
|
+
|
|
510
|
+
Returns: The command response
|
|
511
|
+
|
|
512
|
+
Raises: SerialException
|
|
513
|
+
"""
|
|
514
|
+
data_encode = data.encode()
|
|
515
|
+
retries = retries or self._number_of_retries
|
|
516
|
+
|
|
517
|
+
for retry in range(retries + 1):
|
|
518
|
+
log.debug(f"{self._name}: Write -> {data_encode!r}")
|
|
519
|
+
await self._serial.write(data=data_encode)
|
|
520
|
+
|
|
521
|
+
response: List[bytes] = []
|
|
522
|
+
response.append(await self._serial.read_until(match=self._ack))
|
|
523
|
+
log.debug(f"{self._name}: Read <- {response[-1]!r}")
|
|
524
|
+
|
|
525
|
+
while self._async_error_ack.encode() in response[-1].lower():
|
|
526
|
+
# check for multiple a priori async errors
|
|
527
|
+
response.append(await self._serial.read_until(match=self._ack))
|
|
528
|
+
log.debug(f"{self._name}: Read <- {response[-1]!r}")
|
|
529
|
+
|
|
530
|
+
for r in response:
|
|
531
|
+
if self._async_error_ack.encode() in r:
|
|
532
|
+
# Remove ack from response
|
|
533
|
+
ackless_response = r.replace(self._ack, b"")
|
|
534
|
+
str_response = self.process_raw_response(
|
|
535
|
+
command=data, response=ackless_response.decode()
|
|
536
|
+
)
|
|
537
|
+
self.raise_on_error(response=str_response, request=data)
|
|
538
|
+
|
|
539
|
+
if self._ack in response[-1]:
|
|
540
|
+
# Remove ack from response
|
|
541
|
+
ackless_response = response[-1].replace(self._ack, b"")
|
|
542
|
+
str_response = self.process_raw_response(
|
|
543
|
+
command=data, response=ackless_response.decode()
|
|
544
|
+
)
|
|
545
|
+
self.raise_on_error(response=str_response, request=data)
|
|
546
|
+
return str_response
|
|
547
|
+
|
|
548
|
+
log.info(f"{self._name}: retry number {retry}/{retries}")
|
|
549
|
+
|
|
550
|
+
await self.on_retry()
|
|
551
|
+
|
|
552
|
+
raise NoResponse(port=self._port, command=data)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import List, Optional, Iterator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CommandBuilder:
|
|
7
|
+
"""Class used to build GCODE commands."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, terminator: str = "\n") -> None:
|
|
10
|
+
"""
|
|
11
|
+
Construct a command builder.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
terminator: The command terminator.
|
|
15
|
+
"""
|
|
16
|
+
self._terminator = terminator
|
|
17
|
+
self._elements: List[str] = []
|
|
18
|
+
|
|
19
|
+
def add_float(
|
|
20
|
+
self, prefix: str, value: float, precision: Optional[int] = None
|
|
21
|
+
) -> CommandBuilder:
|
|
22
|
+
"""
|
|
23
|
+
Add a float value.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
prefix: The value prefix.
|
|
27
|
+
value: The float value.
|
|
28
|
+
precision: Rounding precision. If None, there will be no rounding.
|
|
29
|
+
|
|
30
|
+
Returns: self
|
|
31
|
+
"""
|
|
32
|
+
value = round(value, precision) if precision is not None else value
|
|
33
|
+
return self.add_element(f"{prefix}{value}")
|
|
34
|
+
|
|
35
|
+
def add_int(self, prefix: str, value: int) -> CommandBuilder:
|
|
36
|
+
"""
|
|
37
|
+
Add an integer value.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
prefix: The value prefix
|
|
41
|
+
value: The integer value
|
|
42
|
+
|
|
43
|
+
Returns: self
|
|
44
|
+
"""
|
|
45
|
+
return self.add_element(f"{prefix}{value}")
|
|
46
|
+
|
|
47
|
+
def add_gcode(self, gcode: str) -> CommandBuilder:
|
|
48
|
+
"""
|
|
49
|
+
Add a GCODE.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
gcode: The gcode
|
|
53
|
+
|
|
54
|
+
Returns: self
|
|
55
|
+
"""
|
|
56
|
+
return self.add_element(gcode)
|
|
57
|
+
|
|
58
|
+
def add_builder(self, builder: CommandBuilder) -> CommandBuilder:
|
|
59
|
+
"""
|
|
60
|
+
Add all elements from builder
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
builder: a command builder
|
|
64
|
+
|
|
65
|
+
Returns: self
|
|
66
|
+
"""
|
|
67
|
+
self._elements += builder._elements
|
|
68
|
+
return self
|
|
69
|
+
|
|
70
|
+
def add_element(self, element: str) -> CommandBuilder:
|
|
71
|
+
"""
|
|
72
|
+
Add an element to the command builder
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
element: an element as a string
|
|
76
|
+
|
|
77
|
+
Returns: self
|
|
78
|
+
"""
|
|
79
|
+
self._elements.append(element)
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def build(self) -> str:
|
|
83
|
+
"""
|
|
84
|
+
Build command as a string.
|
|
85
|
+
|
|
86
|
+
Returns: string
|
|
87
|
+
"""
|
|
88
|
+
return " ".join(self._elements + [self._terminator])
|
|
89
|
+
|
|
90
|
+
def __str__(self) -> str:
|
|
91
|
+
return self.build()
|
|
92
|
+
|
|
93
|
+
def __iter__(self) -> Iterator[str]:
|
|
94
|
+
return iter(self._elements)
|
|
95
|
+
|
|
96
|
+
def __bool__(self) -> bool:
|
|
97
|
+
return len(self._elements) != 0
|
|
98
|
+
|
|
99
|
+
def __eq__(self, other: object) -> bool:
|
|
100
|
+
if isinstance(other, CommandBuilder):
|
|
101
|
+
return self.build() == other.build()
|
|
102
|
+
return False
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .abstract import AbstractFlexStackerDriver
|
|
2
|
+
from .driver import FlexStackerDriver
|
|
3
|
+
from .simulator import SimulatingDriver
|
|
4
|
+
from . import types as FlexStackerTypes
|
|
5
|
+
from . import utils as FlexStackerUtils
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"AbstractFlexStackerDriver",
|
|
9
|
+
"FlexStackerDriver",
|
|
10
|
+
"SimulatingDriver",
|
|
11
|
+
"FlexStackerTypes",
|
|
12
|
+
"FlexStackerUtils",
|
|
13
|
+
]
|