opentrons 8.2.0a3__py2.py3-none-any.whl → 8.3.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.
Files changed (238) hide show
  1. opentrons/calibration_storage/deck_configuration.py +3 -3
  2. opentrons/calibration_storage/file_operators.py +3 -3
  3. opentrons/calibration_storage/helpers.py +3 -1
  4. opentrons/calibration_storage/ot2/models/v1.py +16 -29
  5. opentrons/calibration_storage/ot2/tip_length.py +7 -4
  6. opentrons/calibration_storage/ot3/models/v1.py +14 -23
  7. opentrons/cli/analyze.py +18 -6
  8. opentrons/config/defaults_ot3.py +1 -0
  9. opentrons/drivers/asyncio/communication/__init__.py +2 -0
  10. opentrons/drivers/asyncio/communication/errors.py +16 -3
  11. opentrons/drivers/asyncio/communication/serial_connection.py +24 -9
  12. opentrons/drivers/command_builder.py +2 -2
  13. opentrons/drivers/flex_stacker/__init__.py +9 -0
  14. opentrons/drivers/flex_stacker/abstract.py +89 -0
  15. opentrons/drivers/flex_stacker/driver.py +260 -0
  16. opentrons/drivers/flex_stacker/simulator.py +109 -0
  17. opentrons/drivers/flex_stacker/types.py +138 -0
  18. opentrons/drivers/heater_shaker/driver.py +18 -3
  19. opentrons/drivers/temp_deck/driver.py +13 -3
  20. opentrons/drivers/thermocycler/driver.py +17 -3
  21. opentrons/execute.py +3 -1
  22. opentrons/hardware_control/__init__.py +1 -2
  23. opentrons/hardware_control/api.py +33 -21
  24. opentrons/hardware_control/backends/flex_protocol.py +17 -7
  25. opentrons/hardware_control/backends/ot3controller.py +213 -63
  26. opentrons/hardware_control/backends/ot3simulator.py +18 -9
  27. opentrons/hardware_control/backends/ot3utils.py +43 -15
  28. opentrons/hardware_control/dev_types.py +4 -0
  29. opentrons/hardware_control/emulation/heater_shaker.py +4 -0
  30. opentrons/hardware_control/emulation/module_server/client.py +1 -1
  31. opentrons/hardware_control/emulation/module_server/server.py +5 -3
  32. opentrons/hardware_control/emulation/settings.py +3 -4
  33. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +2 -1
  34. opentrons/hardware_control/instruments/ot2/pipette.py +15 -22
  35. opentrons/hardware_control/instruments/ot2/pipette_handler.py +8 -1
  36. opentrons/hardware_control/instruments/ot3/gripper.py +2 -2
  37. opentrons/hardware_control/instruments/ot3/pipette.py +23 -22
  38. opentrons/hardware_control/instruments/ot3/pipette_handler.py +10 -1
  39. opentrons/hardware_control/modules/mod_abc.py +2 -2
  40. opentrons/hardware_control/motion_utilities.py +68 -0
  41. opentrons/hardware_control/nozzle_manager.py +39 -41
  42. opentrons/hardware_control/ot3_calibration.py +1 -1
  43. opentrons/hardware_control/ot3api.py +78 -31
  44. opentrons/hardware_control/protocols/gripper_controller.py +3 -0
  45. opentrons/hardware_control/protocols/hardware_manager.py +5 -1
  46. opentrons/hardware_control/protocols/liquid_handler.py +22 -1
  47. opentrons/hardware_control/protocols/motion_controller.py +7 -0
  48. opentrons/hardware_control/robot_calibration.py +1 -1
  49. opentrons/hardware_control/types.py +61 -0
  50. opentrons/legacy_commands/commands.py +37 -0
  51. opentrons/legacy_commands/types.py +39 -0
  52. opentrons/protocol_api/__init__.py +20 -1
  53. opentrons/protocol_api/_liquid.py +24 -49
  54. opentrons/protocol_api/_liquid_properties.py +754 -0
  55. opentrons/protocol_api/_types.py +24 -0
  56. opentrons/protocol_api/core/common.py +2 -0
  57. opentrons/protocol_api/core/engine/instrument.py +191 -10
  58. opentrons/protocol_api/core/engine/labware.py +29 -7
  59. opentrons/protocol_api/core/engine/protocol.py +130 -5
  60. opentrons/protocol_api/core/engine/robot.py +139 -0
  61. opentrons/protocol_api/core/engine/well.py +4 -1
  62. opentrons/protocol_api/core/instrument.py +73 -4
  63. opentrons/protocol_api/core/labware.py +13 -4
  64. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +87 -3
  65. opentrons/protocol_api/core/legacy/legacy_labware_core.py +13 -4
  66. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +32 -1
  67. opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
  68. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +61 -3
  69. opentrons/protocol_api/core/protocol.py +34 -1
  70. opentrons/protocol_api/core/robot.py +51 -0
  71. opentrons/protocol_api/instrument_context.py +299 -44
  72. opentrons/protocol_api/labware.py +248 -9
  73. opentrons/protocol_api/module_contexts.py +21 -17
  74. opentrons/protocol_api/protocol_context.py +125 -4
  75. opentrons/protocol_api/robot_context.py +204 -32
  76. opentrons/protocol_api/validation.py +262 -3
  77. opentrons/protocol_engine/__init__.py +4 -0
  78. opentrons/protocol_engine/actions/actions.py +2 -3
  79. opentrons/protocol_engine/clients/sync_client.py +18 -0
  80. opentrons/protocol_engine/commands/__init__.py +121 -0
  81. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +1 -3
  82. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +20 -6
  83. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +1 -2
  84. opentrons/protocol_engine/commands/absorbance_reader/read.py +40 -10
  85. opentrons/protocol_engine/commands/air_gap_in_place.py +160 -0
  86. opentrons/protocol_engine/commands/aspirate.py +103 -53
  87. opentrons/protocol_engine/commands/aspirate_in_place.py +55 -51
  88. opentrons/protocol_engine/commands/blow_out.py +44 -39
  89. opentrons/protocol_engine/commands/blow_out_in_place.py +21 -32
  90. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +13 -6
  91. opentrons/protocol_engine/commands/calibration/calibrate_module.py +1 -1
  92. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +3 -3
  93. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +1 -1
  94. opentrons/protocol_engine/commands/command.py +73 -66
  95. opentrons/protocol_engine/commands/command_unions.py +140 -1
  96. opentrons/protocol_engine/commands/comment.py +1 -1
  97. opentrons/protocol_engine/commands/configure_for_volume.py +10 -3
  98. opentrons/protocol_engine/commands/configure_nozzle_layout.py +6 -4
  99. opentrons/protocol_engine/commands/custom.py +6 -12
  100. opentrons/protocol_engine/commands/dispense.py +82 -48
  101. opentrons/protocol_engine/commands/dispense_in_place.py +71 -51
  102. opentrons/protocol_engine/commands/drop_tip.py +52 -31
  103. opentrons/protocol_engine/commands/drop_tip_in_place.py +79 -8
  104. opentrons/protocol_engine/commands/evotip_dispense.py +156 -0
  105. opentrons/protocol_engine/commands/evotip_seal_pipette.py +331 -0
  106. opentrons/protocol_engine/commands/evotip_unseal_pipette.py +160 -0
  107. opentrons/protocol_engine/commands/generate_command_schema.py +4 -11
  108. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  109. opentrons/protocol_engine/commands/get_tip_presence.py +1 -1
  110. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +1 -1
  111. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +1 -1
  112. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +1 -1
  113. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +1 -1
  114. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +1 -1
  115. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +1 -1
  116. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +10 -4
  117. opentrons/protocol_engine/commands/home.py +13 -4
  118. opentrons/protocol_engine/commands/liquid_probe.py +125 -31
  119. opentrons/protocol_engine/commands/load_labware.py +33 -6
  120. opentrons/protocol_engine/commands/load_lid.py +146 -0
  121. opentrons/protocol_engine/commands/load_lid_stack.py +189 -0
  122. opentrons/protocol_engine/commands/load_liquid.py +12 -4
  123. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  124. opentrons/protocol_engine/commands/load_module.py +31 -10
  125. opentrons/protocol_engine/commands/load_pipette.py +19 -8
  126. opentrons/protocol_engine/commands/magnetic_module/disengage.py +1 -1
  127. opentrons/protocol_engine/commands/magnetic_module/engage.py +1 -1
  128. opentrons/protocol_engine/commands/move_labware.py +28 -6
  129. opentrons/protocol_engine/commands/move_relative.py +35 -25
  130. opentrons/protocol_engine/commands/move_to_addressable_area.py +40 -27
  131. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +53 -32
  132. opentrons/protocol_engine/commands/move_to_coordinates.py +36 -22
  133. opentrons/protocol_engine/commands/move_to_well.py +40 -24
  134. opentrons/protocol_engine/commands/movement_common.py +338 -0
  135. opentrons/protocol_engine/commands/pick_up_tip.py +49 -27
  136. opentrons/protocol_engine/commands/pipetting_common.py +169 -87
  137. opentrons/protocol_engine/commands/prepare_to_aspirate.py +24 -33
  138. opentrons/protocol_engine/commands/reload_labware.py +1 -1
  139. opentrons/protocol_engine/commands/retract_axis.py +1 -1
  140. opentrons/protocol_engine/commands/robot/__init__.py +69 -0
  141. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +86 -0
  142. opentrons/protocol_engine/commands/robot/common.py +18 -0
  143. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  144. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  145. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  146. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +77 -0
  147. opentrons/protocol_engine/commands/save_position.py +14 -5
  148. opentrons/protocol_engine/commands/set_rail_lights.py +1 -1
  149. opentrons/protocol_engine/commands/set_status_bar.py +1 -1
  150. opentrons/protocol_engine/commands/temperature_module/deactivate.py +1 -1
  151. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +1 -1
  152. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +10 -4
  153. opentrons/protocol_engine/commands/thermocycler/close_lid.py +1 -1
  154. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +1 -1
  155. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +1 -1
  156. opentrons/protocol_engine/commands/thermocycler/open_lid.py +1 -1
  157. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +9 -3
  158. opentrons/protocol_engine/commands/thermocycler/run_profile.py +9 -3
  159. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +11 -4
  160. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +1 -1
  161. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +1 -1
  162. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +1 -1
  163. opentrons/protocol_engine/commands/touch_tip.py +65 -16
  164. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +5 -2
  165. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +13 -4
  166. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +2 -5
  167. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +1 -1
  168. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +4 -2
  169. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +2 -5
  170. opentrons/protocol_engine/commands/verify_tip_presence.py +11 -4
  171. opentrons/protocol_engine/commands/wait_for_duration.py +10 -3
  172. opentrons/protocol_engine/commands/wait_for_resume.py +10 -3
  173. opentrons/protocol_engine/errors/__init__.py +12 -0
  174. opentrons/protocol_engine/errors/error_occurrence.py +19 -20
  175. opentrons/protocol_engine/errors/exceptions.py +76 -0
  176. opentrons/protocol_engine/execution/command_executor.py +1 -1
  177. opentrons/protocol_engine/execution/equipment.py +73 -5
  178. opentrons/protocol_engine/execution/gantry_mover.py +369 -8
  179. opentrons/protocol_engine/execution/hardware_stopper.py +7 -7
  180. opentrons/protocol_engine/execution/movement.py +27 -0
  181. opentrons/protocol_engine/execution/pipetting.py +5 -1
  182. opentrons/protocol_engine/execution/tip_handler.py +34 -15
  183. opentrons/protocol_engine/notes/notes.py +1 -1
  184. opentrons/protocol_engine/protocol_engine.py +7 -6
  185. opentrons/protocol_engine/resources/labware_data_provider.py +1 -1
  186. opentrons/protocol_engine/resources/labware_validation.py +18 -0
  187. opentrons/protocol_engine/resources/module_data_provider.py +1 -1
  188. opentrons/protocol_engine/resources/pipette_data_provider.py +26 -0
  189. opentrons/protocol_engine/slot_standardization.py +9 -9
  190. opentrons/protocol_engine/state/_move_types.py +9 -5
  191. opentrons/protocol_engine/state/_well_math.py +193 -0
  192. opentrons/protocol_engine/state/addressable_areas.py +25 -61
  193. opentrons/protocol_engine/state/command_history.py +12 -0
  194. opentrons/protocol_engine/state/commands.py +22 -14
  195. opentrons/protocol_engine/state/files.py +10 -12
  196. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  197. opentrons/protocol_engine/state/frustum_helpers.py +63 -69
  198. opentrons/protocol_engine/state/geometry.py +47 -1
  199. opentrons/protocol_engine/state/labware.py +92 -26
  200. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  201. opentrons/protocol_engine/state/liquids.py +16 -4
  202. opentrons/protocol_engine/state/modules.py +56 -71
  203. opentrons/protocol_engine/state/motion.py +6 -1
  204. opentrons/protocol_engine/state/pipettes.py +149 -58
  205. opentrons/protocol_engine/state/state.py +21 -2
  206. opentrons/protocol_engine/state/state_summary.py +4 -2
  207. opentrons/protocol_engine/state/tips.py +11 -44
  208. opentrons/protocol_engine/state/update_types.py +343 -48
  209. opentrons/protocol_engine/state/wells.py +19 -11
  210. opentrons/protocol_engine/types.py +176 -28
  211. opentrons/protocol_reader/extract_labware_definitions.py +5 -2
  212. opentrons/protocol_reader/file_format_validator.py +5 -5
  213. opentrons/protocol_runner/json_file_reader.py +9 -3
  214. opentrons/protocol_runner/json_translator.py +51 -25
  215. opentrons/protocol_runner/legacy_command_mapper.py +66 -64
  216. opentrons/protocol_runner/protocol_runner.py +35 -4
  217. opentrons/protocol_runner/python_protocol_wrappers.py +1 -1
  218. opentrons/protocol_runner/run_orchestrator.py +13 -3
  219. opentrons/protocols/advanced_control/common.py +38 -0
  220. opentrons/protocols/advanced_control/mix.py +1 -1
  221. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  222. opentrons/protocols/advanced_control/transfers/common.py +56 -0
  223. opentrons/protocols/advanced_control/{transfers.py → transfers/transfer.py} +10 -85
  224. opentrons/protocols/api_support/definitions.py +1 -1
  225. opentrons/protocols/api_support/instrument.py +1 -1
  226. opentrons/protocols/api_support/util.py +10 -0
  227. opentrons/protocols/labware.py +70 -8
  228. opentrons/protocols/models/json_protocol.py +5 -9
  229. opentrons/simulate.py +3 -1
  230. opentrons/types.py +162 -2
  231. opentrons/util/entrypoint_util.py +2 -5
  232. opentrons/util/logging_config.py +1 -1
  233. {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/METADATA +16 -15
  234. {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/RECORD +238 -208
  235. {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/WHEEL +1 -1
  236. {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/LICENSE +0 -0
  237. {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/entry_points.txt +0 -0
  238. {opentrons-8.2.0a3.dist-info → opentrons-8.3.0.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,7 @@ from . import temperature_module
20
20
  from . import thermocycler
21
21
  from . import calibration
22
22
  from . import unsafe
23
+ from . import robot
23
24
 
24
25
  from .hash_command_params import hash_protocol_command_params
25
26
  from .generate_command_schema import generate_command_schema
@@ -34,13 +35,23 @@ from .command import (
34
35
 
35
36
  from .command_unions import (
36
37
  Command,
38
+ CommandAdapter,
37
39
  CommandParams,
38
40
  CommandCreate,
41
+ CommandCreateAdapter,
39
42
  CommandResult,
40
43
  CommandType,
41
44
  CommandDefinedErrorData,
42
45
  )
43
46
 
47
+ from .air_gap_in_place import (
48
+ AirGapInPlace,
49
+ AirGapInPlaceParams,
50
+ AirGapInPlaceCreate,
51
+ AirGapInPlaceResult,
52
+ AirGapInPlaceCommandType,
53
+ )
54
+
44
55
  from .aspirate import (
45
56
  Aspirate,
46
57
  AspirateParams,
@@ -138,6 +149,15 @@ from .load_liquid import (
138
149
  LoadLiquidImplementation,
139
150
  )
140
151
 
152
+ from .load_liquid_class import (
153
+ LoadLiquidClass,
154
+ LoadLiquidClassParams,
155
+ LoadLiquidClassCreate,
156
+ LoadLiquidClassResult,
157
+ LoadLiquidClassCommandType,
158
+ LoadLiquidClassImplementation,
159
+ )
160
+
141
161
  from .load_module import (
142
162
  LoadModule,
143
163
  LoadModuleParams,
@@ -154,6 +174,22 @@ from .load_pipette import (
154
174
  LoadPipetteCommandType,
155
175
  )
156
176
 
177
+ from .load_lid_stack import (
178
+ LoadLidStack,
179
+ LoadLidStackParams,
180
+ LoadLidStackCreate,
181
+ LoadLidStackResult,
182
+ LoadLidStackCommandType,
183
+ )
184
+
185
+ from .load_lid import (
186
+ LoadLid,
187
+ LoadLidParams,
188
+ LoadLidCreate,
189
+ LoadLidResult,
190
+ LoadLidCommandType,
191
+ )
192
+
157
193
  from .move_labware import (
158
194
  MoveLabware,
159
195
  MoveLabwareParams,
@@ -323,6 +359,14 @@ from .verify_tip_presence import (
323
359
  VerifyTipPresenceCommandType,
324
360
  )
325
361
 
362
+ from .get_next_tip import (
363
+ GetNextTip,
364
+ GetNextTipCreate,
365
+ GetNextTipParams,
366
+ GetNextTipResult,
367
+ GetNextTipCommandType,
368
+ )
369
+
326
370
  from .liquid_probe import (
327
371
  LiquidProbe,
328
372
  LiquidProbeParams,
@@ -336,11 +380,35 @@ from .liquid_probe import (
336
380
  TryLiquidProbeCommandType,
337
381
  )
338
382
 
383
+ from .evotip_seal_pipette import (
384
+ EvotipSealPipette,
385
+ EvotipSealPipetteParams,
386
+ EvotipSealPipetteCreate,
387
+ EvotipSealPipetteResult,
388
+ EvotipSealPipetteCommandType,
389
+ )
390
+ from .evotip_unseal_pipette import (
391
+ EvotipUnsealPipette,
392
+ EvotipUnsealPipetteParams,
393
+ EvotipUnsealPipetteCreate,
394
+ EvotipUnsealPipetteResult,
395
+ EvotipUnsealPipetteCommandType,
396
+ )
397
+ from .evotip_dispense import (
398
+ EvotipDispense,
399
+ EvotipDispenseParams,
400
+ EvotipDispenseCreate,
401
+ EvotipDispenseResult,
402
+ EvotipDispenseCommandType,
403
+ )
404
+
339
405
  __all__ = [
340
406
  # command type unions
341
407
  "Command",
408
+ "CommandAdapter",
342
409
  "CommandParams",
343
410
  "CommandCreate",
411
+ "CommandCreateAdapter",
344
412
  "CommandResult",
345
413
  "CommandType",
346
414
  "CommandPrivateResult",
@@ -355,6 +423,12 @@ __all__ = [
355
423
  "hash_protocol_command_params",
356
424
  # command schema generation
357
425
  "generate_command_schema",
426
+ # air gap command models
427
+ "AirGapInPlace",
428
+ "AirGapInPlaceCreate",
429
+ "AirGapInPlaceParams",
430
+ "AirGapInPlaceResult",
431
+ "AirGapInPlaceCommandType",
358
432
  # aspirate command models
359
433
  "Aspirate",
360
434
  "AspirateCreate",
@@ -440,6 +514,20 @@ __all__ = [
440
514
  "LoadPipetteResult",
441
515
  "LoadPipetteCommandType",
442
516
  "LoadPipettePrivateResult",
517
+ # load lid stack command models
518
+ "LoadLidStack",
519
+ "LoadLidStackCreate",
520
+ "LoadLidStackParams",
521
+ "LoadLidStackResult",
522
+ "LoadLidStackCommandType",
523
+ "LoadLidStackPrivateResult",
524
+ # load lid command models
525
+ "LoadLid",
526
+ "LoadLidCreate",
527
+ "LoadLidParams",
528
+ "LoadLidResult",
529
+ "LoadLidCommandType",
530
+ "LoadLidPrivateResult",
443
531
  # move labware command models
444
532
  "MoveLabware",
445
533
  "MoveLabwareCreate",
@@ -538,6 +626,14 @@ __all__ = [
538
626
  "LoadLiquidParams",
539
627
  "LoadLiquidResult",
540
628
  "LoadLiquidCommandType",
629
+ # load liquid class command models
630
+ "LoadLiquidClass",
631
+ "LoadLiquidClassParams",
632
+ "LoadLiquidClassCreate",
633
+ "LoadLiquidClassResult",
634
+ "LoadLiquidClassImplementation",
635
+ "LoadLiquidClassCommandType",
636
+ # hardware control command models
541
637
  # hardware module command bundles
542
638
  "absorbance_reader",
543
639
  "heater_shaker",
@@ -548,6 +644,7 @@ __all__ = [
548
644
  "calibration",
549
645
  # unsafe command bundle
550
646
  "unsafe",
647
+ "robot",
551
648
  # configure pipette volume command bundle
552
649
  "ConfigureForVolume",
553
650
  "ConfigureForVolumeCreate",
@@ -578,6 +675,12 @@ __all__ = [
578
675
  "VerifyTipPresenceParams",
579
676
  "VerifyTipPresenceResult",
580
677
  "VerifyTipPresenceCommandType",
678
+ # get next tip command bundle
679
+ "GetNextTip",
680
+ "GetNextTipCreate",
681
+ "GetNextTipParams",
682
+ "GetNextTipResult",
683
+ "GetNextTipCommandType",
581
684
  # liquid probe command bundle
582
685
  "LiquidProbe",
583
686
  "LiquidProbeParams",
@@ -589,4 +692,22 @@ __all__ = [
589
692
  "TryLiquidProbeCreate",
590
693
  "TryLiquidProbeResult",
591
694
  "TryLiquidProbeCommandType",
695
+ # evotip seal command bundle
696
+ "EvotipSealPipette",
697
+ "EvotipSealPipetteParams",
698
+ "EvotipSealPipetteCreate",
699
+ "EvotipSealPipetteResult",
700
+ "EvotipSealPipetteCommandType",
701
+ # evotip unseal command bundle
702
+ "EvotipUnsealPipette",
703
+ "EvotipUnsealPipetteParams",
704
+ "EvotipUnsealPipetteCreate",
705
+ "EvotipUnsealPipetteResult",
706
+ "EvotipUnsealPipetteCommandType",
707
+ # evotip dispense command bundle
708
+ "EvotipDispense",
709
+ "EvotipDispenseParams",
710
+ "EvotipDispenseCreate",
711
+ "EvotipDispenseResult",
712
+ "EvotipDispenseCommandType",
592
713
  ]
@@ -60,7 +60,6 @@ class CloseLidImpl(AbstractCommandImpl[CloseLidParams, SuccessData[CloseLidResul
60
60
  hardware_lid_status = AbsorbanceReaderLidStatus.OFF
61
61
  if not self._state_view.config.use_virtual_modules:
62
62
  abs_reader = self._equipment.get_module_hardware_api(mod_substate.module_id)
63
-
64
63
  if abs_reader is not None:
65
64
  hardware_lid_status = await abs_reader.get_current_lid_status()
66
65
  else:
@@ -95,7 +94,6 @@ class CloseLidImpl(AbstractCommandImpl[CloseLidParams, SuccessData[CloseLidResul
95
94
  deck_slot=self._state_view.modules.get_location(
96
95
  params.moduleId
97
96
  ).slotName,
98
- deck_type=self._state_view.config.deck_type,
99
97
  model=absorbance_model,
100
98
  )
101
99
  )
@@ -134,7 +132,7 @@ class CloseLid(BaseCommand[CloseLidParams, CloseLidResult, ErrorOccurrence]):
134
132
 
135
133
  commandType: CloseLidCommandType = "absorbanceReader/closeLid"
136
134
  params: CloseLidParams
137
- result: Optional[CloseLidResult]
135
+ result: Optional[CloseLidResult] = None
138
136
 
139
137
  _ImplementationCls: Type[CloseLidImpl] = CloseLidImpl
140
138
 
@@ -1,9 +1,10 @@
1
1
  """Command models to initialize an Absorbance Reader."""
2
2
  from __future__ import annotations
3
- from typing import List, Optional, Literal, TYPE_CHECKING
3
+ from typing import List, Optional, Literal, TYPE_CHECKING, Any
4
4
  from typing_extensions import Type
5
5
 
6
6
  from pydantic import BaseModel, Field
7
+ from pydantic.json_schema import SkipJsonSchema
7
8
 
8
9
  from opentrons.drivers.types import ABSMeasurementMode
9
10
  from opentrons.protocol_engine.types import ABSMeasureMode
@@ -11,6 +12,7 @@ from opentrons.protocol_engine.types import ABSMeasureMode
11
12
  from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
12
13
  from ...errors.error_occurrence import ErrorOccurrence
13
14
  from ...errors import InvalidWavelengthError
15
+ from ...state import update_types
14
16
 
15
17
  if TYPE_CHECKING:
16
18
  from opentrons.protocol_engine.state.state import StateView
@@ -20,6 +22,10 @@ if TYPE_CHECKING:
20
22
  InitializeCommandType = Literal["absorbanceReader/initialize"]
21
23
 
22
24
 
25
+ def _remove_default(s: dict[str, Any]) -> None:
26
+ s.pop("default", None)
27
+
28
+
23
29
  class InitializeParams(BaseModel):
24
30
  """Input parameters to initialize an absorbance reading."""
25
31
 
@@ -28,8 +34,10 @@ class InitializeParams(BaseModel):
28
34
  ..., description="Initialize single or multi measurement mode."
29
35
  )
30
36
  sampleWavelengths: List[int] = Field(..., description="Sample wavelengths in nm.")
31
- referenceWavelength: Optional[int] = Field(
32
- None, description="Optional reference wavelength in nm."
37
+ referenceWavelength: int | SkipJsonSchema[None] = Field(
38
+ None,
39
+ description="Optional reference wavelength in nm.",
40
+ json_schema_extra=_remove_default,
33
41
  )
34
42
 
35
43
 
@@ -53,6 +61,7 @@ class InitializeImpl(
53
61
 
54
62
  async def execute(self, params: InitializeParams) -> SuccessData[InitializeResult]:
55
63
  """Initiate a single absorbance measurement."""
64
+ state_update = update_types.StateUpdate()
56
65
  abs_reader_substate = self._state_view.modules.get_absorbance_reader_substate(
57
66
  module_id=params.moduleId
58
67
  )
@@ -113,17 +122,22 @@ class InitializeImpl(
113
122
  reference_wavelength=params.referenceWavelength,
114
123
  )
115
124
 
116
- return SuccessData(
117
- public=InitializeResult(),
125
+ state_update.initialize_absorbance_reader(
126
+ abs_reader_substate.module_id,
127
+ params.measureMode,
128
+ params.sampleWavelengths,
129
+ params.referenceWavelength,
118
130
  )
119
131
 
132
+ return SuccessData(public=InitializeResult(), state_update=state_update)
133
+
120
134
 
121
135
  class Initialize(BaseCommand[InitializeParams, InitializeResult, ErrorOccurrence]):
122
136
  """A command to initialize an Absorbance Reader."""
123
137
 
124
138
  commandType: InitializeCommandType = "absorbanceReader/initialize"
125
139
  params: InitializeParams
126
- result: Optional[InitializeResult]
140
+ result: Optional[InitializeResult] = None
127
141
 
128
142
  _ImplementationCls: Type[InitializeImpl] = InitializeImpl
129
143
 
@@ -91,7 +91,6 @@ class OpenLidImpl(AbstractCommandImpl[OpenLidParams, SuccessData[OpenLidResult]]
91
91
  deck_slot=self._state_view.modules.get_location(
92
92
  params.moduleId
93
93
  ).slotName,
94
- deck_type=self._state_view.config.deck_type,
95
94
  model=absorbance_model,
96
95
  )
97
96
  )
@@ -134,7 +133,7 @@ class OpenLid(BaseCommand[OpenLidParams, OpenLidResult, ErrorOccurrence]):
134
133
 
135
134
  commandType: OpenLidCommandType = "absorbanceReader/openLid"
136
135
  params: OpenLidParams
137
- result: Optional[OpenLidResult]
136
+ result: Optional[OpenLidResult] = None
138
137
 
139
138
  _ImplementationCls: Type[OpenLidImpl] = OpenLidImpl
140
139
 
@@ -1,10 +1,11 @@
1
1
  """Command models to read absorbance."""
2
2
  from __future__ import annotations
3
3
  from datetime import datetime
4
- from typing import Optional, Dict, TYPE_CHECKING, List
5
- from typing_extensions import Literal, Type
4
+ from typing import Optional, Dict, TYPE_CHECKING, List, Any
6
5
 
6
+ from typing_extensions import Literal, Type
7
7
  from pydantic import BaseModel, Field
8
+ from pydantic.json_schema import SkipJsonSchema
8
9
 
9
10
  from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
10
11
  from ...errors import CannotPerformModuleAction, StorageLimitReachedError
@@ -16,12 +17,17 @@ from ...resources.file_provider import (
16
17
  MAXIMUM_CSV_FILE_LIMIT,
17
18
  )
18
19
  from ...resources import FileProvider
20
+ from ...state import update_types
19
21
 
20
22
  if TYPE_CHECKING:
21
23
  from opentrons.protocol_engine.state.state import StateView
22
24
  from opentrons.protocol_engine.execution import EquipmentHandler
23
25
 
24
26
 
27
+ def _remove_default(s: dict[str, Any]) -> None:
28
+ s.pop("default", None)
29
+
30
+
25
31
  ReadAbsorbanceCommandType = Literal["absorbanceReader/read"]
26
32
 
27
33
 
@@ -29,9 +35,10 @@ class ReadAbsorbanceParams(BaseModel):
29
35
  """Input parameters for an absorbance reading."""
30
36
 
31
37
  moduleId: str = Field(..., description="Unique ID of the Absorbance Reader.")
32
- fileName: Optional[str] = Field(
38
+ fileName: str | SkipJsonSchema[None] = Field(
33
39
  None,
34
40
  description="Optional file name to use when storing the results of a measurement.",
41
+ json_schema_extra=_remove_default,
35
42
  )
36
43
 
37
44
 
@@ -67,6 +74,7 @@ class ReadAbsorbanceImpl(
67
74
  self, params: ReadAbsorbanceParams
68
75
  ) -> SuccessData[ReadAbsorbanceResult]:
69
76
  """Initiate an absorbance measurement."""
77
+ state_update = update_types.StateUpdate()
70
78
  abs_reader_substate = self._state_view.modules.get_absorbance_reader_substate(
71
79
  module_id=params.moduleId
72
80
  )
@@ -80,6 +88,10 @@ class ReadAbsorbanceImpl(
80
88
  raise CannotPerformModuleAction(
81
89
  "Cannot perform Read action on Absorbance Reader without calling `.initialize(...)` first."
82
90
  )
91
+ if abs_reader_substate.is_lid_on is False:
92
+ raise CannotPerformModuleAction(
93
+ "Absorbance Plate Reader can't read a plate with the lid open. Call `close_lid()` first."
94
+ )
83
95
 
84
96
  # TODO: we need to return a file ID and increase the file count even when a moduel is not attached
85
97
  if (
@@ -113,7 +125,9 @@ class ReadAbsorbanceImpl(
113
125
  )
114
126
  asbsorbance_result[wavelength] = converted_values
115
127
  transform_results.append(
116
- ReadData.construct(wavelength=wavelength, data=converted_values)
128
+ ReadData.model_construct(
129
+ wavelength=wavelength, data=converted_values
130
+ )
117
131
  )
118
132
  # Handle the virtual module case for data creation (all zeroes)
119
133
  elif self._state_view.config.use_virtual_modules:
@@ -127,22 +141,27 @@ class ReadAbsorbanceImpl(
127
141
  )
128
142
  asbsorbance_result[wavelength] = converted_values
129
143
  transform_results.append(
130
- ReadData.construct(wavelength=wavelength, data=converted_values)
144
+ ReadData.model_construct(
145
+ wavelength=wavelength, data=converted_values
146
+ )
131
147
  )
132
148
  else:
133
149
  raise CannotPerformModuleAction(
134
150
  "Plate Reader data cannot be requested with a module that has not been initialized."
135
151
  )
136
152
 
153
+ state_update.set_absorbance_reader_data(
154
+ module_id=abs_reader_substate.module_id, read_result=asbsorbance_result
155
+ )
137
156
  # TODO (cb, 10-17-2024): FILE PROVIDER - Some day we may want to break the file provider behavior into a seperate API function.
138
157
  # When this happens, we probably will to have the change the command results handler we utilize to track file IDs in engine.
139
158
  # Today, the action handler for the FileStore looks for a ReadAbsorbanceResult command action, this will need to be delinked.
140
159
 
141
160
  # Begin interfacing with the file provider if the user provided a filename
142
- file_ids = []
161
+ file_ids: list[str] = []
143
162
  if params.fileName is not None:
144
163
  # Create the Plate Reader Transform
145
- plate_read_result = PlateReaderData.construct(
164
+ plate_read_result = PlateReaderData.model_construct(
146
165
  read_results=transform_results,
147
166
  reference_wavelength=abs_reader_substate.reference_wavelength,
148
167
  start_time=start_time,
@@ -163,15 +182,26 @@ class ReadAbsorbanceImpl(
163
182
  )
164
183
  file_ids.append(file_id)
165
184
 
185
+ state_update.files_added = update_types.FilesAddedUpdate(
186
+ file_ids=file_ids
187
+ )
166
188
  # Return success data to api
167
189
  return SuccessData(
168
190
  public=ReadAbsorbanceResult(
169
- data=asbsorbance_result, fileIds=file_ids
191
+ data=asbsorbance_result,
192
+ fileIds=file_ids,
170
193
  ),
194
+ state_update=state_update,
171
195
  )
172
196
 
197
+ state_update.files_added = update_types.FilesAddedUpdate(file_ids=file_ids)
198
+
173
199
  return SuccessData(
174
- public=ReadAbsorbanceResult(data=asbsorbance_result, fileIds=file_ids),
200
+ public=ReadAbsorbanceResult(
201
+ data=asbsorbance_result,
202
+ fileIds=file_ids,
203
+ ),
204
+ state_update=state_update,
175
205
  )
176
206
 
177
207
 
@@ -182,7 +212,7 @@ class ReadAbsorbance(
182
212
 
183
213
  commandType: ReadAbsorbanceCommandType = "absorbanceReader/read"
184
214
  params: ReadAbsorbanceParams
185
- result: Optional[ReadAbsorbanceResult]
215
+ result: Optional[ReadAbsorbanceResult] = None
186
216
 
187
217
  _ImplementationCls: Type[ReadAbsorbanceImpl] = ReadAbsorbanceImpl
188
218
 
@@ -0,0 +1,160 @@
1
+ """AirGap in place command request, result, and implementation models."""
2
+
3
+ from __future__ import annotations
4
+ from typing import TYPE_CHECKING, Optional, Type, Union
5
+ from typing_extensions import Literal
6
+
7
+ from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
8
+
9
+ from opentrons.hardware_control import HardwareControlAPI
10
+
11
+ from .pipetting_common import (
12
+ PipetteIdMixin,
13
+ AspirateVolumeMixin,
14
+ FlowRateMixin,
15
+ BaseLiquidHandlingResult,
16
+ OverpressureError,
17
+ )
18
+ from .command import (
19
+ AbstractCommandImpl,
20
+ BaseCommand,
21
+ BaseCommandCreate,
22
+ SuccessData,
23
+ DefinedErrorData,
24
+ )
25
+ from ..errors.error_occurrence import ErrorOccurrence
26
+ from ..errors.exceptions import PipetteNotReadyToAspirateError
27
+ from ..state.update_types import StateUpdate
28
+ from ..types import AspiratedFluid, FluidKind
29
+
30
+ if TYPE_CHECKING:
31
+ from ..execution import PipettingHandler, GantryMover
32
+ from ..resources import ModelUtils
33
+ from ..state.state import StateView
34
+ from ..notes import CommandNoteAdder
35
+
36
+ AirGapInPlaceCommandType = Literal["airGapInPlace"]
37
+
38
+
39
+ class AirGapInPlaceParams(PipetteIdMixin, AspirateVolumeMixin, FlowRateMixin):
40
+ """Payload required to air gap in place."""
41
+
42
+ pass
43
+
44
+
45
+ class AirGapInPlaceResult(BaseLiquidHandlingResult):
46
+ """Result data from the execution of a AirGapInPlace command."""
47
+
48
+ pass
49
+
50
+
51
+ _ExecuteReturn = Union[
52
+ SuccessData[AirGapInPlaceResult],
53
+ DefinedErrorData[OverpressureError],
54
+ ]
55
+
56
+
57
+ class AirGapInPlaceImplementation(
58
+ AbstractCommandImpl[AirGapInPlaceParams, _ExecuteReturn]
59
+ ):
60
+ """AirGapInPlace command implementation."""
61
+
62
+ def __init__(
63
+ self,
64
+ pipetting: PipettingHandler,
65
+ hardware_api: HardwareControlAPI,
66
+ state_view: StateView,
67
+ command_note_adder: CommandNoteAdder,
68
+ model_utils: ModelUtils,
69
+ gantry_mover: GantryMover,
70
+ **kwargs: object,
71
+ ) -> None:
72
+ self._pipetting = pipetting
73
+ self._state_view = state_view
74
+ self._hardware_api = hardware_api
75
+ self._command_note_adder = command_note_adder
76
+ self._model_utils = model_utils
77
+ self._gantry_mover = gantry_mover
78
+
79
+ async def execute(self, params: AirGapInPlaceParams) -> _ExecuteReturn:
80
+ """Air gap without moving the pipette.
81
+
82
+ Raises:
83
+ TipNotAttachedError: if no tip is attached to the pipette.
84
+ PipetteNotReadyToAirGapError: pipette plunger is not ready.
85
+ """
86
+ ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
87
+ pipette_id=params.pipetteId,
88
+ )
89
+
90
+ if not ready_to_aspirate:
91
+ raise PipetteNotReadyToAspirateError(
92
+ "Pipette cannot air gap in place because of a previous blow out."
93
+ " The first aspirate following a blow-out must be from a specific well"
94
+ " so the plunger can be reset in a known safe position."
95
+ )
96
+
97
+ state_update = StateUpdate()
98
+
99
+ try:
100
+ current_position = await self._gantry_mover.get_position(params.pipetteId)
101
+ volume = await self._pipetting.aspirate_in_place(
102
+ pipette_id=params.pipetteId,
103
+ volume=params.volume,
104
+ flow_rate=params.flowRate,
105
+ command_note_adder=self._command_note_adder,
106
+ )
107
+ except PipetteOverpressureError as e:
108
+ return DefinedErrorData(
109
+ public=OverpressureError(
110
+ id=self._model_utils.generate_id(),
111
+ createdAt=self._model_utils.get_timestamp(),
112
+ wrappedErrors=[
113
+ ErrorOccurrence.from_failed(
114
+ id=self._model_utils.generate_id(),
115
+ createdAt=self._model_utils.get_timestamp(),
116
+ error=e,
117
+ )
118
+ ],
119
+ errorInfo=(
120
+ {
121
+ "retryLocation": (
122
+ current_position.x,
123
+ current_position.y,
124
+ current_position.z,
125
+ )
126
+ }
127
+ ),
128
+ ),
129
+ state_update=state_update,
130
+ )
131
+ else:
132
+ state_update.set_fluid_aspirated(
133
+ pipette_id=params.pipetteId,
134
+ fluid=AspiratedFluid(kind=FluidKind.AIR, volume=volume),
135
+ )
136
+ return SuccessData(
137
+ public=AirGapInPlaceResult(volume=volume),
138
+ state_update=state_update,
139
+ )
140
+
141
+
142
+ class AirGapInPlace(
143
+ BaseCommand[AirGapInPlaceParams, AirGapInPlaceResult, OverpressureError]
144
+ ):
145
+ """AirGapInPlace command model."""
146
+
147
+ commandType: AirGapInPlaceCommandType = "airGapInPlace"
148
+ params: AirGapInPlaceParams
149
+ result: Optional[AirGapInPlaceResult] = None
150
+
151
+ _ImplementationCls: Type[AirGapInPlaceImplementation] = AirGapInPlaceImplementation
152
+
153
+
154
+ class AirGapInPlaceCreate(BaseCommandCreate[AirGapInPlaceParams]):
155
+ """AirGapInPlace command request model."""
156
+
157
+ commandType: AirGapInPlaceCommandType = "airGapInPlace"
158
+ params: AirGapInPlaceParams
159
+
160
+ _CommandCls: Type[AirGapInPlace] = AirGapInPlace