opentrons 8.3.1a1__py2.py3-none-any.whl → 8.4.0a1__py2.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.
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +2 -0
- opentrons/calibration_storage/ot2/tip_length.py +6 -6
- opentrons/config/advanced_settings.py +9 -11
- opentrons/config/feature_flags.py +0 -4
- opentrons/config/reset.py +7 -2
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/async_serial.py +4 -0
- opentrons/drivers/asyncio/communication/errors.py +41 -8
- opentrons/drivers/asyncio/communication/serial_connection.py +36 -10
- opentrons/drivers/flex_stacker/__init__.py +9 -3
- opentrons/drivers/flex_stacker/abstract.py +140 -15
- opentrons/drivers/flex_stacker/driver.py +593 -47
- opentrons/drivers/flex_stacker/errors.py +64 -0
- opentrons/drivers/flex_stacker/simulator.py +222 -24
- opentrons/drivers/flex_stacker/types.py +211 -15
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/execute.py +4 -2
- opentrons/hardware_control/api.py +5 -0
- opentrons/hardware_control/backends/flex_protocol.py +4 -0
- opentrons/hardware_control/backends/ot3controller.py +12 -1
- opentrons/hardware_control/backends/ot3simulator.py +3 -0
- opentrons/hardware_control/backends/subsystem_manager.py +8 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +10 -6
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +59 -6
- opentrons/hardware_control/modules/__init__.py +12 -1
- opentrons/hardware_control/modules/absorbance_reader.py +11 -9
- opentrons/hardware_control/modules/flex_stacker.py +498 -0
- opentrons/hardware_control/modules/heater_shaker.py +12 -10
- opentrons/hardware_control/modules/magdeck.py +5 -1
- opentrons/hardware_control/modules/tempdeck.py +5 -1
- opentrons/hardware_control/modules/thermocycler.py +15 -14
- opentrons/hardware_control/modules/types.py +191 -1
- opentrons/hardware_control/modules/utils.py +3 -0
- opentrons/hardware_control/motion_utilities.py +20 -0
- opentrons/hardware_control/ot3api.py +145 -15
- opentrons/hardware_control/protocols/liquid_handler.py +47 -1
- opentrons/hardware_control/types.py +6 -0
- opentrons/legacy_commands/commands.py +19 -3
- opentrons/legacy_commands/helpers.py +15 -0
- opentrons/legacy_commands/types.py +3 -2
- opentrons/protocol_api/__init__.py +2 -0
- opentrons/protocol_api/_liquid.py +39 -8
- opentrons/protocol_api/_liquid_properties.py +20 -19
- opentrons/protocol_api/_transfer_liquid_validation.py +91 -0
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/deck_conflict.py +11 -1
- opentrons/protocol_api/core/engine/instrument.py +1233 -65
- opentrons/protocol_api/core/engine/labware.py +8 -4
- opentrons/protocol_api/core/engine/load_labware_params.py +68 -10
- opentrons/protocol_api/core/engine/module_core.py +118 -2
- opentrons/protocol_api/core/engine/protocol.py +253 -11
- opentrons/protocol_api/core/engine/stringify.py +19 -8
- opentrons/protocol_api/core/engine/transfer_components_executor.py +853 -0
- opentrons/protocol_api/core/engine/well.py +60 -5
- opentrons/protocol_api/core/instrument.py +65 -19
- opentrons/protocol_api/core/labware.py +6 -2
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +7 -3
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +69 -21
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +8 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +36 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +25 -1
- opentrons/protocol_api/core/legacy/load_info.py +4 -12
- opentrons/protocol_api/core/legacy/module_geometry.py +6 -1
- opentrons/protocol_api/core/legacy/well_geometry.py +3 -3
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +67 -21
- opentrons/protocol_api/core/module.py +43 -0
- opentrons/protocol_api/core/protocol.py +33 -0
- opentrons/protocol_api/core/well.py +21 -1
- opentrons/protocol_api/instrument_context.py +246 -123
- opentrons/protocol_api/labware.py +75 -11
- opentrons/protocol_api/module_contexts.py +140 -0
- opentrons/protocol_api/protocol_context.py +156 -16
- opentrons/protocol_api/validation.py +51 -41
- opentrons/protocol_engine/__init__.py +21 -2
- opentrons/protocol_engine/actions/actions.py +5 -5
- opentrons/protocol_engine/clients/sync_client.py +6 -0
- opentrons/protocol_engine/commands/__init__.py +30 -0
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +0 -1
- opentrons/protocol_engine/commands/air_gap_in_place.py +3 -2
- opentrons/protocol_engine/commands/aspirate.py +6 -2
- opentrons/protocol_engine/commands/aspirate_in_place.py +3 -1
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +237 -0
- opentrons/protocol_engine/commands/blow_out.py +2 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +4 -1
- opentrons/protocol_engine/commands/command_unions.py +69 -0
- opentrons/protocol_engine/commands/configure_for_volume.py +3 -0
- opentrons/protocol_engine/commands/dispense.py +3 -1
- opentrons/protocol_engine/commands/dispense_in_place.py +3 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +240 -0
- opentrons/protocol_engine/commands/drop_tip.py +23 -1
- opentrons/protocol_engine/commands/evotip_dispense.py +6 -7
- opentrons/protocol_engine/commands/evotip_seal_pipette.py +24 -29
- opentrons/protocol_engine/commands/evotip_unseal_pipette.py +1 -7
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +106 -0
- opentrons/protocol_engine/commands/flex_stacker/close_latch.py +72 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +15 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +161 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +164 -0
- opentrons/protocol_engine/commands/flex_stacker/open_latch.py +70 -0
- opentrons/protocol_engine/commands/flex_stacker/prepare_shuttle.py +112 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +394 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +190 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +288 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
- opentrons/protocol_engine/commands/labware_handling_common.py +24 -0
- opentrons/protocol_engine/commands/liquid_probe.py +21 -12
- opentrons/protocol_engine/commands/load_labware.py +42 -39
- opentrons/protocol_engine/commands/load_lid.py +21 -13
- opentrons/protocol_engine/commands/load_lid_stack.py +130 -47
- opentrons/protocol_engine/commands/load_module.py +18 -17
- opentrons/protocol_engine/commands/load_pipette.py +3 -0
- opentrons/protocol_engine/commands/move_labware.py +139 -20
- opentrons/protocol_engine/commands/pick_up_tip.py +5 -2
- opentrons/protocol_engine/commands/pipetting_common.py +154 -7
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +17 -2
- opentrons/protocol_engine/commands/reload_labware.py +6 -19
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +3 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +6 -1
- opentrons/protocol_engine/errors/__init__.py +8 -0
- opentrons/protocol_engine/errors/exceptions.py +50 -0
- opentrons/protocol_engine/execution/equipment.py +123 -106
- opentrons/protocol_engine/execution/labware_movement.py +8 -6
- opentrons/protocol_engine/execution/pipetting.py +233 -26
- opentrons/protocol_engine/execution/tip_handler.py +14 -5
- opentrons/protocol_engine/labware_offset_standardization.py +173 -0
- opentrons/protocol_engine/protocol_engine.py +22 -13
- opentrons/protocol_engine/resources/deck_configuration_provider.py +94 -2
- opentrons/protocol_engine/resources/deck_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_data_provider.py +32 -12
- opentrons/protocol_engine/resources/labware_validation.py +7 -5
- opentrons/protocol_engine/slot_standardization.py +11 -23
- opentrons/protocol_engine/state/addressable_areas.py +84 -46
- opentrons/protocol_engine/state/frustum_helpers.py +26 -10
- opentrons/protocol_engine/state/geometry.py +683 -100
- opentrons/protocol_engine/state/labware.py +252 -55
- opentrons/protocol_engine/state/module_substates/__init__.py +4 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +68 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +22 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +13 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +20 -0
- opentrons/protocol_engine/state/modules.py +178 -52
- opentrons/protocol_engine/state/pipettes.py +54 -0
- opentrons/protocol_engine/state/state.py +1 -1
- opentrons/protocol_engine/state/tips.py +14 -0
- opentrons/protocol_engine/state/update_types.py +180 -25
- opentrons/protocol_engine/state/wells.py +54 -8
- opentrons/protocol_engine/types/__init__.py +292 -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 +72 -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 +110 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +108 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +33 -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 +137 -0
- opentrons/protocol_engine/types/location.py +193 -0
- opentrons/protocol_engine/types/module.py +269 -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 +107 -0
- opentrons/protocol_reader/extract_labware_definitions.py +7 -3
- opentrons/protocol_reader/file_format_validator.py +5 -3
- opentrons/protocol_runner/json_translator.py +4 -2
- opentrons/protocol_runner/legacy_command_mapper.py +6 -2
- opentrons/protocol_runner/run_orchestrator.py +4 -1
- opentrons/protocols/advanced_control/transfers/common.py +48 -1
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +204 -0
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +16 -3
- opentrons/protocols/labware.py +5 -6
- opentrons/protocols/models/__init__.py +0 -21
- opentrons/simulate.py +4 -2
- opentrons/types.py +15 -6
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/METADATA +4 -4
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/RECORD +188 -148
- opentrons/calibration_storage/ot2/models/defaults.py +0 -0
- opentrons/calibration_storage/ot3/models/defaults.py +0 -0
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_engine/types.py +0 -1311
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/LICENSE +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/WHEEL +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.1a1.dist-info → opentrons-8.4.0a1.dist-info}/top_level.txt +0 -0
|
@@ -89,7 +89,10 @@ class BlowOutInPlaceImplementation(
|
|
|
89
89
|
if isinstance(result, DefinedErrorData):
|
|
90
90
|
return result
|
|
91
91
|
return SuccessData(
|
|
92
|
-
public=BlowOutInPlaceResult(),
|
|
92
|
+
public=BlowOutInPlaceResult(),
|
|
93
|
+
state_update=result.state_update.set_pipette_ready_to_aspirate(
|
|
94
|
+
pipette_id=params.pipetteId, ready_to_aspirate=False
|
|
95
|
+
),
|
|
93
96
|
)
|
|
94
97
|
|
|
95
98
|
|
|
@@ -14,8 +14,10 @@ from .pipetting_common import (
|
|
|
14
14
|
TipPhysicallyAttachedError,
|
|
15
15
|
)
|
|
16
16
|
from .movement_common import StallOrCollisionError
|
|
17
|
+
from .flex_stacker.common import FlexStackerStallOrCollisionError
|
|
17
18
|
|
|
18
19
|
from . import absorbance_reader
|
|
20
|
+
from . import flex_stacker
|
|
19
21
|
from . import heater_shaker
|
|
20
22
|
from . import magnetic_module
|
|
21
23
|
from . import temperature_module
|
|
@@ -57,6 +59,14 @@ from .aspirate_in_place import (
|
|
|
57
59
|
AspirateInPlaceCommandType,
|
|
58
60
|
)
|
|
59
61
|
|
|
62
|
+
from .aspirate_while_tracking import (
|
|
63
|
+
AspirateWhileTracking,
|
|
64
|
+
AspirateWhileTrackingParams,
|
|
65
|
+
AspirateWhileTrackingCreate,
|
|
66
|
+
AspirateWhileTrackingResult,
|
|
67
|
+
AspirateWhileTrackingCommandType,
|
|
68
|
+
)
|
|
69
|
+
|
|
60
70
|
from .comment import (
|
|
61
71
|
Comment,
|
|
62
72
|
CommentParams,
|
|
@@ -81,6 +91,14 @@ from .dispense import (
|
|
|
81
91
|
DispenseCommandType,
|
|
82
92
|
)
|
|
83
93
|
|
|
94
|
+
from .dispense_while_tracking import (
|
|
95
|
+
DispenseWhileTracking,
|
|
96
|
+
DispenseWhileTrackingParams,
|
|
97
|
+
DispenseWhileTrackingCreate,
|
|
98
|
+
DispenseWhileTrackingResult,
|
|
99
|
+
DispenseWhileTrackingCommandType,
|
|
100
|
+
)
|
|
101
|
+
|
|
84
102
|
from .dispense_in_place import (
|
|
85
103
|
DispenseInPlace,
|
|
86
104
|
DispenseInPlaceParams,
|
|
@@ -389,10 +407,12 @@ Command = Annotated[
|
|
|
389
407
|
AirGapInPlace,
|
|
390
408
|
Aspirate,
|
|
391
409
|
AspirateInPlace,
|
|
410
|
+
AspirateWhileTracking,
|
|
392
411
|
Comment,
|
|
393
412
|
Custom,
|
|
394
413
|
Dispense,
|
|
395
414
|
DispenseInPlace,
|
|
415
|
+
DispenseWhileTracking,
|
|
396
416
|
BlowOut,
|
|
397
417
|
BlowOutInPlace,
|
|
398
418
|
ConfigureForVolume,
|
|
@@ -457,6 +477,14 @@ Command = Annotated[
|
|
|
457
477
|
absorbance_reader.OpenLid,
|
|
458
478
|
absorbance_reader.Initialize,
|
|
459
479
|
absorbance_reader.ReadAbsorbance,
|
|
480
|
+
flex_stacker.Retrieve,
|
|
481
|
+
flex_stacker.Store,
|
|
482
|
+
flex_stacker.SetStoredLabware,
|
|
483
|
+
flex_stacker.Fill,
|
|
484
|
+
flex_stacker.Empty,
|
|
485
|
+
flex_stacker.CloseLatch,
|
|
486
|
+
flex_stacker.OpenLatch,
|
|
487
|
+
flex_stacker.PrepareShuttle,
|
|
460
488
|
calibration.CalibrateGripper,
|
|
461
489
|
calibration.CalibratePipette,
|
|
462
490
|
calibration.CalibrateModule,
|
|
@@ -479,6 +507,7 @@ Command = Annotated[
|
|
|
479
507
|
CommandParams = Union[
|
|
480
508
|
AirGapInPlaceParams,
|
|
481
509
|
AspirateParams,
|
|
510
|
+
AspirateWhileTrackingParams,
|
|
482
511
|
AspirateInPlaceParams,
|
|
483
512
|
CommentParams,
|
|
484
513
|
ConfigureForVolumeParams,
|
|
@@ -486,6 +515,7 @@ CommandParams = Union[
|
|
|
486
515
|
CustomParams,
|
|
487
516
|
DispenseParams,
|
|
488
517
|
DispenseInPlaceParams,
|
|
518
|
+
DispenseWhileTrackingParams,
|
|
489
519
|
BlowOutParams,
|
|
490
520
|
BlowOutInPlaceParams,
|
|
491
521
|
DropTipParams,
|
|
@@ -548,6 +578,14 @@ CommandParams = Union[
|
|
|
548
578
|
absorbance_reader.OpenLidParams,
|
|
549
579
|
absorbance_reader.InitializeParams,
|
|
550
580
|
absorbance_reader.ReadAbsorbanceParams,
|
|
581
|
+
flex_stacker.RetrieveParams,
|
|
582
|
+
flex_stacker.StoreParams,
|
|
583
|
+
flex_stacker.SetStoredLabwareParams,
|
|
584
|
+
flex_stacker.FillParams,
|
|
585
|
+
flex_stacker.EmptyParams,
|
|
586
|
+
flex_stacker.CloseLatchParams,
|
|
587
|
+
flex_stacker.OpenLatchParams,
|
|
588
|
+
flex_stacker.PrepareShuttleParams,
|
|
551
589
|
calibration.CalibrateGripperParams,
|
|
552
590
|
calibration.CalibratePipetteParams,
|
|
553
591
|
calibration.CalibrateModuleParams,
|
|
@@ -568,6 +606,7 @@ CommandParams = Union[
|
|
|
568
606
|
CommandType = Union[
|
|
569
607
|
AirGapInPlaceCommandType,
|
|
570
608
|
AspirateCommandType,
|
|
609
|
+
AspirateWhileTrackingCommandType,
|
|
571
610
|
AspirateInPlaceCommandType,
|
|
572
611
|
CommentCommandType,
|
|
573
612
|
ConfigureForVolumeCommandType,
|
|
@@ -575,6 +614,7 @@ CommandType = Union[
|
|
|
575
614
|
CustomCommandType,
|
|
576
615
|
DispenseCommandType,
|
|
577
616
|
DispenseInPlaceCommandType,
|
|
617
|
+
DispenseWhileTrackingCommandType,
|
|
578
618
|
BlowOutCommandType,
|
|
579
619
|
BlowOutInPlaceCommandType,
|
|
580
620
|
DropTipCommandType,
|
|
@@ -637,6 +677,14 @@ CommandType = Union[
|
|
|
637
677
|
absorbance_reader.OpenLidCommandType,
|
|
638
678
|
absorbance_reader.InitializeCommandType,
|
|
639
679
|
absorbance_reader.ReadAbsorbanceCommandType,
|
|
680
|
+
flex_stacker.RetrieveCommandType,
|
|
681
|
+
flex_stacker.StoreCommandType,
|
|
682
|
+
flex_stacker.SetStoredLabwareCommandType,
|
|
683
|
+
flex_stacker.FillCommandType,
|
|
684
|
+
flex_stacker.EmptyCommandType,
|
|
685
|
+
flex_stacker.CloseLatchCommandType,
|
|
686
|
+
flex_stacker.OpenLatchCommandType,
|
|
687
|
+
flex_stacker.PrepareShuttleCommandType,
|
|
640
688
|
calibration.CalibrateGripperCommandType,
|
|
641
689
|
calibration.CalibratePipetteCommandType,
|
|
642
690
|
calibration.CalibrateModuleCommandType,
|
|
@@ -658,6 +706,7 @@ CommandCreate = Annotated[
|
|
|
658
706
|
Union[
|
|
659
707
|
AirGapInPlaceCreate,
|
|
660
708
|
AspirateCreate,
|
|
709
|
+
AspirateWhileTrackingCreate,
|
|
661
710
|
AspirateInPlaceCreate,
|
|
662
711
|
CommentCreate,
|
|
663
712
|
ConfigureForVolumeCreate,
|
|
@@ -665,6 +714,7 @@ CommandCreate = Annotated[
|
|
|
665
714
|
CustomCreate,
|
|
666
715
|
DispenseCreate,
|
|
667
716
|
DispenseInPlaceCreate,
|
|
717
|
+
DispenseWhileTrackingCreate,
|
|
668
718
|
BlowOutCreate,
|
|
669
719
|
BlowOutInPlaceCreate,
|
|
670
720
|
DropTipCreate,
|
|
@@ -727,6 +777,14 @@ CommandCreate = Annotated[
|
|
|
727
777
|
absorbance_reader.OpenLidCreate,
|
|
728
778
|
absorbance_reader.InitializeCreate,
|
|
729
779
|
absorbance_reader.ReadAbsorbanceCreate,
|
|
780
|
+
flex_stacker.RetrieveCreate,
|
|
781
|
+
flex_stacker.StoreCreate,
|
|
782
|
+
flex_stacker.SetStoredLabwareCreate,
|
|
783
|
+
flex_stacker.FillCreate,
|
|
784
|
+
flex_stacker.EmptyCreate,
|
|
785
|
+
flex_stacker.CloseLatchCreate,
|
|
786
|
+
flex_stacker.OpenLatchCreate,
|
|
787
|
+
flex_stacker.PrepareShuttleCreate,
|
|
730
788
|
calibration.CalibrateGripperCreate,
|
|
731
789
|
calibration.CalibratePipetteCreate,
|
|
732
790
|
calibration.CalibrateModuleCreate,
|
|
@@ -756,6 +814,7 @@ CommandAdapter: TypeAdapter[Command] = TypeAdapter(Command)
|
|
|
756
814
|
CommandResult = Union[
|
|
757
815
|
AirGapInPlaceResult,
|
|
758
816
|
AspirateResult,
|
|
817
|
+
AspirateWhileTrackingResult,
|
|
759
818
|
AspirateInPlaceResult,
|
|
760
819
|
CommentResult,
|
|
761
820
|
ConfigureForVolumeResult,
|
|
@@ -763,6 +822,7 @@ CommandResult = Union[
|
|
|
763
822
|
CustomResult,
|
|
764
823
|
DispenseResult,
|
|
765
824
|
DispenseInPlaceResult,
|
|
825
|
+
DispenseWhileTrackingResult,
|
|
766
826
|
BlowOutResult,
|
|
767
827
|
BlowOutInPlaceResult,
|
|
768
828
|
DropTipResult,
|
|
@@ -825,6 +885,14 @@ CommandResult = Union[
|
|
|
825
885
|
absorbance_reader.OpenLidResult,
|
|
826
886
|
absorbance_reader.InitializeResult,
|
|
827
887
|
absorbance_reader.ReadAbsorbanceResult,
|
|
888
|
+
flex_stacker.RetrieveResult,
|
|
889
|
+
flex_stacker.StoreResult,
|
|
890
|
+
flex_stacker.SetStoredLabwareResult,
|
|
891
|
+
flex_stacker.FillResult,
|
|
892
|
+
flex_stacker.EmptyResult,
|
|
893
|
+
flex_stacker.CloseLatchResult,
|
|
894
|
+
flex_stacker.OpenLatchResult,
|
|
895
|
+
flex_stacker.PrepareShuttleResult,
|
|
828
896
|
calibration.CalibrateGripperResult,
|
|
829
897
|
calibration.CalibratePipetteResult,
|
|
830
898
|
calibration.CalibrateModuleResult,
|
|
@@ -851,6 +919,7 @@ CommandDefinedErrorData = Union[
|
|
|
851
919
|
DefinedErrorData[LiquidNotFoundError],
|
|
852
920
|
DefinedErrorData[GripperMovementError],
|
|
853
921
|
DefinedErrorData[StallOrCollisionError],
|
|
922
|
+
DefinedErrorData[FlexStackerStallOrCollisionError],
|
|
854
923
|
]
|
|
855
924
|
|
|
856
925
|
|
|
@@ -74,6 +74,9 @@ class ConfigureForVolumeImplementation(
|
|
|
74
74
|
config=pipette_result.static_config,
|
|
75
75
|
serial_number=pipette_result.serial_number,
|
|
76
76
|
)
|
|
77
|
+
state_update.set_pipette_ready_to_aspirate(
|
|
78
|
+
pipette_result.pipette_id, ready_to_aspirate=False
|
|
79
|
+
)
|
|
77
80
|
|
|
78
81
|
return SuccessData(
|
|
79
82
|
public=ConfigureForVolumeResult(),
|
|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type, Union, Any
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
from pydantic import Field
|
|
9
8
|
from pydantic.json_schema import SkipJsonSchema
|
|
10
9
|
|
|
@@ -16,6 +15,7 @@ from .pipetting_common import (
|
|
|
16
15
|
BaseLiquidHandlingResult,
|
|
17
16
|
OverpressureError,
|
|
18
17
|
dispense_in_place,
|
|
18
|
+
DEFAULT_CORRECTION_VOLUME,
|
|
19
19
|
)
|
|
20
20
|
from .movement_common import (
|
|
21
21
|
LiquidHandlingWellLocationMixin,
|
|
@@ -100,6 +100,7 @@ class DispenseImplementation(AbstractCommandImpl[DispenseParams, _ExecuteReturn]
|
|
|
100
100
|
labware_id=labware_id,
|
|
101
101
|
well_name=well_name,
|
|
102
102
|
well_location=well_location,
|
|
103
|
+
operation_volume=volume,
|
|
103
104
|
)
|
|
104
105
|
if isinstance(move_result, DefinedErrorData):
|
|
105
106
|
return move_result
|
|
@@ -117,6 +118,7 @@ class DispenseImplementation(AbstractCommandImpl[DispenseParams, _ExecuteReturn]
|
|
|
117
118
|
},
|
|
118
119
|
pipetting=self._pipetting,
|
|
119
120
|
model_utils=self._model_utils,
|
|
121
|
+
correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
|
|
120
122
|
)
|
|
121
123
|
|
|
122
124
|
if isinstance(dispense_result, DefinedErrorData):
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type, Union, Any
|
|
5
5
|
from typing_extensions import Literal
|
|
6
|
+
|
|
6
7
|
from pydantic import Field
|
|
7
8
|
from pydantic.json_schema import SkipJsonSchema
|
|
8
9
|
|
|
@@ -13,6 +14,7 @@ from .pipetting_common import (
|
|
|
13
14
|
BaseLiquidHandlingResult,
|
|
14
15
|
OverpressureError,
|
|
15
16
|
dispense_in_place,
|
|
17
|
+
DEFAULT_CORRECTION_VOLUME,
|
|
16
18
|
)
|
|
17
19
|
from .command import (
|
|
18
20
|
AbstractCommandImpl,
|
|
@@ -95,6 +97,7 @@ class DispenseInPlaceImplementation(
|
|
|
95
97
|
},
|
|
96
98
|
pipetting=self._pipetting,
|
|
97
99
|
model_utils=self._model_utils,
|
|
100
|
+
correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
|
|
98
101
|
)
|
|
99
102
|
if isinstance(result, DefinedErrorData):
|
|
100
103
|
if (
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"""Dispense command request, result, and implementation models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import TYPE_CHECKING, Optional, Type, Union, Any
|
|
5
|
+
from typing_extensions import Literal
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from pydantic import Field
|
|
9
|
+
from pydantic.json_schema import SkipJsonSchema
|
|
10
|
+
|
|
11
|
+
from ..state.update_types import CLEAR, StateUpdate
|
|
12
|
+
from ..types import CurrentWell, DeckPoint
|
|
13
|
+
from .pipetting_common import (
|
|
14
|
+
PipetteIdMixin,
|
|
15
|
+
DispenseVolumeMixin,
|
|
16
|
+
FlowRateMixin,
|
|
17
|
+
BaseLiquidHandlingResult,
|
|
18
|
+
OverpressureError,
|
|
19
|
+
dispense_while_tracking,
|
|
20
|
+
)
|
|
21
|
+
from .movement_common import (
|
|
22
|
+
LiquidHandlingWellLocationMixin,
|
|
23
|
+
DestinationPositionResult,
|
|
24
|
+
StallOrCollisionError,
|
|
25
|
+
move_to_well,
|
|
26
|
+
)
|
|
27
|
+
from .command import (
|
|
28
|
+
AbstractCommandImpl,
|
|
29
|
+
BaseCommand,
|
|
30
|
+
BaseCommandCreate,
|
|
31
|
+
DefinedErrorData,
|
|
32
|
+
SuccessData,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
if TYPE_CHECKING:
|
|
36
|
+
from ..execution import PipettingHandler, GantryMover, MovementHandler
|
|
37
|
+
from ..resources import ModelUtils
|
|
38
|
+
from ..state.state import StateView
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
DispenseWhileTrackingCommandType = Literal["dispenseWhileTracking"]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _remove_default(s: dict[str, Any]) -> None:
|
|
45
|
+
s.pop("default", None)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class DispenseWhileTrackingParams(
|
|
49
|
+
PipetteIdMixin,
|
|
50
|
+
DispenseVolumeMixin,
|
|
51
|
+
FlowRateMixin,
|
|
52
|
+
LiquidHandlingWellLocationMixin,
|
|
53
|
+
):
|
|
54
|
+
"""Payload required to dispense to a specific well."""
|
|
55
|
+
|
|
56
|
+
pushOut: float | SkipJsonSchema[None] = Field(
|
|
57
|
+
None,
|
|
58
|
+
description="push the plunger a small amount farther than necessary for accurate low-volume dispensing",
|
|
59
|
+
json_schema_extra=_remove_default,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class DispenseWhileTrackingResult(BaseLiquidHandlingResult, DestinationPositionResult):
|
|
64
|
+
"""Result data from the execution of a Dispense command."""
|
|
65
|
+
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
_ExecuteReturn = Union[
|
|
70
|
+
SuccessData[DispenseWhileTrackingResult],
|
|
71
|
+
DefinedErrorData[OverpressureError] | DefinedErrorData[StallOrCollisionError],
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class DispenseWhileTrackingImplementation(
|
|
76
|
+
AbstractCommandImpl[DispenseWhileTrackingParams, _ExecuteReturn]
|
|
77
|
+
):
|
|
78
|
+
"""Dispense command implementation."""
|
|
79
|
+
|
|
80
|
+
def __init__(
|
|
81
|
+
self,
|
|
82
|
+
state_view: StateView,
|
|
83
|
+
pipetting: PipettingHandler,
|
|
84
|
+
model_utils: ModelUtils,
|
|
85
|
+
gantry_mover: GantryMover,
|
|
86
|
+
movement: MovementHandler,
|
|
87
|
+
**kwargs: object,
|
|
88
|
+
) -> None:
|
|
89
|
+
self._state_view = state_view
|
|
90
|
+
self._pipetting = pipetting
|
|
91
|
+
self._model_utils = model_utils
|
|
92
|
+
self._gantry_mover = gantry_mover
|
|
93
|
+
self._movement = movement
|
|
94
|
+
|
|
95
|
+
async def execute(self, params: DispenseWhileTrackingParams) -> _ExecuteReturn:
|
|
96
|
+
"""Move to and dispense to the requested well."""
|
|
97
|
+
labware_id = params.labwareId
|
|
98
|
+
well_name = params.wellName
|
|
99
|
+
|
|
100
|
+
# TODO(pbm, 10-15-24): call self._state_view.geometry.validate_dispense_volume_into_well()
|
|
101
|
+
|
|
102
|
+
current_location = self._state_view.pipettes.get_current_location()
|
|
103
|
+
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
104
|
+
current_well = CurrentWell(
|
|
105
|
+
pipette_id=params.pipetteId,
|
|
106
|
+
labware_id=params.labwareId,
|
|
107
|
+
well_name=params.wellName,
|
|
108
|
+
)
|
|
109
|
+
state_update = StateUpdate()
|
|
110
|
+
move_result = await move_to_well(
|
|
111
|
+
movement=self._movement,
|
|
112
|
+
model_utils=self._model_utils,
|
|
113
|
+
pipette_id=params.pipetteId,
|
|
114
|
+
labware_id=params.labwareId,
|
|
115
|
+
well_name=params.wellName,
|
|
116
|
+
well_location=params.wellLocation,
|
|
117
|
+
current_well=current_well,
|
|
118
|
+
operation_volume=-params.volume,
|
|
119
|
+
)
|
|
120
|
+
state_update.append(move_result.state_update)
|
|
121
|
+
if isinstance(move_result, DefinedErrorData):
|
|
122
|
+
return DefinedErrorData(
|
|
123
|
+
public=move_result.public, state_update=state_update
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
dispense_result = await dispense_while_tracking(
|
|
127
|
+
pipette_id=params.pipetteId,
|
|
128
|
+
labware_id=labware_id,
|
|
129
|
+
well_name=well_name,
|
|
130
|
+
volume=params.volume,
|
|
131
|
+
flow_rate=params.flowRate,
|
|
132
|
+
push_out=params.pushOut,
|
|
133
|
+
location_if_error={
|
|
134
|
+
"retryLocation": (
|
|
135
|
+
current_position.x,
|
|
136
|
+
current_position.y,
|
|
137
|
+
current_position.z,
|
|
138
|
+
)
|
|
139
|
+
},
|
|
140
|
+
pipetting=self._pipetting,
|
|
141
|
+
model_utils=self._model_utils,
|
|
142
|
+
)
|
|
143
|
+
position_after_dispense = await self._gantry_mover.get_position(
|
|
144
|
+
params.pipetteId
|
|
145
|
+
)
|
|
146
|
+
result_deck_point = DeckPoint.model_construct(
|
|
147
|
+
x=position_after_dispense.x,
|
|
148
|
+
y=position_after_dispense.y,
|
|
149
|
+
z=position_after_dispense.z,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if isinstance(dispense_result, DefinedErrorData):
|
|
153
|
+
if (
|
|
154
|
+
isinstance(current_location, CurrentWell)
|
|
155
|
+
and current_location.pipette_id == params.pipetteId
|
|
156
|
+
):
|
|
157
|
+
return DefinedErrorData(
|
|
158
|
+
public=dispense_result.public,
|
|
159
|
+
state_update=dispense_result.state_update.set_liquid_operated(
|
|
160
|
+
labware_id=current_location.labware_id,
|
|
161
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
162
|
+
current_location.labware_id,
|
|
163
|
+
current_location.well_name,
|
|
164
|
+
params.pipetteId,
|
|
165
|
+
),
|
|
166
|
+
volume_added=CLEAR,
|
|
167
|
+
),
|
|
168
|
+
state_update_if_false_positive=dispense_result.state_update_if_false_positive,
|
|
169
|
+
)
|
|
170
|
+
else:
|
|
171
|
+
return dispense_result
|
|
172
|
+
else:
|
|
173
|
+
if (
|
|
174
|
+
isinstance(current_location, CurrentWell)
|
|
175
|
+
and current_location.pipette_id == params.pipetteId
|
|
176
|
+
):
|
|
177
|
+
volume_added = (
|
|
178
|
+
self._state_view.pipettes.get_liquid_dispensed_by_ejecting_volume(
|
|
179
|
+
pipette_id=params.pipetteId,
|
|
180
|
+
volume=dispense_result.public.volume,
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
if volume_added is not None:
|
|
184
|
+
volume_added *= self._state_view.geometry.get_nozzles_per_well(
|
|
185
|
+
current_location.labware_id,
|
|
186
|
+
current_location.well_name,
|
|
187
|
+
params.pipetteId,
|
|
188
|
+
)
|
|
189
|
+
return SuccessData(
|
|
190
|
+
public=DispenseWhileTrackingResult(
|
|
191
|
+
volume=dispense_result.public.volume,
|
|
192
|
+
position=result_deck_point,
|
|
193
|
+
),
|
|
194
|
+
state_update=dispense_result.state_update.set_liquid_operated(
|
|
195
|
+
labware_id=current_location.labware_id,
|
|
196
|
+
well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
|
|
197
|
+
current_location.labware_id,
|
|
198
|
+
current_location.well_name,
|
|
199
|
+
params.pipetteId,
|
|
200
|
+
),
|
|
201
|
+
volume_added=volume_added
|
|
202
|
+
if volume_added is not None
|
|
203
|
+
else CLEAR,
|
|
204
|
+
),
|
|
205
|
+
)
|
|
206
|
+
else:
|
|
207
|
+
return SuccessData(
|
|
208
|
+
public=DispenseWhileTrackingResult(
|
|
209
|
+
volume=dispense_result.public.volume,
|
|
210
|
+
position=result_deck_point,
|
|
211
|
+
),
|
|
212
|
+
state_update=dispense_result.state_update,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class DispenseWhileTracking(
|
|
217
|
+
BaseCommand[
|
|
218
|
+
DispenseWhileTrackingParams,
|
|
219
|
+
DispenseWhileTrackingResult,
|
|
220
|
+
OverpressureError | StallOrCollisionError,
|
|
221
|
+
]
|
|
222
|
+
):
|
|
223
|
+
"""Dispense command model."""
|
|
224
|
+
|
|
225
|
+
commandType: DispenseWhileTrackingCommandType = "dispenseWhileTracking"
|
|
226
|
+
params: DispenseWhileTrackingParams
|
|
227
|
+
result: Optional[DispenseWhileTrackingResult] = None
|
|
228
|
+
|
|
229
|
+
_ImplementationCls: Type[
|
|
230
|
+
DispenseWhileTrackingImplementation
|
|
231
|
+
] = DispenseWhileTrackingImplementation
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class DispenseWhileTrackingCreate(BaseCommandCreate[DispenseWhileTrackingParams]):
|
|
235
|
+
"""Create dispenseWhileTracking command request model."""
|
|
236
|
+
|
|
237
|
+
commandType: DispenseWhileTrackingCommandType = "dispenseWhileTracking"
|
|
238
|
+
params: DispenseWhileTrackingParams
|
|
239
|
+
|
|
240
|
+
_CommandCls: Type[DispenseWhileTracking] = DispenseWhileTracking
|
|
@@ -35,6 +35,7 @@ if TYPE_CHECKING:
|
|
|
35
35
|
from ..state.state import StateView
|
|
36
36
|
from ..execution import MovementHandler, TipHandler
|
|
37
37
|
|
|
38
|
+
from opentrons.hardware_control.types import TipScrapeType
|
|
38
39
|
|
|
39
40
|
DropTipCommandType = Literal["dropTip"]
|
|
40
41
|
|
|
@@ -72,6 +73,16 @@ class DropTipParams(PipetteIdMixin):
|
|
|
72
73
|
),
|
|
73
74
|
json_schema_extra=_remove_default,
|
|
74
75
|
)
|
|
76
|
+
scrape_tips: bool | SkipJsonSchema[None] = Field(
|
|
77
|
+
False,
|
|
78
|
+
description=(
|
|
79
|
+
"Whether or not to scrape off the tips with the ejector all the way down."
|
|
80
|
+
" If True, and the target location is a tip rack well, it will move the pipette."
|
|
81
|
+
" Towards the center of the tip rack with the ejector in the 'drop_tip' position."
|
|
82
|
+
" If False, no horizontal movement will occur."
|
|
83
|
+
),
|
|
84
|
+
json_schema_extra=_remove_default,
|
|
85
|
+
)
|
|
75
86
|
|
|
76
87
|
|
|
77
88
|
class DropTipResult(DestinationPositionResult):
|
|
@@ -140,9 +151,20 @@ class DropTipImplementation(AbstractCommandImpl[DropTipParams, _ExecuteReturn]):
|
|
|
140
151
|
if isinstance(move_result, DefinedErrorData):
|
|
141
152
|
return move_result
|
|
142
153
|
|
|
154
|
+
scrape_type = TipScrapeType.NONE
|
|
155
|
+
if (
|
|
156
|
+
params.scrape_tips
|
|
157
|
+
and self._state_view.geometry._labware.get_definition(
|
|
158
|
+
labware_id
|
|
159
|
+
).parameters.isTiprack
|
|
160
|
+
):
|
|
161
|
+
if int("".join(filter(str.isdigit, well_name))) <= 6:
|
|
162
|
+
scrape_type = TipScrapeType.RIGHT_ONE_COL
|
|
163
|
+
else:
|
|
164
|
+
scrape_type = TipScrapeType.LEFT_ONE_COL
|
|
143
165
|
try:
|
|
144
166
|
await self._tip_handler.drop_tip(
|
|
145
|
-
pipette_id=pipette_id, home_after=home_after
|
|
167
|
+
pipette_id=pipette_id, home_after=home_after, scrape_type=scrape_type
|
|
146
168
|
)
|
|
147
169
|
except TipAttachedError as exception:
|
|
148
170
|
error = TipPhysicallyAttachedError(
|
|
@@ -4,13 +4,14 @@ from __future__ import annotations
|
|
|
4
4
|
from typing import TYPE_CHECKING, Optional, Type, Union
|
|
5
5
|
from typing_extensions import Literal
|
|
6
6
|
|
|
7
|
-
from opentrons.protocol_engine.errors import UnsupportedLabwareForActionError
|
|
8
7
|
from .pipetting_common import (
|
|
9
8
|
PipetteIdMixin,
|
|
10
9
|
FlowRateMixin,
|
|
11
10
|
DispenseVolumeMixin,
|
|
12
11
|
BaseLiquidHandlingResult,
|
|
13
12
|
dispense_in_place,
|
|
13
|
+
increase_evo_disp_count,
|
|
14
|
+
DEFAULT_CORRECTION_VOLUME,
|
|
14
15
|
)
|
|
15
16
|
from .movement_common import (
|
|
16
17
|
LiquidHandlingWellLocationMixin,
|
|
@@ -26,7 +27,6 @@ from .command import (
|
|
|
26
27
|
DefinedErrorData,
|
|
27
28
|
)
|
|
28
29
|
from ..state.update_types import StateUpdate
|
|
29
|
-
from ..resources import labware_validation
|
|
30
30
|
from ..errors import ProtocolEngineError
|
|
31
31
|
|
|
32
32
|
if TYPE_CHECKING:
|
|
@@ -84,11 +84,6 @@ class EvotipDispenseImplementation(
|
|
|
84
84
|
labware_id = params.labwareId
|
|
85
85
|
well_name = params.wellName
|
|
86
86
|
|
|
87
|
-
labware_definition = self._state_view.labware.get_definition(params.labwareId)
|
|
88
|
-
if not labware_validation.is_evotips(labware_definition.parameters.loadName):
|
|
89
|
-
raise UnsupportedLabwareForActionError(
|
|
90
|
-
f"Cannot use command: `EvotipDispense` with labware: {labware_definition.parameters.loadName}"
|
|
91
|
-
)
|
|
92
87
|
move_result = await move_to_well(
|
|
93
88
|
movement=self._movement,
|
|
94
89
|
model_utils=self._model_utils,
|
|
@@ -101,6 +96,9 @@ class EvotipDispenseImplementation(
|
|
|
101
96
|
return move_result
|
|
102
97
|
|
|
103
98
|
current_position = await self._gantry_mover.get_position(params.pipetteId)
|
|
99
|
+
await increase_evo_disp_count(
|
|
100
|
+
pipette_id=params.pipetteId, pipetting=self._pipetting
|
|
101
|
+
)
|
|
104
102
|
result = await dispense_in_place(
|
|
105
103
|
pipette_id=params.pipetteId,
|
|
106
104
|
volume=params.volume,
|
|
@@ -115,6 +113,7 @@ class EvotipDispenseImplementation(
|
|
|
115
113
|
},
|
|
116
114
|
pipetting=self._pipetting,
|
|
117
115
|
model_utils=self._model_utils,
|
|
116
|
+
correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
|
|
118
117
|
)
|
|
119
118
|
if isinstance(result, DefinedErrorData):
|
|
120
119
|
# TODO (chb, 2025-01-29): Remove this and the OverpressureError returns once disabled for this function
|