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,26 @@
1
+ """Interfaces to provide data and other external system resources.
2
+
3
+ Classes in this module do not maintain state and can be instantiated
4
+ as needed. Some classes may contain solely static methods.
5
+ """
6
+ from . import pipette_data_provider
7
+ from . import labware_validation
8
+ from .model_utils import ModelUtils
9
+ from .deck_data_provider import DeckDataProvider, DeckFixedLabware
10
+ from .labware_data_provider import LabwareDataProvider
11
+ from .module_data_provider import ModuleDataProvider
12
+ from .file_provider import FileProvider
13
+ from .ot3_validation import ensure_ot3_hardware
14
+
15
+
16
+ __all__ = [
17
+ "ModelUtils",
18
+ "LabwareDataProvider",
19
+ "DeckDataProvider",
20
+ "DeckFixedLabware",
21
+ "ModuleDataProvider",
22
+ "FileProvider",
23
+ "ensure_ot3_hardware",
24
+ "pipette_data_provider",
25
+ "labware_validation",
26
+ ]
@@ -0,0 +1,232 @@
1
+ """Deck configuration resource provider."""
2
+
3
+ from typing import List, Set, Tuple
4
+
5
+ from opentrons_shared_data.deck.types import (
6
+ DeckDefinitionV5,
7
+ CutoutFixture,
8
+ )
9
+
10
+ from opentrons.types import DeckSlotName
11
+
12
+ from ..types import (
13
+ AddressableArea,
14
+ AreaType,
15
+ PotentialCutoutFixture,
16
+ DeckPoint,
17
+ Dimensions,
18
+ AddressableOffsetVector,
19
+ )
20
+ from ..errors import (
21
+ CutoutDoesNotExistError,
22
+ FixtureDoesNotExistError,
23
+ AddressableAreaDoesNotExistError,
24
+ SlotDoesNotExistError,
25
+ )
26
+
27
+
28
+ def get_cutout_position(cutout_id: str, deck_definition: DeckDefinitionV5) -> DeckPoint:
29
+ """Get the base position of a cutout on the deck."""
30
+ for cutout in deck_definition["locations"]["cutouts"]:
31
+ if cutout_id == cutout["id"]:
32
+ position = cutout["position"]
33
+ return DeckPoint(x=position[0], y=position[1], z=position[2])
34
+ else:
35
+ raise CutoutDoesNotExistError(f"Could not find cutout with name {cutout_id}")
36
+
37
+
38
+ def get_cutout_fixture(
39
+ cutout_fixture_id: str, deck_definition: DeckDefinitionV5
40
+ ) -> CutoutFixture:
41
+ """Gets cutout fixture from deck that matches the cutout fixture ID provided."""
42
+ for cutout_fixture in deck_definition["cutoutFixtures"]:
43
+ if cutout_fixture["id"] == cutout_fixture_id:
44
+ return cutout_fixture
45
+ raise FixtureDoesNotExistError(
46
+ f"Could not find cutout fixture with name {cutout_fixture_id}"
47
+ )
48
+
49
+
50
+ def get_provided_addressable_area_names(
51
+ cutout_fixture_id: str, cutout_id: str, deck_definition: DeckDefinitionV5
52
+ ) -> List[str]:
53
+ """Gets a list of the addressable areas provided by the cutout fixture on the cutout."""
54
+ cutout_fixture = get_cutout_fixture(cutout_fixture_id, deck_definition)
55
+ try:
56
+ return cutout_fixture["providesAddressableAreas"][cutout_id]
57
+ except KeyError:
58
+ return []
59
+
60
+
61
+ def get_addressable_area_display_name(
62
+ addressable_area_name: str, deck_definition: DeckDefinitionV5
63
+ ) -> str:
64
+ """Get the display name for an addressable area name."""
65
+ for addressable_area in deck_definition["locations"]["addressableAreas"]:
66
+ if addressable_area["id"] == addressable_area_name:
67
+ return addressable_area["displayName"]
68
+ raise AddressableAreaDoesNotExistError(
69
+ f"Could not find addressable area with name {addressable_area_name}"
70
+ )
71
+
72
+
73
+ def get_potential_cutout_fixtures(
74
+ addressable_area_name: str, deck_definition: DeckDefinitionV5
75
+ ) -> Tuple[str, Set[PotentialCutoutFixture]]:
76
+ """Given an addressable area name, gets the cutout ID associated with it and a set of potential fixtures."""
77
+ potential_fixtures = []
78
+ for cutout_fixture in deck_definition["cutoutFixtures"]:
79
+ for cutout_id, provided_areas in cutout_fixture[
80
+ "providesAddressableAreas"
81
+ ].items():
82
+ if addressable_area_name in provided_areas:
83
+ potential_fixtures.append(
84
+ PotentialCutoutFixture(
85
+ cutout_id=cutout_id,
86
+ cutout_fixture_id=cutout_fixture["id"],
87
+ provided_addressable_areas=frozenset(provided_areas),
88
+ )
89
+ )
90
+ # This following logic is making the assumption that every addressable area can only go on one cutout, though
91
+ # it may have multiple cutout fixtures that supply it on that cutout. If this assumption changes, some of the
92
+ # following logic will have to be readjusted
93
+ if not potential_fixtures:
94
+ raise AddressableAreaDoesNotExistError(
95
+ f"{addressable_area_name} is not provided by any cutout fixtures"
96
+ f" in deck definition {deck_definition['otId']}"
97
+ )
98
+ cutout_id = potential_fixtures[0].cutout_id
99
+ assert all(cutout_id == fixture.cutout_id for fixture in potential_fixtures)
100
+ return cutout_id, set(potential_fixtures)
101
+
102
+
103
+ def get_addressable_area_from_name(
104
+ addressable_area_name: str,
105
+ cutout_position: DeckPoint,
106
+ deck_definition: DeckDefinitionV5,
107
+ ) -> AddressableArea:
108
+ """Given a name and a cutout position, get an addressable area on the deck."""
109
+ for addressable_area in deck_definition["locations"]["addressableAreas"]:
110
+ if addressable_area["id"] == addressable_area_name:
111
+ cutout_id, _ = get_potential_cutout_fixtures(
112
+ addressable_area_name, deck_definition
113
+ )
114
+ base_slot = get_deck_slot_for_cutout_id(cutout_id)
115
+ area_offset = addressable_area["offsetFromCutoutFixture"]
116
+ position = AddressableOffsetVector(
117
+ x=area_offset[0] + cutout_position.x,
118
+ y=area_offset[1] + cutout_position.y,
119
+ z=area_offset[2] + cutout_position.z,
120
+ )
121
+ bounding_box = Dimensions(
122
+ x=addressable_area["boundingBox"]["xDimension"],
123
+ y=addressable_area["boundingBox"]["yDimension"],
124
+ z=addressable_area["boundingBox"]["zDimension"],
125
+ )
126
+ features = addressable_area["features"]
127
+ mating_surface_unit_vector = addressable_area.get("matingSurfaceUnitVector")
128
+
129
+ return AddressableArea(
130
+ area_name=addressable_area["id"],
131
+ area_type=AreaType(addressable_area["areaType"]),
132
+ mating_surface_unit_vector=mating_surface_unit_vector,
133
+ base_slot=base_slot,
134
+ display_name=addressable_area["displayName"],
135
+ bounding_box=bounding_box,
136
+ position=position,
137
+ compatible_module_types=addressable_area.get(
138
+ "compatibleModuleTypes", []
139
+ ),
140
+ features=features,
141
+ )
142
+ raise AddressableAreaDoesNotExistError(
143
+ f"Could not find addressable area with name {addressable_area_name}"
144
+ )
145
+
146
+
147
+ def get_deck_slot_for_cutout_id(cutout_id: str) -> DeckSlotName:
148
+ """Get the corresponding deck slot for an addressable area."""
149
+ try:
150
+ return CUTOUT_TO_DECK_SLOT_MAP[cutout_id]
151
+ except KeyError as e:
152
+ raise CutoutDoesNotExistError(
153
+ f"Could not find data for cutout {cutout_id}"
154
+ ) from e
155
+
156
+
157
+ def get_cutout_id_by_deck_slot_name(slot_name: DeckSlotName) -> str:
158
+ """Get the Cutout ID of a given Deck Slot by Deck Slot Name."""
159
+ try:
160
+ return DECK_SLOT_TO_CUTOUT_MAP[slot_name]
161
+ except KeyError as e:
162
+ raise SlotDoesNotExistError(
163
+ f"Could not find data for slot {slot_name.value}"
164
+ ) from e
165
+
166
+
167
+ def get_labware_hosting_addressable_area_name_for_cutout_and_cutout_fixture(
168
+ cutout_id: str, cutout_fixture_id: str, deck_definition: DeckDefinitionV5
169
+ ) -> str:
170
+ """Get the first addressable area that can contain labware for a cutout and fixture.
171
+
172
+ This probably isn't relevant outside of labware offset locations, where (for now) nothing
173
+ provides more than one labware-containing addressable area.
174
+ """
175
+ for cutoutFixture in deck_definition["cutoutFixtures"]:
176
+ if cutoutFixture["id"] != cutout_fixture_id:
177
+ continue
178
+ provided_aas = cutoutFixture["providesAddressableAreas"].get(cutout_id, None)
179
+ if provided_aas is None:
180
+ raise CutoutDoesNotExistError(
181
+ f"{cutout_fixture_id} does not go in {cutout_id}"
182
+ )
183
+ for aa_id in provided_aas:
184
+ for addressable_area in deck_definition["locations"]["addressableAreas"]:
185
+ if addressable_area["id"] != aa_id:
186
+ continue
187
+ # TODO: In deck def v6 this will be easier, but as of right now there isn't really
188
+ # a way to tell from an addressable area whether it takes labware so let's take the
189
+ # first one
190
+ return aa_id
191
+ raise AddressableAreaDoesNotExistError(
192
+ f"Could not find an addressable area that allows labware from cutout fixture {cutout_fixture_id} in cutout {cutout_id}"
193
+ )
194
+
195
+ raise FixtureDoesNotExistError(f"Could not find entry for {cutout_fixture_id}")
196
+
197
+
198
+ # This is a temporary shim while Protocol Engine's conflict-checking code
199
+ # can only take deck slots as input.
200
+ # Long-term solution: Check for conflicts based on bounding boxes, not slot adjacencies.
201
+ # Shorter-term: Change the conflict-checking code to take cutouts instead of deck slots.
202
+ CUTOUT_TO_DECK_SLOT_MAP: dict[str, DeckSlotName] = {
203
+ # OT-2
204
+ "cutout1": DeckSlotName.SLOT_1,
205
+ "cutout2": DeckSlotName.SLOT_2,
206
+ "cutout3": DeckSlotName.SLOT_3,
207
+ "cutout4": DeckSlotName.SLOT_4,
208
+ "cutout5": DeckSlotName.SLOT_5,
209
+ "cutout6": DeckSlotName.SLOT_6,
210
+ "cutout7": DeckSlotName.SLOT_7,
211
+ "cutout8": DeckSlotName.SLOT_8,
212
+ "cutout9": DeckSlotName.SLOT_9,
213
+ "cutout10": DeckSlotName.SLOT_10,
214
+ "cutout11": DeckSlotName.SLOT_11,
215
+ "cutout12": DeckSlotName.FIXED_TRASH,
216
+ # Flex
217
+ "cutoutA1": DeckSlotName.SLOT_A1,
218
+ "cutoutA2": DeckSlotName.SLOT_A2,
219
+ "cutoutA3": DeckSlotName.SLOT_A3,
220
+ "cutoutB1": DeckSlotName.SLOT_B1,
221
+ "cutoutB2": DeckSlotName.SLOT_B2,
222
+ "cutoutB3": DeckSlotName.SLOT_B3,
223
+ "cutoutC1": DeckSlotName.SLOT_C1,
224
+ "cutoutC2": DeckSlotName.SLOT_C2,
225
+ "cutoutC3": DeckSlotName.SLOT_C3,
226
+ "cutoutD1": DeckSlotName.SLOT_D1,
227
+ "cutoutD2": DeckSlotName.SLOT_D2,
228
+ "cutoutD3": DeckSlotName.SLOT_D3,
229
+ }
230
+ DECK_SLOT_TO_CUTOUT_MAP = {
231
+ deck_slot: cutout for cutout, deck_slot in CUTOUT_TO_DECK_SLOT_MAP.items()
232
+ }
@@ -0,0 +1,94 @@
1
+ """Deck data resource provider."""
2
+ from dataclasses import dataclass
3
+ from typing import List, Optional, cast
4
+ from typing_extensions import final
5
+
6
+ import anyio
7
+
8
+ from opentrons_shared_data.deck import (
9
+ load as load_deck,
10
+ DEFAULT_DECK_DEFINITION_VERSION,
11
+ )
12
+ from opentrons_shared_data.deck.types import DeckDefinitionV5
13
+ from opentrons_shared_data.labware.labware_definition import LabwareDefinition
14
+ from opentrons.types import DeckSlotName
15
+
16
+ from ..types import (
17
+ DeckSlotLocation,
18
+ DeckType,
19
+ LabwareLocation,
20
+ DeckConfigurationType,
21
+ )
22
+ from .labware_data_provider import LabwareDataProvider
23
+
24
+
25
+ @final
26
+ @dataclass(frozen=True)
27
+ class DeckFixedLabware:
28
+ """A labware fixture that is always present on a deck."""
29
+
30
+ labware_id: str
31
+ location: LabwareLocation
32
+ definition: LabwareDefinition
33
+
34
+
35
+ class DeckDataProvider:
36
+ """Provider class to wrap deck definition and data retrieval."""
37
+
38
+ _labware_data: LabwareDataProvider
39
+
40
+ def __init__(
41
+ self, deck_type: DeckType, labware_data: Optional[LabwareDataProvider] = None
42
+ ) -> None:
43
+ """Initialize a DeckDataProvider."""
44
+ self._deck_type = deck_type
45
+ self._labware_data = labware_data or LabwareDataProvider()
46
+
47
+ async def get_deck_definition(self) -> DeckDefinitionV5:
48
+ """Get a labware definition given the labware's identification."""
49
+
50
+ def sync() -> DeckDefinitionV5:
51
+ return load_deck(
52
+ name=self._deck_type.value, version=DEFAULT_DECK_DEFINITION_VERSION
53
+ )
54
+
55
+ return await anyio.to_thread.run_sync(sync)
56
+
57
+ async def get_deck_fixed_labware(
58
+ self,
59
+ load_fixed_trash: bool,
60
+ deck_definition: DeckDefinitionV5,
61
+ deck_configuration: Optional[DeckConfigurationType] = None,
62
+ ) -> List[DeckFixedLabware]:
63
+ """Get a list of all labware fixtures from a given deck definition."""
64
+ labware: List[DeckFixedLabware] = []
65
+
66
+ for fixture in deck_definition["locations"]["legacyFixtures"]:
67
+ labware_id = fixture["id"]
68
+ load_name = cast(Optional[str], fixture.get("labware"))
69
+ slot = cast(Optional[str], fixture.get("slot"))
70
+
71
+ if (
72
+ load_fixed_trash
73
+ and load_name is not None
74
+ and slot is not None
75
+ and slot in DeckSlotName._value2member_map_
76
+ ):
77
+ deck_slot_location = DeckSlotLocation(
78
+ slotName=DeckSlotName.from_primitive(slot)
79
+ )
80
+ definition = await self._labware_data.get_labware_definition(
81
+ load_name=load_name,
82
+ namespace="opentrons",
83
+ version=1,
84
+ )
85
+
86
+ labware.append(
87
+ DeckFixedLabware(
88
+ labware_id=labware_id,
89
+ definition=definition,
90
+ location=deck_slot_location,
91
+ )
92
+ )
93
+
94
+ return labware
@@ -0,0 +1,161 @@
1
+ """File interaction resource provider."""
2
+ from datetime import datetime
3
+ from typing import List, Optional, Callable, Awaitable, Dict
4
+ from pydantic import BaseModel
5
+ from ..errors import StorageLimitReachedError
6
+
7
+
8
+ MAXIMUM_CSV_FILE_LIMIT = 400
9
+
10
+
11
+ class GenericCsvTransform:
12
+ """Generic CSV File Type data for rows of data to be seperated by a delimeter."""
13
+
14
+ filename: str
15
+ rows: List[List[str]]
16
+ delimiter: str = ","
17
+
18
+ @staticmethod
19
+ def build(
20
+ filename: str, rows: List[List[str]], delimiter: str = ","
21
+ ) -> "GenericCsvTransform":
22
+ """Build a Generic CSV datatype class."""
23
+ if "." in filename and not filename.endswith(".csv"):
24
+ raise ValueError(
25
+ f"Provided filename {filename} invalid. Only CSV file format is accepted."
26
+ )
27
+ elif "." not in filename:
28
+ filename = f"{filename}.csv"
29
+ csv = GenericCsvTransform()
30
+ csv.filename = filename
31
+ csv.rows = rows
32
+ csv.delimiter = delimiter
33
+ return csv
34
+
35
+
36
+ class ReadData(BaseModel):
37
+ """Read Data type containing the wavelength for a Plate Reader read alongside the Measurement Data of that read."""
38
+
39
+ wavelength: int
40
+ data: Dict[str, float]
41
+
42
+
43
+ class PlateReaderData(BaseModel):
44
+ """Data from a Opentrons Plate Reader Read. Can be converted to CSV template format."""
45
+
46
+ read_results: List[ReadData]
47
+ reference_wavelength: Optional[int] = None
48
+ start_time: datetime
49
+ finish_time: datetime
50
+ serial_number: str
51
+
52
+ def build_generic_csv( # noqa: C901
53
+ self, filename: str, measurement: ReadData
54
+ ) -> GenericCsvTransform:
55
+ """Builds a CSV compatible object containing Plate Reader Measurements.
56
+
57
+ This will also automatically reformat the provided filename to include the wavelength of those measurements.
58
+ """
59
+ plate_alpharows = ["A", "B", "C", "D", "E", "F", "G", "H"]
60
+ rows = []
61
+
62
+ rows.append(["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"])
63
+ for i in range(8):
64
+ row = [plate_alpharows[i]]
65
+ for j in range(12):
66
+ row.append(str(measurement.data[f"{plate_alpharows[i]}{j+1}"]))
67
+ rows.append(row)
68
+ for i in range(3):
69
+ rows.append([])
70
+ rows.append(["", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"])
71
+ for i in range(8):
72
+ row = [plate_alpharows[i]]
73
+ for j in range(12):
74
+ row.append("")
75
+ rows.append(row)
76
+ for i in range(3):
77
+ rows.append([])
78
+ rows.append(
79
+ [
80
+ "",
81
+ "ID",
82
+ "Well",
83
+ "Absorbance (OD)",
84
+ "Mean Absorbance (OD)",
85
+ "Absorbance %CV",
86
+ ]
87
+ )
88
+ for i in range(3):
89
+ rows.append([])
90
+ rows.append(
91
+ [
92
+ "",
93
+ "ID",
94
+ "Well",
95
+ "Absorbance (OD)",
96
+ "Mean Absorbance (OD)",
97
+ "Dilution Factor",
98
+ "Absorbance %CV",
99
+ ]
100
+ )
101
+ rows.append(["1", "Sample 1", "", "", "", "1", "", "", "", "", "", ""])
102
+ for i in range(3):
103
+ rows.append([])
104
+
105
+ # end of file metadata
106
+ rows.append(["Protocol"])
107
+ rows.append(["Assay"])
108
+ rows.append(["Sample Wavelength (nm)", str(measurement.wavelength)])
109
+ if self.reference_wavelength is not None:
110
+ rows.append(["Reference Wavelength (nm)", str(self.reference_wavelength)])
111
+ rows.append(["Serial No.", self.serial_number])
112
+ rows.append(
113
+ ["Measurement started at", self.start_time.strftime("%m %d %H:%M:%S %Y")]
114
+ )
115
+ rows.append(
116
+ ["Measurement finished at", self.finish_time.strftime("%m %d %H:%M:%S %Y")]
117
+ )
118
+
119
+ # Ensure the filename adheres to ruleset contains the wavelength for a given measurement
120
+ if filename.endswith(".csv"):
121
+ filename = filename[:-4]
122
+ filename = filename + str(measurement.wavelength) + "nm.csv"
123
+
124
+ return GenericCsvTransform.build(
125
+ filename=filename,
126
+ rows=rows,
127
+ delimiter=",",
128
+ )
129
+
130
+
131
+ class FileProvider:
132
+ """Provider class to wrap file read write interactions to the data files directory in the engine."""
133
+
134
+ def __init__(
135
+ self,
136
+ data_files_write_csv_callback: Optional[
137
+ Callable[[GenericCsvTransform], Awaitable[str]]
138
+ ] = None,
139
+ data_files_filecount: Optional[Callable[[], Awaitable[int]]] = None,
140
+ ) -> None:
141
+ """Initialize the interface callbacks of the File Provider for data file handling within the Protocol Engine.
142
+
143
+ Params:
144
+ data_files_write_csv_callback: Callback to write a CSV file to the data files directory and add it to the database.
145
+ data_files_filecount: Callback to check the amount of data files already present in the data files directory.
146
+ """
147
+ self._data_files_write_csv_callback = data_files_write_csv_callback
148
+ self._data_files_filecount = data_files_filecount
149
+
150
+ async def write_csv(self, write_data: GenericCsvTransform) -> str:
151
+ """Writes the provided CSV object to a file in the Data Files directory. Returns the File ID of the file created."""
152
+ if self._data_files_filecount is not None:
153
+ file_count = await self._data_files_filecount()
154
+ if file_count >= MAXIMUM_CSV_FILE_LIMIT:
155
+ raise StorageLimitReachedError(
156
+ f"Not enough space to store file {write_data.filename}."
157
+ )
158
+ if self._data_files_write_csv_callback is not None:
159
+ return await self._data_files_write_csv_callback(write_data)
160
+ # If we are in an analysis or simulation state, return an empty file ID
161
+ return ""
@@ -0,0 +1,58 @@
1
+ """Validation file for addressable area reference checking functions."""
2
+
3
+ from opentrons.types import DeckSlotName
4
+
5
+
6
+ def is_waste_chute(addressable_area_name: str) -> bool:
7
+ """Check if an addressable area is a Waste Chute."""
8
+ return addressable_area_name in {
9
+ "1ChannelWasteChute",
10
+ "8ChannelWasteChute",
11
+ "96ChannelWasteChute",
12
+ "gripperWasteChute",
13
+ }
14
+
15
+
16
+ def is_gripper_waste_chute(addressable_area_name: str) -> bool:
17
+ """Check if an addressable area is a gripper-movement-compatible Waste Chute."""
18
+ return addressable_area_name == "gripperWasteChute"
19
+
20
+
21
+ def is_drop_tip_waste_chute(addressable_area_name: str) -> bool:
22
+ """Check if an addressable area is a Waste Chute compatible for dropping tips."""
23
+ return addressable_area_name in {
24
+ "1ChannelWasteChute",
25
+ "8ChannelWasteChute",
26
+ "96ChannelWasteChute",
27
+ }
28
+
29
+
30
+ def is_trash(addressable_area_name: str) -> bool:
31
+ """Check if an addressable area is a trash bin."""
32
+ return any(
33
+ [
34
+ s in addressable_area_name
35
+ for s in {"movableTrash", "fixedTrash", "shortFixedTrash"}
36
+ ]
37
+ )
38
+
39
+
40
+ def is_staging_slot(addressable_area_name: str) -> bool:
41
+ """Check if an addressable area is a staging area slot."""
42
+ return addressable_area_name in {"A4", "B4", "C4", "D4"}
43
+
44
+
45
+ def is_deck_slot(addressable_area_name: str) -> bool:
46
+ """Check if an addressable area is a deck slot (including staging area slots)."""
47
+ if is_staging_slot(addressable_area_name):
48
+ return True
49
+ try:
50
+ DeckSlotName.from_primitive(addressable_area_name)
51
+ except ValueError:
52
+ return False
53
+ return True
54
+
55
+
56
+ def is_abs_reader(addressable_area_name: str) -> bool:
57
+ """Check if an addressable area is an absorbance plate reader area."""
58
+ return "absorbanceReaderV1" in addressable_area_name
@@ -0,0 +1,106 @@
1
+ """Labware data resource provider.
2
+
3
+ This module is a wrapper around existing, but older, internal APIs to
4
+ abstract away rough edges until we can improve those underlying interfaces.
5
+ """
6
+ import logging
7
+ from anyio import to_thread
8
+
9
+ from opentrons_shared_data.labware.labware_definition import (
10
+ LabwareDefinition,
11
+ LabwareDefinition3,
12
+ labware_definition_type_adapter,
13
+ )
14
+
15
+ from opentrons.protocols.labware import get_labware_definition
16
+
17
+ # TODO (lc 09-26-2022) We should conditionally import ot2 or ot3 calibration
18
+ from opentrons.hardware_control.instruments.ot2 import (
19
+ instrument_calibration as instr_cal,
20
+ )
21
+ from opentrons.calibration_storage.types import TipLengthCalNotFound
22
+
23
+
24
+ log = logging.getLogger(__name__)
25
+
26
+
27
+ class LabwareDataProvider:
28
+ """Labware data provider."""
29
+
30
+ @staticmethod
31
+ async def get_labware_definition(
32
+ load_name: str,
33
+ namespace: str,
34
+ version: int,
35
+ ) -> LabwareDefinition:
36
+ """Get a labware definition given the labware's identification.
37
+
38
+ Note: this method hits the filesystem, which will have performance
39
+ implications if it is called often.
40
+ """
41
+ return await to_thread.run_sync(
42
+ LabwareDataProvider._get_labware_definition_sync,
43
+ load_name,
44
+ namespace,
45
+ version,
46
+ )
47
+
48
+ @staticmethod
49
+ def _get_labware_definition_sync(
50
+ load_name: str, namespace: str, version: int
51
+ ) -> LabwareDefinition:
52
+ return labware_definition_type_adapter.validate_python(
53
+ get_labware_definition(load_name, namespace, version)
54
+ )
55
+
56
+ @staticmethod
57
+ async def get_calibrated_tip_length(
58
+ pipette_serial: str,
59
+ labware_definition: LabwareDefinition,
60
+ nominal_fallback: float,
61
+ ) -> float:
62
+ """Get the calibrated tip length of a tip rack / pipette pair.
63
+
64
+ Note: this method hits the filesystem, which will have performance
65
+ implications if it is called often.
66
+ """
67
+ return await to_thread.run_sync(
68
+ LabwareDataProvider._get_calibrated_tip_length_sync,
69
+ pipette_serial,
70
+ labware_definition,
71
+ nominal_fallback,
72
+ )
73
+
74
+ @staticmethod
75
+ def _get_calibrated_tip_length_sync(
76
+ pipette_serial: str,
77
+ labware_definition: LabwareDefinition,
78
+ nominal_fallback: float,
79
+ ) -> float:
80
+ if isinstance(labware_definition, LabwareDefinition3):
81
+ # FIXME(mm, 2025-02-19): This needs to be resolved for v8.4.0.
82
+ # Tip length calibration internals don't yet support schema 3 because
83
+ # it's probably an incompatible change at the filesystem level
84
+ # (not downgrade-safe), and because robot-server's calibration sessions
85
+ # are built atop opentrons.protocol_api.core.legacy, which does not (yet?)
86
+ # support labware schema 3.
87
+ # https://opentrons.atlassian.net/browse/EXEC-1230
88
+ log.warning(
89
+ f"Tip rack"
90
+ f" {labware_definition.namespace}/{labware_definition.parameters.loadName}/{labware_definition.version}"
91
+ f" has schema 3, so tip length calibration is currently unsupported."
92
+ f" Using nominal fallback of {nominal_fallback}."
93
+ )
94
+ return nominal_fallback
95
+ else:
96
+ try:
97
+ return instr_cal.load_tip_length_for_pipette(
98
+ pipette_serial, labware_definition
99
+ ).tip_length
100
+ except TipLengthCalNotFound as e:
101
+ message = (
102
+ f"No calibrated tip length found for {pipette_serial},"
103
+ f" using nominal fallback value of {nominal_fallback}"
104
+ )
105
+ log.debug(message, exc_info=e)
106
+ return nominal_fallback