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,226 @@
1
+ """Command models to read absorbance."""
2
+ from __future__ import annotations
3
+ from datetime import datetime
4
+ from typing import Optional, Dict, TYPE_CHECKING, List, Any
5
+
6
+ from typing_extensions import Literal, Type
7
+ from pydantic import BaseModel, Field
8
+ from pydantic.json_schema import SkipJsonSchema
9
+
10
+ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
11
+ from ...errors import CannotPerformModuleAction, StorageLimitReachedError
12
+ from ...errors.error_occurrence import ErrorOccurrence
13
+
14
+ from ...resources.file_provider import (
15
+ PlateReaderData,
16
+ ReadData,
17
+ MAXIMUM_CSV_FILE_LIMIT,
18
+ )
19
+ from ...resources import FileProvider
20
+ from ...state import update_types
21
+
22
+ if TYPE_CHECKING:
23
+ from opentrons.protocol_engine.state.state import StateView
24
+ from opentrons.protocol_engine.execution import EquipmentHandler
25
+
26
+
27
+ def _remove_default(s: dict[str, Any]) -> None:
28
+ s.pop("default", None)
29
+
30
+
31
+ ReadAbsorbanceCommandType = Literal["absorbanceReader/read"]
32
+
33
+
34
+ class ReadAbsorbanceParams(BaseModel):
35
+ """Input parameters for an absorbance reading."""
36
+
37
+ moduleId: str = Field(..., description="Unique ID of the Absorbance Reader.")
38
+ fileName: str | SkipJsonSchema[None] = Field(
39
+ None,
40
+ description="Optional file name to use when storing the results of a measurement.",
41
+ json_schema_extra=_remove_default,
42
+ )
43
+
44
+
45
+ class ReadAbsorbanceResult(BaseModel):
46
+ """Result data from running an aborbance reading, returned as a dictionary map of wavelengths containing a map of values by well name (eg. {450: {"A1": 0.0, ...}})."""
47
+
48
+ data: Optional[Dict[int, Dict[str, float]]] = Field(
49
+ ..., description="Absorbance data points per wavelength."
50
+ )
51
+ fileIds: Optional[List[str]] = Field(
52
+ ...,
53
+ description="List of file IDs for files output as a result of a Read action.",
54
+ )
55
+
56
+
57
+ class ReadAbsorbanceImpl(
58
+ AbstractCommandImpl[ReadAbsorbanceParams, SuccessData[ReadAbsorbanceResult]]
59
+ ):
60
+ """Execution implementation of an Absorbance Reader measurement."""
61
+
62
+ def __init__(
63
+ self,
64
+ state_view: StateView,
65
+ equipment: EquipmentHandler,
66
+ file_provider: FileProvider,
67
+ **unused_dependencies: object,
68
+ ) -> None:
69
+ self._state_view = state_view
70
+ self._equipment = equipment
71
+ self._file_provider = file_provider
72
+
73
+ async def execute( # noqa: C901
74
+ self, params: ReadAbsorbanceParams
75
+ ) -> SuccessData[ReadAbsorbanceResult]:
76
+ """Initiate an absorbance measurement."""
77
+ state_update = update_types.StateUpdate()
78
+ abs_reader_substate = self._state_view.modules.get_absorbance_reader_substate(
79
+ module_id=params.moduleId
80
+ )
81
+
82
+ # Allow propagation of ModuleNotAttachedError.
83
+ abs_reader = self._equipment.get_module_hardware_api(
84
+ abs_reader_substate.module_id
85
+ )
86
+
87
+ if abs_reader_substate.configured is False:
88
+ raise CannotPerformModuleAction(
89
+ "Cannot perform Read action on Absorbance Reader without calling `.initialize(...)` first."
90
+ )
91
+ if abs_reader_substate.is_lid_on is False:
92
+ raise CannotPerformModuleAction(
93
+ "Absorbance Plate Reader can't read a plate with the lid open. Call `close_lid()` first."
94
+ )
95
+
96
+ # TODO: we need to return a file ID and increase the file count even when a moduel is not attached
97
+ if (
98
+ params.fileName is not None
99
+ and abs_reader_substate.configured_wavelengths is not None
100
+ ):
101
+ # Validate that the amount of files we are about to generate does not put us higher than the limit
102
+ if (
103
+ self._state_view.files.get_filecount()
104
+ + len(abs_reader_substate.configured_wavelengths)
105
+ > MAXIMUM_CSV_FILE_LIMIT
106
+ ):
107
+ raise StorageLimitReachedError(
108
+ message=f"Attempt to write file {params.fileName} exceeds file creation limit of {MAXIMUM_CSV_FILE_LIMIT} files."
109
+ )
110
+
111
+ asbsorbance_result: Dict[int, Dict[str, float]] = {}
112
+ transform_results = []
113
+ # Handle the measurement and begin building data for return
114
+ if abs_reader is not None:
115
+ start_time = datetime.now()
116
+ results = await abs_reader.start_measure()
117
+ finish_time = datetime.now()
118
+ if abs_reader._measurement_config is not None:
119
+ sample_wavelengths = abs_reader._measurement_config.sample_wavelengths
120
+ for wavelength, result in zip(sample_wavelengths, results):
121
+ converted_values = (
122
+ self._state_view.modules.convert_absorbance_reader_data_points(
123
+ data=result
124
+ )
125
+ )
126
+ asbsorbance_result[wavelength] = converted_values
127
+ transform_results.append(
128
+ ReadData.model_construct(
129
+ wavelength=wavelength, data=converted_values
130
+ )
131
+ )
132
+ # Handle the virtual module case for data creation (all zeroes)
133
+ elif self._state_view.config.use_virtual_modules:
134
+ start_time = finish_time = datetime.now()
135
+ if abs_reader_substate.configured_wavelengths is not None:
136
+ for wavelength in abs_reader_substate.configured_wavelengths:
137
+ converted_values = (
138
+ self._state_view.modules.convert_absorbance_reader_data_points(
139
+ data=[0] * 96
140
+ )
141
+ )
142
+ asbsorbance_result[wavelength] = converted_values
143
+ transform_results.append(
144
+ ReadData.model_construct(
145
+ wavelength=wavelength, data=converted_values
146
+ )
147
+ )
148
+ else:
149
+ raise CannotPerformModuleAction(
150
+ "Plate Reader data cannot be requested with a module that has not been initialized."
151
+ )
152
+
153
+ state_update.set_absorbance_reader_data(
154
+ module_id=abs_reader_substate.module_id, read_result=asbsorbance_result
155
+ )
156
+ # TODO (cb, 10-17-2024): FILE PROVIDER - Some day we may want to break the file provider behavior into a seperate API function.
157
+ # When this happens, we probably will to have the change the command results handler we utilize to track file IDs in engine.
158
+ # Today, the action handler for the FileStore looks for a ReadAbsorbanceResult command action, this will need to be delinked.
159
+
160
+ # Begin interfacing with the file provider if the user provided a filename
161
+ file_ids: list[str] = []
162
+ if params.fileName is not None:
163
+ # Create the Plate Reader Transform
164
+ plate_read_result = PlateReaderData.model_construct(
165
+ read_results=transform_results,
166
+ reference_wavelength=abs_reader_substate.reference_wavelength,
167
+ start_time=start_time,
168
+ finish_time=finish_time,
169
+ serial_number=abs_reader.serial_number
170
+ if (abs_reader is not None and abs_reader.serial_number is not None)
171
+ else "VIRTUAL_SERIAL",
172
+ )
173
+
174
+ if isinstance(plate_read_result, PlateReaderData):
175
+ # Write a CSV file for each of the measurements taken
176
+ for measurement in plate_read_result.read_results:
177
+ file_id = await self._file_provider.write_csv(
178
+ write_data=plate_read_result.build_generic_csv(
179
+ filename=params.fileName,
180
+ measurement=measurement,
181
+ )
182
+ )
183
+ file_ids.append(file_id)
184
+
185
+ state_update.files_added = update_types.FilesAddedUpdate(
186
+ file_ids=file_ids
187
+ )
188
+ # Return success data to api
189
+ return SuccessData(
190
+ public=ReadAbsorbanceResult(
191
+ data=asbsorbance_result,
192
+ fileIds=file_ids,
193
+ ),
194
+ state_update=state_update,
195
+ )
196
+
197
+ state_update.files_added = update_types.FilesAddedUpdate(file_ids=file_ids)
198
+
199
+ return SuccessData(
200
+ public=ReadAbsorbanceResult(
201
+ data=asbsorbance_result,
202
+ fileIds=file_ids,
203
+ ),
204
+ state_update=state_update,
205
+ )
206
+
207
+
208
+ class ReadAbsorbance(
209
+ BaseCommand[ReadAbsorbanceParams, ReadAbsorbanceResult, ErrorOccurrence]
210
+ ):
211
+ """A command to execute an Absorbance Reader measurement."""
212
+
213
+ commandType: ReadAbsorbanceCommandType = "absorbanceReader/read"
214
+ params: ReadAbsorbanceParams
215
+ result: Optional[ReadAbsorbanceResult] = None
216
+
217
+ _ImplementationCls: Type[ReadAbsorbanceImpl] = ReadAbsorbanceImpl
218
+
219
+
220
+ class ReadAbsorbanceCreate(BaseCommandCreate[ReadAbsorbanceParams]):
221
+ """A request to execute an Absorbance Reader measurement."""
222
+
223
+ commandType: ReadAbsorbanceCommandType = "absorbanceReader/read"
224
+ params: ReadAbsorbanceParams
225
+
226
+ _CommandCls: Type[ReadAbsorbance] = ReadAbsorbance
@@ -0,0 +1,162 @@
1
+ """AirGap in place command request, result, and implementation models."""
2
+
3
+ from __future__ import annotations
4
+ from typing import TYPE_CHECKING, Optional, Type, Union
5
+ from typing_extensions import Literal
6
+
7
+ from opentrons_shared_data.errors.exceptions import PipetteOverpressureError
8
+
9
+ from opentrons.hardware_control import HardwareControlAPI
10
+
11
+ from .pipetting_common import (
12
+ PipetteIdMixin,
13
+ AspirateVolumeMixin,
14
+ FlowRateMixin,
15
+ BaseLiquidHandlingResult,
16
+ OverpressureError,
17
+ DEFAULT_CORRECTION_VOLUME,
18
+ )
19
+ from .command import (
20
+ AbstractCommandImpl,
21
+ BaseCommand,
22
+ BaseCommandCreate,
23
+ SuccessData,
24
+ DefinedErrorData,
25
+ )
26
+ from ..errors.error_occurrence import ErrorOccurrence
27
+ from ..errors.exceptions import PipetteNotReadyToAspirateError
28
+ from ..state.update_types import StateUpdate
29
+ from ..types import AspiratedFluid, FluidKind
30
+
31
+ if TYPE_CHECKING:
32
+ from ..execution import PipettingHandler, GantryMover
33
+ from ..resources import ModelUtils
34
+ from ..state.state import StateView
35
+ from ..notes import CommandNoteAdder
36
+
37
+ AirGapInPlaceCommandType = Literal["airGapInPlace"]
38
+
39
+
40
+ class AirGapInPlaceParams(PipetteIdMixin, AspirateVolumeMixin, FlowRateMixin):
41
+ """Payload required to air gap in place."""
42
+
43
+ pass
44
+
45
+
46
+ class AirGapInPlaceResult(BaseLiquidHandlingResult):
47
+ """Result data from the execution of a AirGapInPlace command."""
48
+
49
+ pass
50
+
51
+
52
+ _ExecuteReturn = Union[
53
+ SuccessData[AirGapInPlaceResult],
54
+ DefinedErrorData[OverpressureError],
55
+ ]
56
+
57
+
58
+ class AirGapInPlaceImplementation(
59
+ AbstractCommandImpl[AirGapInPlaceParams, _ExecuteReturn]
60
+ ):
61
+ """AirGapInPlace command implementation."""
62
+
63
+ def __init__(
64
+ self,
65
+ pipetting: PipettingHandler,
66
+ hardware_api: HardwareControlAPI,
67
+ state_view: StateView,
68
+ command_note_adder: CommandNoteAdder,
69
+ model_utils: ModelUtils,
70
+ gantry_mover: GantryMover,
71
+ **kwargs: object,
72
+ ) -> None:
73
+ self._pipetting = pipetting
74
+ self._state_view = state_view
75
+ self._hardware_api = hardware_api
76
+ self._command_note_adder = command_note_adder
77
+ self._model_utils = model_utils
78
+ self._gantry_mover = gantry_mover
79
+
80
+ async def execute(self, params: AirGapInPlaceParams) -> _ExecuteReturn:
81
+ """Air gap without moving the pipette.
82
+
83
+ Raises:
84
+ TipNotAttachedError: if no tip is attached to the pipette.
85
+ PipetteNotReadyToAirGapError: pipette plunger is not ready.
86
+ """
87
+ ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
88
+ pipette_id=params.pipetteId
89
+ )
90
+ if not ready_to_aspirate:
91
+ raise PipetteNotReadyToAspirateError(
92
+ "Pipette cannot air gap in place because a previous dispense or blowout"
93
+ " pushed the plunger beyond the bottom position."
94
+ " The subsequent aspirate must be from a specific well so the plunger"
95
+ " can be reset in a known safe position."
96
+ )
97
+
98
+ state_update = StateUpdate()
99
+
100
+ try:
101
+ current_position = await self._gantry_mover.get_position(params.pipetteId)
102
+ volume = await self._pipetting.aspirate_in_place(
103
+ pipette_id=params.pipetteId,
104
+ volume=params.volume,
105
+ flow_rate=params.flowRate,
106
+ command_note_adder=self._command_note_adder,
107
+ correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
108
+ )
109
+ except PipetteOverpressureError as e:
110
+ return DefinedErrorData(
111
+ public=OverpressureError(
112
+ id=self._model_utils.generate_id(),
113
+ createdAt=self._model_utils.get_timestamp(),
114
+ wrappedErrors=[
115
+ ErrorOccurrence.from_failed(
116
+ id=self._model_utils.generate_id(),
117
+ createdAt=self._model_utils.get_timestamp(),
118
+ error=e,
119
+ )
120
+ ],
121
+ errorInfo=(
122
+ {
123
+ "retryLocation": (
124
+ current_position.x,
125
+ current_position.y,
126
+ current_position.z,
127
+ )
128
+ }
129
+ ),
130
+ ),
131
+ state_update=state_update,
132
+ )
133
+ else:
134
+ state_update.set_fluid_aspirated(
135
+ pipette_id=params.pipetteId,
136
+ fluid=AspiratedFluid(kind=FluidKind.AIR, volume=volume),
137
+ )
138
+ return SuccessData(
139
+ public=AirGapInPlaceResult(volume=volume),
140
+ state_update=state_update,
141
+ )
142
+
143
+
144
+ class AirGapInPlace(
145
+ BaseCommand[AirGapInPlaceParams, AirGapInPlaceResult, OverpressureError]
146
+ ):
147
+ """AirGapInPlace command model."""
148
+
149
+ commandType: AirGapInPlaceCommandType = "airGapInPlace"
150
+ params: AirGapInPlaceParams
151
+ result: Optional[AirGapInPlaceResult] = None
152
+
153
+ _ImplementationCls: Type[AirGapInPlaceImplementation] = AirGapInPlaceImplementation
154
+
155
+
156
+ class AirGapInPlaceCreate(BaseCommandCreate[AirGapInPlaceParams]):
157
+ """AirGapInPlace command request model."""
158
+
159
+ commandType: AirGapInPlaceCommandType = "airGapInPlace"
160
+ params: AirGapInPlaceParams
161
+
162
+ _CommandCls: Type[AirGapInPlace] = AirGapInPlace
@@ -0,0 +1,244 @@
1
+ """Aspirate command request, result, and implementation models."""
2
+
3
+ from __future__ import annotations
4
+ from typing import TYPE_CHECKING, Optional, Type, Union
5
+ from typing_extensions import Literal
6
+
7
+ from .pipetting_common import (
8
+ OverpressureError,
9
+ PipetteIdMixin,
10
+ AspirateVolumeMixin,
11
+ FlowRateMixin,
12
+ BaseLiquidHandlingResult,
13
+ aspirate_in_place,
14
+ prepare_for_aspirate,
15
+ DEFAULT_CORRECTION_VOLUME,
16
+ )
17
+ from .movement_common import (
18
+ LiquidHandlingWellLocationMixin,
19
+ DestinationPositionResult,
20
+ StallOrCollisionError,
21
+ move_to_well,
22
+ )
23
+ from .command import (
24
+ AbstractCommandImpl,
25
+ BaseCommand,
26
+ BaseCommandCreate,
27
+ DefinedErrorData,
28
+ SuccessData,
29
+ )
30
+
31
+ from opentrons.hardware_control import HardwareControlAPI
32
+
33
+ from ..state.update_types import StateUpdate, CLEAR
34
+ from ..types import (
35
+ WellLocation,
36
+ WellOrigin,
37
+ CurrentWell,
38
+ )
39
+
40
+ if TYPE_CHECKING:
41
+ from ..execution import MovementHandler, PipettingHandler
42
+ from ..resources import ModelUtils
43
+ from ..state.state import StateView
44
+ from ..notes import CommandNoteAdder
45
+
46
+
47
+ AspirateCommandType = Literal["aspirate"]
48
+
49
+
50
+ class AspirateParams(
51
+ PipetteIdMixin,
52
+ AspirateVolumeMixin,
53
+ FlowRateMixin,
54
+ LiquidHandlingWellLocationMixin,
55
+ ):
56
+ """Parameters required to aspirate from a specific well."""
57
+
58
+ pass
59
+
60
+
61
+ class AspirateResult(BaseLiquidHandlingResult, DestinationPositionResult):
62
+ """Result data from execution of an Aspirate command."""
63
+
64
+ pass
65
+
66
+
67
+ _ExecuteReturn = Union[
68
+ SuccessData[AspirateResult],
69
+ DefinedErrorData[OverpressureError] | DefinedErrorData[StallOrCollisionError],
70
+ ]
71
+
72
+
73
+ class AspirateImplementation(AbstractCommandImpl[AspirateParams, _ExecuteReturn]):
74
+ """Aspirate command implementation."""
75
+
76
+ def __init__(
77
+ self,
78
+ pipetting: PipettingHandler,
79
+ state_view: StateView,
80
+ hardware_api: HardwareControlAPI,
81
+ movement: MovementHandler,
82
+ command_note_adder: CommandNoteAdder,
83
+ model_utils: ModelUtils,
84
+ **kwargs: object,
85
+ ) -> None:
86
+ self._pipetting = pipetting
87
+ self._state_view = state_view
88
+ self._hardware_api = hardware_api
89
+ self._movement = movement
90
+ self._command_note_adder = command_note_adder
91
+ self._model_utils = model_utils
92
+
93
+ async def execute(self, params: AspirateParams) -> _ExecuteReturn:
94
+ """Move to and aspirate from the requested well.
95
+
96
+ Raises:
97
+ TipNotAttachedError: if no tip is attached to the pipette.
98
+ """
99
+ pipette_id = params.pipetteId
100
+ labware_id = params.labwareId
101
+ well_name = params.wellName
102
+ well_location = params.wellLocation
103
+
104
+ state_update = StateUpdate()
105
+
106
+ final_location = self._state_view.geometry.get_well_position(
107
+ labware_id=labware_id,
108
+ well_name=well_name,
109
+ well_location=well_location,
110
+ operation_volume=-params.volume,
111
+ pipette_id=pipette_id,
112
+ )
113
+
114
+ ready_to_aspirate = self._pipetting.get_is_ready_to_aspirate(
115
+ pipette_id=pipette_id
116
+ )
117
+
118
+ current_well = None
119
+
120
+ if not ready_to_aspirate:
121
+ move_result = await move_to_well(
122
+ movement=self._movement,
123
+ model_utils=self._model_utils,
124
+ pipette_id=pipette_id,
125
+ labware_id=labware_id,
126
+ well_name=well_name,
127
+ well_location=WellLocation(origin=WellOrigin.TOP),
128
+ )
129
+ state_update.append(move_result.state_update)
130
+ if isinstance(move_result, DefinedErrorData):
131
+ return DefinedErrorData(move_result.public, state_update=state_update)
132
+
133
+ prepare_result = await prepare_for_aspirate(
134
+ pipette_id=pipette_id,
135
+ pipetting=self._pipetting,
136
+ model_utils=self._model_utils,
137
+ # Note that the retryLocation is the final location, inside the liquid,
138
+ # because that's where we'd want the client to try re-aspirating if this
139
+ # command fails and the run enters error recovery.
140
+ location_if_error={"retryLocation": final_location},
141
+ )
142
+ state_update.append(prepare_result.state_update)
143
+ if isinstance(prepare_result, DefinedErrorData):
144
+ return DefinedErrorData(
145
+ public=prepare_result.public, state_update=state_update
146
+ )
147
+
148
+ # set our current deck location to the well now that we've made
149
+ # an intermediate move for the "prepare for aspirate" step
150
+ current_well = CurrentWell(
151
+ pipette_id=pipette_id,
152
+ labware_id=labware_id,
153
+ well_name=well_name,
154
+ )
155
+ move_result = await move_to_well(
156
+ movement=self._movement,
157
+ model_utils=self._model_utils,
158
+ pipette_id=pipette_id,
159
+ labware_id=labware_id,
160
+ well_name=well_name,
161
+ well_location=well_location,
162
+ current_well=current_well,
163
+ operation_volume=-params.volume,
164
+ )
165
+ state_update.append(move_result.state_update)
166
+ if isinstance(move_result, DefinedErrorData):
167
+ return DefinedErrorData(
168
+ public=move_result.public, state_update=state_update
169
+ )
170
+
171
+ aspirate_result = await aspirate_in_place(
172
+ pipette_id=pipette_id,
173
+ volume=params.volume,
174
+ flow_rate=params.flowRate,
175
+ location_if_error={
176
+ "retryLocation": (
177
+ move_result.public.position.x,
178
+ move_result.public.position.y,
179
+ move_result.public.position.z,
180
+ )
181
+ },
182
+ command_note_adder=self._command_note_adder,
183
+ pipetting=self._pipetting,
184
+ model_utils=self._model_utils,
185
+ correction_volume=params.correctionVolume or DEFAULT_CORRECTION_VOLUME,
186
+ )
187
+ state_update.append(aspirate_result.state_update)
188
+ if isinstance(aspirate_result, DefinedErrorData):
189
+ state_update.set_liquid_operated(
190
+ labware_id=labware_id,
191
+ well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
192
+ labware_id,
193
+ well_name,
194
+ params.pipetteId,
195
+ ),
196
+ volume_added=CLEAR,
197
+ )
198
+ return DefinedErrorData(
199
+ public=aspirate_result.public, state_update=state_update
200
+ )
201
+
202
+ state_update.set_liquid_operated(
203
+ labware_id=labware_id,
204
+ well_names=self._state_view.geometry.get_wells_covered_by_pipette_with_active_well(
205
+ labware_id, well_name, pipette_id
206
+ ),
207
+ volume_added=-aspirate_result.public.volume
208
+ * self._state_view.geometry.get_nozzles_per_well(
209
+ labware_id,
210
+ well_name,
211
+ params.pipetteId,
212
+ ),
213
+ )
214
+
215
+ return SuccessData(
216
+ public=AspirateResult(
217
+ volume=aspirate_result.public.volume,
218
+ position=move_result.public.position,
219
+ ),
220
+ state_update=state_update,
221
+ )
222
+
223
+
224
+ class Aspirate(
225
+ BaseCommand[
226
+ AspirateParams, AspirateResult, OverpressureError | StallOrCollisionError
227
+ ]
228
+ ):
229
+ """Aspirate command model."""
230
+
231
+ commandType: AspirateCommandType = "aspirate"
232
+ params: AspirateParams
233
+ result: Optional[AspirateResult] = None
234
+
235
+ _ImplementationCls: Type[AspirateImplementation] = AspirateImplementation
236
+
237
+
238
+ class AspirateCreate(BaseCommandCreate[AspirateParams]):
239
+ """Create aspirate command request model."""
240
+
241
+ commandType: AspirateCommandType = "aspirate"
242
+ params: AspirateParams
243
+
244
+ _CommandCls: Type[Aspirate] = Aspirate