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,683 @@
1
+ """ProtocolEngine class definition."""
2
+
3
+ from contextlib import AsyncExitStack
4
+ from logging import getLogger
5
+ from typing import Dict, Optional, Union, AsyncGenerator, Callable
6
+
7
+ from opentrons_shared_data.errors import (
8
+ ErrorCodes,
9
+ EnumeratedError,
10
+ )
11
+ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
12
+
13
+ from opentrons.hardware_control import HardwareControlAPI
14
+ from opentrons.hardware_control.modules import AbstractModule as HardwareModuleAPI
15
+ from opentrons.hardware_control.types import PauseType as HardwarePauseType
16
+
17
+ from .actions.actions import (
18
+ ResumeFromRecoveryAction,
19
+ SetErrorRecoveryPolicyAction,
20
+ )
21
+ from .errors import ProtocolCommandFailedError, ErrorOccurrence, CommandNotAllowedError
22
+ from .errors.exceptions import EStopActivatedError
23
+ from .error_recovery_policy import ErrorRecoveryPolicy
24
+ from . import commands, slot_standardization, labware_offset_standardization
25
+ from .resources import ModelUtils, ModuleDataProvider, FileProvider
26
+ from .types import (
27
+ LabwareOffset,
28
+ LabwareOffsetCreate,
29
+ LegacyLabwareOffsetCreate,
30
+ LabwareUri,
31
+ ModuleModel,
32
+ Liquid,
33
+ HexColor,
34
+ PostRunHardwareState,
35
+ DeckConfigurationType,
36
+ )
37
+ from .execution import (
38
+ QueueWorker,
39
+ create_queue_worker,
40
+ DoorWatcher,
41
+ HardwareStopper,
42
+ )
43
+ from .state.state import StateStore, StateView
44
+ from .state.update_types import StateUpdate
45
+ from .plugins import AbstractPlugin, PluginStarter
46
+ from .actions import (
47
+ ActionDispatcher,
48
+ PlayAction,
49
+ PauseAction,
50
+ PauseSource,
51
+ StopAction,
52
+ FinishAction,
53
+ FinishErrorDetails,
54
+ QueueCommandAction,
55
+ AddLabwareOffsetAction,
56
+ AddLabwareDefinitionAction,
57
+ AddLiquidAction,
58
+ SetDeckConfigurationAction,
59
+ AddAddressableAreaAction,
60
+ AddModuleAction,
61
+ HardwareStoppedAction,
62
+ ResetTipsAction,
63
+ SetPipetteMovementSpeedAction,
64
+ )
65
+
66
+
67
+ _log = getLogger(__name__)
68
+
69
+
70
+ class ProtocolEngine:
71
+ """Main ProtocolEngine class.
72
+
73
+ A ProtocolEngine instance holds the state of a protocol as it executes,
74
+ and manages calls to a command executor that actually implements the logic
75
+ of the commands themselves.
76
+
77
+ Lifetime:
78
+ Instances are single-use. Each instance is associated with a single protocol,
79
+ or a a single chain of robot control such as Labware Position Check.
80
+
81
+ Concurrency:
82
+ Instances live in `asyncio` event loops. Each instance must be constructed inside an
83
+ event loop, and then must be interacted with exclusively through that
84
+ event loop's thread--even for regular non-`async` methods, like `.pause()`.
85
+ (This is because there are background async tasks that monitor state changes using
86
+ primitives that aren't thread-safe. See ChangeNotifier.)
87
+ """
88
+
89
+ def __init__(
90
+ self,
91
+ hardware_api: HardwareControlAPI,
92
+ state_store: StateStore,
93
+ action_dispatcher: ActionDispatcher,
94
+ plugin_starter: PluginStarter,
95
+ model_utils: ModelUtils,
96
+ hardware_stopper: HardwareStopper,
97
+ door_watcher: DoorWatcher,
98
+ module_data_provider: ModuleDataProvider,
99
+ file_provider: FileProvider,
100
+ queue_worker: Optional[QueueWorker] = None,
101
+ ) -> None:
102
+ """Initialize a ProtocolEngine instance.
103
+
104
+ Must be called while an event loop is active.
105
+
106
+ This constructor is only for `ProtocolEngine` unit tests.
107
+ Prefer the `create_protocol_engine()` factory function.
108
+ """
109
+ self._hardware_api = hardware_api
110
+ self._file_provider = file_provider
111
+ self._state_store = state_store
112
+ self._model_utils = model_utils
113
+ self._action_dispatcher = action_dispatcher
114
+ self._plugin_starter = plugin_starter
115
+ self._hardware_stopper = hardware_stopper
116
+ self._door_watcher = door_watcher
117
+ self._module_data_provider = module_data_provider
118
+ self._queue_worker = queue_worker
119
+ if self._queue_worker:
120
+ self._queue_worker.start()
121
+ self._door_watcher.start()
122
+
123
+ @property
124
+ def state_view(self) -> StateView:
125
+ """Get an interface to retrieve calculated state values."""
126
+ return self._state_store
127
+
128
+ @property
129
+ def _get_queue_worker(self) -> QueueWorker:
130
+ """Get the queue worker instance."""
131
+ assert self._queue_worker is not None
132
+ return self._queue_worker
133
+
134
+ def add_plugin(self, plugin: AbstractPlugin) -> None:
135
+ """Add a plugin to the engine to customize behavior."""
136
+ self._plugin_starter.start(plugin)
137
+
138
+ def set_deck_configuration(
139
+ self, deck_configuration: Optional[DeckConfigurationType]
140
+ ) -> None:
141
+ """Inform the engine of the robot's current deck configuration.
142
+
143
+ If `Config.use_simulated_deck_config` is `True`, this is meaningless and unused.
144
+ You can call this with `None` if you want to be explicit--it will no-op.
145
+
146
+ If `Config.use_simulated_deck_config` is `False`, you should call this with the
147
+ robot's actual, full, non-`None` deck configuration, before you play the run for
148
+ the first time. Do not call this in the middle of a run.
149
+ """
150
+ self._action_dispatcher.dispatch(SetDeckConfigurationAction(deck_configuration))
151
+
152
+ def play(self) -> None:
153
+ """Start or resume executing commands in the queue."""
154
+ requested_at = self._model_utils.get_timestamp()
155
+ # TODO(mc, 2021-08-05): if starting, ensure plungers motors are
156
+ # homed if necessary
157
+ action = self._state_store.commands.validate_action_allowed(
158
+ PlayAction(requested_at=requested_at)
159
+ )
160
+ self._action_dispatcher.dispatch(action)
161
+
162
+ if self._state_store.commands.get_is_door_blocking():
163
+ self._hardware_api.pause(HardwarePauseType.PAUSE)
164
+ else:
165
+ self._hardware_api.resume(HardwarePauseType.PAUSE)
166
+
167
+ def request_pause(self) -> None:
168
+ """Make command execution pause soon.
169
+
170
+ This will try to pause in the middle of the ongoing command, if there is one.
171
+ Otherwise, whenever the next command begins, the pause will happen then.
172
+ """
173
+ action = self._state_store.commands.validate_action_allowed(
174
+ PauseAction(source=PauseSource.CLIENT)
175
+ )
176
+ self._action_dispatcher.dispatch(action)
177
+ self._hardware_api.pause(HardwarePauseType.PAUSE)
178
+
179
+ def resume_from_recovery(self, reconcile_false_positive: bool) -> None:
180
+ """Resume normal protocol execution after the engine was `AWAITING_RECOVERY`.
181
+
182
+ If `reconcile_false_positive` is `False`, the engine will continue naively from
183
+ whatever state the error left it in. (Each defined error individually documents
184
+ exactly how it affects state.) This is appropriate for client-driven error
185
+ recovery, where the client wants predictable behavior from the engine.
186
+
187
+ If `reconcile_false_positive` is `True`, the engine may apply additional fixups
188
+ to its state to try to get the rest of the run to just work, assuming the error
189
+ was a false-positive.
190
+
191
+ For example, a `tipPhysicallyMissing` error from a `pickUpTip` would normally
192
+ leave the engine state without a tip on the pipette. If `reconcile_false_positive=True`,
193
+ the engine will set the pipette to have that missing tip before continuing, so
194
+ subsequent path planning, aspirates, dispenses, etc. will work as if nothing
195
+ went wrong.
196
+ """
197
+ if reconcile_false_positive:
198
+ state_update = (
199
+ self._state_store.commands.get_state_update_for_false_positive()
200
+ )
201
+ else:
202
+ state_update = StateUpdate() # Empty/no-op.
203
+
204
+ action = self._state_store.commands.validate_action_allowed(
205
+ ResumeFromRecoveryAction(state_update)
206
+ )
207
+
208
+ self._action_dispatcher.dispatch(action)
209
+
210
+ def add_command(
211
+ self, request: commands.CommandCreate, failed_command_id: Optional[str] = None
212
+ ) -> commands.Command:
213
+ """Add a command to the `ProtocolEngine`'s queue.
214
+
215
+ Arguments:
216
+ request: The command type and payload data used to construct
217
+ the command in state.
218
+
219
+ Returns:
220
+ The full, newly queued command.
221
+
222
+ Raises:
223
+ SetupCommandNotAllowed: the request specified a setup command,
224
+ but the engine was not idle or paused.
225
+ RunStoppedError: the run has been stopped, so no new commands
226
+ may be added.
227
+ CommandNotAllowedError: the request specified a failed command id
228
+ with a non fixit command.
229
+ """
230
+ request = slot_standardization.standardize_command(
231
+ request, self.state_view.config.robot_type
232
+ )
233
+
234
+ if failed_command_id and request.intent != commands.CommandIntent.FIXIT:
235
+ raise CommandNotAllowedError(
236
+ "failed command id should be supplied with a FIXIT command."
237
+ )
238
+
239
+ command_id = self._model_utils.generate_id()
240
+ if request.intent in (
241
+ commands.CommandIntent.SETUP,
242
+ commands.CommandIntent.FIXIT,
243
+ ):
244
+ request_hash = None
245
+ else:
246
+ request_hash = commands.hash_protocol_command_params(
247
+ create=request,
248
+ last_hash=self._state_store.commands.get_latest_protocol_command_hash(),
249
+ )
250
+
251
+ action = self.state_view.commands.validate_action_allowed(
252
+ QueueCommandAction(
253
+ request=request,
254
+ request_hash=request_hash,
255
+ command_id=command_id,
256
+ created_at=self._model_utils.get_timestamp(),
257
+ failed_command_id=failed_command_id,
258
+ )
259
+ )
260
+ self._action_dispatcher.dispatch(action)
261
+ return self._state_store.commands.get(command_id)
262
+
263
+ async def wait_for_command(self, command_id: str) -> None:
264
+ """Wait for a command to be completed.
265
+
266
+ Will also return if the engine was stopped before it reached the command.
267
+ """
268
+ await self._state_store.wait_for(
269
+ self._state_store.commands.get_command_is_final,
270
+ command_id=command_id,
271
+ )
272
+
273
+ async def add_and_execute_command(
274
+ self, request: commands.CommandCreate
275
+ ) -> commands.Command:
276
+ """Add a command to the queue and wait for it to complete.
277
+
278
+ The engine must be started by calling `play` before the command will
279
+ execute. You only need to call `play` once.
280
+
281
+ Arguments:
282
+ request: The command type and payload data used to construct
283
+ the command in state.
284
+
285
+ Returns:
286
+ The command.
287
+
288
+ If the command completed, it will be succeeded or failed.
289
+
290
+ If the engine was stopped before it reached the command,
291
+ the command will be queued.
292
+ """
293
+ command = self.add_command(request)
294
+ await self.wait_for_command(command.id)
295
+ return self._state_store.commands.get(command.id)
296
+
297
+ async def add_and_execute_command_wait_for_recovery(
298
+ self, request: commands.CommandCreate
299
+ ) -> commands.Command:
300
+ """Like `add_and_execute_command()`, except wait for error recovery.
301
+
302
+ Unlike `add_and_execute_command()`, if the command fails, this will not
303
+ immediately return the failed command. Instead, if the error is recoverable,
304
+ it will wait until error recovery has completed (e.g. when some other task
305
+ calls `self.resume_from_recovery()`).
306
+
307
+ Returns:
308
+ The command.
309
+
310
+ If the command completed, it will be succeeded or failed. If it failed
311
+ and then its failure was recovered from, it will still be failed.
312
+
313
+ If the engine was stopped before it reached the command,
314
+ the command will be queued.
315
+ """
316
+ queued_command = self.add_command(request)
317
+ await self.wait_for_command(command_id=queued_command.id)
318
+ completed_command = self._state_store.commands.get(queued_command.id)
319
+ await self._state_store.wait_for_not(
320
+ self.state_view.commands.get_recovery_in_progress_for_command,
321
+ queued_command.id,
322
+ )
323
+ return completed_command
324
+
325
+ def estop(self) -> None:
326
+ """Signal to the engine that an E-stop event occurred.
327
+
328
+ If an estop happens while the robot is moving, lower layers physically stop
329
+ motion and raise the event as an exception, which fails the Protocol Engine
330
+ command. No action from the `ProtocolEngine` caller is needed to handle that.
331
+
332
+ However, if an estop happens in between commands, or in the middle of
333
+ a command like `comment` or `waitForDuration` that doesn't access the hardware,
334
+ `ProtocolEngine` needs to be told about it so it can interrupt the command
335
+ and stop executing any more. This method is how to do that.
336
+
337
+ This acts roughly like `request_stop()`. After calling this, you should call
338
+ `finish()` with an EStopActivatedError.
339
+ """
340
+ try:
341
+ action = self._state_store.commands.validate_action_allowed(
342
+ StopAction(from_estop=True)
343
+ )
344
+ except Exception: # todo(mm, 2024-04-16): Catch a more specific type.
345
+ # This is likely called from some hardware API callback that doesn't care
346
+ # about ProtocolEngine lifecycle or what methods are valid to call at what
347
+ # times. So it makes more sense for us to no-op here than to propagate this
348
+ # as an error.
349
+ _log.info(
350
+ "ProtocolEngine cannot handle E-stop event right now. Ignoring it.",
351
+ exc_info=True,
352
+ )
353
+ return
354
+ self._action_dispatcher.dispatch(action)
355
+ # self._queue_worker.cancel() will try to interrupt any ongoing command.
356
+ # Unfortunately, if it's a hardware command, this interruption will race
357
+ # against the E-stop exception propagating up from lower layers. But we need to
358
+ # do this because we want to make sure non-hardware commands, like
359
+ # `waitForDuration`, are also interrupted.
360
+ self._get_queue_worker.cancel()
361
+ # Unlike self.request_stop(), we don't need to do
362
+ # self._hardware_api.cancel_execution_and_running_tasks(). Since this was an
363
+ # E-stop event, the hardware API already knows.
364
+
365
+ async def request_stop(self) -> None:
366
+ """Make command execution stop soon.
367
+
368
+ This will try to interrupt the ongoing command, if there is one. Future commands
369
+ are canceled. However, by the time this method returns, things may not have
370
+ settled by the time this method returns; the last command may still be
371
+ running.
372
+
373
+ After a stop has been requested, the engine cannot be restarted.
374
+
375
+ After a stop request, you must still call `finish` to give the engine a chance
376
+ to clean up resources and propagate errors.
377
+ """
378
+ action = self._state_store.commands.validate_action_allowed(StopAction())
379
+ self._action_dispatcher.dispatch(action)
380
+ self._get_queue_worker.cancel()
381
+ if self._hardware_api.is_movement_execution_taskified():
382
+ # We 'taskify' hardware controller movement functions when running protocols
383
+ # that are not backed by the engine. Such runs cannot be stopped by cancelling
384
+ # the queue worker and hence need to be stopped via the execution manager.
385
+ # `cancel_execution_and_running_tasks()` sets the execution manager in a CANCELLED state
386
+ # and cancels the running tasks, which raises an error and gets us out of the
387
+ # run function execution, just like `_queue_worker.cancel()` does for
388
+ # engine-backed runs.
389
+ await self._hardware_api.cancel_execution_and_running_tasks()
390
+
391
+ async def wait_until_complete(self) -> None:
392
+ """Wait until there are no more commands to execute.
393
+
394
+ If a command encountered a fatal error, it's raised as an exception.
395
+ """
396
+ await self._state_store.wait_for(
397
+ condition=self._state_store.commands.get_all_commands_final
398
+ )
399
+ self._state_store.commands.raise_fatal_command_error()
400
+
401
+ async def finish(
402
+ self,
403
+ error: Optional[Exception] = None,
404
+ drop_tips_after_run: bool = True,
405
+ set_run_status: bool = True,
406
+ post_run_hardware_state: PostRunHardwareState = PostRunHardwareState.HOME_AND_STAY_ENGAGED,
407
+ ) -> None:
408
+ """Finish using the `ProtocolEngine`.
409
+
410
+ This does a few things:
411
+
412
+ 1. It may do post-run actions like homing and dropping tips. This depends on the
413
+ arguments passed as well as heuristics based on the history of the engine.
414
+ 2. It waits for the engine to be done controlling the robot's hardware.
415
+ 3. It releases internal resources, like background tasks.
416
+
417
+ It's safe to call `finish()` multiple times. After you call `finish()`,
418
+ the engine can't be restarted.
419
+
420
+ This method should not raise. If any exceptions happened during execution that were not
421
+ properly caught by `ProtocolEngine` internals, or if any exceptions happen during this
422
+ `finish()` call, they should be saved as `.state_view.get_summary().errors`.
423
+
424
+ Arguments:
425
+ error: An error that caused the stop, if applicable.
426
+ drop_tips_after_run: Whether to drop tips as part of cleanup.
427
+ set_run_status: Whether to calculate a `success` or `failure` run status.
428
+ If `False`, will set status to `stopped`.
429
+ post_run_hardware_state: The state in which to leave the gantry and motors in
430
+ after the run is over.
431
+ """
432
+ if self._state_store.commands.get_is_stopped_by_estop():
433
+ # This handles the case where the E-stop was pressed while we were *not* in the middle
434
+ # of some hardware interaction that would raise it as an exception. For example, imagine
435
+ # we were paused between two commands, or imagine we were executing a waitForDuration.
436
+ drop_tips_after_run = False
437
+ post_run_hardware_state = PostRunHardwareState.DISENGAGE_IN_PLACE
438
+ if error is None:
439
+ error = EStopActivatedError()
440
+
441
+ if error:
442
+ # If the run had an error, check if that error indicates an E-stop.
443
+ # This handles the case where the run was in the middle of some hardware control
444
+ # method and the hardware controller raised an E-stop error from it.
445
+ #
446
+ # To do this, we need to scan all the way through the error tree.
447
+ # By the time E-stop error has gotten to us, it may have been wrapped in other errors,
448
+ # so we need to unwrap them to uncover the E-stop error's inner beauty.
449
+ #
450
+ # We don't use self._hardware_api.get_estop_state() because the E-stop may have been
451
+ # released by the time we get here.
452
+ if isinstance(error, EnumeratedError):
453
+ if code_in_error_tree(
454
+ root_error=error, code=ErrorCodes.E_STOP_ACTIVATED
455
+ ) or code_in_error_tree(
456
+ # Request from the hardware team for the v7.0 betas: to help in-house debugging
457
+ # of pipette overpressure events, leave the pipette where it was like we do
458
+ # for E-stops.
459
+ root_error=error,
460
+ code=ErrorCodes.PIPETTE_OVERPRESSURE,
461
+ ):
462
+ drop_tips_after_run = False
463
+ post_run_hardware_state = PostRunHardwareState.DISENGAGE_IN_PLACE
464
+
465
+ error_details: Optional[FinishErrorDetails] = FinishErrorDetails(
466
+ error_id=self._model_utils.generate_id(),
467
+ created_at=self._model_utils.get_timestamp(),
468
+ error=error,
469
+ )
470
+ else:
471
+ error_details = None
472
+
473
+ self._action_dispatcher.dispatch(
474
+ FinishAction(error_details=error_details, set_run_status=set_run_status)
475
+ )
476
+
477
+ # We have a lot of independent things to tear down. If any teardown fails, we want
478
+ # to continue with the rest, to avoid leaking resources or leaving the engine with a broken
479
+ # state. We use an AsyncExitStack to avoid a gigantic try/finally tree. Note that execution
480
+ # order will be backwards because the stack is first-in-last-out.
481
+ exit_stack = AsyncExitStack()
482
+ exit_stack.push_async_callback(self._plugin_starter.stop) # Last step.
483
+ exit_stack.push_async_callback(
484
+ # Cleanup after hardware halt and reset the hardware controller
485
+ self._hardware_stopper.do_stop_and_recover,
486
+ post_run_hardware_state=post_run_hardware_state,
487
+ drop_tips_after_run=drop_tips_after_run,
488
+ )
489
+ exit_stack.callback(self._door_watcher.stop)
490
+
491
+ disengage_before_stopping = (
492
+ False
493
+ if post_run_hardware_state == PostRunHardwareState.STAY_ENGAGED_IN_PLACE
494
+ else True
495
+ )
496
+ # Halt any movements immediately
497
+ exit_stack.push_async_callback(
498
+ self._hardware_stopper.do_halt,
499
+ disengage_before_stopping=disengage_before_stopping,
500
+ )
501
+ exit_stack.push_async_callback(self._get_queue_worker.join) # First step.
502
+ try:
503
+ # If any teardown steps failed, this will raise something.
504
+ await exit_stack.aclose()
505
+ except Exception as hardware_stopped_exception:
506
+ _log.exception("Exception during post-run finish steps.")
507
+ finish_error_details: Optional[FinishErrorDetails] = FinishErrorDetails(
508
+ error_id=self._model_utils.generate_id(),
509
+ created_at=self._model_utils.get_timestamp(),
510
+ error=hardware_stopped_exception,
511
+ )
512
+ else:
513
+ finish_error_details = None
514
+
515
+ self._action_dispatcher.dispatch(
516
+ HardwareStoppedAction(
517
+ completed_at=self._model_utils.get_timestamp(),
518
+ finish_error_details=finish_error_details,
519
+ )
520
+ )
521
+
522
+ def add_labware_offset(
523
+ self, request: LabwareOffsetCreate | LegacyLabwareOffsetCreate
524
+ ) -> LabwareOffset:
525
+ """Add a new labware offset and return it.
526
+
527
+ The added offset will apply to subsequent `LoadLabwareCommand`s.
528
+
529
+ To retrieve offsets later, see `.state_view.labware`.
530
+ """
531
+ internal_request = (
532
+ labware_offset_standardization.standardize_labware_offset_create(
533
+ request,
534
+ self.state_view.config.robot_type,
535
+ self.state_view.addressable_areas.deck_definition,
536
+ )
537
+ )
538
+
539
+ labware_offset_id = self._model_utils.generate_id()
540
+ created_at = self._model_utils.get_timestamp()
541
+ self._action_dispatcher.dispatch(
542
+ AddLabwareOffsetAction(
543
+ labware_offset_id=labware_offset_id,
544
+ created_at=created_at,
545
+ request=internal_request,
546
+ )
547
+ )
548
+ return self.state_view.labware.get_labware_offset(
549
+ labware_offset_id=labware_offset_id
550
+ )
551
+
552
+ def add_labware_definition(self, definition: LabwareDefinition) -> LabwareUri:
553
+ """Add a labware definition to the state for subsequent labware loads."""
554
+ self._action_dispatcher.dispatch(
555
+ AddLabwareDefinitionAction(definition=definition)
556
+ )
557
+ return self._state_store.labware.get_uri_from_definition(definition)
558
+
559
+ def add_liquid(
560
+ self,
561
+ name: str,
562
+ color: Optional[HexColor],
563
+ description: Optional[str],
564
+ id: Optional[str] = None,
565
+ ) -> Liquid:
566
+ """Add a liquid to the state for subsequent liquid loads."""
567
+ if id is None:
568
+ id = self._model_utils.generate_id()
569
+
570
+ liquid = Liquid(
571
+ id=id,
572
+ displayName=name,
573
+ description=(description or ""),
574
+ displayColor=color,
575
+ )
576
+ validated_liquid = self._state_store.liquid.validate_liquid_allowed(
577
+ liquid=liquid
578
+ )
579
+
580
+ self._action_dispatcher.dispatch(AddLiquidAction(liquid=validated_liquid))
581
+ return validated_liquid
582
+
583
+ def add_addressable_area(self, addressable_area_name: str) -> None:
584
+ """Add an addressable area to state."""
585
+ self._action_dispatcher.dispatch(
586
+ AddAddressableAreaAction(addressable_area_name)
587
+ )
588
+
589
+ def reset_tips(self, labware_id: str) -> None:
590
+ """Reset the tip state of a given labware."""
591
+ # TODO(mm, 2023-03-10): Safely raise an error if the given labware isn't a
592
+ # tip rack?
593
+ self._action_dispatcher.dispatch(ResetTipsAction(labware_id=labware_id))
594
+
595
+ # TODO(mm, 2022-11-10): This is a method on ProtocolEngine instead of a command
596
+ # as a quick hack to support Python protocols. We should consider making this a
597
+ # command, or adding speed parameters to existing commands.
598
+ # https://opentrons.atlassian.net/browse/RCORE-373
599
+ def set_pipette_movement_speed(
600
+ self, pipette_id: str, speed: Optional[float]
601
+ ) -> None:
602
+ """Set the speed of a pipette's X/Y/Z movements. Does not affect plunger speed.
603
+
604
+ None will use the hardware API's default.
605
+ """
606
+ self._action_dispatcher.dispatch(
607
+ SetPipetteMovementSpeedAction(pipette_id=pipette_id, speed=speed)
608
+ )
609
+
610
+ async def use_attached_modules(
611
+ self,
612
+ modules_by_id: Dict[str, HardwareModuleAPI],
613
+ ) -> None:
614
+ """Load attached modules directly into state, without locations."""
615
+ actions = [
616
+ AddModuleAction(
617
+ module_id=module_id,
618
+ serial_number=mod.device_info["serial"],
619
+ definition=self._module_data_provider.get_definition(
620
+ ModuleModel(mod.model())
621
+ ),
622
+ module_live_data=mod.live_data,
623
+ )
624
+ for module_id, mod in modules_by_id.items()
625
+ ]
626
+
627
+ for a in actions:
628
+ self._action_dispatcher.dispatch(a)
629
+
630
+ def set_and_start_queue_worker(
631
+ self, command_generator: Callable[[], AsyncGenerator[str, None]]
632
+ ) -> None:
633
+ """Set QueueWorker and start it."""
634
+ assert self._queue_worker is None
635
+ self._queue_worker = create_queue_worker(
636
+ hardware_api=self._hardware_api,
637
+ file_provider=self._file_provider,
638
+ state_store=self._state_store,
639
+ action_dispatcher=self._action_dispatcher,
640
+ command_generator=command_generator,
641
+ )
642
+ self._queue_worker.start()
643
+
644
+ def set_error_recovery_policy(self, policy: ErrorRecoveryPolicy) -> None:
645
+ """Replace the run's error recovery policy with a new one."""
646
+ self._action_dispatcher.dispatch(SetErrorRecoveryPolicyAction(policy))
647
+
648
+ def clear_command_history(self) -> None:
649
+ """Clear command history."""
650
+ self._state_store.clear_command_history()
651
+
652
+
653
+ # TODO(tz, 7-12-23): move this to shared data when we dont relay on ErrorOccurrence
654
+ def code_in_error_tree(
655
+ root_error: Union[EnumeratedError, ErrorOccurrence], code: ErrorCodes
656
+ ) -> bool:
657
+ """Check if the specified error code can be found in the given error tree."""
658
+ if isinstance(root_error, ErrorOccurrence):
659
+ # ErrorOccurrence is not the same as the enumerated error exceptions. Check the
660
+ # code by a string value.
661
+ if root_error.errorCode == code.value.code:
662
+ return True
663
+ return any(
664
+ code_in_error_tree(wrapped, code) for wrapped in root_error.wrappedErrors
665
+ )
666
+
667
+ # From here we have an exception, can just check the code + recurse to wrapped errors.
668
+ if root_error.code == code:
669
+ return True
670
+
671
+ if (
672
+ isinstance(root_error, ProtocolCommandFailedError)
673
+ and root_error.original_error is not None
674
+ ):
675
+ # For this specific EnumeratedError child, we recurse on the original_error field
676
+ # in favor of the general error.wrapping field.
677
+ return code_in_error_tree(root_error.original_error, code)
678
+
679
+ if len(root_error.wrapping) == 0:
680
+ return False
681
+ return any(
682
+ code_in_error_tree(wrapped_error, code) for wrapped_error in root_error.wrapping
683
+ )