opentrons 8.6.0__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 (601) 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 +557 -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 +187 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +557 -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/scripts/update_module_fw.py +274 -0
  200. opentrons/hardware_control/simulator_setup.py +260 -0
  201. opentrons/hardware_control/thread_manager.py +431 -0
  202. opentrons/hardware_control/threaded_async_lock.py +97 -0
  203. opentrons/hardware_control/types.py +792 -0
  204. opentrons/hardware_control/util.py +234 -0
  205. opentrons/legacy_broker.py +53 -0
  206. opentrons/legacy_commands/__init__.py +1 -0
  207. opentrons/legacy_commands/commands.py +483 -0
  208. opentrons/legacy_commands/helpers.py +153 -0
  209. opentrons/legacy_commands/module_commands.py +276 -0
  210. opentrons/legacy_commands/protocol_commands.py +54 -0
  211. opentrons/legacy_commands/publisher.py +155 -0
  212. opentrons/legacy_commands/robot_commands.py +51 -0
  213. opentrons/legacy_commands/types.py +1186 -0
  214. opentrons/motion_planning/__init__.py +32 -0
  215. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  216. opentrons/motion_planning/deck_conflict.py +501 -0
  217. opentrons/motion_planning/errors.py +35 -0
  218. opentrons/motion_planning/types.py +42 -0
  219. opentrons/motion_planning/waypoints.py +218 -0
  220. opentrons/ordered_set.py +138 -0
  221. opentrons/protocol_api/__init__.py +105 -0
  222. opentrons/protocol_api/_liquid.py +157 -0
  223. opentrons/protocol_api/_liquid_properties.py +814 -0
  224. opentrons/protocol_api/_nozzle_layout.py +31 -0
  225. opentrons/protocol_api/_parameter_context.py +300 -0
  226. opentrons/protocol_api/_parameters.py +31 -0
  227. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  228. opentrons/protocol_api/_types.py +43 -0
  229. opentrons/protocol_api/config.py +23 -0
  230. opentrons/protocol_api/core/__init__.py +23 -0
  231. opentrons/protocol_api/core/common.py +33 -0
  232. opentrons/protocol_api/core/core_map.py +74 -0
  233. opentrons/protocol_api/core/engine/__init__.py +22 -0
  234. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  235. opentrons/protocol_api/core/engine/deck_conflict.py +400 -0
  236. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  237. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  238. opentrons/protocol_api/core/engine/labware.py +238 -0
  239. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  240. opentrons/protocol_api/core/engine/module_core.py +1027 -0
  241. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  242. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  243. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  244. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  245. opentrons/protocol_api/core/engine/robot.py +139 -0
  246. opentrons/protocol_api/core/engine/stringify.py +74 -0
  247. opentrons/protocol_api/core/engine/transfer_components_executor.py +1006 -0
  248. opentrons/protocol_api/core/engine/well.py +241 -0
  249. opentrons/protocol_api/core/instrument.py +459 -0
  250. opentrons/protocol_api/core/labware.py +151 -0
  251. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  252. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  253. opentrons/protocol_api/core/legacy/deck.py +369 -0
  254. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  255. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  256. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  257. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  258. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  259. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  260. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  261. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  262. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  263. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  265. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  266. opentrons/protocol_api/core/module.py +484 -0
  267. opentrons/protocol_api/core/protocol.py +311 -0
  268. opentrons/protocol_api/core/robot.py +51 -0
  269. opentrons/protocol_api/core/well.py +116 -0
  270. opentrons/protocol_api/core/well_grid.py +45 -0
  271. opentrons/protocol_api/create_protocol_context.py +177 -0
  272. opentrons/protocol_api/deck.py +223 -0
  273. opentrons/protocol_api/disposal_locations.py +244 -0
  274. opentrons/protocol_api/instrument_context.py +3272 -0
  275. opentrons/protocol_api/labware.py +1579 -0
  276. opentrons/protocol_api/module_contexts.py +1447 -0
  277. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  278. opentrons/protocol_api/protocol_context.py +1688 -0
  279. opentrons/protocol_api/robot_context.py +303 -0
  280. opentrons/protocol_api/validation.py +761 -0
  281. opentrons/protocol_engine/__init__.py +155 -0
  282. opentrons/protocol_engine/actions/__init__.py +65 -0
  283. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  284. opentrons/protocol_engine/actions/action_handler.py +13 -0
  285. opentrons/protocol_engine/actions/actions.py +302 -0
  286. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  287. opentrons/protocol_engine/clients/__init__.py +5 -0
  288. opentrons/protocol_engine/clients/sync_client.py +174 -0
  289. opentrons/protocol_engine/clients/transports.py +197 -0
  290. opentrons/protocol_engine/commands/__init__.py +757 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  296. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  297. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  298. opentrons/protocol_engine/commands/aspirate.py +244 -0
  299. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  300. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  301. opentrons/protocol_engine/commands/blow_out.py +146 -0
  302. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  303. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  306. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  307. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  308. opentrons/protocol_engine/commands/command.py +308 -0
  309. opentrons/protocol_engine/commands/command_unions.py +974 -0
  310. opentrons/protocol_engine/commands/comment.py +57 -0
  311. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  312. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  313. opentrons/protocol_engine/commands/custom.py +67 -0
  314. opentrons/protocol_engine/commands/dispense.py +194 -0
  315. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  316. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  317. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  318. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  319. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  320. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  321. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  322. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  323. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  324. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  325. opentrons/protocol_engine/commands/flex_stacker/store.py +339 -0
  326. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  327. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  328. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  329. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  330. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  331. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  333. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  334. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  336. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  337. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  338. opentrons/protocol_engine/commands/home.py +100 -0
  339. opentrons/protocol_engine/commands/identify_module.py +86 -0
  340. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  341. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  342. opentrons/protocol_engine/commands/load_labware.py +210 -0
  343. opentrons/protocol_engine/commands/load_lid.py +154 -0
  344. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  345. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  346. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  347. opentrons/protocol_engine/commands/load_module.py +223 -0
  348. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  349. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  350. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  351. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  352. opentrons/protocol_engine/commands/move_labware.py +546 -0
  353. opentrons/protocol_engine/commands/move_relative.py +102 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  355. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  356. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  357. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  358. opentrons/protocol_engine/commands/movement_common.py +338 -0
  359. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  360. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  361. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  362. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  363. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  364. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  365. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  366. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  367. opentrons/protocol_engine/commands/robot/common.py +18 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  369. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  370. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  371. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  372. opentrons/protocol_engine/commands/save_position.py +109 -0
  373. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  374. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  375. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  376. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  377. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  378. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  379. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  380. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  381. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  384. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  386. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  388. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  390. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  391. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  392. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  401. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  402. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  403. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  404. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  405. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  406. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  407. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  408. opentrons/protocol_engine/engine_support.py +28 -0
  409. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  410. opentrons/protocol_engine/errors/__init__.py +191 -0
  411. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  412. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  413. opentrons/protocol_engine/execution/__init__.py +50 -0
  414. opentrons/protocol_engine/execution/command_executor.py +216 -0
  415. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  416. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  417. opentrons/protocol_engine/execution/equipment.py +819 -0
  418. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  419. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  420. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  421. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  422. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  423. opentrons/protocol_engine/execution/movement.py +350 -0
  424. opentrons/protocol_engine/execution/pipetting.py +607 -0
  425. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  426. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  427. opentrons/protocol_engine/execution/run_control.py +33 -0
  428. opentrons/protocol_engine/execution/status_bar.py +34 -0
  429. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  430. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  431. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  432. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  433. opentrons/protocol_engine/notes/__init__.py +17 -0
  434. opentrons/protocol_engine/notes/notes.py +59 -0
  435. opentrons/protocol_engine/plugins.py +104 -0
  436. opentrons/protocol_engine/protocol_engine.py +683 -0
  437. opentrons/protocol_engine/resources/__init__.py +26 -0
  438. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  439. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  440. opentrons/protocol_engine/resources/file_provider.py +161 -0
  441. opentrons/protocol_engine/resources/fixture_validation.py +68 -0
  442. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  443. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  444. opentrons/protocol_engine/resources/model_utils.py +32 -0
  445. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  446. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  447. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  448. opentrons/protocol_engine/slot_standardization.py +128 -0
  449. opentrons/protocol_engine/state/__init__.py +1 -0
  450. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  451. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  452. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  453. opentrons/protocol_engine/state/_move_types.py +83 -0
  454. opentrons/protocol_engine/state/_well_math.py +193 -0
  455. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  456. opentrons/protocol_engine/state/command_history.py +309 -0
  457. opentrons/protocol_engine/state/commands.py +1164 -0
  458. opentrons/protocol_engine/state/config.py +39 -0
  459. opentrons/protocol_engine/state/files.py +57 -0
  460. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  461. opentrons/protocol_engine/state/geometry.py +2408 -0
  462. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  463. opentrons/protocol_engine/state/labware.py +1432 -0
  464. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  465. opentrons/protocol_engine/state/liquids.py +73 -0
  466. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  467. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  468. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  469. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  471. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  472. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  473. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  474. opentrons/protocol_engine/state/modules.py +1515 -0
  475. opentrons/protocol_engine/state/motion.py +373 -0
  476. opentrons/protocol_engine/state/pipettes.py +905 -0
  477. opentrons/protocol_engine/state/state.py +421 -0
  478. opentrons/protocol_engine/state/state_summary.py +36 -0
  479. opentrons/protocol_engine/state/tips.py +420 -0
  480. opentrons/protocol_engine/state/update_types.py +904 -0
  481. opentrons/protocol_engine/state/wells.py +290 -0
  482. opentrons/protocol_engine/types/__init__.py +310 -0
  483. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  484. opentrons/protocol_engine/types/command_annotations.py +53 -0
  485. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  486. opentrons/protocol_engine/types/execution.py +96 -0
  487. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  488. opentrons/protocol_engine/types/instrument.py +47 -0
  489. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  490. opentrons/protocol_engine/types/labware.py +131 -0
  491. opentrons/protocol_engine/types/labware_movement.py +22 -0
  492. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  493. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  494. opentrons/protocol_engine/types/liquid.py +40 -0
  495. opentrons/protocol_engine/types/liquid_class.py +59 -0
  496. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  497. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  498. opentrons/protocol_engine/types/location.py +194 -0
  499. opentrons/protocol_engine/types/module.py +310 -0
  500. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  501. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  502. opentrons/protocol_engine/types/tip.py +18 -0
  503. opentrons/protocol_engine/types/util.py +21 -0
  504. opentrons/protocol_engine/types/well_position.py +124 -0
  505. opentrons/protocol_reader/__init__.py +37 -0
  506. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  507. opentrons/protocol_reader/file_format_validator.py +152 -0
  508. opentrons/protocol_reader/file_hasher.py +27 -0
  509. opentrons/protocol_reader/file_identifier.py +284 -0
  510. opentrons/protocol_reader/file_reader_writer.py +90 -0
  511. opentrons/protocol_reader/input_file.py +16 -0
  512. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  513. opentrons/protocol_reader/protocol_reader.py +188 -0
  514. opentrons/protocol_reader/protocol_source.py +124 -0
  515. opentrons/protocol_reader/role_analyzer.py +86 -0
  516. opentrons/protocol_runner/__init__.py +26 -0
  517. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  518. opentrons/protocol_runner/json_file_reader.py +55 -0
  519. opentrons/protocol_runner/json_translator.py +314 -0
  520. opentrons/protocol_runner/legacy_command_mapper.py +852 -0
  521. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  522. opentrons/protocol_runner/protocol_runner.py +530 -0
  523. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  524. opentrons/protocol_runner/run_orchestrator.py +496 -0
  525. opentrons/protocol_runner/task_queue.py +95 -0
  526. opentrons/protocols/__init__.py +6 -0
  527. opentrons/protocols/advanced_control/__init__.py +0 -0
  528. opentrons/protocols/advanced_control/common.py +38 -0
  529. opentrons/protocols/advanced_control/mix.py +60 -0
  530. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  531. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  532. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  533. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  534. opentrons/protocols/api_support/__init__.py +0 -0
  535. opentrons/protocols/api_support/constants.py +8 -0
  536. opentrons/protocols/api_support/deck_type.py +110 -0
  537. opentrons/protocols/api_support/definitions.py +18 -0
  538. opentrons/protocols/api_support/instrument.py +151 -0
  539. opentrons/protocols/api_support/labware_like.py +233 -0
  540. opentrons/protocols/api_support/tip_tracker.py +175 -0
  541. opentrons/protocols/api_support/types.py +32 -0
  542. opentrons/protocols/api_support/util.py +403 -0
  543. opentrons/protocols/bundle.py +89 -0
  544. opentrons/protocols/duration/__init__.py +4 -0
  545. opentrons/protocols/duration/errors.py +5 -0
  546. opentrons/protocols/duration/estimator.py +628 -0
  547. opentrons/protocols/execution/__init__.py +0 -0
  548. opentrons/protocols/execution/dev_types.py +181 -0
  549. opentrons/protocols/execution/errors.py +40 -0
  550. opentrons/protocols/execution/execute.py +84 -0
  551. opentrons/protocols/execution/execute_json_v3.py +275 -0
  552. opentrons/protocols/execution/execute_json_v4.py +359 -0
  553. opentrons/protocols/execution/execute_json_v5.py +28 -0
  554. opentrons/protocols/execution/execute_python.py +169 -0
  555. opentrons/protocols/execution/json_dispatchers.py +87 -0
  556. opentrons/protocols/execution/types.py +7 -0
  557. opentrons/protocols/geometry/__init__.py +0 -0
  558. opentrons/protocols/geometry/planning.py +297 -0
  559. opentrons/protocols/labware.py +312 -0
  560. opentrons/protocols/models/__init__.py +0 -0
  561. opentrons/protocols/models/json_protocol.py +679 -0
  562. opentrons/protocols/parameters/__init__.py +0 -0
  563. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  564. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  565. opentrons/protocols/parameters/exceptions.py +34 -0
  566. opentrons/protocols/parameters/parameter_definition.py +272 -0
  567. opentrons/protocols/parameters/types.py +17 -0
  568. opentrons/protocols/parameters/validation.py +267 -0
  569. opentrons/protocols/parse.py +671 -0
  570. opentrons/protocols/types.py +159 -0
  571. opentrons/py.typed +0 -0
  572. opentrons/resources/scripts/lpc21isp +0 -0
  573. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  574. opentrons/simulate.py +1065 -0
  575. opentrons/system/__init__.py +6 -0
  576. opentrons/system/camera.py +51 -0
  577. opentrons/system/log_control.py +59 -0
  578. opentrons/system/nmcli.py +856 -0
  579. opentrons/system/resin.py +24 -0
  580. opentrons/system/smoothie_update.py +15 -0
  581. opentrons/system/wifi.py +204 -0
  582. opentrons/tools/__init__.py +0 -0
  583. opentrons/tools/args_handler.py +22 -0
  584. opentrons/tools/write_pipette_memory.py +157 -0
  585. opentrons/types.py +618 -0
  586. opentrons/util/__init__.py +1 -0
  587. opentrons/util/async_helpers.py +166 -0
  588. opentrons/util/broker.py +84 -0
  589. opentrons/util/change_notifier.py +47 -0
  590. opentrons/util/entrypoint_util.py +278 -0
  591. opentrons/util/get_union_elements.py +26 -0
  592. opentrons/util/helpers.py +6 -0
  593. opentrons/util/linal.py +178 -0
  594. opentrons/util/logging_config.py +265 -0
  595. opentrons/util/logging_queue_handler.py +61 -0
  596. opentrons/util/performance_helpers.py +157 -0
  597. opentrons-8.6.0.dist-info/METADATA +37 -0
  598. opentrons-8.6.0.dist-info/RECORD +601 -0
  599. opentrons-8.6.0.dist-info/WHEEL +4 -0
  600. opentrons-8.6.0.dist-info/entry_points.txt +3 -0
  601. opentrons-8.6.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,546 @@
1
+ """Models and implementation for the ``moveLabware`` command."""
2
+
3
+ from __future__ import annotations
4
+ from typing import TYPE_CHECKING, Optional, Type, Any, List
5
+ from typing_extensions import (
6
+ TypedDict,
7
+ assert_type,
8
+ ) # note: need this instead of typing for py<3.12
9
+
10
+ from pydantic.json_schema import SkipJsonSchema
11
+ from pydantic import BaseModel, Field
12
+ from typing_extensions import Literal
13
+
14
+ from opentrons_shared_data.labware.labware_definition import (
15
+ LabwareDefinition,
16
+ LabwareDefinition2,
17
+ LabwareDefinition3,
18
+ )
19
+ from opentrons_shared_data.errors.exceptions import (
20
+ FailedGripperPickupError,
21
+ LabwareDroppedError,
22
+ StallOrCollisionDetectedError,
23
+ )
24
+ from opentrons_shared_data.gripper.constants import GRIPPER_PADDLE_WIDTH
25
+
26
+ from opentrons.protocol_engine.resources.model_utils import ModelUtils
27
+ from opentrons.types import Point
28
+ from ..types import (
29
+ ModuleModel,
30
+ CurrentWell,
31
+ LoadableLabwareLocation,
32
+ DeckSlotLocation,
33
+ ModuleLocation,
34
+ OnLabwareLocation,
35
+ AddressableAreaLocation,
36
+ LabwareMovementStrategy,
37
+ LabwareOffsetVector,
38
+ LabwareLocationSequence,
39
+ NotOnDeckLocationSequenceComponent,
40
+ OFF_DECK_LOCATION,
41
+ )
42
+ from ..errors import (
43
+ LabwareMovementNotAllowedError,
44
+ NotSupportedOnRobotType,
45
+ LabwareOffsetDoesNotExistError,
46
+ )
47
+ from ..resources import labware_validation, fixture_validation
48
+ from .command import (
49
+ AbstractCommandImpl,
50
+ BaseCommand,
51
+ BaseCommandCreate,
52
+ DefinedErrorData,
53
+ SuccessData,
54
+ )
55
+ from ..errors.error_occurrence import ErrorOccurrence
56
+ from ..state.update_types import StateUpdate
57
+
58
+ if TYPE_CHECKING:
59
+ from ..execution import EquipmentHandler, RunControlHandler, LabwareMovementHandler
60
+ from ..state.state import StateView
61
+
62
+
63
+ MoveLabwareCommandType = Literal["moveLabware"]
64
+
65
+
66
+ def _remove_default(s: dict[str, Any]) -> None:
67
+ s.pop("default", None)
68
+
69
+
70
+ # Extra buffer on top of minimum distance to move to the right
71
+ _TRASH_CHUTE_DROP_BUFFER_MM = 8
72
+
73
+
74
+ class MoveLabwareParams(BaseModel):
75
+ """Input parameters for a ``moveLabware`` command."""
76
+
77
+ labwareId: str = Field(..., description="The ID of the labware to move.")
78
+ newLocation: LoadableLabwareLocation = Field(
79
+ ..., description="Where to move the labware."
80
+ )
81
+ strategy: LabwareMovementStrategy = Field(
82
+ ...,
83
+ description="Whether to use the gripper to perform the labware movement"
84
+ " or to perform a manual movement with an option to pause.",
85
+ )
86
+ pickUpOffset: LabwareOffsetVector | SkipJsonSchema[None] = Field(
87
+ None,
88
+ description="Offset to use when picking up labware. "
89
+ "Experimental param, subject to change",
90
+ json_schema_extra=_remove_default,
91
+ )
92
+ dropOffset: LabwareOffsetVector | SkipJsonSchema[None] = Field(
93
+ None,
94
+ description="Offset to use when dropping off labware. "
95
+ "Experimental param, subject to change",
96
+ json_schema_extra=_remove_default,
97
+ )
98
+
99
+
100
+ class MoveLabwareResult(BaseModel):
101
+ """The output of a successful ``moveLabware`` command."""
102
+
103
+ offsetId: Optional[str] = Field(
104
+ # Default `None` instead of `...` so this field shows up as non-required in
105
+ # OpenAPI. The server is allowed to omit it or make it null.
106
+ None,
107
+ description=(
108
+ "An ID referencing the labware offset that will apply to this labware"
109
+ " now that it's in the new location."
110
+ " This offset will be in effect until the labware is moved"
111
+ " with another `moveLabware` command."
112
+ " Null or undefined means no offset applies,"
113
+ " so the default of (0, 0, 0) will be used."
114
+ ),
115
+ )
116
+ eventualDestinationLocationSequence: LabwareLocationSequence | None = Field(
117
+ None,
118
+ description=(
119
+ "The full location in which this labware will eventually reside. This will typically be the same as its "
120
+ "immediate destination, but if this labware is going to the trash then this field will be off deck."
121
+ ),
122
+ )
123
+ immediateDestinationLocationSequence: LabwareLocationSequence | None = Field(
124
+ None,
125
+ description=(
126
+ "The full location to which this labware is being moved, right now."
127
+ ),
128
+ )
129
+ originLocationSequence: LabwareLocationSequence | None = Field(
130
+ None,
131
+ description="The full location down to the deck of the labware before this command.",
132
+ )
133
+
134
+
135
+ class ErrorDetails(TypedDict):
136
+ """Location details for a failed gripper move."""
137
+
138
+ originLocationSequence: LabwareLocationSequence
139
+ immediateDestinationLocationSequence: LabwareLocationSequence
140
+ eventualDestinationLocationSequence: LabwareLocationSequence
141
+
142
+
143
+ class GripperMovementError(ErrorOccurrence):
144
+ """Returned when something physically goes wrong when the gripper moves labware.
145
+
146
+ When this error happens, the engine will leave the labware in its original place.
147
+ """
148
+
149
+ isDefined: bool = True
150
+
151
+ errorType: Literal["gripperMovement"] = "gripperMovement"
152
+
153
+ errorInfo: ErrorDetails
154
+
155
+
156
+ _ExecuteReturn = SuccessData[MoveLabwareResult] | DefinedErrorData[GripperMovementError]
157
+
158
+
159
+ class MoveLabwareImplementation(AbstractCommandImpl[MoveLabwareParams, _ExecuteReturn]):
160
+ """The execution implementation for ``moveLabware`` commands."""
161
+
162
+ def __init__(
163
+ self,
164
+ model_utils: ModelUtils,
165
+ state_view: StateView,
166
+ equipment: EquipmentHandler,
167
+ labware_movement: LabwareMovementHandler,
168
+ run_control: RunControlHandler,
169
+ **kwargs: object,
170
+ ) -> None:
171
+ self._model_utils = model_utils
172
+ self._state_view = state_view
173
+ self._equipment = equipment
174
+ self._labware_movement = labware_movement
175
+ self._run_control = run_control
176
+
177
+ async def execute(self, params: MoveLabwareParams) -> _ExecuteReturn: # noqa: C901
178
+ """Move a loaded labware to a new location."""
179
+ state_update = StateUpdate()
180
+
181
+ # Allow propagation of LabwareNotLoadedError.
182
+ current_labware = self._state_view.labware.get(labware_id=params.labwareId)
183
+ current_labware_definition = self._state_view.labware.get_definition(
184
+ labware_id=params.labwareId
185
+ )
186
+ definition_uri = current_labware.definitionUri
187
+ post_drop_slide_offset: Optional[Point] = None
188
+ trash_lid_drop_offset: Optional[Point] = None
189
+
190
+ if self._state_view.labware.is_fixed_trash(params.labwareId):
191
+ raise LabwareMovementNotAllowedError(
192
+ f"Cannot move fixed trash labware '{current_labware_definition.parameters.loadName}'."
193
+ )
194
+
195
+ origin_location_sequence = self._state_view.geometry.get_location_sequence(
196
+ params.labwareId
197
+ )
198
+ eventual_destination_location_sequence: LabwareLocationSequence | None = None
199
+
200
+ if isinstance(params.newLocation, AddressableAreaLocation):
201
+ area_name = params.newLocation.addressableAreaName
202
+ if (
203
+ not fixture_validation.is_gripper_waste_chute(area_name)
204
+ and not fixture_validation.is_deck_slot(area_name)
205
+ and not fixture_validation.is_trash(area_name)
206
+ ):
207
+ raise LabwareMovementNotAllowedError(
208
+ f"Cannot move {current_labware.loadName} to addressable area {area_name}"
209
+ )
210
+ self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
211
+ area_name
212
+ )
213
+ state_update.set_addressable_area_used(addressable_area_name=area_name)
214
+
215
+ if fixture_validation.is_gripper_waste_chute(area_name):
216
+ # When dropping off labware in the waste chute, some bigger pieces
217
+ # of labware (namely tipracks) can get stuck between a gripper
218
+ # paddle and the bottom of the waste chute, even after the gripper
219
+ # has homed all the way to the top of its travel. We add a "post-drop
220
+ # slide" to dropoffs in the waste chute in order to guarantee that the
221
+ # labware can drop fully through the chute before the gripper jaws close.
222
+ post_drop_slide_offset = Point(
223
+ x=(_labware_x_dimension(current_labware_definition) / 2.0)
224
+ + (GRIPPER_PADDLE_WIDTH / 2.0)
225
+ + _TRASH_CHUTE_DROP_BUFFER_MM,
226
+ y=0,
227
+ z=0,
228
+ )
229
+ eventual_destination_location_sequence = [
230
+ NotOnDeckLocationSequenceComponent(
231
+ logicalLocationName=OFF_DECK_LOCATION
232
+ )
233
+ ]
234
+ elif fixture_validation.is_trash(area_name):
235
+ # When dropping labware in the trash bins we want to ensure they are lids
236
+ # and enforce a y-axis drop offset to ensure they fall within the trash bin
237
+ eventual_destination_location_sequence = [
238
+ NotOnDeckLocationSequenceComponent(
239
+ logicalLocationName=OFF_DECK_LOCATION
240
+ )
241
+ ]
242
+ if labware_validation.validate_definition_is_lid(
243
+ self._state_view.labware.get_definition(params.labwareId)
244
+ ):
245
+ lid_disposable_offsets = (
246
+ current_labware_definition.gripperOffsets.get(
247
+ "lidDisposalOffsets"
248
+ )
249
+ )
250
+ if lid_disposable_offsets is not None:
251
+ trash_lid_drop_offset = Point.from_xyz_attrs(
252
+ lid_disposable_offsets.dropOffset
253
+ )
254
+ else:
255
+ raise LabwareOffsetDoesNotExistError(
256
+ f"Labware Definition {current_labware.loadName} does not contain required field 'lidDisposalOffsets' of 'gripperOffsets'."
257
+ )
258
+ else:
259
+ raise LabwareMovementNotAllowedError(
260
+ "Can only move labware with allowed role 'Lid' to a Trash Bin."
261
+ )
262
+
263
+ elif isinstance(params.newLocation, DeckSlotLocation):
264
+ self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
265
+ params.newLocation.slotName.id
266
+ )
267
+ state_update.set_addressable_area_used(
268
+ addressable_area_name=params.newLocation.slotName.id
269
+ )
270
+
271
+ available_new_location = self._state_view.geometry.ensure_location_not_occupied(
272
+ location=params.newLocation
273
+ )
274
+
275
+ # Check that labware and destination do not have labware on top
276
+ self._state_view.labware.raise_if_labware_has_non_lid_labware_on_top(
277
+ labware_id=params.labwareId
278
+ )
279
+
280
+ if isinstance(available_new_location, DeckSlotLocation):
281
+ self._state_view.labware.raise_if_labware_cannot_be_ondeck(
282
+ location=available_new_location,
283
+ labware_definition=self._state_view.labware.get_definition(
284
+ params.labwareId
285
+ ),
286
+ )
287
+
288
+ module_location_error = None
289
+ if isinstance(available_new_location, OnLabwareLocation):
290
+ self._state_view.labware.raise_if_labware_has_labware_on_top(
291
+ available_new_location.labwareId
292
+ )
293
+ # Ensure that labware can be placed on requested labware
294
+ self._state_view.labware.raise_if_labware_cannot_be_stacked(
295
+ top_labware_definition=current_labware_definition,
296
+ bottom_labware_id=available_new_location.labwareId,
297
+ )
298
+ if params.labwareId == available_new_location.labwareId:
299
+ raise LabwareMovementNotAllowedError(
300
+ "Cannot move a labware onto itself."
301
+ )
302
+ # Validate labware for the module placement
303
+ elif isinstance(available_new_location, ModuleLocation):
304
+ module = self._state_view.modules.get(available_new_location.moduleId)
305
+ if module is not None and module.model == ModuleModel.ABSORBANCE_READER_V1:
306
+ self._state_view.labware.raise_if_labware_incompatible_with_plate_reader(
307
+ current_labware_definition
308
+ )
309
+
310
+ # Allow propagation of ModuleNotLoadedError.
311
+ new_offset_id = self._equipment.find_applicable_labware_offset_id(
312
+ labware_definition_uri=definition_uri,
313
+ labware_location=available_new_location,
314
+ )
315
+ await self._labware_movement.ensure_movement_not_obstructed_by_module(
316
+ labware_id=params.labwareId, new_location=available_new_location
317
+ )
318
+
319
+ if params.strategy == LabwareMovementStrategy.USING_GRIPPER:
320
+ if self._state_view.config.robot_type == "OT-2 Standard":
321
+ raise NotSupportedOnRobotType(
322
+ message="Labware movement using a gripper is not supported on the OT-2",
323
+ details={"strategy": params.strategy},
324
+ )
325
+ if not labware_validation.validate_gripper_compatible(
326
+ current_labware_definition
327
+ ):
328
+ raise LabwareMovementNotAllowedError(
329
+ f"Cannot move labware '{current_labware_definition.parameters.loadName}' with gripper."
330
+ f" If trying to move a labware on an adapter, load the adapter separately to allow"
331
+ f" gripper movement."
332
+ )
333
+ if labware_validation.validate_definition_is_adapter(
334
+ current_labware_definition
335
+ ):
336
+ raise LabwareMovementNotAllowedError(
337
+ f"Cannot move adapter '{current_labware_definition.parameters.loadName}' with gripper."
338
+ )
339
+ validated_current_loc = (
340
+ self._state_view.geometry.ensure_valid_gripper_location(
341
+ current_labware.location
342
+ )
343
+ )
344
+
345
+ if module_location_error:
346
+ return DefinedErrorData(
347
+ public=module_location_error,
348
+ state_update=state_update,
349
+ )
350
+
351
+ validated_new_loc = self._state_view.geometry.ensure_valid_gripper_location(
352
+ available_new_location,
353
+ )
354
+
355
+ user_pick_up_offset = (
356
+ Point.from_xyz_attrs(params.pickUpOffset)
357
+ if params.pickUpOffset is not None
358
+ else Point()
359
+ )
360
+ user_drop_offset = (
361
+ Point.from_xyz_attrs(params.dropOffset)
362
+ if params.dropOffset is not None
363
+ else Point()
364
+ )
365
+
366
+ if trash_lid_drop_offset:
367
+ user_drop_offset += trash_lid_drop_offset
368
+
369
+ immediate_destination_location_sequence = (
370
+ self._state_view.geometry.get_predicted_location_sequence(
371
+ validated_new_loc
372
+ )
373
+ )
374
+ if eventual_destination_location_sequence is None:
375
+ eventual_destination_location_sequence = (
376
+ immediate_destination_location_sequence
377
+ )
378
+
379
+ try:
380
+ # Skips gripper moves when using virtual gripper
381
+ await self._labware_movement.move_labware_with_gripper(
382
+ labware_id=params.labwareId,
383
+ current_location=validated_current_loc,
384
+ new_location=validated_new_loc,
385
+ user_pick_up_offset=user_pick_up_offset,
386
+ user_drop_offset=user_drop_offset,
387
+ post_drop_slide_offset=post_drop_slide_offset,
388
+ )
389
+ except (
390
+ FailedGripperPickupError,
391
+ LabwareDroppedError,
392
+ StallOrCollisionDetectedError,
393
+ # todo(mm, 2024-09-26): Catch LabwareNotPickedUpError when that exists and
394
+ # move_labware_with_gripper() raises it.
395
+ ) as exception:
396
+ gripper_movement_error: GripperMovementError | None = GripperMovementError(
397
+ id=self._model_utils.generate_id(),
398
+ createdAt=self._model_utils.get_timestamp(),
399
+ errorCode=exception.code.value.code,
400
+ detail=exception.code.value.detail,
401
+ errorInfo={
402
+ "originLocationSequence": origin_location_sequence,
403
+ "immediateDestinationLocationSequence": immediate_destination_location_sequence,
404
+ "eventualDestinationLocationSequence": eventual_destination_location_sequence,
405
+ },
406
+ wrappedErrors=[
407
+ ErrorOccurrence.from_failed(
408
+ id=self._model_utils.generate_id(),
409
+ createdAt=self._model_utils.get_timestamp(),
410
+ error=exception,
411
+ )
412
+ ],
413
+ )
414
+ else:
415
+ gripper_movement_error = None
416
+
417
+ # All mounts will have been retracted as part of the gripper move.
418
+ state_update.clear_all_pipette_locations()
419
+
420
+ if gripper_movement_error:
421
+ return DefinedErrorData(
422
+ public=gripper_movement_error,
423
+ state_update=state_update,
424
+ )
425
+
426
+ elif params.strategy == LabwareMovementStrategy.MANUAL_MOVE_WITH_PAUSE:
427
+ # Pause to allow for manual labware movement
428
+ immediate_destination_location_sequence = (
429
+ self._state_view.geometry.get_predicted_location_sequence(
430
+ params.newLocation
431
+ )
432
+ )
433
+ if eventual_destination_location_sequence is None:
434
+ eventual_destination_location_sequence = (
435
+ immediate_destination_location_sequence
436
+ )
437
+
438
+ await self._run_control.wait_for_resume()
439
+ else:
440
+ immediate_destination_location_sequence = (
441
+ self._state_view.geometry.get_predicted_location_sequence(
442
+ params.newLocation
443
+ )
444
+ )
445
+ if eventual_destination_location_sequence is None:
446
+ eventual_destination_location_sequence = (
447
+ immediate_destination_location_sequence
448
+ )
449
+
450
+ # We may have just moved the labware that contains the current well out from
451
+ # under the pipette. Clear the current location to reflect the fact that the
452
+ # pipette is no longer over any labware. This is necessary for safe path
453
+ # planning in case the next movement goes to the same labware (now in a new
454
+ # place).
455
+ pipette_location = self._state_view.pipettes.get_current_location()
456
+ if (
457
+ isinstance(pipette_location, CurrentWell)
458
+ and pipette_location.labware_id == params.labwareId
459
+ ):
460
+ state_update.clear_all_pipette_locations()
461
+
462
+ state_update.set_labware_location(
463
+ labware_id=params.labwareId,
464
+ new_location=available_new_location,
465
+ new_offset_id=new_offset_id,
466
+ )
467
+
468
+ if labware_validation.validate_definition_is_lid(
469
+ definition=self._state_view.labware.get_definition(params.labwareId)
470
+ ):
471
+ parent_updates: List[str] = []
472
+ lid_updates: List[str | None] = []
473
+ # when moving a lid between locations we need to:
474
+ if (
475
+ isinstance(current_labware.location, OnLabwareLocation)
476
+ and self._state_view.labware.get_lid_by_labware_id(
477
+ current_labware.location.labwareId
478
+ )
479
+ is not None
480
+ ):
481
+ # if the source location was a parent labware and not a lid stack or lid, update the parent labware lid ID to None (no more lid)
482
+ parent_updates.append(current_labware.location.labwareId)
483
+ lid_updates.append(None)
484
+
485
+ # If we're moving to a non lid object, add to the setlids list of things to do
486
+ if isinstance(
487
+ available_new_location, OnLabwareLocation
488
+ ) and not labware_validation.validate_definition_is_lid(
489
+ self._state_view.labware.get_definition(
490
+ available_new_location.labwareId
491
+ )
492
+ ):
493
+ parent_updates.append(available_new_location.labwareId)
494
+ lid_updates.append(params.labwareId)
495
+ # Add to setlids
496
+ if len(parent_updates) > 0:
497
+ state_update.set_lids(
498
+ parent_labware_ids=parent_updates,
499
+ lid_ids=lid_updates,
500
+ )
501
+
502
+ return SuccessData(
503
+ public=MoveLabwareResult(
504
+ offsetId=new_offset_id,
505
+ originLocationSequence=origin_location_sequence,
506
+ immediateDestinationLocationSequence=immediate_destination_location_sequence,
507
+ eventualDestinationLocationSequence=eventual_destination_location_sequence,
508
+ ),
509
+ state_update=state_update,
510
+ )
511
+
512
+
513
+ class MoveLabware(
514
+ BaseCommand[
515
+ MoveLabwareParams,
516
+ MoveLabwareResult,
517
+ GripperMovementError,
518
+ ]
519
+ ):
520
+ """A ``moveLabware`` command."""
521
+
522
+ commandType: MoveLabwareCommandType = "moveLabware"
523
+ params: MoveLabwareParams
524
+ result: Optional[MoveLabwareResult] = None
525
+
526
+ _ImplementationCls: Type[MoveLabwareImplementation] = MoveLabwareImplementation
527
+
528
+
529
+ class MoveLabwareCreate(BaseCommandCreate[MoveLabwareParams]):
530
+ """A request to create a ``moveLabware`` command."""
531
+
532
+ commandType: MoveLabwareCommandType = "moveLabware"
533
+ params: MoveLabwareParams
534
+
535
+ _CommandCls: Type[MoveLabware] = MoveLabware
536
+
537
+
538
+ def _labware_x_dimension(labware_definition: LabwareDefinition) -> float:
539
+ if isinstance(labware_definition, LabwareDefinition2):
540
+ return labware_definition.dimensions.xDimension
541
+ else:
542
+ assert_type(labware_definition, LabwareDefinition3)
543
+ return (
544
+ labware_definition.extents.total.frontRightTop.x
545
+ - labware_definition.extents.total.backLeftBottom.x
546
+ )
@@ -0,0 +1,102 @@
1
+ """Move relative (jog) command payload, result, and implementation models."""
2
+ from __future__ import annotations
3
+ from pydantic import BaseModel, Field
4
+ from typing import TYPE_CHECKING, Optional, Type
5
+ from typing_extensions import Literal
6
+
7
+
8
+ from ..types import MovementAxis
9
+ from .command import (
10
+ AbstractCommandImpl,
11
+ BaseCommand,
12
+ BaseCommandCreate,
13
+ SuccessData,
14
+ DefinedErrorData,
15
+ )
16
+ from .movement_common import (
17
+ DestinationPositionResult,
18
+ move_relative,
19
+ StallOrCollisionError,
20
+ )
21
+
22
+ if TYPE_CHECKING:
23
+ from ..execution import MovementHandler
24
+ from ..resources.model_utils import ModelUtils
25
+
26
+
27
+ MoveRelativeCommandType = Literal["moveRelative"]
28
+
29
+
30
+ class MoveRelativeParams(BaseModel):
31
+ """Payload required for a MoveRelative command."""
32
+
33
+ pipetteId: str = Field(..., description="Pipette to move.")
34
+ axis: MovementAxis = Field(..., description="Axis along which to move.")
35
+ distance: float = Field(
36
+ ...,
37
+ description=(
38
+ "Distance to move in millimeters. A positive number will move"
39
+ " towards the right (x), back (y), top (z) of the deck."
40
+ ),
41
+ )
42
+
43
+
44
+ class MoveRelativeResult(DestinationPositionResult):
45
+ """Result data from the execution of a MoveRelative command."""
46
+
47
+ pass
48
+
49
+
50
+ class MoveRelativeImplementation(
51
+ AbstractCommandImpl[
52
+ MoveRelativeParams,
53
+ SuccessData[MoveRelativeResult] | DefinedErrorData[StallOrCollisionError],
54
+ ]
55
+ ):
56
+ """Move relative command implementation."""
57
+
58
+ def __init__(
59
+ self, movement: MovementHandler, model_utils: ModelUtils, **kwargs: object
60
+ ) -> None:
61
+ self._movement = movement
62
+ self._model_utils = model_utils
63
+
64
+ async def execute(
65
+ self, params: MoveRelativeParams
66
+ ) -> SuccessData[MoveRelativeResult] | DefinedErrorData[StallOrCollisionError]:
67
+ """Move (jog) a given pipette a relative distance."""
68
+ result = await move_relative(
69
+ movement=self._movement,
70
+ model_utils=self._model_utils,
71
+ pipette_id=params.pipetteId,
72
+ axis=params.axis,
73
+ distance=params.distance,
74
+ )
75
+ if isinstance(result, DefinedErrorData):
76
+ return result
77
+ else:
78
+ return SuccessData(
79
+ public=MoveRelativeResult(position=result.public.position),
80
+ state_update=result.state_update,
81
+ )
82
+
83
+
84
+ class MoveRelative(
85
+ BaseCommand[MoveRelativeParams, MoveRelativeResult, StallOrCollisionError]
86
+ ):
87
+ """Command to move (jog) a given pipette a relative distance."""
88
+
89
+ commandType: MoveRelativeCommandType = "moveRelative"
90
+ params: MoveRelativeParams
91
+ result: Optional[MoveRelativeResult] = None
92
+
93
+ _ImplementationCls: Type[MoveRelativeImplementation] = MoveRelativeImplementation
94
+
95
+
96
+ class MoveRelativeCreate(BaseCommandCreate[MoveRelativeParams]):
97
+ """Data to create a MoveRelative command."""
98
+
99
+ commandType: MoveRelativeCommandType = "moveRelative"
100
+ params: MoveRelativeParams
101
+
102
+ _CommandCls: Type[MoveRelative] = MoveRelative