opentrons 8.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of opentrons might be problematic. Click here for more details.

Files changed (601) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +557 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +187 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +557 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/scripts/update_module_fw.py +274 -0
  200. opentrons/hardware_control/simulator_setup.py +260 -0
  201. opentrons/hardware_control/thread_manager.py +431 -0
  202. opentrons/hardware_control/threaded_async_lock.py +97 -0
  203. opentrons/hardware_control/types.py +792 -0
  204. opentrons/hardware_control/util.py +234 -0
  205. opentrons/legacy_broker.py +53 -0
  206. opentrons/legacy_commands/__init__.py +1 -0
  207. opentrons/legacy_commands/commands.py +483 -0
  208. opentrons/legacy_commands/helpers.py +153 -0
  209. opentrons/legacy_commands/module_commands.py +276 -0
  210. opentrons/legacy_commands/protocol_commands.py +54 -0
  211. opentrons/legacy_commands/publisher.py +155 -0
  212. opentrons/legacy_commands/robot_commands.py +51 -0
  213. opentrons/legacy_commands/types.py +1186 -0
  214. opentrons/motion_planning/__init__.py +32 -0
  215. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  216. opentrons/motion_planning/deck_conflict.py +501 -0
  217. opentrons/motion_planning/errors.py +35 -0
  218. opentrons/motion_planning/types.py +42 -0
  219. opentrons/motion_planning/waypoints.py +218 -0
  220. opentrons/ordered_set.py +138 -0
  221. opentrons/protocol_api/__init__.py +105 -0
  222. opentrons/protocol_api/_liquid.py +157 -0
  223. opentrons/protocol_api/_liquid_properties.py +814 -0
  224. opentrons/protocol_api/_nozzle_layout.py +31 -0
  225. opentrons/protocol_api/_parameter_context.py +300 -0
  226. opentrons/protocol_api/_parameters.py +31 -0
  227. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  228. opentrons/protocol_api/_types.py +43 -0
  229. opentrons/protocol_api/config.py +23 -0
  230. opentrons/protocol_api/core/__init__.py +23 -0
  231. opentrons/protocol_api/core/common.py +33 -0
  232. opentrons/protocol_api/core/core_map.py +74 -0
  233. opentrons/protocol_api/core/engine/__init__.py +22 -0
  234. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  235. opentrons/protocol_api/core/engine/deck_conflict.py +400 -0
  236. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  237. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  238. opentrons/protocol_api/core/engine/labware.py +238 -0
  239. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  240. opentrons/protocol_api/core/engine/module_core.py +1027 -0
  241. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  242. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  243. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  244. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  245. opentrons/protocol_api/core/engine/robot.py +139 -0
  246. opentrons/protocol_api/core/engine/stringify.py +74 -0
  247. opentrons/protocol_api/core/engine/transfer_components_executor.py +1006 -0
  248. opentrons/protocol_api/core/engine/well.py +241 -0
  249. opentrons/protocol_api/core/instrument.py +459 -0
  250. opentrons/protocol_api/core/labware.py +151 -0
  251. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  252. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  253. opentrons/protocol_api/core/legacy/deck.py +369 -0
  254. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  255. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  256. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  257. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  258. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  259. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  260. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  261. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  262. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  263. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  265. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  266. opentrons/protocol_api/core/module.py +484 -0
  267. opentrons/protocol_api/core/protocol.py +311 -0
  268. opentrons/protocol_api/core/robot.py +51 -0
  269. opentrons/protocol_api/core/well.py +116 -0
  270. opentrons/protocol_api/core/well_grid.py +45 -0
  271. opentrons/protocol_api/create_protocol_context.py +177 -0
  272. opentrons/protocol_api/deck.py +223 -0
  273. opentrons/protocol_api/disposal_locations.py +244 -0
  274. opentrons/protocol_api/instrument_context.py +3272 -0
  275. opentrons/protocol_api/labware.py +1579 -0
  276. opentrons/protocol_api/module_contexts.py +1447 -0
  277. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  278. opentrons/protocol_api/protocol_context.py +1688 -0
  279. opentrons/protocol_api/robot_context.py +303 -0
  280. opentrons/protocol_api/validation.py +761 -0
  281. opentrons/protocol_engine/__init__.py +155 -0
  282. opentrons/protocol_engine/actions/__init__.py +65 -0
  283. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  284. opentrons/protocol_engine/actions/action_handler.py +13 -0
  285. opentrons/protocol_engine/actions/actions.py +302 -0
  286. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  287. opentrons/protocol_engine/clients/__init__.py +5 -0
  288. opentrons/protocol_engine/clients/sync_client.py +174 -0
  289. opentrons/protocol_engine/clients/transports.py +197 -0
  290. opentrons/protocol_engine/commands/__init__.py +757 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  296. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  297. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  298. opentrons/protocol_engine/commands/aspirate.py +244 -0
  299. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  300. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  301. opentrons/protocol_engine/commands/blow_out.py +146 -0
  302. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  303. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  306. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  307. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  308. opentrons/protocol_engine/commands/command.py +308 -0
  309. opentrons/protocol_engine/commands/command_unions.py +974 -0
  310. opentrons/protocol_engine/commands/comment.py +57 -0
  311. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  312. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  313. opentrons/protocol_engine/commands/custom.py +67 -0
  314. opentrons/protocol_engine/commands/dispense.py +194 -0
  315. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  316. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  317. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  318. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  319. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  320. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  321. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  322. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  323. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  324. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  325. opentrons/protocol_engine/commands/flex_stacker/store.py +339 -0
  326. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  327. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  328. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  329. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  330. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  331. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  333. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  334. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  336. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  337. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  338. opentrons/protocol_engine/commands/home.py +100 -0
  339. opentrons/protocol_engine/commands/identify_module.py +86 -0
  340. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  341. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  342. opentrons/protocol_engine/commands/load_labware.py +210 -0
  343. opentrons/protocol_engine/commands/load_lid.py +154 -0
  344. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  345. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  346. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  347. opentrons/protocol_engine/commands/load_module.py +223 -0
  348. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  349. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  350. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  351. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  352. opentrons/protocol_engine/commands/move_labware.py +546 -0
  353. opentrons/protocol_engine/commands/move_relative.py +102 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  355. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  356. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  357. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  358. opentrons/protocol_engine/commands/movement_common.py +338 -0
  359. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  360. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  361. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  362. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  363. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  364. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  365. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  366. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  367. opentrons/protocol_engine/commands/robot/common.py +18 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  369. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  370. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  371. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  372. opentrons/protocol_engine/commands/save_position.py +109 -0
  373. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  374. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  375. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  376. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  377. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  378. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  379. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  380. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  381. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  384. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  386. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  388. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  390. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  391. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  392. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  401. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  402. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  403. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  404. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  405. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  406. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  407. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  408. opentrons/protocol_engine/engine_support.py +28 -0
  409. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  410. opentrons/protocol_engine/errors/__init__.py +191 -0
  411. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  412. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  413. opentrons/protocol_engine/execution/__init__.py +50 -0
  414. opentrons/protocol_engine/execution/command_executor.py +216 -0
  415. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  416. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  417. opentrons/protocol_engine/execution/equipment.py +819 -0
  418. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  419. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  420. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  421. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  422. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  423. opentrons/protocol_engine/execution/movement.py +350 -0
  424. opentrons/protocol_engine/execution/pipetting.py +607 -0
  425. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  426. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  427. opentrons/protocol_engine/execution/run_control.py +33 -0
  428. opentrons/protocol_engine/execution/status_bar.py +34 -0
  429. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  430. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  431. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  432. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  433. opentrons/protocol_engine/notes/__init__.py +17 -0
  434. opentrons/protocol_engine/notes/notes.py +59 -0
  435. opentrons/protocol_engine/plugins.py +104 -0
  436. opentrons/protocol_engine/protocol_engine.py +683 -0
  437. opentrons/protocol_engine/resources/__init__.py +26 -0
  438. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  439. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  440. opentrons/protocol_engine/resources/file_provider.py +161 -0
  441. opentrons/protocol_engine/resources/fixture_validation.py +68 -0
  442. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  443. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  444. opentrons/protocol_engine/resources/model_utils.py +32 -0
  445. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  446. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  447. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  448. opentrons/protocol_engine/slot_standardization.py +128 -0
  449. opentrons/protocol_engine/state/__init__.py +1 -0
  450. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  451. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  452. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  453. opentrons/protocol_engine/state/_move_types.py +83 -0
  454. opentrons/protocol_engine/state/_well_math.py +193 -0
  455. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  456. opentrons/protocol_engine/state/command_history.py +309 -0
  457. opentrons/protocol_engine/state/commands.py +1164 -0
  458. opentrons/protocol_engine/state/config.py +39 -0
  459. opentrons/protocol_engine/state/files.py +57 -0
  460. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  461. opentrons/protocol_engine/state/geometry.py +2408 -0
  462. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  463. opentrons/protocol_engine/state/labware.py +1432 -0
  464. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  465. opentrons/protocol_engine/state/liquids.py +73 -0
  466. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  467. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  468. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  469. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  471. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  472. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  473. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  474. opentrons/protocol_engine/state/modules.py +1515 -0
  475. opentrons/protocol_engine/state/motion.py +373 -0
  476. opentrons/protocol_engine/state/pipettes.py +905 -0
  477. opentrons/protocol_engine/state/state.py +421 -0
  478. opentrons/protocol_engine/state/state_summary.py +36 -0
  479. opentrons/protocol_engine/state/tips.py +420 -0
  480. opentrons/protocol_engine/state/update_types.py +904 -0
  481. opentrons/protocol_engine/state/wells.py +290 -0
  482. opentrons/protocol_engine/types/__init__.py +310 -0
  483. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  484. opentrons/protocol_engine/types/command_annotations.py +53 -0
  485. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  486. opentrons/protocol_engine/types/execution.py +96 -0
  487. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  488. opentrons/protocol_engine/types/instrument.py +47 -0
  489. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  490. opentrons/protocol_engine/types/labware.py +131 -0
  491. opentrons/protocol_engine/types/labware_movement.py +22 -0
  492. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  493. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  494. opentrons/protocol_engine/types/liquid.py +40 -0
  495. opentrons/protocol_engine/types/liquid_class.py +59 -0
  496. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  497. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  498. opentrons/protocol_engine/types/location.py +194 -0
  499. opentrons/protocol_engine/types/module.py +310 -0
  500. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  501. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  502. opentrons/protocol_engine/types/tip.py +18 -0
  503. opentrons/protocol_engine/types/util.py +21 -0
  504. opentrons/protocol_engine/types/well_position.py +124 -0
  505. opentrons/protocol_reader/__init__.py +37 -0
  506. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  507. opentrons/protocol_reader/file_format_validator.py +152 -0
  508. opentrons/protocol_reader/file_hasher.py +27 -0
  509. opentrons/protocol_reader/file_identifier.py +284 -0
  510. opentrons/protocol_reader/file_reader_writer.py +90 -0
  511. opentrons/protocol_reader/input_file.py +16 -0
  512. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  513. opentrons/protocol_reader/protocol_reader.py +188 -0
  514. opentrons/protocol_reader/protocol_source.py +124 -0
  515. opentrons/protocol_reader/role_analyzer.py +86 -0
  516. opentrons/protocol_runner/__init__.py +26 -0
  517. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  518. opentrons/protocol_runner/json_file_reader.py +55 -0
  519. opentrons/protocol_runner/json_translator.py +314 -0
  520. opentrons/protocol_runner/legacy_command_mapper.py +852 -0
  521. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  522. opentrons/protocol_runner/protocol_runner.py +530 -0
  523. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  524. opentrons/protocol_runner/run_orchestrator.py +496 -0
  525. opentrons/protocol_runner/task_queue.py +95 -0
  526. opentrons/protocols/__init__.py +6 -0
  527. opentrons/protocols/advanced_control/__init__.py +0 -0
  528. opentrons/protocols/advanced_control/common.py +38 -0
  529. opentrons/protocols/advanced_control/mix.py +60 -0
  530. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  531. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  532. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  533. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  534. opentrons/protocols/api_support/__init__.py +0 -0
  535. opentrons/protocols/api_support/constants.py +8 -0
  536. opentrons/protocols/api_support/deck_type.py +110 -0
  537. opentrons/protocols/api_support/definitions.py +18 -0
  538. opentrons/protocols/api_support/instrument.py +151 -0
  539. opentrons/protocols/api_support/labware_like.py +233 -0
  540. opentrons/protocols/api_support/tip_tracker.py +175 -0
  541. opentrons/protocols/api_support/types.py +32 -0
  542. opentrons/protocols/api_support/util.py +403 -0
  543. opentrons/protocols/bundle.py +89 -0
  544. opentrons/protocols/duration/__init__.py +4 -0
  545. opentrons/protocols/duration/errors.py +5 -0
  546. opentrons/protocols/duration/estimator.py +628 -0
  547. opentrons/protocols/execution/__init__.py +0 -0
  548. opentrons/protocols/execution/dev_types.py +181 -0
  549. opentrons/protocols/execution/errors.py +40 -0
  550. opentrons/protocols/execution/execute.py +84 -0
  551. opentrons/protocols/execution/execute_json_v3.py +275 -0
  552. opentrons/protocols/execution/execute_json_v4.py +359 -0
  553. opentrons/protocols/execution/execute_json_v5.py +28 -0
  554. opentrons/protocols/execution/execute_python.py +169 -0
  555. opentrons/protocols/execution/json_dispatchers.py +87 -0
  556. opentrons/protocols/execution/types.py +7 -0
  557. opentrons/protocols/geometry/__init__.py +0 -0
  558. opentrons/protocols/geometry/planning.py +297 -0
  559. opentrons/protocols/labware.py +312 -0
  560. opentrons/protocols/models/__init__.py +0 -0
  561. opentrons/protocols/models/json_protocol.py +679 -0
  562. opentrons/protocols/parameters/__init__.py +0 -0
  563. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  564. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  565. opentrons/protocols/parameters/exceptions.py +34 -0
  566. opentrons/protocols/parameters/parameter_definition.py +272 -0
  567. opentrons/protocols/parameters/types.py +17 -0
  568. opentrons/protocols/parameters/validation.py +267 -0
  569. opentrons/protocols/parse.py +671 -0
  570. opentrons/protocols/types.py +159 -0
  571. opentrons/py.typed +0 -0
  572. opentrons/resources/scripts/lpc21isp +0 -0
  573. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  574. opentrons/simulate.py +1065 -0
  575. opentrons/system/__init__.py +6 -0
  576. opentrons/system/camera.py +51 -0
  577. opentrons/system/log_control.py +59 -0
  578. opentrons/system/nmcli.py +856 -0
  579. opentrons/system/resin.py +24 -0
  580. opentrons/system/smoothie_update.py +15 -0
  581. opentrons/system/wifi.py +204 -0
  582. opentrons/tools/__init__.py +0 -0
  583. opentrons/tools/args_handler.py +22 -0
  584. opentrons/tools/write_pipette_memory.py +157 -0
  585. opentrons/types.py +618 -0
  586. opentrons/util/__init__.py +1 -0
  587. opentrons/util/async_helpers.py +166 -0
  588. opentrons/util/broker.py +84 -0
  589. opentrons/util/change_notifier.py +47 -0
  590. opentrons/util/entrypoint_util.py +278 -0
  591. opentrons/util/get_union_elements.py +26 -0
  592. opentrons/util/helpers.py +6 -0
  593. opentrons/util/linal.py +178 -0
  594. opentrons/util/logging_config.py +265 -0
  595. opentrons/util/logging_queue_handler.py +61 -0
  596. opentrons/util/performance_helpers.py +157 -0
  597. opentrons-8.6.0.dist-info/METADATA +37 -0
  598. opentrons-8.6.0.dist-info/RECORD +601 -0
  599. opentrons-8.6.0.dist-info/WHEEL +4 -0
  600. opentrons-8.6.0.dist-info/entry_points.txt +3 -0
  601. opentrons-8.6.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,223 @@
1
+ """Implementation, request models, and response models for the load module command."""
2
+ from __future__ import annotations
3
+ from typing import TYPE_CHECKING, Optional, Type, Any
4
+ from typing_extensions import Literal
5
+ from pydantic import BaseModel, Field
6
+ from pydantic.json_schema import SkipJsonSchema
7
+
8
+ from opentrons.protocol_engine.state.update_types import StateUpdate
9
+
10
+ from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
11
+ from ..errors.error_occurrence import ErrorOccurrence
12
+ from ..types import (
13
+ DeckSlotLocation,
14
+ AddressableAreaLocation,
15
+ ModuleType,
16
+ ModuleModel,
17
+ )
18
+ from opentrons.types import DeckSlotName
19
+
20
+ from opentrons.protocol_engine.resources import deck_configuration_provider
21
+
22
+
23
+ if TYPE_CHECKING:
24
+ from ..state.state import StateView
25
+ from ..execution import EquipmentHandler
26
+
27
+
28
+ LoadModuleCommandType = Literal["loadModule"]
29
+
30
+
31
+ def _remove_default(s: dict[str, Any]) -> None:
32
+ s.pop("default", None)
33
+
34
+
35
+ class LoadModuleParams(BaseModel):
36
+ """Payload required to load a module."""
37
+
38
+ model: ModuleModel = Field(
39
+ ...,
40
+ description=(
41
+ "The model name of the module to load."
42
+ "\n\n"
43
+ "Protocol Engine will look for a connected module that either"
44
+ " exactly matches this one, or is compatible."
45
+ "\n\n"
46
+ " For example, if you request a `temperatureModuleV1` here,"
47
+ " Protocol Engine might load a `temperatureModuleV1` or a `temperatureModuleV2`."
48
+ "\n\n"
49
+ " The model that it finds connected will be available through `result.model`."
50
+ ),
51
+ )
52
+
53
+ # Note: Our assumption here that a module's position can be boiled down to a
54
+ # single deck slot precludes loading a Thermocycler in its special "shifted slightly
55
+ # to the left" position. This is okay for now because neither the Python Protocol
56
+ # API nor Protocol Designer attempt to support it, either.
57
+ location: DeckSlotLocation = Field(
58
+ ...,
59
+ description=(
60
+ "The location into which this module should be loaded."
61
+ "\n\n"
62
+ "For the Thermocycler Module, which occupies multiple deck slots,"
63
+ " this should be the front-most occupied slot (normally slot 7)."
64
+ ),
65
+ )
66
+
67
+ moduleId: str | SkipJsonSchema[None] = Field(
68
+ None,
69
+ description=(
70
+ "An optional ID to assign to this module."
71
+ " If None, an ID will be generated."
72
+ ),
73
+ json_schema_extra=_remove_default,
74
+ )
75
+
76
+
77
+ class LoadModuleResult(BaseModel):
78
+ """The results of loading a module."""
79
+
80
+ # The `definition` used to exist here, but we intentionally removed it. See #18639.
81
+
82
+ moduleId: str = Field(
83
+ description="An ID to reference this module in subsequent commands."
84
+ )
85
+
86
+ model: ModuleModel = Field(
87
+ ...,
88
+ description=(
89
+ "The hardware model of the connected module."
90
+ " This can be different from the exact model that this command requested."
91
+ " See `params.model`."
92
+ "\n\n"
93
+ "This field is only meaningful in the run's actual execution,"
94
+ " not in the protocol's analysis."
95
+ " In analysis, it will be an arbitrary placeholder."
96
+ ),
97
+ )
98
+
99
+ serialNumber: Optional[str] = Field(
100
+ None,
101
+ description="Hardware serial number of the connected module. "
102
+ "Will be `None` if a module is not electrically connected to the robot (like the Magnetic Block).",
103
+ )
104
+
105
+
106
+ class LoadModuleImplementation(
107
+ AbstractCommandImpl[LoadModuleParams, SuccessData[LoadModuleResult]]
108
+ ):
109
+ """The implementation of the load module command."""
110
+
111
+ def __init__(
112
+ self, equipment: EquipmentHandler, state_view: StateView, **kwargs: object
113
+ ) -> None:
114
+ self._equipment = equipment
115
+ self._state_view = state_view
116
+
117
+ async def execute(self, params: LoadModuleParams) -> SuccessData[LoadModuleResult]:
118
+ """Check that the requested module is attached and assign its identifier."""
119
+ state_update = StateUpdate()
120
+
121
+ module_type = params.model.as_type()
122
+ self._ensure_module_location(params.location.slotName, module_type)
123
+
124
+ if self._state_view.modules.get_deck_supports_module_fixtures():
125
+ addressable_area_module_reference = (
126
+ self._state_view.modules.ensure_and_convert_module_fixture_location(
127
+ deck_slot=params.location.slotName,
128
+ model=params.model,
129
+ )
130
+ )
131
+ else:
132
+ addressable_area_module_reference = params.location.slotName.id
133
+ state_update.set_addressable_area_used(
134
+ addressable_area_name=addressable_area_module_reference
135
+ )
136
+
137
+ self._state_view.addressable_areas.raise_if_area_not_in_deck_configuration(
138
+ addressable_area_module_reference
139
+ )
140
+
141
+ self._state_view.geometry.ensure_location_not_occupied(
142
+ params.location, addressable_area_module_reference
143
+ )
144
+
145
+ if params.model == ModuleModel.MAGNETIC_BLOCK_V1:
146
+ loaded_module = await self._equipment.load_magnetic_block(
147
+ model=params.model,
148
+ location=AddressableAreaLocation(
149
+ addressableAreaName=addressable_area_module_reference
150
+ ),
151
+ module_id=params.moduleId,
152
+ )
153
+ else:
154
+ loaded_module = await self._equipment.load_module(
155
+ model=params.model,
156
+ location=AddressableAreaLocation(
157
+ addressableAreaName=addressable_area_module_reference
158
+ ),
159
+ module_id=params.moduleId,
160
+ )
161
+
162
+ state_update.set_load_module(
163
+ module_id=loaded_module.module_id,
164
+ definition=loaded_module.definition,
165
+ requested_model=params.model,
166
+ serial_number=loaded_module.serial_number,
167
+ slot_name=params.location.slotName,
168
+ )
169
+
170
+ return SuccessData(
171
+ public=LoadModuleResult(
172
+ moduleId=loaded_module.module_id,
173
+ serialNumber=loaded_module.serial_number,
174
+ model=loaded_module.definition.model,
175
+ ),
176
+ state_update=state_update,
177
+ )
178
+
179
+ def _ensure_module_location(
180
+ self, slot: DeckSlotName, module_type: ModuleType
181
+ ) -> None:
182
+ # todo(mm, 2024-12-03): Theoretically, we should be able to deal with
183
+ # addressable areas and deck configurations the same way between OT-2 and Flex.
184
+ # Can this be simplified?
185
+ if self._state_view.config.robot_type == "OT-2 Standard":
186
+ slot_def = self._state_view.addressable_areas.get_slot_definition(slot.id)
187
+ compatible_modules = slot_def["compatibleModuleTypes"]
188
+ if module_type.value not in compatible_modules:
189
+ raise ValueError(
190
+ f"A {module_type.value} cannot be loaded into slot {slot}"
191
+ )
192
+ else:
193
+ cutout_fixture_id = ModuleType.to_module_fixture_id(module_type)
194
+ module_fixture = deck_configuration_provider.get_cutout_fixture(
195
+ cutout_fixture_id,
196
+ self._state_view.labware.get_deck_definition(),
197
+ )
198
+ cutout_id = (
199
+ self._state_view.addressable_areas.get_cutout_id_by_deck_slot_name(slot)
200
+ )
201
+ if cutout_id not in module_fixture["mayMountTo"]:
202
+ raise ValueError(
203
+ f"A {module_type.value} cannot be loaded into slot {slot}"
204
+ )
205
+
206
+
207
+ class LoadModule(BaseCommand[LoadModuleParams, LoadModuleResult, ErrorOccurrence]):
208
+ """The model for a load module command."""
209
+
210
+ commandType: LoadModuleCommandType = "loadModule"
211
+ params: LoadModuleParams
212
+ result: Optional[LoadModuleResult] = None
213
+
214
+ _ImplementationCls: Type[LoadModuleImplementation] = LoadModuleImplementation
215
+
216
+
217
+ class LoadModuleCreate(BaseCommandCreate[LoadModuleParams]):
218
+ """The model for a creation request for a load module command."""
219
+
220
+ commandType: LoadModuleCommandType = "loadModule"
221
+ params: LoadModuleParams
222
+
223
+ _CommandCls: Type[LoadModule] = LoadModule
@@ -0,0 +1,167 @@
1
+ """Load pipette command request, result, and implementation models."""
2
+ from __future__ import annotations
3
+ from typing import TYPE_CHECKING, Optional, Type, Any
4
+
5
+ from pydantic import BaseModel, Field
6
+ from pydantic.json_schema import SkipJsonSchema
7
+ from typing_extensions import Literal
8
+
9
+ from opentrons_shared_data.pipette.pipette_load_name_conversions import (
10
+ convert_to_pipette_name_type,
11
+ )
12
+ from opentrons_shared_data.pipette.types import PipetteGenerationType
13
+ from opentrons_shared_data.robot import user_facing_robot_type
14
+ from opentrons_shared_data.robot.types import RobotTypeEnum
15
+
16
+
17
+ from opentrons_shared_data.pipette.types import PipetteNameType
18
+ from opentrons.types import MountType
19
+
20
+ from opentrons.protocol_engine.state.update_types import StateUpdate
21
+ from .command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
22
+ from ..errors.error_occurrence import ErrorOccurrence
23
+ from ..errors import InvalidSpecificationForRobotTypeError, InvalidLoadPipetteSpecsError
24
+
25
+ if TYPE_CHECKING:
26
+ from ..execution import EquipmentHandler
27
+ from ..state.state import StateView
28
+
29
+
30
+ LoadPipetteCommandType = Literal["loadPipette"]
31
+
32
+
33
+ def _remove_default(s: dict[str, Any]) -> None:
34
+ s.pop("default", None)
35
+
36
+
37
+ class LoadPipetteParams(BaseModel):
38
+ """Payload needed to load a pipette on to a mount."""
39
+
40
+ pipetteName: PipetteNameType = Field(
41
+ ...,
42
+ description="The load name of the pipette to be required.",
43
+ )
44
+ mount: MountType = Field(
45
+ ...,
46
+ description="The mount the pipette should be present on.",
47
+ )
48
+ pipetteId: str | SkipJsonSchema[None] = Field(
49
+ None,
50
+ description="An optional ID to assign to this pipette. If None, an ID "
51
+ "will be generated.",
52
+ json_schema_extra=_remove_default,
53
+ )
54
+ tipOverlapNotAfterVersion: str | SkipJsonSchema[None] = Field(
55
+ None,
56
+ description="A version of tip overlap data to not exceed. The highest-versioned "
57
+ "tip overlap data that does not exceed this version will be used. Versions are "
58
+ "expressed as vN where N is an integer, counting up from v0. If None, the current "
59
+ "highest version will be used.",
60
+ json_schema_extra=_remove_default,
61
+ )
62
+ liquidPresenceDetection: bool | SkipJsonSchema[None] = Field(
63
+ None,
64
+ description="Enable liquid presence detection for this pipette. Defaults to False.",
65
+ json_schema_extra=_remove_default,
66
+ )
67
+
68
+
69
+ class LoadPipetteResult(BaseModel):
70
+ """Result data for executing a LoadPipette."""
71
+
72
+ pipetteId: str = Field(
73
+ ...,
74
+ description="An ID to reference this pipette in subsequent commands.",
75
+ )
76
+
77
+
78
+ class LoadPipetteImplementation(
79
+ AbstractCommandImpl[LoadPipetteParams, SuccessData[LoadPipetteResult]]
80
+ ):
81
+ """Load pipette command implementation."""
82
+
83
+ def __init__(
84
+ self, equipment: EquipmentHandler, state_view: StateView, **kwargs: object
85
+ ) -> None:
86
+ self._equipment = equipment
87
+ self._state_view = state_view
88
+
89
+ async def execute(
90
+ self, params: LoadPipetteParams
91
+ ) -> SuccessData[LoadPipetteResult]:
92
+ """Check that requested pipette is attached and assign its identifier."""
93
+ pipette_generation = convert_to_pipette_name_type(
94
+ params.pipetteName.value
95
+ ).pipette_generation
96
+ robot_type = RobotTypeEnum.robot_literal_to_enum(
97
+ self._state_view.config.robot_type
98
+ )
99
+ if (
100
+ (
101
+ robot_type == RobotTypeEnum.FLEX
102
+ and pipette_generation != PipetteGenerationType.FLEX
103
+ )
104
+ ) or (
105
+ (
106
+ robot_type == RobotTypeEnum.OT2
107
+ and pipette_generation
108
+ not in [PipetteGenerationType.GEN1, PipetteGenerationType.GEN2]
109
+ )
110
+ ):
111
+ raise InvalidSpecificationForRobotTypeError(
112
+ f"Cannot load a {pipette_generation.value.capitalize()} pipette on "
113
+ f"{user_facing_robot_type(robot_type=self._state_view.config.robot_type, include_article=True)}."
114
+ )
115
+
116
+ if params.mount == MountType.EXTENSION:
117
+ raise InvalidLoadPipetteSpecsError(
118
+ "Cannot load a pipette on the EXTENSION mount. Use mount LEFT or RIGHT."
119
+ )
120
+
121
+ loaded_pipette = await self._equipment.load_pipette(
122
+ pipette_name=params.pipetteName,
123
+ mount=params.mount,
124
+ pipette_id=params.pipetteId,
125
+ tip_overlap_version=params.tipOverlapNotAfterVersion,
126
+ )
127
+
128
+ state_update = StateUpdate()
129
+ state_update.set_load_pipette(
130
+ pipette_id=loaded_pipette.pipette_id,
131
+ pipette_name=params.pipetteName,
132
+ mount=params.mount,
133
+ liquid_presence_detection=params.liquidPresenceDetection,
134
+ )
135
+ state_update.update_pipette_config(
136
+ pipette_id=loaded_pipette.pipette_id,
137
+ serial_number=loaded_pipette.serial_number,
138
+ config=loaded_pipette.static_config,
139
+ )
140
+ state_update.set_fluid_unknown(pipette_id=loaded_pipette.pipette_id)
141
+ state_update.set_pipette_ready_to_aspirate(
142
+ pipette_id=loaded_pipette.pipette_id, ready_to_aspirate=False
143
+ ),
144
+
145
+ return SuccessData(
146
+ public=LoadPipetteResult(pipetteId=loaded_pipette.pipette_id),
147
+ state_update=state_update,
148
+ )
149
+
150
+
151
+ class LoadPipette(BaseCommand[LoadPipetteParams, LoadPipetteResult, ErrorOccurrence]):
152
+ """Load pipette command model."""
153
+
154
+ commandType: LoadPipetteCommandType = "loadPipette"
155
+ params: LoadPipetteParams
156
+ result: Optional[LoadPipetteResult] = None
157
+
158
+ _ImplementationCls: Type[LoadPipetteImplementation] = LoadPipetteImplementation
159
+
160
+
161
+ class LoadPipetteCreate(BaseCommandCreate[LoadPipetteParams]):
162
+ """Load pipette command creation request model."""
163
+
164
+ commandType: LoadPipetteCommandType = "loadPipette"
165
+ params: LoadPipetteParams
166
+
167
+ _CommandCls: Type[LoadPipette] = LoadPipette
@@ -0,0 +1,32 @@
1
+ """Magnetic Module protocol commands."""
2
+
3
+ from .disengage import (
4
+ Disengage,
5
+ DisengageCreate,
6
+ DisengageParams,
7
+ DisengageResult,
8
+ DisengageCommandType,
9
+ )
10
+ from .engage import (
11
+ Engage,
12
+ EngageCreate,
13
+ EngageParams,
14
+ EngageResult,
15
+ EngageCommandType,
16
+ )
17
+
18
+
19
+ __all__ = [
20
+ # magneticModule/disengageMagnet
21
+ "Disengage",
22
+ "DisengageCreate",
23
+ "DisengageParams",
24
+ "DisengageResult",
25
+ "DisengageCommandType",
26
+ # magneticModule/engageMagnet
27
+ "Engage",
28
+ "EngageCreate",
29
+ "EngageParams",
30
+ "EngageResult",
31
+ "EngageCommandType",
32
+ ]
@@ -0,0 +1,97 @@
1
+ """Magnetic Module disengage command request, result, and implementation models."""
2
+
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Optional, TYPE_CHECKING
7
+ from typing_extensions import Literal, Type
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
12
+ from ...errors.error_occurrence import ErrorOccurrence
13
+
14
+ if TYPE_CHECKING:
15
+ from opentrons.protocol_engine.execution import EquipmentHandler
16
+ from opentrons.protocol_engine.state.state import StateView
17
+
18
+
19
+ DisengageCommandType = Literal["magneticModule/disengage"]
20
+
21
+
22
+ class DisengageParams(BaseModel):
23
+ """Input data to disengage a Magnetic Module's magnets."""
24
+
25
+ moduleId: str = Field(
26
+ ...,
27
+ description=(
28
+ "The ID of the Magnetic Module whose magnets you want to disengage,"
29
+ " from a prior `loadModule` command."
30
+ ),
31
+ )
32
+
33
+
34
+ class DisengageResult(BaseModel):
35
+ """The result of a Magnetic Module disengage command."""
36
+
37
+ pass
38
+
39
+
40
+ class DisengageImplementation(
41
+ AbstractCommandImpl[DisengageParams, SuccessData[DisengageResult]]
42
+ ):
43
+ """The implementation of a Magnetic Module disengage command."""
44
+
45
+ def __init__(
46
+ self,
47
+ state_view: StateView,
48
+ equipment: EquipmentHandler,
49
+ **unused_dependencies: object,
50
+ ) -> None:
51
+ self._state_view = state_view
52
+ self._equipment = equipment
53
+
54
+ async def execute(self, params: DisengageParams) -> SuccessData[DisengageResult]:
55
+ """Execute a Magnetic Module disengage command.
56
+
57
+ Raises:
58
+ ModuleNotLoadedError: If the given module ID has not been loaded.
59
+ WrongModuleTypeError: If the given module ID has been loaded,
60
+ but it's not a Magnetic Module.
61
+ ModuleNotAttachedError: If the given module ID points to a valid loaded
62
+ Magnetic Module, but that module's hardware wasn't found attached.
63
+ """
64
+ # Allow propagation of ModuleNotLoadedError and WrongModuleTypeError.
65
+ mag_module_substate = self._state_view.modules.get_magnetic_module_substate(
66
+ module_id=params.moduleId
67
+ )
68
+ # Allow propagation of ModuleNotAttachedError.
69
+ hardware_module = self._equipment.get_module_hardware_api(
70
+ mag_module_substate.module_id
71
+ )
72
+
73
+ if hardware_module is not None: # Not virtualizing modules.
74
+ await hardware_module.deactivate()
75
+
76
+ return SuccessData(
77
+ public=DisengageResult(),
78
+ )
79
+
80
+
81
+ class Disengage(BaseCommand[DisengageParams, DisengageResult, ErrorOccurrence]):
82
+ """A command to disengage a Magnetic Module's magnets."""
83
+
84
+ commandType: DisengageCommandType = "magneticModule/disengage"
85
+ params: DisengageParams
86
+ result: Optional[DisengageResult] = None
87
+
88
+ _ImplementationCls: Type[DisengageImplementation] = DisengageImplementation
89
+
90
+
91
+ class DisengageCreate(BaseCommandCreate[DisengageParams]):
92
+ """A request to create a Magnetic Module disengage command."""
93
+
94
+ commandType: DisengageCommandType = "magneticModule/disengage"
95
+ params: DisengageParams
96
+
97
+ _CommandCls: Type[Disengage] = Disengage
@@ -0,0 +1,119 @@
1
+ """Magnetic Module engage command request, result, and implementation models."""
2
+ from __future__ import annotations
3
+ from typing import Optional, TYPE_CHECKING
4
+ from typing_extensions import Literal, Type
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+ from ..command import AbstractCommandImpl, BaseCommand, BaseCommandCreate, SuccessData
9
+ from ...errors.error_occurrence import ErrorOccurrence
10
+
11
+ if TYPE_CHECKING:
12
+ from opentrons.protocol_engine.execution import EquipmentHandler
13
+ from opentrons.protocol_engine.state.state import StateView
14
+
15
+
16
+ EngageCommandType = Literal["magneticModule/engage"]
17
+
18
+
19
+ class EngageParams(BaseModel):
20
+ """Input data to engage a Magnetic Module."""
21
+
22
+ moduleId: str = Field(
23
+ ...,
24
+ description=(
25
+ "The ID of the Magnetic Module whose magnets you want to raise,"
26
+ " from a prior `loadModule` command."
27
+ ),
28
+ )
29
+
30
+ height: float = Field(
31
+ ...,
32
+ description=(
33
+ "How high, in millimeters, to raise the magnets."
34
+ "\n\n"
35
+ "Zero means the tops of the magnets are level with the ledge"
36
+ " that the labware rests on."
37
+ " This will be slightly above the magnets' minimum height,"
38
+ " the hardware home position."
39
+ " Negative values are allowed, to put the magnets below the ledge."
40
+ "\n\n"
41
+ "Units are always true millimeters."
42
+ " This is unlike certain labware definitions,"
43
+ " engage commands in the Python Protocol API,"
44
+ " and engage commands in older versions of the JSON protocol schema."
45
+ " Take care to convert properly."
46
+ ),
47
+ )
48
+
49
+
50
+ class EngageResult(BaseModel):
51
+ """The result of a Magnetic Module engage command."""
52
+
53
+ pass
54
+
55
+
56
+ class EngageImplementation(
57
+ AbstractCommandImpl[EngageParams, SuccessData[EngageResult]]
58
+ ):
59
+ """The implementation of a Magnetic Module engage command."""
60
+
61
+ def __init__(
62
+ self,
63
+ state_view: StateView,
64
+ equipment: EquipmentHandler,
65
+ **unused_dependencies: object,
66
+ ) -> None:
67
+ self._state_view = state_view
68
+ self._equipment = equipment
69
+
70
+ async def execute(self, params: EngageParams) -> SuccessData[EngageResult]:
71
+ """Execute a Magnetic Module engage command.
72
+
73
+ Raises:
74
+ ModuleNotLoadedError: If the given module ID doesn't point to a
75
+ module that's already been loaded.
76
+ WrongModuleTypeError: If the given module ID points to a non-Magnetic
77
+ module.
78
+ ModuleNotAttachedError: If the given module ID points to a valid loaded
79
+ Magnetic Module, but that module's hardware wasn't found attached.
80
+ EngageHeightOutOfRangeError: If the given height is unreachable.
81
+ """
82
+ # Allow propagation of ModuleNotLoadedError and WrongModuleTypeError.
83
+ mag_module_substate = self._state_view.modules.get_magnetic_module_substate(
84
+ module_id=params.moduleId
85
+ )
86
+ # Allow propagation of EngageHeightOutOfRangeError.
87
+ hardware_height = mag_module_substate.calculate_magnet_hardware_height(
88
+ mm_from_base=params.height,
89
+ )
90
+ # Allow propagation of ModuleNotAttachedError.
91
+ hardware_module = self._equipment.get_module_hardware_api(
92
+ mag_module_substate.module_id
93
+ )
94
+
95
+ if hardware_module is not None: # Not virtualizing modules.
96
+ await hardware_module.engage(height=hardware_height)
97
+
98
+ return SuccessData(
99
+ public=EngageResult(),
100
+ )
101
+
102
+
103
+ class Engage(BaseCommand[EngageParams, EngageResult, ErrorOccurrence]):
104
+ """A command to engage a Magnetic Module's magnets."""
105
+
106
+ commandType: EngageCommandType = "magneticModule/engage"
107
+ params: EngageParams
108
+ result: Optional[EngageResult] = None
109
+
110
+ _ImplementationCls: Type[EngageImplementation] = EngageImplementation
111
+
112
+
113
+ class EngageCreate(BaseCommandCreate[EngageParams]):
114
+ """A request to create a Magnetic Module engage command."""
115
+
116
+ commandType: EngageCommandType = "magneticModule/engage"
117
+ params: EngageParams
118
+
119
+ _CommandCls: Type[Engage] = Engage