opentrons 8.6.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (600) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +501 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +183 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/simulator_setup.py +260 -0
  200. opentrons/hardware_control/thread_manager.py +431 -0
  201. opentrons/hardware_control/threaded_async_lock.py +97 -0
  202. opentrons/hardware_control/types.py +792 -0
  203. opentrons/hardware_control/util.py +234 -0
  204. opentrons/legacy_broker.py +53 -0
  205. opentrons/legacy_commands/__init__.py +1 -0
  206. opentrons/legacy_commands/commands.py +483 -0
  207. opentrons/legacy_commands/helpers.py +153 -0
  208. opentrons/legacy_commands/module_commands.py +215 -0
  209. opentrons/legacy_commands/protocol_commands.py +54 -0
  210. opentrons/legacy_commands/publisher.py +155 -0
  211. opentrons/legacy_commands/robot_commands.py +51 -0
  212. opentrons/legacy_commands/types.py +1115 -0
  213. opentrons/motion_planning/__init__.py +32 -0
  214. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  215. opentrons/motion_planning/deck_conflict.py +396 -0
  216. opentrons/motion_planning/errors.py +35 -0
  217. opentrons/motion_planning/types.py +42 -0
  218. opentrons/motion_planning/waypoints.py +218 -0
  219. opentrons/ordered_set.py +138 -0
  220. opentrons/protocol_api/__init__.py +105 -0
  221. opentrons/protocol_api/_liquid.py +157 -0
  222. opentrons/protocol_api/_liquid_properties.py +814 -0
  223. opentrons/protocol_api/_nozzle_layout.py +31 -0
  224. opentrons/protocol_api/_parameter_context.py +300 -0
  225. opentrons/protocol_api/_parameters.py +31 -0
  226. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  227. opentrons/protocol_api/_types.py +43 -0
  228. opentrons/protocol_api/config.py +23 -0
  229. opentrons/protocol_api/core/__init__.py +23 -0
  230. opentrons/protocol_api/core/common.py +33 -0
  231. opentrons/protocol_api/core/core_map.py +74 -0
  232. opentrons/protocol_api/core/engine/__init__.py +22 -0
  233. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  234. opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
  235. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  236. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  237. opentrons/protocol_api/core/engine/labware.py +238 -0
  238. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  239. opentrons/protocol_api/core/engine/module_core.py +1025 -0
  240. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  241. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  242. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  243. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  244. opentrons/protocol_api/core/engine/robot.py +139 -0
  245. opentrons/protocol_api/core/engine/stringify.py +74 -0
  246. opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
  247. opentrons/protocol_api/core/engine/well.py +241 -0
  248. opentrons/protocol_api/core/instrument.py +459 -0
  249. opentrons/protocol_api/core/labware.py +151 -0
  250. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  251. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  252. opentrons/protocol_api/core/legacy/deck.py +369 -0
  253. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  254. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  255. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  256. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  257. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  258. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  259. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  260. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  261. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  262. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  263. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  265. opentrons/protocol_api/core/module.py +484 -0
  266. opentrons/protocol_api/core/protocol.py +311 -0
  267. opentrons/protocol_api/core/robot.py +51 -0
  268. opentrons/protocol_api/core/well.py +116 -0
  269. opentrons/protocol_api/core/well_grid.py +45 -0
  270. opentrons/protocol_api/create_protocol_context.py +177 -0
  271. opentrons/protocol_api/deck.py +223 -0
  272. opentrons/protocol_api/disposal_locations.py +244 -0
  273. opentrons/protocol_api/instrument_context.py +3212 -0
  274. opentrons/protocol_api/labware.py +1579 -0
  275. opentrons/protocol_api/module_contexts.py +1425 -0
  276. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  277. opentrons/protocol_api/protocol_context.py +1688 -0
  278. opentrons/protocol_api/robot_context.py +303 -0
  279. opentrons/protocol_api/validation.py +761 -0
  280. opentrons/protocol_engine/__init__.py +155 -0
  281. opentrons/protocol_engine/actions/__init__.py +65 -0
  282. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  283. opentrons/protocol_engine/actions/action_handler.py +13 -0
  284. opentrons/protocol_engine/actions/actions.py +302 -0
  285. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  286. opentrons/protocol_engine/clients/__init__.py +5 -0
  287. opentrons/protocol_engine/clients/sync_client.py +174 -0
  288. opentrons/protocol_engine/clients/transports.py +197 -0
  289. opentrons/protocol_engine/commands/__init__.py +757 -0
  290. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  296. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  297. opentrons/protocol_engine/commands/aspirate.py +244 -0
  298. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  299. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  300. opentrons/protocol_engine/commands/blow_out.py +146 -0
  301. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  302. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  303. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  306. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  307. opentrons/protocol_engine/commands/command.py +308 -0
  308. opentrons/protocol_engine/commands/command_unions.py +974 -0
  309. opentrons/protocol_engine/commands/comment.py +57 -0
  310. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  311. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  312. opentrons/protocol_engine/commands/custom.py +67 -0
  313. opentrons/protocol_engine/commands/dispense.py +194 -0
  314. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  315. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  316. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  317. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  318. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  319. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  320. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  321. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  322. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  323. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  324. opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
  325. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  326. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  327. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  328. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  329. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  330. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  331. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  333. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  334. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  336. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  337. opentrons/protocol_engine/commands/home.py +100 -0
  338. opentrons/protocol_engine/commands/identify_module.py +86 -0
  339. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  340. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  341. opentrons/protocol_engine/commands/load_labware.py +210 -0
  342. opentrons/protocol_engine/commands/load_lid.py +154 -0
  343. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  344. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  345. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  346. opentrons/protocol_engine/commands/load_module.py +223 -0
  347. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  348. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  349. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  350. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  351. opentrons/protocol_engine/commands/move_labware.py +546 -0
  352. opentrons/protocol_engine/commands/move_relative.py +102 -0
  353. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  355. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  356. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  357. opentrons/protocol_engine/commands/movement_common.py +338 -0
  358. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  359. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  360. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  361. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  362. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  363. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  364. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  365. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  366. opentrons/protocol_engine/commands/robot/common.py +18 -0
  367. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  369. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  370. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  371. opentrons/protocol_engine/commands/save_position.py +109 -0
  372. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  373. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  374. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  375. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  376. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  377. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  378. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  379. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  380. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  381. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  384. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  386. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  388. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  390. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  391. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  392. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  401. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  402. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  403. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  404. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  405. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  406. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  407. opentrons/protocol_engine/engine_support.py +28 -0
  408. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  409. opentrons/protocol_engine/errors/__init__.py +191 -0
  410. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  411. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  412. opentrons/protocol_engine/execution/__init__.py +50 -0
  413. opentrons/protocol_engine/execution/command_executor.py +216 -0
  414. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  415. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  416. opentrons/protocol_engine/execution/equipment.py +819 -0
  417. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  418. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  419. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  420. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  421. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  422. opentrons/protocol_engine/execution/movement.py +349 -0
  423. opentrons/protocol_engine/execution/pipetting.py +607 -0
  424. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  425. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  426. opentrons/protocol_engine/execution/run_control.py +33 -0
  427. opentrons/protocol_engine/execution/status_bar.py +34 -0
  428. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  429. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  430. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  431. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  432. opentrons/protocol_engine/notes/__init__.py +17 -0
  433. opentrons/protocol_engine/notes/notes.py +59 -0
  434. opentrons/protocol_engine/plugins.py +104 -0
  435. opentrons/protocol_engine/protocol_engine.py +683 -0
  436. opentrons/protocol_engine/resources/__init__.py +26 -0
  437. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  438. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  439. opentrons/protocol_engine/resources/file_provider.py +161 -0
  440. opentrons/protocol_engine/resources/fixture_validation.py +58 -0
  441. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  442. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  443. opentrons/protocol_engine/resources/model_utils.py +32 -0
  444. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  445. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  446. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  447. opentrons/protocol_engine/slot_standardization.py +128 -0
  448. opentrons/protocol_engine/state/__init__.py +1 -0
  449. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  450. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  451. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  452. opentrons/protocol_engine/state/_move_types.py +83 -0
  453. opentrons/protocol_engine/state/_well_math.py +193 -0
  454. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  455. opentrons/protocol_engine/state/command_history.py +309 -0
  456. opentrons/protocol_engine/state/commands.py +1158 -0
  457. opentrons/protocol_engine/state/config.py +39 -0
  458. opentrons/protocol_engine/state/files.py +57 -0
  459. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  460. opentrons/protocol_engine/state/geometry.py +2359 -0
  461. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  462. opentrons/protocol_engine/state/labware.py +1459 -0
  463. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  464. opentrons/protocol_engine/state/liquids.py +73 -0
  465. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  466. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  467. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  468. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  469. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  471. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  472. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  473. opentrons/protocol_engine/state/modules.py +1500 -0
  474. opentrons/protocol_engine/state/motion.py +373 -0
  475. opentrons/protocol_engine/state/pipettes.py +905 -0
  476. opentrons/protocol_engine/state/state.py +421 -0
  477. opentrons/protocol_engine/state/state_summary.py +36 -0
  478. opentrons/protocol_engine/state/tips.py +420 -0
  479. opentrons/protocol_engine/state/update_types.py +904 -0
  480. opentrons/protocol_engine/state/wells.py +290 -0
  481. opentrons/protocol_engine/types/__init__.py +308 -0
  482. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  483. opentrons/protocol_engine/types/command_annotations.py +53 -0
  484. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  485. opentrons/protocol_engine/types/execution.py +96 -0
  486. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  487. opentrons/protocol_engine/types/instrument.py +47 -0
  488. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  489. opentrons/protocol_engine/types/labware.py +131 -0
  490. opentrons/protocol_engine/types/labware_movement.py +22 -0
  491. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  492. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  493. opentrons/protocol_engine/types/liquid.py +40 -0
  494. opentrons/protocol_engine/types/liquid_class.py +59 -0
  495. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  496. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  497. opentrons/protocol_engine/types/location.py +194 -0
  498. opentrons/protocol_engine/types/module.py +303 -0
  499. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  500. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  501. opentrons/protocol_engine/types/tip.py +18 -0
  502. opentrons/protocol_engine/types/util.py +21 -0
  503. opentrons/protocol_engine/types/well_position.py +124 -0
  504. opentrons/protocol_reader/__init__.py +37 -0
  505. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  506. opentrons/protocol_reader/file_format_validator.py +152 -0
  507. opentrons/protocol_reader/file_hasher.py +27 -0
  508. opentrons/protocol_reader/file_identifier.py +284 -0
  509. opentrons/protocol_reader/file_reader_writer.py +90 -0
  510. opentrons/protocol_reader/input_file.py +16 -0
  511. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  512. opentrons/protocol_reader/protocol_reader.py +188 -0
  513. opentrons/protocol_reader/protocol_source.py +124 -0
  514. opentrons/protocol_reader/role_analyzer.py +86 -0
  515. opentrons/protocol_runner/__init__.py +26 -0
  516. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  517. opentrons/protocol_runner/json_file_reader.py +55 -0
  518. opentrons/protocol_runner/json_translator.py +314 -0
  519. opentrons/protocol_runner/legacy_command_mapper.py +848 -0
  520. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  521. opentrons/protocol_runner/protocol_runner.py +530 -0
  522. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  523. opentrons/protocol_runner/run_orchestrator.py +496 -0
  524. opentrons/protocol_runner/task_queue.py +95 -0
  525. opentrons/protocols/__init__.py +6 -0
  526. opentrons/protocols/advanced_control/__init__.py +0 -0
  527. opentrons/protocols/advanced_control/common.py +38 -0
  528. opentrons/protocols/advanced_control/mix.py +60 -0
  529. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  530. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  531. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  532. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  533. opentrons/protocols/api_support/__init__.py +0 -0
  534. opentrons/protocols/api_support/constants.py +8 -0
  535. opentrons/protocols/api_support/deck_type.py +110 -0
  536. opentrons/protocols/api_support/definitions.py +18 -0
  537. opentrons/protocols/api_support/instrument.py +151 -0
  538. opentrons/protocols/api_support/labware_like.py +233 -0
  539. opentrons/protocols/api_support/tip_tracker.py +175 -0
  540. opentrons/protocols/api_support/types.py +32 -0
  541. opentrons/protocols/api_support/util.py +403 -0
  542. opentrons/protocols/bundle.py +89 -0
  543. opentrons/protocols/duration/__init__.py +4 -0
  544. opentrons/protocols/duration/errors.py +5 -0
  545. opentrons/protocols/duration/estimator.py +628 -0
  546. opentrons/protocols/execution/__init__.py +0 -0
  547. opentrons/protocols/execution/dev_types.py +181 -0
  548. opentrons/protocols/execution/errors.py +40 -0
  549. opentrons/protocols/execution/execute.py +84 -0
  550. opentrons/protocols/execution/execute_json_v3.py +275 -0
  551. opentrons/protocols/execution/execute_json_v4.py +359 -0
  552. opentrons/protocols/execution/execute_json_v5.py +28 -0
  553. opentrons/protocols/execution/execute_python.py +169 -0
  554. opentrons/protocols/execution/json_dispatchers.py +87 -0
  555. opentrons/protocols/execution/types.py +7 -0
  556. opentrons/protocols/geometry/__init__.py +0 -0
  557. opentrons/protocols/geometry/planning.py +297 -0
  558. opentrons/protocols/labware.py +312 -0
  559. opentrons/protocols/models/__init__.py +0 -0
  560. opentrons/protocols/models/json_protocol.py +679 -0
  561. opentrons/protocols/parameters/__init__.py +0 -0
  562. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  563. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  564. opentrons/protocols/parameters/exceptions.py +34 -0
  565. opentrons/protocols/parameters/parameter_definition.py +272 -0
  566. opentrons/protocols/parameters/types.py +17 -0
  567. opentrons/protocols/parameters/validation.py +267 -0
  568. opentrons/protocols/parse.py +671 -0
  569. opentrons/protocols/types.py +159 -0
  570. opentrons/py.typed +0 -0
  571. opentrons/resources/scripts/lpc21isp +0 -0
  572. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  573. opentrons/simulate.py +1065 -0
  574. opentrons/system/__init__.py +6 -0
  575. opentrons/system/camera.py +51 -0
  576. opentrons/system/log_control.py +59 -0
  577. opentrons/system/nmcli.py +856 -0
  578. opentrons/system/resin.py +24 -0
  579. opentrons/system/smoothie_update.py +15 -0
  580. opentrons/system/wifi.py +204 -0
  581. opentrons/tools/__init__.py +0 -0
  582. opentrons/tools/args_handler.py +22 -0
  583. opentrons/tools/write_pipette_memory.py +157 -0
  584. opentrons/types.py +618 -0
  585. opentrons/util/__init__.py +1 -0
  586. opentrons/util/async_helpers.py +166 -0
  587. opentrons/util/broker.py +84 -0
  588. opentrons/util/change_notifier.py +47 -0
  589. opentrons/util/entrypoint_util.py +278 -0
  590. opentrons/util/get_union_elements.py +26 -0
  591. opentrons/util/helpers.py +6 -0
  592. opentrons/util/linal.py +178 -0
  593. opentrons/util/logging_config.py +265 -0
  594. opentrons/util/logging_queue_handler.py +61 -0
  595. opentrons/util/performance_helpers.py +157 -0
  596. opentrons-8.6.0a1.dist-info/METADATA +37 -0
  597. opentrons-8.6.0a1.dist-info/RECORD +600 -0
  598. opentrons-8.6.0a1.dist-info/WHEEL +4 -0
  599. opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
  600. opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,550 @@
1
+ """Tip pickup and drop procedures."""
2
+
3
+ from typing import Optional, Dict, Tuple
4
+ from typing_extensions import Protocol as TypingProtocol
5
+
6
+ from opentrons.hardware_control import HardwareControlAPI
7
+ from opentrons.hardware_control.types import (
8
+ FailedTipStateCheck,
9
+ InstrumentProbeType,
10
+ TipScrapeType,
11
+ )
12
+ from opentrons.protocol_engine.errors.exceptions import PickUpTipTipNotAttachedError
13
+ from opentrons.types import Mount, NozzleConfigurationType
14
+
15
+ from opentrons_shared_data.errors.exceptions import (
16
+ CommandPreconditionViolated,
17
+ CommandParameterLimitViolated,
18
+ PythonException,
19
+ )
20
+
21
+ from ..resources import LabwareDataProvider, ensure_ot3_hardware
22
+ from ..state.state import StateView
23
+ from ..types import TipGeometry, TipPresenceStatus
24
+ from ..errors import (
25
+ HardwareNotSupportedError,
26
+ TipNotAttachedError,
27
+ TipAttachedError,
28
+ ProtocolEngineError,
29
+ )
30
+
31
+ PRIMARY_NOZZLE_TO_ENDING_NOZZLE_MAP = {
32
+ "A1": {"COLUMN": "H1", "ROW": "A12"},
33
+ "H1": {"COLUMN": "A1", "ROW": "H12"},
34
+ "A12": {"COLUMN": "H12", "ROW": "A1"},
35
+ "H12": {"COLUMN": "A12", "ROW": "H1"},
36
+ }
37
+
38
+ PRIMARY_NOZZLE_TO_BACK_LEFT_NOZZLE_MAP = {
39
+ "A1": {"COLUMN": "A1", "ROW": "A1"},
40
+ "H1": {"COLUMN": "A1", "ROW": "H1"},
41
+ "A12": {"COLUMN": "A12", "ROW": "A1"},
42
+ "H12": {"COLUMN": "A12", "ROW": "H1"},
43
+ }
44
+
45
+
46
+ class TipHandler(TypingProtocol):
47
+ """Pick up and drop tips."""
48
+
49
+ async def available_for_nozzle_layout(
50
+ self,
51
+ pipette_id: str,
52
+ style: str,
53
+ primary_nozzle: Optional[str] = None,
54
+ front_right_nozzle: Optional[str] = None,
55
+ back_left_nozzle: Optional[str] = None,
56
+ ) -> Dict[str, str]:
57
+ """Check nozzle layout is compatible with the pipette.
58
+
59
+ Returns:
60
+ A dict of nozzles used to configure the pipette.
61
+ """
62
+ ...
63
+
64
+ async def pick_up_tip(
65
+ self,
66
+ pipette_id: str,
67
+ labware_id: str,
68
+ well_name: str,
69
+ do_not_ignore_tip_presence: bool = True,
70
+ ) -> TipGeometry:
71
+ """Pick up the named tip.
72
+
73
+ Pipette should be in place over the named tip prior to calling this method.
74
+
75
+ Returns:
76
+ Tip geometry of the picked up tip.
77
+
78
+ Raises:
79
+ PickUpTipTipNotAttachedError
80
+ """
81
+ ...
82
+
83
+ async def drop_tip(
84
+ self,
85
+ pipette_id: str,
86
+ home_after: Optional[bool],
87
+ do_not_ignore_tip_presence: bool = True,
88
+ ignore_plunger: bool = False,
89
+ scrape_type: TipScrapeType = TipScrapeType.NONE,
90
+ ) -> None:
91
+ """Drop the attached tip into the current location.
92
+
93
+ Pipette should be in place over the destination prior to calling this method.
94
+
95
+ Raises:
96
+ TipAttachedError
97
+ """
98
+
99
+ def cache_tip(self, pipette_id: str, tip: TipGeometry) -> None:
100
+ """Tell the Hardware API that a tip is attached."""
101
+
102
+ def remove_tip(self, pipette_id: str) -> None:
103
+ """Tell the hardware API that no tip is attached."""
104
+
105
+ async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
106
+ """Get tip presence status on the pipette."""
107
+
108
+ async def verify_tip_presence(
109
+ self,
110
+ pipette_id: str,
111
+ expected: TipPresenceStatus,
112
+ follow_singular_sensor: Optional[InstrumentProbeType] = None,
113
+ ) -> None:
114
+ """Use sensors to verify that a tip is or is not physically attached.
115
+
116
+ Raises:
117
+ TipNotAttachedError or TipAttachedError, as appropriate, if the physical
118
+ status doesn't match what was expected.
119
+ """
120
+
121
+
122
+ async def _available_for_nozzle_layout( # noqa: C901
123
+ channels: int,
124
+ style: str,
125
+ primary_nozzle: Optional[str],
126
+ front_right_nozzle: Optional[str],
127
+ back_left_nozzle: Optional[str],
128
+ ) -> Dict[str, str]:
129
+ """Check nozzle layout is compatible with the pipette.
130
+
131
+ Returns:
132
+ A dict of nozzles used to configure the pipette.
133
+ """
134
+ if channels == 1:
135
+ raise CommandPreconditionViolated(
136
+ message=f"Cannot configure nozzle layout with a {channels} channel pipette."
137
+ )
138
+ if style == "ALL":
139
+ return {}
140
+ if style == "ROW" and channels == 8:
141
+ raise CommandParameterLimitViolated(
142
+ command_name="configure_nozzle_layout",
143
+ parameter_name="RowNozzleLayout",
144
+ limit_statement="RowNozzleLayout is incompatible with {channels} channel pipettes.",
145
+ actual_value=str(primary_nozzle),
146
+ )
147
+ if style == "PARTIAL_COLUM" and channels == 96:
148
+ raise CommandParameterLimitViolated(
149
+ command_name="configure_nozzle_layout",
150
+ parameter_name="PartialColumnNozzleLayout",
151
+ limit_statement="PartialColumnNozzleLayout is incompatible with {channels} channel pipettes.",
152
+ actual_value=str(primary_nozzle),
153
+ )
154
+ if not primary_nozzle:
155
+ return {"primary_nozzle": "A1"}
156
+ if style == "SINGLE":
157
+ return {"primary_nozzle": primary_nozzle}
158
+ if style == "QUADRANT" and front_right_nozzle and not back_left_nozzle:
159
+ return {
160
+ "primary_nozzle": primary_nozzle,
161
+ "front_right_nozzle": front_right_nozzle,
162
+ "back_left_nozzle": primary_nozzle,
163
+ }
164
+ if style == "QUADRANT" and back_left_nozzle and not front_right_nozzle:
165
+ return {
166
+ "primary_nozzle": primary_nozzle,
167
+ "front_right_nozzle": primary_nozzle,
168
+ "back_left_nozzle": back_left_nozzle,
169
+ }
170
+ if not front_right_nozzle and back_left_nozzle:
171
+ return {
172
+ "primary_nozzle": primary_nozzle,
173
+ "front_right_nozzle": PRIMARY_NOZZLE_TO_ENDING_NOZZLE_MAP[primary_nozzle][
174
+ style
175
+ ],
176
+ "back_left_nozzle": back_left_nozzle,
177
+ }
178
+ if front_right_nozzle and not back_left_nozzle:
179
+ return {
180
+ "primary_nozzle": primary_nozzle,
181
+ "front_right_nozzle": front_right_nozzle,
182
+ "back_left_nozzle": PRIMARY_NOZZLE_TO_BACK_LEFT_NOZZLE_MAP[primary_nozzle][
183
+ style
184
+ ],
185
+ }
186
+ if front_right_nozzle and back_left_nozzle:
187
+ return {
188
+ "primary_nozzle": primary_nozzle,
189
+ "front_right_nozzle": front_right_nozzle,
190
+ "back_left_nozzle": back_left_nozzle,
191
+ }
192
+
193
+ return {
194
+ "primary_nozzle": primary_nozzle,
195
+ "front_right_nozzle": PRIMARY_NOZZLE_TO_ENDING_NOZZLE_MAP[primary_nozzle][
196
+ style
197
+ ],
198
+ "back_left_nozzle": PRIMARY_NOZZLE_TO_BACK_LEFT_NOZZLE_MAP[primary_nozzle][
199
+ style
200
+ ],
201
+ }
202
+
203
+
204
+ def tip_on_left_side_96(back_left_nozzle: str) -> bool:
205
+ """Return if there is a tip on the left edge of the 96 channel."""
206
+ left_most_column = int(back_left_nozzle[1:])
207
+ return left_most_column == 1
208
+
209
+
210
+ def tip_on_right_side_96(front_right_nozzle: str) -> bool:
211
+ """Return if there is a tip on the left edge of the 96 channel."""
212
+ right_most_column = int(front_right_nozzle[1:])
213
+ return right_most_column == 12
214
+
215
+
216
+ class HardwareTipHandler(TipHandler):
217
+ """Pick up and drop tips, using the Hardware API."""
218
+
219
+ def __init__(
220
+ self,
221
+ state_view: StateView,
222
+ hardware_api: HardwareControlAPI,
223
+ labware_data_provider: Optional[LabwareDataProvider] = None,
224
+ ) -> None:
225
+ self._hardware_api = hardware_api
226
+ self._labware_data_provider = labware_data_provider or LabwareDataProvider()
227
+ self._state_view = state_view
228
+
229
+ # WARNING: ErrorRecoveryHardwareStateSynchronizer can currently construct several
230
+ # instances of this class per run, in addition to the main instance used
231
+ # for command execution. We're therefore depending on this class being
232
+ # stateless, so consider that before adding additional attributes here.
233
+
234
+ async def available_for_nozzle_layout(
235
+ self,
236
+ pipette_id: str,
237
+ style: str,
238
+ primary_nozzle: Optional[str] = None,
239
+ front_right_nozzle: Optional[str] = None,
240
+ back_left_nozzle: Optional[str] = None,
241
+ ) -> Dict[str, str]:
242
+ """See documentation on abstract base class."""
243
+ if self._state_view.pipettes.get_attached_tip(pipette_id):
244
+ raise CommandPreconditionViolated(
245
+ message=f"Cannot configure nozzle layout of {str(self)} while it has tips attached."
246
+ )
247
+ channels = self._state_view.pipettes.get_channels(pipette_id)
248
+ return await _available_for_nozzle_layout(
249
+ channels, style, primary_nozzle, front_right_nozzle, back_left_nozzle
250
+ )
251
+
252
+ def get_tip_presence_config(
253
+ self, pipette_id: str
254
+ ) -> Tuple[bool, Optional[InstrumentProbeType]]:
255
+ """Return the supported settings for tip presence on a given pipette depending on it's current nozzle map."""
256
+ follow_singular_sensor = None
257
+
258
+ unsupported_layout_types_96 = [NozzleConfigurationType.SINGLE]
259
+ # NOTE: (09-20-2024) Current on multi-channel pipettes, utilizing less than 4 nozzles risks false positives on the tip presence sensor
260
+ supported_partial_nozzle_minimum = 4
261
+
262
+ nozzle_configuration = self._state_view.pipettes.get_nozzle_configuration(
263
+ pipette_id=pipette_id
264
+ )
265
+
266
+ match self._state_view.pipettes.get_channels(pipette_id):
267
+ case 1:
268
+ tip_presence_supported = True
269
+ case 8:
270
+ tip_presence_supported = (
271
+ nozzle_configuration.tip_count >= supported_partial_nozzle_minimum
272
+ )
273
+ case 96:
274
+ tip_presence_supported = (
275
+ nozzle_configuration.configuration
276
+ not in unsupported_layout_types_96
277
+ and nozzle_configuration.tip_count
278
+ >= supported_partial_nozzle_minimum
279
+ )
280
+ if (
281
+ nozzle_configuration.configuration != NozzleConfigurationType.FULL
282
+ and tip_presence_supported
283
+ ):
284
+ use_left = tip_on_left_side_96(nozzle_configuration.back_left)
285
+ use_right = tip_on_right_side_96(nozzle_configuration.front_right)
286
+ if not (use_left and use_right):
287
+ if use_left:
288
+ follow_singular_sensor = InstrumentProbeType.PRIMARY
289
+ else:
290
+ follow_singular_sensor = InstrumentProbeType.SECONDARY
291
+ case _:
292
+ raise ValueError("Unknown pipette type.")
293
+
294
+ return (tip_presence_supported, follow_singular_sensor)
295
+
296
+ async def pick_up_tip(
297
+ self,
298
+ pipette_id: str,
299
+ labware_id: str,
300
+ well_name: str,
301
+ do_not_ignore_tip_presence: bool = True,
302
+ ) -> TipGeometry:
303
+ """See documentation on abstract base class."""
304
+ hw_mount = self._get_hw_mount(pipette_id)
305
+
306
+ nominal_tip_geometry = self._state_view.geometry.get_nominal_tip_geometry(
307
+ pipette_id=pipette_id, labware_id=labware_id, well_name=well_name
308
+ )
309
+
310
+ actual_tip_length = await self._labware_data_provider.get_calibrated_tip_length(
311
+ pipette_serial=self._state_view.pipettes.get_serial_number(pipette_id),
312
+ labware_definition=self._state_view.labware.get_definition(labware_id),
313
+ nominal_fallback=nominal_tip_geometry.length,
314
+ )
315
+
316
+ tip_geometry = TipGeometry(
317
+ length=actual_tip_length,
318
+ diameter=nominal_tip_geometry.diameter,
319
+ volume=nominal_tip_geometry.volume,
320
+ )
321
+
322
+ await self._hardware_api.tip_pickup_moves(
323
+ mount=hw_mount, presses=None, increment=None
324
+ )
325
+
326
+ tip_presence_supported, follow_singular_sensor = self.get_tip_presence_config(
327
+ pipette_id
328
+ )
329
+
330
+ if do_not_ignore_tip_presence and tip_presence_supported:
331
+ try:
332
+ await self.verify_tip_presence(
333
+ pipette_id,
334
+ TipPresenceStatus.PRESENT,
335
+ follow_singular_sensor=follow_singular_sensor,
336
+ )
337
+ except TipNotAttachedError as e:
338
+ raise PickUpTipTipNotAttachedError(tip_geometry=tip_geometry) from e
339
+
340
+ self.cache_tip(pipette_id, tip_geometry)
341
+
342
+ await self._hardware_api.prepare_for_aspirate(hw_mount)
343
+
344
+ return tip_geometry
345
+
346
+ async def drop_tip(
347
+ self,
348
+ pipette_id: str,
349
+ home_after: Optional[bool],
350
+ do_not_ignore_tip_presence: bool = True,
351
+ ignore_plunger: bool = False,
352
+ scrape_type: TipScrapeType = TipScrapeType.NONE,
353
+ ) -> None:
354
+ """See documentation on abstract base class."""
355
+ hw_mount = self._get_hw_mount(pipette_id)
356
+
357
+ # Let the hardware controller handle defaulting home_after since its behavior
358
+ # differs between machines
359
+ kwargs = {}
360
+ if home_after is not None:
361
+ kwargs["home_after"] = home_after
362
+
363
+ await self._hardware_api.tip_drop_moves(
364
+ mount=hw_mount,
365
+ ignore_plunger=ignore_plunger,
366
+ scrape_type=scrape_type,
367
+ **kwargs,
368
+ )
369
+
370
+ if do_not_ignore_tip_presence:
371
+ # Allow TipNotAttachedError to propagate.
372
+ await self.verify_tip_presence(pipette_id, TipPresenceStatus.ABSENT)
373
+
374
+ self.remove_tip(pipette_id)
375
+
376
+ def cache_tip(self, pipette_id: str, tip: TipGeometry) -> None:
377
+ """See documentation on abstract base class."""
378
+ hw_mount = self._get_hw_mount(pipette_id)
379
+
380
+ self._hardware_api.cache_tip(mount=hw_mount, tip_length=tip.length)
381
+
382
+ self._hardware_api.set_current_tiprack_diameter(
383
+ mount=hw_mount,
384
+ tiprack_diameter=tip.diameter,
385
+ )
386
+
387
+ self._hardware_api.set_working_volume(
388
+ mount=hw_mount,
389
+ tip_volume=tip.volume,
390
+ )
391
+
392
+ def remove_tip(self, pipette_id: str) -> None:
393
+ """See documentation on abstract base class."""
394
+ hw_mount = self._get_hw_mount(pipette_id)
395
+ self._hardware_api.remove_tip(hw_mount)
396
+ self._hardware_api.set_current_tiprack_diameter(hw_mount, 0)
397
+
398
+ async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
399
+ """See documentation on abstract base class."""
400
+ try:
401
+ ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
402
+
403
+ hw_mount = self._get_hw_mount(pipette_id)
404
+
405
+ status = await ot3api.get_tip_presence_status(hw_mount)
406
+ return TipPresenceStatus.from_hw_state(status)
407
+ except HardwareNotSupportedError:
408
+ # Tip presence sensing is not supported on the OT2
409
+ return TipPresenceStatus.UNKNOWN
410
+
411
+ async def verify_tip_presence(
412
+ self,
413
+ pipette_id: str,
414
+ expected: TipPresenceStatus,
415
+ follow_singular_sensor: Optional[InstrumentProbeType] = None,
416
+ ) -> None:
417
+ """See documentation on abstract base class."""
418
+ try:
419
+ ot3api = ensure_ot3_hardware(hardware_api=self._hardware_api)
420
+ hw_mount = self._get_hw_mount(pipette_id)
421
+ await ot3api.verify_tip_presence(
422
+ hw_mount, expected.to_hw_state(), follow_singular_sensor
423
+ )
424
+ except HardwareNotSupportedError:
425
+ # Tip presence sensing is not supported on the OT2
426
+ pass
427
+ except FailedTipStateCheck as e:
428
+ if expected == TipPresenceStatus.ABSENT:
429
+ raise TipAttachedError(wrapping=[PythonException(e)])
430
+ elif expected == TipPresenceStatus.PRESENT:
431
+ raise TipNotAttachedError(wrapping=[PythonException(e)])
432
+ else:
433
+ raise ProtocolEngineError(
434
+ message="Unknown tip status in tip status check",
435
+ wrapping=[PythonException(e)],
436
+ )
437
+
438
+ def _get_hw_mount(self, pipette_id: str) -> Mount:
439
+ return self._state_view.pipettes.get_mount(pipette_id).to_hw_mount()
440
+
441
+
442
+ class VirtualTipHandler(TipHandler):
443
+ """Pick up and drop tips, using a virtual pipette."""
444
+
445
+ def __init__(self, state_view: StateView) -> None:
446
+ self._state_view = state_view
447
+
448
+ async def pick_up_tip(
449
+ self,
450
+ pipette_id: str,
451
+ labware_id: str,
452
+ well_name: str,
453
+ do_not_ignore_tip_presence: bool = True,
454
+ ) -> TipGeometry:
455
+ """Pick up a tip at the current location using a virtual pipette.
456
+
457
+ - Fetch nominal tip geometry
458
+ - Check that there's no tip currently attached
459
+ """
460
+ nominal_tip_geometry = self._state_view.geometry.get_nominal_tip_geometry(
461
+ pipette_id=pipette_id,
462
+ labware_id=labware_id,
463
+ well_name=well_name,
464
+ )
465
+
466
+ self._state_view.pipettes.validate_tip_state(
467
+ pipette_id=pipette_id,
468
+ expected_has_tip=False,
469
+ )
470
+
471
+ return nominal_tip_geometry
472
+
473
+ async def available_for_nozzle_layout(
474
+ self,
475
+ pipette_id: str,
476
+ style: str,
477
+ primary_nozzle: Optional[str] = None,
478
+ front_right_nozzle: Optional[str] = None,
479
+ back_left_nozzle: Optional[str] = None,
480
+ ) -> Dict[str, str]:
481
+ """See documentation on abstract base class."""
482
+ if self._state_view.pipettes.get_attached_tip(pipette_id):
483
+ raise CommandPreconditionViolated(
484
+ message=f"Cannot configure nozzle layout of {str(self)} while it has tips attached."
485
+ )
486
+ channels = self._state_view.pipettes.get_channels(pipette_id)
487
+ return await _available_for_nozzle_layout(
488
+ channels, style, primary_nozzle, front_right_nozzle, back_left_nozzle
489
+ )
490
+
491
+ async def drop_tip(
492
+ self,
493
+ pipette_id: str,
494
+ home_after: Optional[bool],
495
+ do_not_ignore_tip_presence: bool = True,
496
+ ignore_plunger: bool = False,
497
+ scrape_type: TipScrapeType = TipScrapeType.NONE,
498
+ ) -> None:
499
+ """Pick up a tip at the current location using a virtual pipette.
500
+
501
+ - Check that there's no tip currently attached
502
+ """
503
+ self._state_view.pipettes.validate_tip_state(
504
+ pipette_id=pipette_id,
505
+ expected_has_tip=True,
506
+ )
507
+
508
+ def cache_tip(self, pipette_id: str, tip: TipGeometry) -> None:
509
+ """See documentation on abstract base class.
510
+
511
+ This should not be called when using virtual pipettes.
512
+ """
513
+ assert False, "TipHandler.cache_tip should not be used with virtual pipettes"
514
+
515
+ def remove_tip(self, pipette_id: str) -> None:
516
+ """See documentation on abstract base class.
517
+
518
+ This should not be called when using virtual pipettes.
519
+ """
520
+ assert False, "TipHandler.remove_tip should not be used with virtual pipettes"
521
+
522
+ async def verify_tip_presence(
523
+ self,
524
+ pipette_id: str,
525
+ expected: TipPresenceStatus,
526
+ follow_singular_sensor: Optional[InstrumentProbeType] = None,
527
+ ) -> None:
528
+ """Verify tip presence.
529
+
530
+ This should not be called when using virtual pipettes.
531
+ """
532
+
533
+ async def get_tip_presence(self, pipette_id: str) -> TipPresenceStatus:
534
+ """Get tip presence.
535
+
536
+ This is a check to the physical machine's sensors and should not be
537
+ called on a virtual pipette.
538
+ """
539
+ raise RuntimeError("Do not call VirtualTipHandler.get_tip_presence")
540
+
541
+
542
+ def create_tip_handler(
543
+ state_view: StateView, hardware_api: HardwareControlAPI
544
+ ) -> TipHandler:
545
+ """Create a tip handler."""
546
+ return (
547
+ HardwareTipHandler(state_view=state_view, hardware_api=hardware_api)
548
+ if state_view.config.use_virtual_pipettes is False
549
+ else VirtualTipHandler(state_view=state_view)
550
+ )