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,297 @@
1
+ import functools
2
+ import logging
3
+ from dataclasses import dataclass
4
+ from typing import Any, List, Optional, Tuple, Type
5
+
6
+ from opentrons import types
7
+ from opentrons.hardware_control.types import CriticalPoint
8
+ from opentrons.hardware_control.util import plan_arc
9
+
10
+ from opentrons.motion_planning import (
11
+ DEFAULT_GENERAL_ARC_Z_MARGIN,
12
+ DEFAULT_IN_LABWARE_ARC_Z_MARGIN,
13
+ MINIMUM_Z_MARGIN,
14
+ MoveType,
15
+ get_waypoints,
16
+ )
17
+
18
+ from opentrons.protocols.api_support.labware_like import LabwareLike
19
+ from opentrons.protocol_api.core.legacy.deck import Deck
20
+ from opentrons.protocol_api.core.legacy.module_geometry import ModuleGeometry
21
+
22
+
23
+ MODULE_LOG = logging.getLogger(__name__)
24
+
25
+
26
+ class LabwareHeightError(Exception):
27
+ pass
28
+
29
+
30
+ def max_many(*args: float) -> float:
31
+ return functools.reduce(max, args[1:], args[0])
32
+
33
+
34
+ BAD_PAIRS = {
35
+ ("1", "12"),
36
+ ("12", "1"),
37
+ ("4", "12"),
38
+ ("12", "4"),
39
+ ("4", "9"),
40
+ ("9", "4"),
41
+ ("4", "8"),
42
+ ("8", "4"),
43
+ ("1", "8"),
44
+ ("8", "1"),
45
+ ("4", "11"),
46
+ ("11", "4"),
47
+ ("1", "11"),
48
+ ("11", "1"),
49
+ }
50
+
51
+
52
+ def should_dodge_thermocycler(
53
+ deck: Deck, from_loc: types.Location, to_loc: types.Location
54
+ ) -> bool:
55
+ """
56
+ Decide if the requested path would cross the thermocycler, if
57
+ installed.
58
+
59
+ Returns True if we need to dodge, False otherwise
60
+ """
61
+ if deck.thermocycler_present:
62
+ transit = (from_loc.labware.first_parent(), to_loc.labware.first_parent())
63
+ # mypy doesn't like this because transit could be none, but it's
64
+ # checked by value in BAD_PAIRS which has only strings
65
+ return transit in BAD_PAIRS
66
+
67
+ return False
68
+
69
+
70
+ @dataclass
71
+ class MoveConstraints:
72
+ instr_max_height: float
73
+ well_z_margin: float = DEFAULT_IN_LABWARE_ARC_Z_MARGIN
74
+ lw_z_margin: float = DEFAULT_GENERAL_ARC_Z_MARGIN
75
+ minimum_lw_z_margin: float = MINIMUM_Z_MARGIN
76
+ minimum_z_height: float = 0.0
77
+
78
+ @classmethod
79
+ def build(cls: Type["MoveConstraints"], **kwargs: Any) -> "MoveConstraints":
80
+ return cls(**{k: v for k, v in kwargs.items() if v is not None})
81
+
82
+
83
+ def get_move_type(
84
+ from_loc: types.Location,
85
+ to_loc: types.Location,
86
+ force_direct: bool = False,
87
+ ) -> MoveType:
88
+ """Given two Locations, return the type of move."""
89
+ move_type = MoveType.GENERAL_ARC
90
+ from_labware, from_well = from_loc.labware.get_parent_labware_and_well()
91
+ to_labware, to_well = to_loc.labware.get_parent_labware_and_well()
92
+ same_labware = to_labware is not None and to_labware == from_labware
93
+ same_well = to_well is not None and to_well == from_well
94
+
95
+ if same_labware:
96
+ move_type = MoveType.DIRECT if same_well else MoveType.IN_LABWARE_ARC
97
+
98
+ return move_type if not force_direct else MoveType.DIRECT
99
+
100
+
101
+ def safe_height(
102
+ from_loc: types.Location,
103
+ to_loc: types.Location,
104
+ deck: Deck,
105
+ instr_max_height: float,
106
+ well_z_margin: Optional[float] = None,
107
+ lw_z_margin: Optional[float] = None,
108
+ minimum_lw_z_margin: Optional[float] = None,
109
+ minimum_z_height: Optional[float] = None,
110
+ ) -> float:
111
+ """
112
+ Derive the height required to clear the current deck setup along
113
+ with other constraints
114
+ :param from_loc: The last location.
115
+ :param to_loc: The location to move to.
116
+ :param deck: The :py:class:`Deck` instance describing the robot.
117
+ :param float instr_max_height: The highest z location this pipette can
118
+ achieve
119
+ :param float well_z_margin: How much extra Z margin to raise the cp by over
120
+ the bare minimum to clear wells within the same
121
+ labware. Default: 5mm
122
+ :param float lw_z_margin: How much extra Z margin to raise the cp by over
123
+ the bare minimum to clear different pieces of
124
+ labware.
125
+ :param minimum_z_height: When specified, this Z margin is able to raise
126
+ (but never lower) the mid-arc height.
127
+ """
128
+ constraints = MoveConstraints.build(
129
+ instr_max_height=instr_max_height,
130
+ well_z_margin=well_z_margin,
131
+ lw_z_margin=lw_z_margin,
132
+ minimum_lw_z_margin=minimum_lw_z_margin,
133
+ minimum_z_height=minimum_z_height,
134
+ )
135
+ assert constraints.minimum_z_height >= 0.0
136
+ return _build_safe_height(from_loc, to_loc, deck, constraints)
137
+
138
+
139
+ def _build_safe_height(
140
+ from_loc: types.Location,
141
+ to_loc: types.Location,
142
+ deck: Deck,
143
+ constraints: MoveConstraints,
144
+ ) -> float:
145
+ to_point = to_loc.point
146
+ to_lw, to_well = to_loc.labware.get_parent_labware_and_well()
147
+ from_point = from_loc.point
148
+ from_lw, from_well = from_loc.labware.get_parent_labware_and_well()
149
+
150
+ if to_lw and from_lw and to_lw == from_lw:
151
+ # If we know the labwares we’re moving from and to, we can calculate
152
+ # a safe z based on their heights
153
+ if to_well:
154
+ to_safety = to_well.top().point.z + constraints.well_z_margin
155
+ else:
156
+ to_safety = to_lw.highest_z + constraints.well_z_margin
157
+ if from_well:
158
+ from_safety = from_well.top().point.z + constraints.well_z_margin
159
+ else:
160
+ from_safety = from_lw.highest_z + constraints.well_z_margin
161
+ # if we are already at the labware, we know the instr max height would
162
+ # be tall enough
163
+ if max(from_safety, to_safety) > constraints.instr_max_height:
164
+ to_safety = constraints.instr_max_height
165
+ from_safety = 0.0 # (ignore since it's in a max())
166
+ else:
167
+ # One of our labwares is invalid so we have to just go above
168
+ # deck.highest_z since we don’t know where we are
169
+ to_safety = deck.highest_z + constraints.lw_z_margin
170
+
171
+ if to_safety > constraints.instr_max_height:
172
+ if constraints.instr_max_height >= (
173
+ deck.highest_z + constraints.minimum_lw_z_margin
174
+ ):
175
+ to_safety = constraints.instr_max_height
176
+ else:
177
+ tallest_lw = list(
178
+ filter(
179
+ lambda lw: lw.highest_z == deck.highest_z,
180
+ [lw for lw in deck.data.values() if lw],
181
+ )
182
+ )[0]
183
+ if isinstance(tallest_lw, ModuleGeometry) and tallest_lw.labware:
184
+ tallest_lw = tallest_lw.labware
185
+ raise LabwareHeightError(
186
+ f"The {tallest_lw} has a total height of {deck.highest_z}"
187
+ " mm, which is too tall for your current pipette "
188
+ "configurations. The longest pipette on your robot can "
189
+ f"only be raised to {constraints.instr_max_height} mm "
190
+ "above the deck. "
191
+ "This may be because the labware is incorrectly defined, "
192
+ "incorrectly calibrated, or physically too tall. This "
193
+ "could also be caused by the pipette and its tipracks "
194
+ "being mismatched. Please check your protocol, labware "
195
+ "definitions and calibrations."
196
+ )
197
+ from_safety = 0.0 # (ignore since it’s in a max())
198
+
199
+ return max_many(
200
+ to_point.z, from_point.z, to_safety, from_safety, constraints.minimum_z_height
201
+ )
202
+
203
+
204
+ def plan_moves(
205
+ from_loc: types.Location,
206
+ to_loc: types.Location,
207
+ deck: Deck,
208
+ instr_max_height: float,
209
+ well_z_margin: Optional[float] = None,
210
+ lw_z_margin: Optional[float] = None,
211
+ force_direct: bool = False,
212
+ minimum_lw_z_margin: Optional[float] = None,
213
+ minimum_z_height: Optional[float] = None,
214
+ use_experimental_waypoint_planning: bool = False,
215
+ ) -> List[Tuple[types.Point, Optional[CriticalPoint]]]:
216
+ """Plan moves between one :py:class:`.Location` and another.
217
+
218
+ Each :py:class:`.Location` instance might or might not have a specific
219
+ kind of geometry attached. This function is intended to return series
220
+ of moves that contain the minimum safe retractions to avoid (known)
221
+ labware on the specified :py:class:`Deck`.
222
+ :param from_loc: The last location.
223
+ :param to_loc: The location to move to.
224
+ :param deck: The :py:class:`Deck` instance describing the robot.
225
+ :param force_direct: If True, ignore any Z margins force a direct move
226
+ :param use_experimental_waypoint_planning: If True, use waypoint logic
227
+ from opentrons.motion_planning
228
+
229
+ The other parameters are as :py:meth:`safe_height`.
230
+
231
+ :returns: A list of tuples of :py:class:`.Point` and critical point
232
+ overrides to move through.
233
+ """
234
+ constraints = MoveConstraints.build(
235
+ instr_max_height=instr_max_height,
236
+ well_z_margin=well_z_margin,
237
+ lw_z_margin=lw_z_margin,
238
+ minimum_lw_z_margin=minimum_lw_z_margin,
239
+ minimum_z_height=minimum_z_height,
240
+ )
241
+ assert constraints.minimum_z_height >= 0.0
242
+
243
+ to_point = to_loc.point
244
+ to_lw, to_well = to_loc.labware.get_parent_labware_and_well()
245
+ from_point = from_loc.point
246
+ from_lw, from_well = from_loc.labware.get_parent_labware_and_well()
247
+ from_center = LabwareLike(from_lw).center_multichannel_on_wells()
248
+ to_center = LabwareLike(to_lw).center_multichannel_on_wells()
249
+ dest_cp_override = CriticalPoint.XY_CENTER if to_center else None
250
+ origin_cp_override = CriticalPoint.XY_CENTER if from_center else None
251
+ extra_waypoints = []
252
+
253
+ if should_dodge_thermocycler(deck, from_loc, to_loc):
254
+ sc = deck.get_slot_center("5")
255
+ extra_waypoints = [(sc.x, sc.y)]
256
+
257
+ if use_experimental_waypoint_planning:
258
+ move_type = get_move_type(from_loc, to_loc, force_direct)
259
+ min_travel_z = deck.highest_z
260
+
261
+ if to_lw is not None and move_type == MoveType.IN_LABWARE_ARC:
262
+ min_travel_z = to_lw.highest_z
263
+
264
+ # TODO(mc, 2020-11-05): if this ever needs to be used, we need a
265
+ # story to re-create error messaging from LabwareHeightError above if
266
+ # this raises a MotionPlanningError
267
+ waypoints = get_waypoints(
268
+ origin=from_point,
269
+ dest=to_point,
270
+ min_travel_z=min_travel_z,
271
+ max_travel_z=instr_max_height,
272
+ move_type=move_type,
273
+ xy_waypoints=extra_waypoints,
274
+ origin_cp=origin_cp_override,
275
+ dest_cp=dest_cp_override,
276
+ )
277
+ return [(wp.position, wp.critical_point) for wp in waypoints]
278
+
279
+ is_same_location = (to_lw and to_lw == from_lw) and (
280
+ to_well and to_well == from_well
281
+ )
282
+ if force_direct or (is_same_location and not (minimum_z_height or 0) > 0):
283
+ # If we’re going direct, we can assume we’re already in the correct
284
+ # cp so we can use the override without prep
285
+ return [(to_point, dest_cp_override)]
286
+
287
+ # Find the safe z heights based on the destination and origin labware/well
288
+ safe = _build_safe_height(from_loc, to_loc, deck, constraints)
289
+
290
+ return plan_arc(
291
+ from_point,
292
+ to_point,
293
+ safe,
294
+ origin_cp_override,
295
+ dest_cp_override,
296
+ extra_waypoints,
297
+ )
@@ -0,0 +1,312 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import json
5
+ import os
6
+ from pathlib import Path
7
+ from typing import Mapping, Optional, Union, List, Sequence, Literal
8
+
9
+ import jsonschema # type: ignore
10
+
11
+ from opentrons_shared_data import load_shared_data, get_shared_data_root
12
+ from opentrons.protocols.api_support.util import ModifiedList
13
+ from opentrons.protocols.api_support.constants import (
14
+ OPENTRONS_NAMESPACE,
15
+ CUSTOM_NAMESPACE,
16
+ STANDARD_DEFS_PATH,
17
+ USER_DEFS_PATH,
18
+ )
19
+ from opentrons_shared_data.labware.types import LabwareDefinition
20
+ from opentrons_shared_data.errors.exceptions import InvalidProtocolData
21
+
22
+
23
+ MODULE_LOG = logging.getLogger(__name__)
24
+
25
+ LabwareProblem = Literal[
26
+ "no-schema-id", "bad-schema-id", "schema-mismatch", "invalid-json"
27
+ ]
28
+
29
+
30
+ class NotALabwareError(InvalidProtocolData):
31
+ def __init__(
32
+ self, problem: LabwareProblem, wrapping: Sequence[BaseException]
33
+ ) -> None:
34
+ messages: dict[LabwareProblem, str] = {
35
+ "no-schema-id": "No schema ID present in file",
36
+ "bad-schema-id": "Bad schema ID in file",
37
+ "invalid-json": "File does not contain valid JSON",
38
+ "schema-mismatch": "File does not match labware schema",
39
+ }
40
+ super().__init__(
41
+ message=messages[problem], detail={"kind": problem}, wrapping=wrapping
42
+ )
43
+
44
+
45
+ def get_labware_definition(
46
+ load_name: str,
47
+ namespace: Optional[str] = None,
48
+ version: Optional[int] = None,
49
+ bundled_defs: Optional[Mapping[str, LabwareDefinition]] = None,
50
+ extra_defs: Optional[Mapping[str, LabwareDefinition]] = None,
51
+ ) -> LabwareDefinition:
52
+ """
53
+ Look up and return a definition by load_name + namespace + version and
54
+ return it or raise an exception
55
+
56
+ :param str load_name: corresponds to 'loadName' key in definition
57
+ :param str namespace: The namespace the labware definition belongs to.
58
+ If unspecified, will search 'opentrons' then 'custom_beta'
59
+ :param int version: The version of the labware definition. If unspecified,
60
+ will use version 1.
61
+ :param bundled_defs: A bundle of labware definitions to exclusively use for
62
+ finding labware definitions, if specified
63
+ :param extra_defs: An extra set of definitions (in addition to the system
64
+ definitions) in which to search
65
+ """
66
+ load_name = load_name.lower()
67
+
68
+ if bundled_defs is not None:
69
+ return _get_labware_definition_from_bundle(
70
+ bundled_defs, load_name, namespace, version
71
+ )
72
+
73
+ checked_extras = extra_defs or {}
74
+
75
+ try:
76
+ return _get_labware_definition_from_bundle(
77
+ checked_extras, load_name, namespace, version
78
+ )
79
+ except (FileNotFoundError, RuntimeError):
80
+ pass
81
+
82
+ return _get_standard_labware_definition(load_name, namespace, version)
83
+
84
+
85
+ def get_all_labware_definitions(schema_version: str = "2") -> List[str]:
86
+ """
87
+ Return a list of standard and custom labware definitions with load_name +
88
+ name_space + version existing on the robot
89
+ """
90
+ labware_list = ModifiedList()
91
+
92
+ def _check_for_subdirectories(path: Union[str, Path, os.DirEntry[str]]) -> None:
93
+ with os.scandir(path) as top_path:
94
+ for sub_dir in top_path:
95
+ if sub_dir.is_dir():
96
+ labware_list.append(sub_dir.name)
97
+
98
+ # check for standard labware
99
+ _check_for_subdirectories(
100
+ get_shared_data_root() / STANDARD_DEFS_PATH / schema_version
101
+ )
102
+ # check for custom labware
103
+ for namespace in os.scandir(USER_DEFS_PATH):
104
+ _check_for_subdirectories(namespace)
105
+ return labware_list
106
+
107
+
108
+ def save_definition(
109
+ labware_def: LabwareDefinition, force: bool = False, location: Optional[Path] = None
110
+ ) -> None:
111
+ """
112
+ Save a labware definition
113
+
114
+ :param labware_def: A deserialized JSON labware definition
115
+ :param bool force: If true, overwrite an existing definition if found.
116
+ Cannot overwrite Opentrons definitions.
117
+ :param location: File path
118
+ """
119
+ namespace = labware_def["namespace"]
120
+ load_name = labware_def["parameters"]["loadName"]
121
+ version = labware_def["version"]
122
+
123
+ verify_definition(labware_def)
124
+
125
+ if not namespace or not load_name or not version:
126
+ raise RuntimeError(
127
+ "Could not save definition, labware def is missing a field: "
128
+ + f"{namespace}, {load_name}, {version}"
129
+ )
130
+
131
+ if namespace == OPENTRONS_NAMESPACE:
132
+ raise RuntimeError(
133
+ f'Saving definitions to the "{OPENTRONS_NAMESPACE}" namespace '
134
+ + "is not permitted"
135
+ )
136
+ def_path = _get_path_to_labware(load_name, namespace, version, location)
137
+
138
+ if not force and def_path.is_file():
139
+ raise RuntimeError(
140
+ f"The given definition ({namespace}/{load_name} v{version}) "
141
+ + "already exists. Cannot save definition without force=True"
142
+ )
143
+
144
+ Path(def_path).parent.mkdir(parents=True, exist_ok=True)
145
+ with open(def_path, "w") as f:
146
+ json.dump(labware_def, f)
147
+
148
+
149
+ def verify_definition( # noqa: C901
150
+ contents: str | bytes | LabwareDefinition | object,
151
+ ) -> LabwareDefinition:
152
+ """Verify that an input string is a labware definition and return it.
153
+
154
+ :param contents: The untrusted input to parse and validate. If str or bytes, it's
155
+ parsed as JSON. Otherwise, it should be the output of json.load().
156
+
157
+ :raises NotALabwareError:
158
+
159
+ :returns: The parsed and validated definition
160
+ """
161
+ schemata_by_version = {
162
+ 2: json.loads(load_shared_data("labware/schemas/2.json").decode("utf-8")),
163
+ 3: json.loads(load_shared_data("labware/schemas/3.json").decode("utf-8")),
164
+ }
165
+
166
+ try:
167
+ parsed_json: object = (
168
+ json.loads(contents) if isinstance(contents, (str, bytes)) else contents
169
+ )
170
+ except json.JSONDecodeError as e:
171
+ raise NotALabwareError("invalid-json", [e]) from e
172
+
173
+ if isinstance(parsed_json, dict):
174
+ try:
175
+ schema_version: object = parsed_json["schemaVersion"]
176
+ except KeyError as e:
177
+ raise NotALabwareError("no-schema-id", [e]) from e
178
+ else:
179
+ raise NotALabwareError("no-schema-id", [])
180
+
181
+ try:
182
+ # we can type ignore this because we handle the KeyError below
183
+ schema = schemata_by_version[schema_version] # type: ignore[index]
184
+ except KeyError as e:
185
+ raise NotALabwareError("bad-schema-id", [e]) from e
186
+
187
+ try:
188
+ jsonschema.validate(parsed_json, schema)
189
+ except jsonschema.ValidationError as e:
190
+ raise NotALabwareError("schema-mismatch", [e]) from e
191
+
192
+ # we can type ignore this because if it passes the jsonschema it has
193
+ # the correct structure
194
+ return parsed_json # type: ignore[return-value]
195
+
196
+
197
+ def _get_labware_definition_from_bundle(
198
+ bundled_labware: Mapping[str, LabwareDefinition],
199
+ load_name: str,
200
+ namespace: Optional[str] = None,
201
+ version: Optional[int] = None,
202
+ ) -> LabwareDefinition:
203
+ """
204
+ Look up and return a bundled definition by ``load_name`` + ``namespace``
205
+ + ``version`` and return it or raise an exception. The``namespace`` and
206
+ ``version`` args are optional, they only have to be specified if there is
207
+ ambiguity (eg when multiple labware in the bundle share the same
208
+ ``load_name``)
209
+
210
+ :param str load_name: corresponds to 'loadName' key in definition
211
+ :param str namespace: The namespace the labware definition belongs to
212
+ :param int version: The version of the labware definition
213
+ :param Dict bundled_labware: A dictionary of labware definitions to search
214
+ """
215
+ load_name = load_name.lower()
216
+
217
+ bundled_candidates = [
218
+ b for b in bundled_labware.values() if b["parameters"]["loadName"] == load_name
219
+ ]
220
+ if namespace:
221
+ namespace = namespace.lower()
222
+ bundled_candidates = [
223
+ b for b in bundled_candidates if b["namespace"] == namespace
224
+ ]
225
+ if version:
226
+ bundled_candidates = [b for b in bundled_candidates if b["version"] == version]
227
+
228
+ if len(bundled_candidates) == 1:
229
+ return bundled_candidates[0]
230
+ elif len(bundled_candidates) > 1:
231
+ raise RuntimeError(
232
+ f"Ambiguous labware access. Bundle contains multiple "
233
+ f"labware with load name {load_name}, "
234
+ f"namespace {namespace}, and version {version}."
235
+ )
236
+ else:
237
+ raise RuntimeError(
238
+ f"No labware found in bundle with load name {load_name}, "
239
+ f"namespace {namespace}, and version {version}."
240
+ )
241
+
242
+
243
+ def _get_standard_labware_definition(
244
+ load_name: str, namespace: Optional[str] = None, version: Optional[int] = None
245
+ ) -> LabwareDefinition:
246
+ if version is None:
247
+ checked_version = 1
248
+ else:
249
+ checked_version = version
250
+ error_msg_string = """Unable to find a labware
251
+ definition for "{0}",
252
+ version {1}, in the {2} namespace.
253
+ Please confirm your protocol includes the correct
254
+ labware spelling and (optionally) the correct version
255
+ number and namespace.
256
+
257
+ If you are referencing a custom labware in your
258
+ protocol, you must add it to your Custom Labware
259
+ Definitions Folder from the Opentrons App before
260
+ uploading your protocol.
261
+ """
262
+ if namespace is None:
263
+ for fallback_namespace in [OPENTRONS_NAMESPACE, CUSTOM_NAMESPACE]:
264
+ try:
265
+ return _get_standard_labware_definition(
266
+ load_name, fallback_namespace, checked_version
267
+ )
268
+ except FileNotFoundError:
269
+ pass
270
+
271
+ raise FileNotFoundError(
272
+ error_msg_string.format(load_name, checked_version, OPENTRONS_NAMESPACE)
273
+ )
274
+
275
+ namespace = namespace.lower()
276
+ def_path = _get_path_to_labware(load_name, namespace, checked_version)
277
+
278
+ try:
279
+ with open(def_path, "rb") as f:
280
+ labware_def = json.loads(f.read().decode("utf-8"))
281
+ except FileNotFoundError:
282
+ raise FileNotFoundError(
283
+ f'Labware "{load_name}" not found with version {checked_version} '
284
+ f'in namespace "{namespace}".'
285
+ )
286
+ return labware_def # type: ignore[no-any-return]
287
+
288
+
289
+ def _get_path_to_labware(
290
+ load_name: str, namespace: str, version: int, base_path: Optional[Path] = None
291
+ ) -> Path:
292
+ if namespace == OPENTRONS_NAMESPACE:
293
+ # all labware in OPENTRONS_NAMESPACE is stored in shared data
294
+ schema_3_path = (
295
+ get_shared_data_root()
296
+ / STANDARD_DEFS_PATH
297
+ / "3"
298
+ / load_name
299
+ / f"{version}.json"
300
+ )
301
+ schema_2_path = (
302
+ get_shared_data_root()
303
+ / STANDARD_DEFS_PATH
304
+ / "2"
305
+ / load_name
306
+ / f"{version}.json"
307
+ )
308
+ return schema_3_path if schema_3_path.exists() else schema_2_path
309
+ if not base_path:
310
+ base_path = USER_DEFS_PATH
311
+ def_path = base_path / namespace / load_name / f"{version}.json"
312
+ return def_path
File without changes