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,403 @@
1
+ """ Utility functions and classes for the protocol api """
2
+ from __future__ import annotations
3
+
4
+ from collections import UserDict
5
+ import functools
6
+ import logging
7
+ from dataclasses import dataclass, field, astuple
8
+ from typing import (
9
+ TYPE_CHECKING,
10
+ Any,
11
+ Callable,
12
+ Dict,
13
+ List,
14
+ Iterator,
15
+ Optional,
16
+ TypeVar,
17
+ Union,
18
+ cast,
19
+ KeysView,
20
+ ItemsView,
21
+ )
22
+
23
+ from opentrons import types as top_types
24
+ from opentrons.protocols.api_support.types import APIVersion
25
+ from opentrons.hardware_control.types import Axis
26
+ from opentrons.hardware_control.util import ot2_axis_to_string
27
+ from opentrons_shared_data.robot.types import RobotType
28
+ from opentrons_shared_data.errors.exceptions import (
29
+ APIRemoved,
30
+ IncorrectAPIVersion,
31
+ UnsupportedHardwareCommand,
32
+ )
33
+
34
+ if TYPE_CHECKING:
35
+ from opentrons.protocol_api.labware import Well, Labware
36
+ from opentrons.protocol_api.core.engine.instrument import InstrumentCore
37
+ from opentrons.protocol_api.core.legacy.deck import Deck
38
+ from opentrons.protocol_api.core.legacy.legacy_instrument_core import (
39
+ LegacyInstrumentCore,
40
+ )
41
+ from opentrons.protocol_api.core.legacy_simulator.legacy_instrument_core import (
42
+ LegacyInstrumentCoreSimulator,
43
+ )
44
+
45
+ MODULE_LOG = logging.getLogger(__name__)
46
+
47
+
48
+ class RobotTypeError(UnsupportedHardwareCommand):
49
+ """Error raised when a protocol attempts to access behavior not available to the robot type in use."""
50
+
51
+ pass
52
+
53
+
54
+ class APIVersionError(IncorrectAPIVersion):
55
+ """Error raised when a protocol attempts to access behavior not implemented in the API in use."""
56
+
57
+ pass
58
+
59
+
60
+ class UnsupportedAPIError(APIRemoved):
61
+ """Error raised when a protocol attempts to use unsupported API."""
62
+
63
+ pass
64
+
65
+
66
+ def _assert_gzero(val: Any, message: str) -> float:
67
+ try:
68
+ new_val = float(val)
69
+ assert new_val > 0.0
70
+ return new_val
71
+ except (TypeError, ValueError, AssertionError):
72
+ raise AssertionError(message)
73
+
74
+
75
+ @dataclass
76
+ class EdgeList:
77
+ right: Optional[top_types.Point] = field(default_factory=top_types.Point)
78
+ left: Optional[top_types.Point] = field(default_factory=top_types.Point)
79
+ center: Optional[top_types.Point] = field(default_factory=top_types.Point)
80
+ up: top_types.Point = field(default_factory=top_types.Point)
81
+ down: top_types.Point = field(default_factory=top_types.Point)
82
+
83
+
84
+ def determine_edge_path(
85
+ where: "Well", mount: top_types.Mount, default_edges: EdgeList, deck: "Deck"
86
+ ) -> EdgeList:
87
+ left_path = EdgeList(
88
+ left=default_edges.left,
89
+ right=None,
90
+ center=default_edges.center,
91
+ up=default_edges.up,
92
+ down=default_edges.down,
93
+ )
94
+ right_path = EdgeList(
95
+ left=None,
96
+ right=default_edges.right,
97
+ center=default_edges.center,
98
+ up=default_edges.up,
99
+ down=default_edges.down,
100
+ )
101
+ labware = where.parent
102
+
103
+ r_mount = top_types.Mount.RIGHT
104
+ l_mount = top_types.Mount.LEFT
105
+ l_col = labware.columns()[0]
106
+ r_col = labware.columns()[-1]
107
+ right_pip_criteria = mount is r_mount and where in l_col
108
+ left_pip_criteria = mount is l_mount and where in r_col
109
+
110
+ next_to_mod = deck.is_edge_move_unsafe(mount, labware)
111
+ if labware.parent in ["3", "6", "9"] and left_pip_criteria:
112
+ return left_path
113
+ elif left_pip_criteria and next_to_mod:
114
+ return left_path
115
+ elif right_pip_criteria and next_to_mod:
116
+ return right_path
117
+ return default_edges
118
+
119
+
120
+ def build_edges(
121
+ where: "Well",
122
+ offset: float,
123
+ mount: top_types.Mount,
124
+ deck: "Deck",
125
+ radius: float = 1.0,
126
+ version: APIVersion = APIVersion(2, 7),
127
+ ) -> List[top_types.Point]:
128
+ # Determine the touch_tip edges/points
129
+ offset_pt = top_types.Point(0, 0, offset)
130
+ edge_list = EdgeList(
131
+ right=where.from_center_cartesian(x=radius, y=0, z=1) + offset_pt,
132
+ left=where.from_center_cartesian(x=-radius, y=0, z=1) + offset_pt,
133
+ center=where.from_center_cartesian(x=0, y=0, z=1) + offset_pt,
134
+ up=where.from_center_cartesian(x=0, y=radius, z=1) + offset_pt,
135
+ down=where.from_center_cartesian(x=0, y=-radius, z=1) + offset_pt,
136
+ )
137
+
138
+ if version < APIVersion(2, 4):
139
+ edge_list.center = None
140
+ # Add the center value before switching axes
141
+ return [edge for edge in astuple(edge_list) if edge]
142
+ new_edges = determine_edge_path(where, mount, edge_list, deck)
143
+ return [edge for edge in astuple(new_edges) if edge]
144
+
145
+
146
+ def labware_column_shift(
147
+ initial_well: "Well",
148
+ tiprack: "Labware",
149
+ well_spacing: int = 4,
150
+ modulo_value: int = 8,
151
+ ) -> "Well":
152
+ unshifted_index = tiprack.wells().index(initial_well)
153
+ unshifted_column = unshifted_index // modulo_value
154
+ shifted_column = unshifted_column + well_spacing
155
+ shifted_well = unshifted_index % modulo_value
156
+ return tiprack.columns()[shifted_column][shifted_well]
157
+
158
+
159
+ class FlowRates:
160
+ """Utility class for rich setters/getters for flow rates"""
161
+
162
+ def __init__(
163
+ self,
164
+ instr: Union[
165
+ InstrumentCore, LegacyInstrumentCore, LegacyInstrumentCoreSimulator
166
+ ],
167
+ ) -> None:
168
+ self._instr = instr
169
+
170
+ def set_defaults(
171
+ self,
172
+ aspirate_defaults: Dict[str, float],
173
+ dispense_defaults: Dict[str, float],
174
+ blow_out_defaults: Dict[str, float],
175
+ api_level: APIVersion,
176
+ ) -> None:
177
+ self.aspirate = find_value_for_api_version(api_level, aspirate_defaults)
178
+ self.dispense = find_value_for_api_version(api_level, dispense_defaults)
179
+ self.blow_out = find_value_for_api_version(api_level, blow_out_defaults)
180
+
181
+ @property
182
+ def aspirate(self) -> float:
183
+ return self._instr.get_aspirate_flow_rate()
184
+
185
+ @aspirate.setter
186
+ def aspirate(self, new_val: float) -> None:
187
+ self._instr.set_flow_rate(
188
+ aspirate=_assert_gzero(
189
+ new_val, "flow rate should be a numerical value in ul/s"
190
+ )
191
+ )
192
+
193
+ @property
194
+ def dispense(self) -> float:
195
+ return self._instr.get_dispense_flow_rate()
196
+
197
+ @dispense.setter
198
+ def dispense(self, new_val: float) -> None:
199
+ self._instr.set_flow_rate(
200
+ dispense=_assert_gzero(
201
+ new_val, "flow rate should be a numerical value in ul/s"
202
+ )
203
+ )
204
+
205
+ @property
206
+ def blow_out(self) -> float:
207
+ return self._instr.get_blow_out_flow_rate()
208
+
209
+ @blow_out.setter
210
+ def blow_out(self, new_val: float) -> None:
211
+ self._instr.set_flow_rate(
212
+ blow_out=_assert_gzero(
213
+ new_val, "flow rate should be a numerical value in ul/s"
214
+ )
215
+ )
216
+
217
+
218
+ def find_value_for_api_version(
219
+ for_version: APIVersion, values: Dict[str, float]
220
+ ) -> float:
221
+ """
222
+ Either parse a dict that looks like
223
+ {"2.0": 5,
224
+ "2.5": 4}
225
+ (aka the flow rate values from pipette config) and return the value for
226
+ the highest api level that is at or underneath ``for_version``,
227
+ or return the value passed in, if it's only a float.
228
+ """
229
+ if isinstance(values, float):
230
+ return values
231
+ sorted_versions = sorted({APIVersion.from_string(k): v for k, v in values.items()})
232
+ last = values[str(sorted_versions[0])]
233
+ for version in sorted_versions:
234
+ if version > for_version:
235
+ break
236
+ last = values[str(version)]
237
+ return last
238
+
239
+
240
+ class PlungerSpeeds:
241
+ """Utility class for rich setters/getters for speeds"""
242
+
243
+ def __init__(
244
+ self, instr: Union[LegacyInstrumentCore, LegacyInstrumentCoreSimulator]
245
+ ) -> None:
246
+ self._instr = instr
247
+
248
+ @property
249
+ def aspirate(self) -> float:
250
+ return self._instr.get_hardware_state()["aspirate_speed"]
251
+
252
+ @aspirate.setter
253
+ def aspirate(self, new_val: float) -> None:
254
+ self._instr.set_pipette_speed(
255
+ aspirate=_assert_gzero(new_val, "speed should be a numerical value in mm/s")
256
+ )
257
+
258
+ @property
259
+ def dispense(self) -> float:
260
+ return self._instr.get_hardware_state()["dispense_speed"]
261
+
262
+ @dispense.setter
263
+ def dispense(self, new_val: float) -> None:
264
+ self._instr.set_pipette_speed(
265
+ dispense=_assert_gzero(new_val, "speed should be a numerical value in mm/s")
266
+ )
267
+
268
+ @property
269
+ def blow_out(self) -> float:
270
+ return self._instr.get_hardware_state()["blow_out_speed"]
271
+
272
+ @blow_out.setter
273
+ def blow_out(self, new_val: float) -> None:
274
+ self._instr.set_pipette_speed(
275
+ blow_out=_assert_gzero(new_val, "speed should be a numerical value in mm/s")
276
+ )
277
+
278
+
279
+ class AxisMaxSpeeds(UserDict[Union[str, Axis], float]):
280
+ """Special mapping allowing internal storage by Mount enums and
281
+ user access by string
282
+ """
283
+
284
+ def __init__(self, robot_type: RobotType) -> None:
285
+ """"""
286
+ super().__init__()
287
+ self._robot_type = robot_type
288
+
289
+ def __getitem__(self, key: Union[str, Axis]) -> float:
290
+ checked_key = AxisMaxSpeeds._verify_key(key)
291
+ return self.data[checked_key]
292
+
293
+ @staticmethod
294
+ def _verify_key(key: object) -> Axis:
295
+ if isinstance(key, Axis):
296
+ checked_key: Optional[Axis] = key
297
+ elif isinstance(key, str):
298
+ checked_key = Axis[key.upper()]
299
+ else:
300
+ checked_key = None
301
+ if checked_key not in Axis.gantry_axes():
302
+ raise KeyError(key)
303
+ return checked_key
304
+
305
+ def __setitem__(self, key: object, value: object) -> None:
306
+
307
+ checked_key = AxisMaxSpeeds._verify_key(key)
308
+ if value is None:
309
+ del self[checked_key]
310
+ return
311
+
312
+ checked_val = _assert_gzero(
313
+ value, "max speeds should be numerical values in mm/s"
314
+ )
315
+
316
+ self.data[checked_key] = checked_val
317
+
318
+ def _axis_to_string(self, axis: Union[str, Axis]) -> str:
319
+ if isinstance(axis, str):
320
+ return axis
321
+ if self._robot_type == "OT-3 Standard":
322
+ return axis.name
323
+ return ot2_axis_to_string(axis)
324
+
325
+ def __delitem__(self, key: Union[str, Axis]) -> None:
326
+ checked_key = AxisMaxSpeeds._verify_key(key)
327
+ del self.data[checked_key]
328
+
329
+ def __iter__(self) -> Iterator[str]:
330
+ """keys() and dict iteration return string keys"""
331
+ string_keys = (self._axis_to_string(k) for k in self.data.keys())
332
+ return string_keys
333
+
334
+ def keys(self) -> KeysView[str]:
335
+ return ({self._axis_to_string(k): v for k, v in self.data.items()}).keys()
336
+
337
+ def items(self) -> ItemsView[str, float]:
338
+ return ({self._axis_to_string(k): v for k, v in self.data.items()}).items()
339
+
340
+
341
+ def clamp_value(
342
+ input_value: float, max_value: float, min_value: float, log_tag: str = ""
343
+ ) -> float:
344
+ if input_value > max_value:
345
+ MODULE_LOG.info(f"{log_tag} clamped input {input_value} to {max_value}")
346
+ return max_value
347
+ if input_value < min_value:
348
+ MODULE_LOG.info(f"{log_tag} clamped input {input_value} to {min_value}")
349
+ return min_value
350
+ return input_value
351
+
352
+
353
+ FuncT = TypeVar("FuncT", bound=Callable[..., Any])
354
+
355
+
356
+ def requires_version(major: int, minor: int) -> Callable[[FuncT], FuncT]:
357
+ """Decorator. Apply to Protocol API methods or attributes to indicate
358
+ the first version in which the method or attribute was present.
359
+ """
360
+
361
+ def _set_version(decorated_obj: FuncT) -> FuncT:
362
+ added_version = APIVersion(major, minor)
363
+ setattr(decorated_obj, "__opentrons_version_added", added_version)
364
+ if hasattr(decorated_obj, "__doc__"):
365
+ # Add the versionadded stanza to everything decorated if we can
366
+ docstr = decorated_obj.__doc__ or ""
367
+ # this newline and initial space has to be there for sphinx to
368
+ # parse this correctly and not add it into for instance a
369
+ # previous code-block
370
+ docstr += f"\n\n .. versionadded:: {added_version}\n\n"
371
+ decorated_obj.__doc__ = docstr
372
+
373
+ @functools.wraps(decorated_obj)
374
+ def _check_version_wrapper(*args: Any, **kwargs: Any) -> Any:
375
+ slf = args[0]
376
+ added_in = decorated_obj.__opentrons_version_added # type: ignore
377
+ current_version = slf._api_version
378
+
379
+ if APIVersion(2, 0) <= current_version < added_in:
380
+ # __qualname__ is *probably* set on every kind of object we care
381
+ # about, but the docs leave it ambiguous, so fall back to str().
382
+ name = getattr(decorated_obj, "__qualname__", str(decorated_obj))
383
+
384
+ raise APIVersionError(
385
+ api_element=name,
386
+ until_version=added_in,
387
+ current_version=current_version,
388
+ )
389
+ return decorated_obj(*args, **kwargs)
390
+
391
+ return cast(FuncT, _check_version_wrapper)
392
+
393
+ return _set_version
394
+
395
+
396
+ class ModifiedList(list[str]):
397
+ def __contains__(self, item: object) -> bool:
398
+ if not isinstance(item, str):
399
+ return False
400
+ for name in self:
401
+ if name == item.replace("-", "_").lower():
402
+ return True
403
+ return False
@@ -0,0 +1,89 @@
1
+ """
2
+ functions and utilities for handling zipped protocol bundles
3
+ """
4
+ from datetime import date
5
+ import json
6
+ from pathlib import PurePosixPath, PurePath
7
+ from typing import Dict, BinaryIO, TYPE_CHECKING
8
+ from zipfile import ZipFile
9
+
10
+ from opentrons.calibration_storage.helpers import uri_from_definition
11
+
12
+ from .types import BundleContents
13
+
14
+ if TYPE_CHECKING:
15
+ from opentrons_shared_data.labware.types import LabwareDefinition
16
+
17
+ MAIN_PROTOCOL_FILENAME = "protocol.ot2.py"
18
+ LABWARE_DIR = "labware"
19
+ DATA_DIR = "data"
20
+
21
+
22
+ def _has_files_at_root(zipFile: ZipFile) -> bool:
23
+ for zipInfo in zipFile.infolist():
24
+ if zipInfo.filename.count("/") == 0:
25
+ return True
26
+ return False
27
+
28
+
29
+ def extract_bundle(bundle: ZipFile) -> BundleContents: # noqa: C901
30
+ """Extract a bundle and verify its contents and structure."""
31
+ if not _has_files_at_root(bundle):
32
+ raise RuntimeError(
33
+ "No files found in ZIP file's root directory. When selecting "
34
+ "files to zip, make sure to directly select the files "
35
+ "themselves. Do not select their parent directory, which would "
36
+ "result in nesting all files inside that directory in the ZIP."
37
+ )
38
+ try:
39
+ with bundle.open(MAIN_PROTOCOL_FILENAME, "r") as protocol_file:
40
+ py_protocol = protocol_file.read().decode("utf-8")
41
+ except KeyError:
42
+ raise RuntimeError(
43
+ f"Bundled protocol should have a {MAIN_PROTOCOL_FILENAME} "
44
+ + "file in the root directory"
45
+ )
46
+ bundled_labware: Dict[str, "LabwareDefinition"] = {}
47
+ bundled_data = {}
48
+ bundled_python = {}
49
+ for zipInfo in bundle.infolist():
50
+ filepath = PurePosixPath(zipInfo.filename)
51
+ rootpath = filepath.parts[0]
52
+
53
+ # skip directories and weird OS-added directories
54
+ # (note: the __MACOSX dir would contain '__MACOSX/foo.py'
55
+ # and other files. This would break our inferences, so we need
56
+ # to exclude all contents of that directory)
57
+ if rootpath == "__MACOSX" or zipInfo.is_dir():
58
+ continue
59
+
60
+ with bundle.open(zipInfo) as f:
61
+ if rootpath == LABWARE_DIR and filepath.suffix == ".json":
62
+ labware_def = json.loads(f.read().decode("utf-8"))
63
+ labware_key = uri_from_definition(labware_def)
64
+ if labware_key in bundled_labware:
65
+ raise RuntimeError(f"Conflicting labware in bundle: {labware_key}")
66
+ bundled_labware[labware_key] = labware_def
67
+ elif rootpath == DATA_DIR:
68
+ # note: data files are read as binary
69
+ bundled_data[str(filepath.relative_to(DATA_DIR))] = f.read()
70
+ elif filepath.suffix == ".py" and str(filepath) != MAIN_PROTOCOL_FILENAME:
71
+ bundled_python[str(filepath)] = f.read().decode("utf-8")
72
+
73
+ if not bundled_labware:
74
+ raise RuntimeError("No labware definitions found in bundle.")
75
+
76
+ return BundleContents(py_protocol, bundled_labware, bundled_data, bundled_python)
77
+
78
+
79
+ def create_bundle(contents: BundleContents, into_file: BinaryIO) -> None:
80
+ """Create a bundle from assumed-good contents"""
81
+ with ZipFile(into_file, mode="w") as zf:
82
+ zf.writestr(MAIN_PROTOCOL_FILENAME, contents.protocol)
83
+ for dataname, datafile in contents.bundled_data.items():
84
+ name = PurePath(dataname).name
85
+ zf.writestr(f"{DATA_DIR}/{name}", datafile)
86
+ for lwdef in contents.bundled_labware.values():
87
+ zipsafe = uri_from_definition(lwdef, "-")
88
+ zf.writestr(f"{LABWARE_DIR}/{zipsafe}.json", json.dumps(lwdef))
89
+ zf.writestr(".bundle_beta", str(date.today()))
@@ -0,0 +1,4 @@
1
+ from .estimator import DurationEstimator
2
+
3
+
4
+ __all__ = ["DurationEstimator"]
@@ -0,0 +1,5 @@
1
+ class DurationEstimatorException(Exception):
2
+ def __init__(self, message: str) -> None:
3
+ super().__init__(
4
+ f"Error encountered while estimating protocol duration: '{message}'"
5
+ )