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,326 @@
1
+ """Command models to retrieve a labware from a Flex Stacker."""
2
+
3
+ from __future__ import annotations
4
+ from typing import Optional, Literal, TYPE_CHECKING, Type, Union, cast
5
+
6
+ from pydantic import BaseModel, Field
7
+ from pydantic.json_schema import SkipJsonSchema
8
+
9
+ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
10
+ from opentrons_shared_data.errors.exceptions import (
11
+ FlexStackerStallError,
12
+ FlexStackerShuttleMissingError,
13
+ )
14
+
15
+ from ..command import (
16
+ AbstractCommandImpl,
17
+ BaseCommand,
18
+ BaseCommandCreate,
19
+ SuccessData,
20
+ DefinedErrorData,
21
+ )
22
+ from ..flex_stacker.common import (
23
+ FlexStackerStallOrCollisionError,
24
+ FlexStackerShuttleError,
25
+ labware_locations_for_group,
26
+ labware_location_base_sequence,
27
+ primary_location_sequence,
28
+ adapter_location_sequence,
29
+ lid_location_sequence,
30
+ )
31
+ from ...errors import (
32
+ ErrorOccurrence,
33
+ CannotPerformModuleAction,
34
+ LabwareNotLoadedOnModuleError,
35
+ FlexStackerLabwarePoolNotYetDefinedError,
36
+ )
37
+ from ...resources import ModelUtils
38
+ from ...state import update_types
39
+ from ...types import (
40
+ LabwareLocationSequence,
41
+ InStackerHopperLocation,
42
+ StackerStoredLabwareGroup,
43
+ ModuleLocation,
44
+ )
45
+
46
+ if TYPE_CHECKING:
47
+ from opentrons.protocol_engine.state.state import StateView
48
+ from opentrons.protocol_engine.state.module_substates import FlexStackerSubState
49
+ from opentrons.protocol_engine.execution import EquipmentHandler
50
+
51
+
52
+ StoreCommandType = Literal["flexStacker/store"]
53
+
54
+
55
+ class StoreParams(BaseModel):
56
+ """Input parameters for a labware storage command."""
57
+
58
+ moduleId: str = Field(
59
+ ...,
60
+ description="Unique ID of the flex stacker.",
61
+ )
62
+
63
+
64
+ class StoreResult(BaseModel):
65
+ """Result data from a labware storage command."""
66
+
67
+ eventualDestinationLocationSequence: (
68
+ LabwareLocationSequence | SkipJsonSchema[None]
69
+ ) = Field(
70
+ None,
71
+ description=(
72
+ "The full location in which all labware moved by this command will eventually reside."
73
+ ),
74
+ )
75
+ primaryOriginLocationSequence: LabwareLocationSequence | SkipJsonSchema[
76
+ None
77
+ ] = Field(None, description=("The origin location of the primary labware."))
78
+ primaryLabwareId: str | SkipJsonSchema[None] = Field(
79
+ None, description="The primary labware in the stack that was stored."
80
+ )
81
+ adapterOriginLocationSequence: LabwareLocationSequence | SkipJsonSchema[
82
+ None
83
+ ] = Field(None, description=("The origin location of the adapter labware, if any."))
84
+ adapterLabwareId: str | SkipJsonSchema[None] = Field(
85
+ None, description="The adapter in the stack that was stored, if any."
86
+ )
87
+ lidOriginLocationSequence: LabwareLocationSequence | SkipJsonSchema[None] = Field(
88
+ None, description=("The origin location of the lid labware, if any.")
89
+ )
90
+ lidLabwareId: str | SkipJsonSchema[None] = Field(
91
+ None, description="The lid in the stack that was stored, if any."
92
+ )
93
+ primaryLabwareURI: str = Field(
94
+ ...,
95
+ description="The labware definition URI of the primary labware.",
96
+ )
97
+ adapterLabwareURI: str | SkipJsonSchema[None] = Field(
98
+ None,
99
+ description="The labware definition URI of the adapter labware.",
100
+ )
101
+ lidLabwareURI: str | SkipJsonSchema[None] = Field(
102
+ None,
103
+ description="The labware definition URI of the lid labware.",
104
+ )
105
+
106
+
107
+ _ExecuteReturn = Union[
108
+ SuccessData[StoreResult],
109
+ DefinedErrorData[FlexStackerStallOrCollisionError]
110
+ | DefinedErrorData[FlexStackerShuttleError],
111
+ ]
112
+
113
+
114
+ class StoreImpl(AbstractCommandImpl[StoreParams, _ExecuteReturn]):
115
+ """Implementation of a labware storage command."""
116
+
117
+ def __init__(
118
+ self,
119
+ state_view: StateView,
120
+ equipment: EquipmentHandler,
121
+ model_utils: ModelUtils,
122
+ **kwargs: object,
123
+ ) -> None:
124
+ self._state_view = state_view
125
+ self._equipment = equipment
126
+ self._model_utils = model_utils
127
+
128
+ def _verify_labware_to_store(
129
+ self, params: StoreParams, stacker_state: FlexStackerSubState
130
+ ) -> tuple[str, str | None, str | None]:
131
+ location = self._state_view.modules.get_location(params.moduleId)
132
+ try:
133
+ bottom_id = self._state_view.labware.get_id_by_module(params.moduleId)
134
+ except LabwareNotLoadedOnModuleError:
135
+ raise CannotPerformModuleAction(
136
+ f"Flex Stacker in {location} cannot store labware because its carriage is empty"
137
+ )
138
+ labware_ids = self._state_view.labware.get_labware_stack_from_parent(bottom_id)
139
+ labware_defs = [
140
+ self._state_view.labware.get_definition(id) for id in labware_ids
141
+ ]
142
+
143
+ lid_id: str | None = None
144
+
145
+ pool_list = stacker_state.get_pool_definition_ordered_list()
146
+ assert pool_list is not None
147
+ if len(labware_ids) != len(pool_list):
148
+ raise CannotPerformModuleAction(
149
+ f"Cannot store labware stack that does not correspond with the configuration of Flex Stacker in {location}"
150
+ )
151
+ if stacker_state.pool_lid_definition is not None:
152
+ if labware_defs[-1] != stacker_state.pool_lid_definition:
153
+ raise CannotPerformModuleAction(
154
+ f"Cannot store labware stack that does not correspond with the configuration of Flex Stacker in {location}"
155
+ )
156
+ lid_id = labware_ids[-1]
157
+
158
+ if stacker_state.pool_adapter_definition is not None:
159
+ if (
160
+ labware_defs[0] != stacker_state.pool_adapter_definition
161
+ or labware_defs[1] != stacker_state.pool_primary_definition
162
+ ):
163
+ raise CannotPerformModuleAction(
164
+ f"Cannot store labware stack that does not correspond with the configuration of Flex Stacker in {location}"
165
+ )
166
+ else:
167
+ return labware_ids[1], labware_ids[0], lid_id
168
+ else:
169
+ if labware_defs[0] != stacker_state.pool_primary_definition:
170
+ raise CannotPerformModuleAction(
171
+ f"Cannot store labware stack that does not correspond with the configuration of Flex Stacker in {location}"
172
+ )
173
+ return labware_ids[0], None, lid_id
174
+
175
+ async def execute(self, params: StoreParams) -> _ExecuteReturn:
176
+ """Execute the labware storage command."""
177
+ stacker_state = self._state_view.modules.get_flex_stacker_substate(
178
+ params.moduleId
179
+ )
180
+
181
+ location = self._state_view.modules.get_location(params.moduleId)
182
+ pool_definitions = stacker_state.get_pool_definition_ordered_list()
183
+ if pool_definitions is None:
184
+ raise FlexStackerLabwarePoolNotYetDefinedError(
185
+ message=f"The Flex Stacker in {location} has not been configured yet and cannot be filled."
186
+ )
187
+
188
+ if (
189
+ len(stacker_state.contained_labware_bottom_first)
190
+ == stacker_state.max_pool_count
191
+ ):
192
+ raise CannotPerformModuleAction(
193
+ f"Cannot store labware in Flex Stacker in {location} because it is full"
194
+ )
195
+
196
+ primary_id, maybe_adapter_id, maybe_lid_id = self._verify_labware_to_store(
197
+ params, stacker_state
198
+ )
199
+
200
+ # Allow propagation of ModuleNotAttachedError.
201
+ stacker_hw = self._equipment.get_module_hardware_api(stacker_state.module_id)
202
+
203
+ state_update = update_types.StateUpdate()
204
+ try:
205
+ if stacker_hw is not None:
206
+ stacker_hw.set_stacker_identify(True)
207
+ await stacker_hw.store_labware(
208
+ labware_height=stacker_state.get_pool_height_minus_overlap()
209
+ )
210
+ except FlexStackerStallError as e:
211
+ return DefinedErrorData(
212
+ public=FlexStackerStallOrCollisionError(
213
+ id=self._model_utils.generate_id(),
214
+ createdAt=self._model_utils.get_timestamp(),
215
+ wrappedErrors=[
216
+ ErrorOccurrence.from_failed(
217
+ id=self._model_utils.generate_id(),
218
+ createdAt=self._model_utils.get_timestamp(),
219
+ error=e,
220
+ )
221
+ ],
222
+ errorInfo={"labwareId": primary_id},
223
+ ),
224
+ )
225
+ except FlexStackerShuttleMissingError as e:
226
+ return DefinedErrorData(
227
+ public=FlexStackerShuttleError(
228
+ id=self._model_utils.generate_id(),
229
+ createdAt=self._model_utils.get_timestamp(),
230
+ wrappedErrors=[
231
+ ErrorOccurrence.from_failed(
232
+ id=self._model_utils.generate_id(),
233
+ createdAt=self._model_utils.get_timestamp(),
234
+ error=e,
235
+ )
236
+ ],
237
+ errorInfo={"labwareId": primary_id},
238
+ ),
239
+ )
240
+
241
+ id_list = [
242
+ id for id in (primary_id, maybe_adapter_id, maybe_lid_id) if id is not None
243
+ ]
244
+
245
+ group = StackerStoredLabwareGroup(
246
+ primaryLabwareId=primary_id,
247
+ adapterLabwareId=maybe_adapter_id,
248
+ lidLabwareId=maybe_lid_id,
249
+ )
250
+
251
+ state_update.set_batch_labware_location(
252
+ new_locations_by_id={
253
+ id: InStackerHopperLocation(moduleId=params.moduleId) for id in id_list
254
+ },
255
+ new_offset_ids_by_id={id: None for id in id_list},
256
+ )
257
+
258
+ state_update.update_flex_stacker_contained_labware(
259
+ module_id=params.moduleId,
260
+ contained_labware_bottom_first=(
261
+ [group] + stacker_state.contained_labware_bottom_first
262
+ ),
263
+ )
264
+
265
+ original_location_sequences = labware_locations_for_group(
266
+ group,
267
+ labware_location_base_sequence(
268
+ group,
269
+ self._state_view,
270
+ self._state_view.geometry.get_predicted_location_sequence(
271
+ ModuleLocation(moduleId=params.moduleId)
272
+ ),
273
+ ),
274
+ )
275
+
276
+ if stacker_hw is not None:
277
+ stacker_hw.set_stacker_identify(False)
278
+
279
+ return SuccessData(
280
+ public=StoreResult.model_construct(
281
+ eventualDestinationLocationSequence=[
282
+ InStackerHopperLocation(moduleId=params.moduleId)
283
+ ],
284
+ primaryOriginLocationSequence=primary_location_sequence(
285
+ original_location_sequences
286
+ ),
287
+ primaryLabwareId=primary_id,
288
+ adapterOriginLocationSequence=adapter_location_sequence(
289
+ original_location_sequences
290
+ ),
291
+ adapterLabwareId=maybe_adapter_id,
292
+ lidOriginLocationSequence=lid_location_sequence(
293
+ original_location_sequences
294
+ ),
295
+ lidLabwareId=maybe_lid_id,
296
+ primaryLabwareURI=self._state_view.labware.get_uri_from_definition_unless_none(
297
+ cast(LabwareDefinition, stacker_state.pool_primary_definition)
298
+ ),
299
+ adapterLabwareURI=self._state_view.labware.get_uri_from_definition_unless_none(
300
+ stacker_state.pool_adapter_definition
301
+ ),
302
+ lidLabwareURI=self._state_view.labware.get_uri_from_definition_unless_none(
303
+ stacker_state.pool_lid_definition
304
+ ),
305
+ ),
306
+ state_update=state_update,
307
+ )
308
+
309
+
310
+ class Store(BaseCommand[StoreParams, StoreResult, ErrorOccurrence]):
311
+ """A command to store a labware in a Flex Stacker."""
312
+
313
+ commandType: StoreCommandType = "flexStacker/store"
314
+ params: StoreParams
315
+ result: Optional[StoreResult] = None
316
+
317
+ _ImplementationCls: Type[StoreImpl] = StoreImpl
318
+
319
+
320
+ class StoreCreate(BaseCommandCreate[StoreParams]):
321
+ """A request to execute a Flex Stacker store command."""
322
+
323
+ commandType: StoreCommandType = "flexStacker/store"
324
+ params: StoreParams
325
+
326
+ _CommandCls: Type[Store] = Store
@@ -0,0 +1,61 @@
1
+ """Generate a JSON schema against which all create commands statically validate."""
2
+
3
+ import json
4
+ import argparse
5
+ import sys
6
+ from opentrons.protocol_engine.commands.command_unions import CommandCreateAdapter
7
+
8
+ from opentrons_shared_data.command import get_newest_schema_version
9
+ from opentrons_shared_data.load import get_shared_data_root
10
+
11
+
12
+ def generate_command_schema(version: str) -> str:
13
+ """Generate a JSON Schema that all valid create commands can validate against."""
14
+ schema_as_dict = CommandCreateAdapter.json_schema(mode="validation", by_alias=False)
15
+ schema_as_dict["$id"] = f"opentronsCommandSchemaV{version}"
16
+ schema_as_dict["$schema"] = "http://json-schema.org/draft-07/schema#"
17
+ return json.dumps(schema_as_dict, indent=2, sort_keys=True)
18
+
19
+
20
+ def write_command_schema(json_string: str, version: str) -> None:
21
+ """Write a JSON command schema to the shared-data command schema directory."""
22
+ path = get_shared_data_root() / "command" / "schemas" / f"{version}.json"
23
+ with open(path, "w") as schema_file:
24
+ schema_file.write(json_string)
25
+
26
+
27
+ if __name__ == "__main__":
28
+ parser = argparse.ArgumentParser(
29
+ prog="generate_command_schema",
30
+ description="Generate A JSON-schema of all possible Create-Commands accepted by the current Protocol Engine",
31
+ )
32
+ parser.add_argument(
33
+ "version",
34
+ type=str,
35
+ nargs="?",
36
+ help="The command schema version. This is a single integer (e.g. 7) that will be used to name the generated"
37
+ " schema file. If not included, it will automatically use the latest version in shared-data.",
38
+ )
39
+ parser.add_argument(
40
+ "--overwrite-shared-data",
41
+ action="store_true",
42
+ help="If used, overwrites the specified or automatically chosen command schema version in shared-data."
43
+ " If not included, the generated schema will be printed to stdout.",
44
+ )
45
+ args = parser.parse_args()
46
+
47
+ if args.version is None:
48
+ version_string = get_newest_schema_version()
49
+ else:
50
+ version_string = args.version
51
+
52
+ command_schema = generate_command_schema(version_string)
53
+
54
+ if args.overwrite_shared_data:
55
+ write_command_schema(command_schema, version_string)
56
+ else:
57
+ print(command_schema)
58
+
59
+ sys.exit()
60
+
61
+ __all__ = ["generate_command_schema"]
@@ -0,0 +1,134 @@
1
+ """Get next tip command request, result, and implementation models."""
2
+
3
+ from __future__ import annotations
4
+ from pydantic import BaseModel, Field
5
+ from typing import TYPE_CHECKING, Any, Optional, Type, List, Literal, Union
6
+
7
+ from pydantic.json_schema import SkipJsonSchema
8
+
9
+ from opentrons.types import NozzleConfigurationType
10
+
11
+ from ..errors import ErrorOccurrence
12
+ from ..types import NextTipInfo, NoTipAvailable, NoTipReason
13
+ from .pipetting_common import PipetteIdMixin
14
+
15
+ from .command import (
16
+ AbstractCommandImpl,
17
+ BaseCommand,
18
+ BaseCommandCreate,
19
+ SuccessData,
20
+ )
21
+
22
+ if TYPE_CHECKING:
23
+ from ..state.state import StateView
24
+
25
+
26
+ def _remove_default(s: dict[str, Any]) -> None:
27
+ s.pop("default", None)
28
+
29
+
30
+ GetNextTipCommandType = Literal["getNextTip"]
31
+
32
+
33
+ class GetNextTipParams(PipetteIdMixin):
34
+ """Payload needed to resolve the next available tip."""
35
+
36
+ labwareIds: List[str] = Field(
37
+ ...,
38
+ description="Labware ID(s) of tip racks to resolve next available tip(s) from"
39
+ " Labware IDs will be resolved sequentially",
40
+ )
41
+ startingTipWell: str | SkipJsonSchema[None] = Field(
42
+ None,
43
+ description="Name of starting tip rack 'well'."
44
+ " This only applies to the first tip rack in the list provided in labwareIDs",
45
+ json_schema_extra=_remove_default,
46
+ )
47
+
48
+
49
+ class GetNextTipResult(BaseModel):
50
+ """Result data from the execution of a GetNextTip."""
51
+
52
+ nextTipInfo: Union[NextTipInfo, NoTipAvailable] = Field(
53
+ ...,
54
+ description="Labware ID and well name of next available tip for a pipette,"
55
+ " or information why no tip could be resolved.",
56
+ )
57
+
58
+
59
+ class GetNextTipImplementation(
60
+ AbstractCommandImpl[GetNextTipParams, SuccessData[GetNextTipResult]]
61
+ ):
62
+ """Get next tip command implementation."""
63
+
64
+ def __init__(
65
+ self,
66
+ state_view: StateView,
67
+ **kwargs: object,
68
+ ) -> None:
69
+ self._state_view = state_view
70
+
71
+ async def execute(self, params: GetNextTipParams) -> SuccessData[GetNextTipResult]:
72
+ """Get the next available tip for the requested pipette."""
73
+ pipette_id = params.pipetteId
74
+ starting_tip_name = params.startingTipWell
75
+
76
+ num_tips = self._state_view.pipettes.get_active_channels(pipette_id)
77
+ nozzle_map = self._state_view.pipettes.get_nozzle_configuration(pipette_id)
78
+
79
+ if (
80
+ starting_tip_name is not None
81
+ and nozzle_map.configuration != NozzleConfigurationType.FULL
82
+ ):
83
+ # This is to match the behavior found in PAPI, but also because we don't have logic to automatically find
84
+ # the next tip with partial configuration and a starting tip. This will never work for a 96-channel due to
85
+ # x-axis overlap, but could eventually work with 8-channel if we better define starting tip USED or CLEAN
86
+ # state when starting a protocol to prevent accidental tip pick-up with starting non-full tip racks.
87
+ return SuccessData(
88
+ public=GetNextTipResult(
89
+ nextTipInfo=NoTipAvailable(
90
+ noTipReason=NoTipReason.STARTING_TIP_WITH_PARTIAL,
91
+ message="Cannot automatically resolve next tip with starting tip and partial tip configuration.",
92
+ )
93
+ )
94
+ )
95
+
96
+ next_tip: Union[NextTipInfo, NoTipAvailable]
97
+ for labware_id in params.labwareIds:
98
+ well_name = self._state_view.tips.get_next_tip(
99
+ labware_id=labware_id,
100
+ num_tips=num_tips,
101
+ starting_tip_name=starting_tip_name,
102
+ nozzle_map=nozzle_map,
103
+ )
104
+ if well_name is not None:
105
+ next_tip = NextTipInfo(labwareId=labware_id, tipStartingWell=well_name)
106
+ break
107
+ # After the first tip rack is exhausted, starting tip no longer applies
108
+ starting_tip_name = None
109
+ else:
110
+ next_tip = NoTipAvailable(
111
+ noTipReason=NoTipReason.NO_AVAILABLE_TIPS,
112
+ message="No available tips for given pipette, nozzle configuration and provided tip racks.",
113
+ )
114
+
115
+ return SuccessData(public=GetNextTipResult(nextTipInfo=next_tip))
116
+
117
+
118
+ class GetNextTip(BaseCommand[GetNextTipParams, GetNextTipResult, ErrorOccurrence]):
119
+ """Get next tip command model."""
120
+
121
+ commandType: GetNextTipCommandType = "getNextTip"
122
+ params: GetNextTipParams
123
+ result: Optional[GetNextTipResult] = None
124
+
125
+ _ImplementationCls: Type[GetNextTipImplementation] = GetNextTipImplementation
126
+
127
+
128
+ class GetNextTipCreate(BaseCommandCreate[GetNextTipParams]):
129
+ """Get next tip command creation request model."""
130
+
131
+ commandType: GetNextTipCommandType = "getNextTip"
132
+ params: GetNextTipParams
133
+
134
+ _CommandCls: Type[GetNextTip] = GetNextTip
@@ -0,0 +1,87 @@
1
+ """Get tip presence command request, result and implementation models."""
2
+ from __future__ import annotations
3
+
4
+ from pydantic import Field, BaseModel
5
+ from typing import TYPE_CHECKING, Optional, Type
6
+ from typing_extensions import Literal
7
+
8
+ from .pipetting_common import PipetteIdMixin
9
+ from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
10
+ from ..errors.error_occurrence import ErrorOccurrence
11
+
12
+ from ..types import TipPresenceStatus
13
+
14
+ if TYPE_CHECKING:
15
+ from ..execution import TipHandler
16
+
17
+
18
+ GetTipPresenceCommandType = Literal["getTipPresence"]
19
+
20
+
21
+ class GetTipPresenceParams(PipetteIdMixin):
22
+ """Payload required for a GetTipPresence command."""
23
+
24
+ pass
25
+
26
+
27
+ class GetTipPresenceResult(BaseModel):
28
+ """Result data from the execution of a GetTipPresence command."""
29
+
30
+ status: TipPresenceStatus = Field(
31
+ ...,
32
+ description=(
33
+ "Whether or not a tip is attached on the pipette. This only works on"
34
+ " on FLEX because OT-2 pipettes do not possess tip presence sensors,"
35
+ " hence, will always return TipPresenceStatus.UNKNOWN."
36
+ ),
37
+ )
38
+
39
+
40
+ class GetTipPresenceImplementation(
41
+ AbstractCommandImpl[GetTipPresenceParams, SuccessData[GetTipPresenceResult]]
42
+ ):
43
+ """GetTipPresence command implementation."""
44
+
45
+ def __init__(
46
+ self,
47
+ tip_handler: TipHandler,
48
+ **kwargs: object,
49
+ ) -> None:
50
+ self._tip_handler = tip_handler
51
+
52
+ async def execute(
53
+ self, params: GetTipPresenceParams
54
+ ) -> SuccessData[GetTipPresenceResult]:
55
+ """Verify if tip presence is as expected for the requested pipette."""
56
+ pipette_id = params.pipetteId
57
+
58
+ result = await self._tip_handler.get_tip_presence(
59
+ pipette_id=pipette_id,
60
+ )
61
+
62
+ return SuccessData(
63
+ public=GetTipPresenceResult(status=result),
64
+ )
65
+
66
+
67
+ class GetTipPresence(
68
+ BaseCommand[GetTipPresenceParams, GetTipPresenceResult, ErrorOccurrence]
69
+ ):
70
+ """GetTipPresence command model."""
71
+
72
+ commandType: GetTipPresenceCommandType = "getTipPresence"
73
+ params: GetTipPresenceParams
74
+ result: Optional[GetTipPresenceResult] = None
75
+
76
+ _ImplementationCls: Type[
77
+ GetTipPresenceImplementation
78
+ ] = GetTipPresenceImplementation
79
+
80
+
81
+ class GetTipPresenceCreate(BaseCommandCreate[GetTipPresenceParams]):
82
+ """GetTipPresence command creation request model."""
83
+
84
+ commandType: GetTipPresenceCommandType = "getTipPresence"
85
+ params: GetTipPresenceParams
86
+
87
+ _CommandCls: Type[GetTipPresence] = GetTipPresence
@@ -0,0 +1,38 @@
1
+ """Hash command params into idempotent keys to track commands from analysis to run."""
2
+ from hashlib import md5
3
+ from typing import Optional
4
+
5
+ from .command import CommandIntent
6
+ from .command_unions import CommandCreate
7
+
8
+
9
+ # TODO(mm, 2023-04-28):
10
+ # This implementation will not notice that commands are different if they have different params
11
+ # but share the same commandType. We should also hash command params. (Jira RCORE-326.)
12
+ def hash_protocol_command_params(
13
+ create: CommandCreate, last_hash: Optional[str]
14
+ ) -> Optional[str]:
15
+ """Given a command create object, return a hash.
16
+
17
+ The hash is based on three things:
18
+ - The command parameters
19
+ - The latest hash (yo dawg I heard you like blockchains)
20
+ - Whether the command is a setup command or a protocol command;
21
+ setup commands are not hashed
22
+
23
+ Args:
24
+ create: The command create request.
25
+ last_hash: The last command hash, if it exists.
26
+
27
+ Returns:
28
+ The command hash, if the command is a protocol command.
29
+ `None` if the command is a setup command.
30
+ """
31
+ if create.intent in [CommandIntent.SETUP, CommandIntent.FIXIT]:
32
+ return None
33
+ # We avoid Python's built-in hash() function because it's not stable across
34
+ # runs of the Python interpreter. (Jira RSS-215.)
35
+ last_contribution = b"" if last_hash is None else last_hash.encode("ascii")
36
+ this_contribution = md5(create.commandType.encode("ascii")).digest()
37
+ to_hash = last_contribution + this_contribution
38
+ return md5(to_hash).hexdigest()