opentrons 8.3.2a0__py2.py3-none-any.whl → 8.4.0__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.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

Files changed (196) hide show
  1. opentrons/calibration_storage/ot2/mark_bad_calibration.py +2 -0
  2. opentrons/calibration_storage/ot2/tip_length.py +6 -6
  3. opentrons/config/advanced_settings.py +9 -11
  4. opentrons/config/feature_flags.py +0 -4
  5. opentrons/config/reset.py +7 -2
  6. opentrons/drivers/asyncio/communication/__init__.py +2 -0
  7. opentrons/drivers/asyncio/communication/async_serial.py +4 -0
  8. opentrons/drivers/asyncio/communication/errors.py +41 -8
  9. opentrons/drivers/asyncio/communication/serial_connection.py +36 -10
  10. opentrons/drivers/flex_stacker/__init__.py +9 -3
  11. opentrons/drivers/flex_stacker/abstract.py +140 -15
  12. opentrons/drivers/flex_stacker/driver.py +593 -47
  13. opentrons/drivers/flex_stacker/errors.py +64 -0
  14. opentrons/drivers/flex_stacker/simulator.py +222 -24
  15. opentrons/drivers/flex_stacker/types.py +211 -15
  16. opentrons/drivers/flex_stacker/utils.py +19 -0
  17. opentrons/execute.py +4 -2
  18. opentrons/hardware_control/api.py +5 -0
  19. opentrons/hardware_control/backends/flex_protocol.py +4 -0
  20. opentrons/hardware_control/backends/ot3controller.py +12 -1
  21. opentrons/hardware_control/backends/ot3simulator.py +3 -0
  22. opentrons/hardware_control/backends/subsystem_manager.py +8 -4
  23. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +10 -6
  24. opentrons/hardware_control/instruments/ot3/pipette_handler.py +59 -6
  25. opentrons/hardware_control/modules/__init__.py +12 -1
  26. opentrons/hardware_control/modules/absorbance_reader.py +11 -9
  27. opentrons/hardware_control/modules/flex_stacker.py +498 -0
  28. opentrons/hardware_control/modules/heater_shaker.py +12 -10
  29. opentrons/hardware_control/modules/magdeck.py +5 -1
  30. opentrons/hardware_control/modules/tempdeck.py +5 -1
  31. opentrons/hardware_control/modules/thermocycler.py +15 -14
  32. opentrons/hardware_control/modules/types.py +191 -1
  33. opentrons/hardware_control/modules/utils.py +3 -0
  34. opentrons/hardware_control/motion_utilities.py +20 -0
  35. opentrons/hardware_control/ot3api.py +145 -15
  36. opentrons/hardware_control/protocols/liquid_handler.py +47 -1
  37. opentrons/hardware_control/types.py +6 -0
  38. opentrons/legacy_commands/commands.py +102 -5
  39. opentrons/legacy_commands/helpers.py +74 -1
  40. opentrons/legacy_commands/types.py +33 -2
  41. opentrons/protocol_api/__init__.py +2 -0
  42. opentrons/protocol_api/_liquid.py +39 -8
  43. opentrons/protocol_api/_liquid_properties.py +20 -19
  44. opentrons/protocol_api/_transfer_liquid_validation.py +91 -0
  45. opentrons/protocol_api/core/common.py +3 -1
  46. opentrons/protocol_api/core/engine/deck_conflict.py +11 -1
  47. opentrons/protocol_api/core/engine/instrument.py +1356 -107
  48. opentrons/protocol_api/core/engine/labware.py +8 -4
  49. opentrons/protocol_api/core/engine/load_labware_params.py +68 -10
  50. opentrons/protocol_api/core/engine/module_core.py +118 -2
  51. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +6 -14
  52. opentrons/protocol_api/core/engine/protocol.py +253 -11
  53. opentrons/protocol_api/core/engine/stringify.py +19 -8
  54. opentrons/protocol_api/core/engine/transfer_components_executor.py +858 -0
  55. opentrons/protocol_api/core/engine/well.py +73 -5
  56. opentrons/protocol_api/core/instrument.py +71 -21
  57. opentrons/protocol_api/core/labware.py +6 -2
  58. opentrons/protocol_api/core/legacy/labware_offset_provider.py +7 -3
  59. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +76 -49
  60. opentrons/protocol_api/core/legacy/legacy_labware_core.py +8 -4
  61. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +36 -0
  62. opentrons/protocol_api/core/legacy/legacy_well_core.py +27 -2
  63. opentrons/protocol_api/core/legacy/load_info.py +4 -12
  64. opentrons/protocol_api/core/legacy/module_geometry.py +6 -1
  65. opentrons/protocol_api/core/legacy/well_geometry.py +3 -3
  66. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +73 -23
  67. opentrons/protocol_api/core/module.py +43 -0
  68. opentrons/protocol_api/core/protocol.py +33 -0
  69. opentrons/protocol_api/core/well.py +23 -2
  70. opentrons/protocol_api/instrument_context.py +454 -150
  71. opentrons/protocol_api/labware.py +98 -50
  72. opentrons/protocol_api/module_contexts.py +140 -0
  73. opentrons/protocol_api/protocol_context.py +163 -19
  74. opentrons/protocol_api/validation.py +51 -41
  75. opentrons/protocol_engine/__init__.py +21 -2
  76. opentrons/protocol_engine/actions/actions.py +5 -5
  77. opentrons/protocol_engine/clients/sync_client.py +6 -0
  78. opentrons/protocol_engine/commands/__init__.py +66 -36
  79. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +0 -1
  80. opentrons/protocol_engine/commands/air_gap_in_place.py +3 -2
  81. opentrons/protocol_engine/commands/aspirate.py +6 -2
  82. opentrons/protocol_engine/commands/aspirate_in_place.py +3 -1
  83. opentrons/protocol_engine/commands/aspirate_while_tracking.py +210 -0
  84. opentrons/protocol_engine/commands/blow_out.py +2 -0
  85. opentrons/protocol_engine/commands/blow_out_in_place.py +4 -1
  86. opentrons/protocol_engine/commands/command_unions.py +102 -33
  87. opentrons/protocol_engine/commands/configure_for_volume.py +3 -0
  88. opentrons/protocol_engine/commands/dispense.py +3 -1
  89. opentrons/protocol_engine/commands/dispense_in_place.py +3 -0
  90. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  91. opentrons/protocol_engine/commands/drop_tip.py +23 -1
  92. opentrons/protocol_engine/commands/flex_stacker/__init__.py +106 -0
  93. opentrons/protocol_engine/commands/flex_stacker/close_latch.py +72 -0
  94. opentrons/protocol_engine/commands/flex_stacker/common.py +15 -0
  95. opentrons/protocol_engine/commands/flex_stacker/empty.py +161 -0
  96. opentrons/protocol_engine/commands/flex_stacker/fill.py +164 -0
  97. opentrons/protocol_engine/commands/flex_stacker/open_latch.py +70 -0
  98. opentrons/protocol_engine/commands/flex_stacker/prepare_shuttle.py +112 -0
  99. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +394 -0
  100. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +190 -0
  101. opentrons/protocol_engine/commands/flex_stacker/store.py +291 -0
  102. opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
  103. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  104. opentrons/protocol_engine/commands/liquid_probe.py +27 -13
  105. opentrons/protocol_engine/commands/load_labware.py +42 -39
  106. opentrons/protocol_engine/commands/load_lid.py +21 -13
  107. opentrons/protocol_engine/commands/load_lid_stack.py +130 -47
  108. opentrons/protocol_engine/commands/load_module.py +18 -17
  109. opentrons/protocol_engine/commands/load_pipette.py +3 -0
  110. opentrons/protocol_engine/commands/move_labware.py +139 -20
  111. opentrons/protocol_engine/commands/move_to_well.py +5 -11
  112. opentrons/protocol_engine/commands/pick_up_tip.py +5 -2
  113. opentrons/protocol_engine/commands/pipetting_common.py +159 -8
  114. opentrons/protocol_engine/commands/prepare_to_aspirate.py +15 -5
  115. opentrons/protocol_engine/commands/{evotip_dispense.py → pressure_dispense.py} +33 -34
  116. opentrons/protocol_engine/commands/reload_labware.py +6 -19
  117. opentrons/protocol_engine/commands/{evotip_seal_pipette.py → seal_pipette_to_tip.py} +97 -76
  118. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +3 -1
  119. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +6 -1
  120. opentrons/protocol_engine/commands/{evotip_unseal_pipette.py → unseal_pipette_from_tip.py} +31 -40
  121. opentrons/protocol_engine/errors/__init__.py +10 -0
  122. opentrons/protocol_engine/errors/exceptions.py +62 -0
  123. opentrons/protocol_engine/execution/equipment.py +123 -106
  124. opentrons/protocol_engine/execution/labware_movement.py +8 -6
  125. opentrons/protocol_engine/execution/pipetting.py +235 -25
  126. opentrons/protocol_engine/execution/tip_handler.py +82 -32
  127. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  128. opentrons/protocol_engine/protocol_engine.py +22 -13
  129. opentrons/protocol_engine/resources/deck_configuration_provider.py +98 -2
  130. opentrons/protocol_engine/resources/deck_data_provider.py +1 -1
  131. opentrons/protocol_engine/resources/labware_data_provider.py +32 -12
  132. opentrons/protocol_engine/resources/labware_validation.py +7 -5
  133. opentrons/protocol_engine/slot_standardization.py +11 -23
  134. opentrons/protocol_engine/state/addressable_areas.py +84 -46
  135. opentrons/protocol_engine/state/frustum_helpers.py +36 -14
  136. opentrons/protocol_engine/state/geometry.py +892 -227
  137. opentrons/protocol_engine/state/labware.py +252 -55
  138. opentrons/protocol_engine/state/module_substates/__init__.py +4 -0
  139. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +68 -0
  140. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +22 -0
  141. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +13 -0
  142. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +20 -0
  143. opentrons/protocol_engine/state/modules.py +210 -67
  144. opentrons/protocol_engine/state/pipettes.py +54 -0
  145. opentrons/protocol_engine/state/state.py +1 -1
  146. opentrons/protocol_engine/state/tips.py +14 -0
  147. opentrons/protocol_engine/state/update_types.py +180 -25
  148. opentrons/protocol_engine/state/wells.py +55 -9
  149. opentrons/protocol_engine/types/__init__.py +300 -0
  150. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  151. opentrons/protocol_engine/types/command_annotations.py +53 -0
  152. opentrons/protocol_engine/types/deck_configuration.py +72 -0
  153. opentrons/protocol_engine/types/execution.py +96 -0
  154. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  155. opentrons/protocol_engine/types/instrument.py +47 -0
  156. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  157. opentrons/protocol_engine/types/labware.py +111 -0
  158. opentrons/protocol_engine/types/labware_movement.py +22 -0
  159. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  160. opentrons/protocol_engine/types/labware_offset_vector.py +33 -0
  161. opentrons/protocol_engine/types/liquid.py +40 -0
  162. opentrons/protocol_engine/types/liquid_class.py +59 -0
  163. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  164. opentrons/protocol_engine/types/liquid_level_detection.py +131 -0
  165. opentrons/protocol_engine/types/location.py +194 -0
  166. opentrons/protocol_engine/types/module.py +301 -0
  167. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  168. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  169. opentrons/protocol_engine/types/tip.py +18 -0
  170. opentrons/protocol_engine/types/util.py +21 -0
  171. opentrons/protocol_engine/types/well_position.py +124 -0
  172. opentrons/protocol_reader/extract_labware_definitions.py +7 -3
  173. opentrons/protocol_reader/file_format_validator.py +5 -3
  174. opentrons/protocol_runner/json_translator.py +4 -2
  175. opentrons/protocol_runner/legacy_command_mapper.py +6 -2
  176. opentrons/protocol_runner/run_orchestrator.py +4 -1
  177. opentrons/protocols/advanced_control/transfers/common.py +48 -1
  178. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +204 -0
  179. opentrons/protocols/api_support/definitions.py +1 -1
  180. opentrons/protocols/api_support/instrument.py +16 -3
  181. opentrons/protocols/labware.py +27 -23
  182. opentrons/protocols/models/__init__.py +0 -21
  183. opentrons/simulate.py +4 -2
  184. opentrons/types.py +20 -7
  185. opentrons/util/logging_config.py +94 -25
  186. opentrons/util/logging_queue_handler.py +61 -0
  187. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/METADATA +4 -4
  188. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/RECORD +192 -151
  189. opentrons/calibration_storage/ot2/models/defaults.py +0 -0
  190. opentrons/calibration_storage/ot3/models/defaults.py +0 -0
  191. opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
  192. opentrons/protocol_engine/types.py +0 -1311
  193. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/LICENSE +0 -0
  194. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/WHEEL +0 -0
  195. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/entry_points.txt +0 -0
  196. {opentrons-8.3.2a0.dist-info → opentrons-8.4.0.dist-info}/top_level.txt +0 -0
@@ -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,
@@ -360,28 +378,28 @@ from .liquid_probe import (
360
378
  TryLiquidProbeCommandType,
361
379
  )
362
380
 
363
- from .evotip_seal_pipette import (
364
- EvotipSealPipette,
365
- EvotipSealPipetteParams,
366
- EvotipSealPipetteCreate,
367
- EvotipSealPipetteResult,
368
- EvotipSealPipetteCommandType,
381
+ from .seal_pipette_to_tip import (
382
+ SealPipetteToTip,
383
+ SealPipetteToTipParams,
384
+ SealPipetteToTipCreate,
385
+ SealPipetteToTipResult,
386
+ SealPipetteToTipCommandType,
369
387
  )
370
388
 
371
- from .evotip_dispense import (
372
- EvotipDispense,
373
- EvotipDispenseParams,
374
- EvotipDispenseCreate,
375
- EvotipDispenseResult,
376
- EvotipDispenseCommandType,
389
+ from .pressure_dispense import (
390
+ PressureDispense,
391
+ PressureDispenseParams,
392
+ PressureDispenseCreate,
393
+ PressureDispenseResult,
394
+ PressureDispenseCommandType,
377
395
  )
378
396
 
379
- from .evotip_unseal_pipette import (
380
- EvotipUnsealPipette,
381
- EvotipUnsealPipetteParams,
382
- EvotipUnsealPipetteCreate,
383
- EvotipUnsealPipetteResult,
384
- EvotipUnsealPipetteCommandType,
397
+ from .unseal_pipette_from_tip import (
398
+ UnsealPipetteFromTip,
399
+ UnsealPipetteFromTipParams,
400
+ UnsealPipetteFromTipCreate,
401
+ UnsealPipetteFromTipResult,
402
+ UnsealPipetteFromTipCommandType,
385
403
  )
386
404
 
387
405
  Command = Annotated[
@@ -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,
@@ -428,9 +448,9 @@ Command = Annotated[
428
448
  GetNextTip,
429
449
  LiquidProbe,
430
450
  TryLiquidProbe,
431
- EvotipSealPipette,
432
- EvotipDispense,
433
- EvotipUnsealPipette,
451
+ SealPipetteToTip,
452
+ PressureDispense,
453
+ UnsealPipetteFromTip,
434
454
  heater_shaker.WaitForTemperature,
435
455
  heater_shaker.SetTargetTemperature,
436
456
  heater_shaker.DeactivateHeater,
@@ -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,
@@ -519,9 +549,9 @@ CommandParams = Union[
519
549
  GetNextTipParams,
520
550
  LiquidProbeParams,
521
551
  TryLiquidProbeParams,
522
- EvotipSealPipetteParams,
523
- EvotipDispenseParams,
524
- EvotipUnsealPipetteParams,
552
+ SealPipetteToTipParams,
553
+ PressureDispenseParams,
554
+ UnsealPipetteFromTipParams,
525
555
  heater_shaker.WaitForTemperatureParams,
526
556
  heater_shaker.SetTargetTemperatureParams,
527
557
  heater_shaker.DeactivateHeaterParams,
@@ -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,
@@ -608,9 +648,9 @@ CommandType = Union[
608
648
  GetNextTipCommandType,
609
649
  LiquidProbeCommandType,
610
650
  TryLiquidProbeCommandType,
611
- EvotipSealPipetteCommandType,
612
- EvotipDispenseCommandType,
613
- EvotipUnsealPipetteCommandType,
651
+ SealPipetteToTipCommandType,
652
+ PressureDispenseCommandType,
653
+ UnsealPipetteFromTipCommandType,
614
654
  heater_shaker.WaitForTemperatureCommandType,
615
655
  heater_shaker.SetTargetTemperatureCommandType,
616
656
  heater_shaker.DeactivateHeaterCommandType,
@@ -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,
@@ -698,9 +748,9 @@ CommandCreate = Annotated[
698
748
  GetNextTipCreate,
699
749
  LiquidProbeCreate,
700
750
  TryLiquidProbeCreate,
701
- EvotipSealPipetteCreate,
702
- EvotipDispenseCreate,
703
- EvotipUnsealPipetteCreate,
751
+ SealPipetteToTipCreate,
752
+ PressureDispenseCreate,
753
+ UnsealPipetteFromTipCreate,
704
754
  heater_shaker.WaitForTemperatureCreate,
705
755
  heater_shaker.SetTargetTemperatureCreate,
706
756
  heater_shaker.DeactivateHeaterCreate,
@@ -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,
@@ -796,9 +856,9 @@ CommandResult = Union[
796
856
  GetNextTipResult,
797
857
  LiquidProbeResult,
798
858
  TryLiquidProbeResult,
799
- EvotipSealPipetteResult,
800
- EvotipDispenseResult,
801
- EvotipUnsealPipetteResult,
859
+ SealPipetteToTipResult,
860
+ PressureDispenseResult,
861
+ UnsealPipetteFromTipResult,
802
862
  heater_shaker.WaitForTemperatureResult,
803
863
  heater_shaker.SetTargetTemperatureResult,
804
864
  heater_shaker.DeactivateHeaterResult,
@@ -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,204 @@
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 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
+ state_update = StateUpdate()
103
+ move_result = await move_to_well(
104
+ movement=self._movement,
105
+ model_utils=self._model_utils,
106
+ pipette_id=params.pipetteId,
107
+ labware_id=params.labwareId,
108
+ well_name=params.wellName,
109
+ well_location=params.wellLocation,
110
+ )
111
+ state_update.append(move_result.state_update)
112
+ if isinstance(move_result, DefinedErrorData):
113
+ return DefinedErrorData(
114
+ public=move_result.public, state_update=state_update
115
+ )
116
+
117
+ dispense_result = await dispense_while_tracking(
118
+ pipette_id=params.pipetteId,
119
+ labware_id=labware_id,
120
+ well_name=well_name,
121
+ volume=params.volume,
122
+ flow_rate=params.flowRate,
123
+ push_out=params.pushOut,
124
+ location_if_error={
125
+ "retryLocation": (
126
+ move_result.public.position.x,
127
+ move_result.public.position.y,
128
+ move_result.public.position.z,
129
+ )
130
+ },
131
+ pipetting=self._pipetting,
132
+ model_utils=self._model_utils,
133
+ )
134
+ position_after_dispense = await self._gantry_mover.get_position(
135
+ params.pipetteId
136
+ )
137
+ result_deck_point = DeckPoint.model_construct(
138
+ x=position_after_dispense.x,
139
+ y=position_after_dispense.y,
140
+ z=position_after_dispense.z,
141
+ )
142
+
143
+ if isinstance(dispense_result, DefinedErrorData):
144
+ return DefinedErrorData(
145
+ public=dispense_result.public,
146
+ state_update=dispense_result.state_update.set_liquid_operated(
147
+ labware_id=params.labwareId,
148
+ well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
149
+ params.labwareId,
150
+ params.wellName,
151
+ params.pipetteId,
152
+ ),
153
+ volume_added=CLEAR,
154
+ ),
155
+ state_update_if_false_positive=dispense_result.state_update_if_false_positive,
156
+ )
157
+
158
+ return SuccessData(
159
+ public=DispenseWhileTrackingResult(
160
+ volume=dispense_result.public.volume,
161
+ position=result_deck_point,
162
+ ),
163
+ state_update=dispense_result.state_update.set_liquid_operated(
164
+ labware_id=params.labwareId,
165
+ well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
166
+ params.labwareId,
167
+ params.wellName,
168
+ params.pipetteId,
169
+ ),
170
+ volume_added=dispense_result.public.volume
171
+ * self._state_view.geometry.get_nozzles_per_well(
172
+ params.labwareId,
173
+ params.wellName,
174
+ params.pipetteId,
175
+ ),
176
+ ),
177
+ )
178
+
179
+
180
+ class DispenseWhileTracking(
181
+ BaseCommand[
182
+ DispenseWhileTrackingParams,
183
+ DispenseWhileTrackingResult,
184
+ OverpressureError | StallOrCollisionError,
185
+ ]
186
+ ):
187
+ """Dispense command model."""
188
+
189
+ commandType: DispenseWhileTrackingCommandType = "dispenseWhileTracking"
190
+ params: DispenseWhileTrackingParams
191
+ result: Optional[DispenseWhileTrackingResult] = None
192
+
193
+ _ImplementationCls: Type[
194
+ DispenseWhileTrackingImplementation
195
+ ] = DispenseWhileTrackingImplementation
196
+
197
+
198
+ class DispenseWhileTrackingCreate(BaseCommandCreate[DispenseWhileTrackingParams]):
199
+ """Create dispenseWhileTracking command request model."""
200
+
201
+ commandType: DispenseWhileTrackingCommandType = "dispenseWhileTracking"
202
+ params: DispenseWhileTrackingParams
203
+
204
+ _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(