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,73 @@
1
+ """Validation file for labware role and location checking functions."""
2
+
3
+ from opentrons_shared_data.labware.labware_definition import (
4
+ LabwareDefinition,
5
+ LabwareRole,
6
+ )
7
+
8
+
9
+ def is_flex_trash(load_name: str) -> bool:
10
+ """Check if a labware is a large trash."""
11
+ return load_name == "opentrons_1_trash_3200ml_fixed"
12
+
13
+
14
+ def is_absorbance_reader_lid(load_name: str) -> bool:
15
+ """Check if a labware is an absorbance reader lid."""
16
+ return load_name == "opentrons_flex_lid_absorbance_plate_reader_module"
17
+
18
+
19
+ def is_lid_stack(load_name: str) -> bool:
20
+ """Check if a labware object is a system lid stack object."""
21
+ return load_name == "protocol_engine_lid_stack_object"
22
+
23
+
24
+ def validate_definition_is_labware(definition: LabwareDefinition) -> bool:
25
+ """Validate that one of the definition's allowed roles is `labware`.
26
+
27
+ An empty `allowedRoles` is equivalent to `labware` being the only allowed role.
28
+ """
29
+ return not definition.allowedRoles or LabwareRole.labware in definition.allowedRoles
30
+
31
+
32
+ def validate_definition_is_adapter(definition: LabwareDefinition) -> bool:
33
+ """Validate that one of the definition's allowed roles is `adapter`."""
34
+ return LabwareRole.adapter in definition.allowedRoles
35
+
36
+
37
+ def validate_definition_is_lid(definition: LabwareDefinition) -> bool:
38
+ """Validate that one of the definition's allowed roles is `lid`."""
39
+ return LabwareRole.lid in definition.allowedRoles
40
+
41
+
42
+ def validate_definition_is_system(definition: LabwareDefinition) -> bool:
43
+ """Validate that one of the definition's allowed roles is `system`."""
44
+ return LabwareRole.system in definition.allowedRoles
45
+
46
+
47
+ def validate_labware_can_be_stacked(
48
+ top_labware_definition: LabwareDefinition, below_labware_load_name: str
49
+ ) -> bool:
50
+ """Validate that the labware being loaded onto is in the above labware's stackingOffsetWithLabware definition."""
51
+ return (
52
+ below_labware_load_name in top_labware_definition.stackingOffsetWithLabware
53
+ or (
54
+ "default" in top_labware_definition.stackingOffsetWithLabware
55
+ and top_labware_definition.compatibleParentLabware is None
56
+ )
57
+ )
58
+
59
+
60
+ def validate_labware_can_be_ondeck(definition: LabwareDefinition) -> bool:
61
+ """Validate that the labware being loaded onto the deck can sit in a slot."""
62
+ return (
63
+ definition.parameters.quirks is None
64
+ or "stackingOnly" not in definition.parameters.quirks
65
+ )
66
+
67
+
68
+ def validate_gripper_compatible(definition: LabwareDefinition) -> bool:
69
+ """Validate that the labware definition does not have a quirk disallowing movement with gripper."""
70
+ return (
71
+ definition.parameters.quirks is None
72
+ or "gripperIncompatible" not in definition.parameters.quirks
73
+ )
@@ -0,0 +1,32 @@
1
+ """Unique ID generation provider."""
2
+ from datetime import datetime, timezone
3
+ from uuid import uuid4
4
+ from typing import Optional
5
+
6
+
7
+ class ModelUtils:
8
+ """Common resource model utilities provider."""
9
+
10
+ @staticmethod
11
+ def generate_id(prefix: str = "") -> str:
12
+ """Generate a unique identifier.
13
+
14
+ Uses UUIDv4 for safety in a multiprocessing environment.
15
+
16
+ Params:
17
+ prefix: Prepended to the UUIDv4.
18
+ """
19
+ return prefix + str(uuid4())
20
+
21
+ @staticmethod
22
+ def ensure_id(maybe_id: Optional[str] = None) -> str:
23
+ """Generate a unique identifier only if the given input is None.
24
+
25
+ Uses UUIDv4 for safety in a multiprocessing environment.
26
+ """
27
+ return maybe_id if maybe_id is not None else ModelUtils.generate_id()
28
+
29
+ @staticmethod
30
+ def get_timestamp() -> datetime:
31
+ """Get a timestamp of the current time."""
32
+ return datetime.now(tz=timezone.utc)
@@ -0,0 +1,44 @@
1
+ """Module data resource provider."""
2
+ from typing import Dict
3
+ from opentrons.hardware_control.modules.module_calibration import (
4
+ load_all_module_calibrations,
5
+ )
6
+ from opentrons_shared_data.module import load_definition
7
+
8
+ from opentrons.types import DeckSlotName
9
+ from ..types import (
10
+ ModuleModel,
11
+ ModuleDefinition,
12
+ ModuleOffsetVector,
13
+ ModuleOffsetData,
14
+ DeckSlotLocation,
15
+ )
16
+
17
+
18
+ class ModuleDataProvider:
19
+ """Module data provider."""
20
+
21
+ @staticmethod
22
+ def get_definition(model: ModuleModel) -> ModuleDefinition:
23
+ """Get the module definition."""
24
+ data = load_definition(model_or_loadname=model.value, version="3")
25
+ return ModuleDefinition.model_validate(data)
26
+
27
+ @staticmethod
28
+ def load_module_calibrations() -> Dict[str, ModuleOffsetData]:
29
+ """Load the module calibration offsets."""
30
+ module_calibrations: Dict[str, ModuleOffsetData] = dict()
31
+ calibration_data = load_all_module_calibrations()
32
+ for calibration in calibration_data:
33
+ # NOTE module_id is really the module serial number, change this
34
+ module_calibrations[calibration.module_id] = ModuleOffsetData(
35
+ moduleOffsetVector=ModuleOffsetVector(
36
+ x=calibration.offset.x,
37
+ y=calibration.offset.y,
38
+ z=calibration.offset.z,
39
+ ),
40
+ location=DeckSlotLocation(
41
+ slotName=DeckSlotName.from_primitive(calibration.slot),
42
+ ),
43
+ )
44
+ return module_calibrations
@@ -0,0 +1,21 @@
1
+ """Validation file for protocol engine commandsot."""
2
+ from __future__ import annotations
3
+ from typing import Optional
4
+
5
+ from opentrons.protocol_engine.errors import HardwareNotSupportedError
6
+ from opentrons.hardware_control.protocols.types import FlexRobotType
7
+
8
+ from opentrons.hardware_control import HardwareControlAPI, OT3HardwareControlAPI
9
+
10
+
11
+ def ensure_ot3_hardware(
12
+ hardware_api: HardwareControlAPI,
13
+ error_msg: Optional[str] = None,
14
+ ) -> OT3HardwareControlAPI:
15
+ """Validate that the HardwareControlAPI is of OT-3 instance."""
16
+ if hardware_api.get_robot_type() == FlexRobotType:
17
+ return hardware_api # type: ignore
18
+
19
+ raise HardwareNotSupportedError(
20
+ error_msg or "This command is supported by OT-3 only."
21
+ )
@@ -0,0 +1,379 @@
1
+ """Pipette config data providers."""
2
+ from dataclasses import dataclass
3
+ from typing import Dict, Optional, Sequence
4
+ import re
5
+
6
+ from opentrons_shared_data.pipette.types import PipetteName, PipetteModel
7
+ from opentrons_shared_data.pipette import (
8
+ pipette_load_name_conversions as pipette_load_name,
9
+ load_data as load_pipette_data,
10
+ types as pip_types,
11
+ pipette_definition,
12
+ )
13
+
14
+ from opentrons.hardware_control.dev_types import PipetteDict
15
+ from opentrons.hardware_control.nozzle_manager import (
16
+ NozzleConfigurationManager,
17
+ NozzleMap,
18
+ )
19
+ from opentrons_shared_data.errors.exceptions import MissingConfigurationData
20
+
21
+ from ..errors.exceptions import InvalidLoadPipetteSpecsError
22
+ from ..types import FlowRates
23
+ from ...types import Point
24
+
25
+ _TIP_OVERLAP_VERSION_RE = re.compile(r"^v\d+$")
26
+
27
+
28
+ def validate_and_default_tip_overlap_version(version_spec: Optional[str]) -> str:
29
+ """Validate and sanitize tip overlap versions for later consumption.
30
+
31
+ Something that comes out of this function will be of the correct format, but a given kind of
32
+ pipette may not have this version of data.
33
+ """
34
+ if version_spec is None:
35
+ return f"v{pipette_definition.TIP_OVERLAP_VERSION_MAXIMUM}"
36
+ valid = _TIP_OVERLAP_VERSION_RE.match(version_spec)
37
+ if not valid:
38
+ raise InvalidLoadPipetteSpecsError(
39
+ f"Tip overlap version specification {version_spec} is invalid."
40
+ )
41
+ try:
42
+ _ = int(version_spec[1:])
43
+ except ValueError:
44
+ raise InvalidLoadPipetteSpecsError(
45
+ f"Tip overlap version specification {version_spec} is invalid."
46
+ )
47
+ return version_spec
48
+
49
+
50
+ @dataclass(frozen=True)
51
+ class LoadedStaticPipetteData:
52
+ """Static pipette config data for load pipette."""
53
+
54
+ model: str
55
+ display_name: str
56
+ min_volume: float
57
+ max_volume: float
58
+ channels: int
59
+ home_position: float
60
+ nozzle_offset_z: float
61
+ flow_rates: FlowRates
62
+ tip_configuration_lookup_table: Dict[
63
+ float, pipette_definition.SupportedTipsDefinition
64
+ ]
65
+ nominal_tip_overlap: Dict[str, float]
66
+ nozzle_map: NozzleMap
67
+ back_left_corner_offset: Point
68
+ front_right_corner_offset: Point
69
+ pipette_lld_settings: Optional[Dict[str, Dict[str, float]]]
70
+ plunger_positions: Dict[str, float]
71
+ shaft_ul_per_mm: float
72
+ available_sensors: pipette_definition.AvailableSensorDefinition
73
+
74
+
75
+ class VirtualPipetteDataProvider:
76
+ """Provide pipette data without requiring hardware control."""
77
+
78
+ def __init__(self) -> None:
79
+ """Build a VirtualPipetteDataProvider."""
80
+ self._liquid_class_by_id: Dict[str, pip_types.LiquidClasses] = {}
81
+ self._nozzle_manager_layout_by_id: Dict[str, NozzleConfigurationManager] = {}
82
+
83
+ def configure_virtual_pipette_nozzle_layout(
84
+ self,
85
+ pipette_id: str,
86
+ pipette_model_string: str,
87
+ back_left_nozzle: Optional[str] = None,
88
+ front_right_nozzle: Optional[str] = None,
89
+ starting_nozzle: Optional[str] = None,
90
+ ) -> None:
91
+ """Emulate update_nozzle_configuration_for_mount."""
92
+ if pipette_id not in self._nozzle_manager_layout_by_id:
93
+ config = self._get_virtual_pipette_full_config_by_model_string(
94
+ pipette_model_string
95
+ )
96
+
97
+ valid_nozzle_maps = load_pipette_data.load_valid_nozzle_maps(
98
+ config.pipette_type,
99
+ config.channels,
100
+ config.version,
101
+ pip_types.PipetteOEMType.OT,
102
+ )
103
+ new_nozzle_manager = NozzleConfigurationManager.build_from_config(
104
+ config, valid_nozzle_maps
105
+ )
106
+ if back_left_nozzle and front_right_nozzle:
107
+ new_nozzle_manager.update_nozzle_configuration(
108
+ back_left_nozzle, front_right_nozzle, starting_nozzle
109
+ )
110
+ self._nozzle_manager_layout_by_id[pipette_id] = new_nozzle_manager
111
+ elif back_left_nozzle and front_right_nozzle:
112
+ # Need to make sure that we pass all the right nozzles here.
113
+ self._nozzle_manager_layout_by_id[pipette_id].update_nozzle_configuration(
114
+ back_left_nozzle, front_right_nozzle, starting_nozzle
115
+ )
116
+ else:
117
+ self._nozzle_manager_layout_by_id[
118
+ pipette_id
119
+ ].reset_to_default_configuration()
120
+
121
+ def configure_virtual_pipette_for_volume(
122
+ self, pipette_id: str, volume: float, pipette_model_string: str
123
+ ) -> None:
124
+ """Emulate configure_for_volume with the same logic for changing modes."""
125
+ if pipette_id not in self._liquid_class_by_id:
126
+ self._liquid_class_by_id[pipette_id] = pip_types.LiquidClasses.default
127
+ pipette_model = pipette_load_name.convert_pipette_model(
128
+ PipetteModel(pipette_model_string)
129
+ )
130
+ config = load_pipette_data.load_definition(
131
+ pipette_model.pipette_type,
132
+ pipette_model.pipette_channels,
133
+ pipette_model.pipette_version,
134
+ pipette_model.oem_type,
135
+ )
136
+
137
+ liquid_class = pipette_definition.liquid_class_for_volume_between_default_and_defaultlowvolume(
138
+ volume, self._liquid_class_by_id[pipette_id], config.liquid_properties
139
+ )
140
+ self._liquid_class_by_id[pipette_id] = liquid_class
141
+
142
+ def get_nozzle_layout_for_pipette(self, pipette_id: str) -> NozzleMap:
143
+ """Get the current nozzle layout stored for a virtual pipette."""
144
+ return self._nozzle_manager_layout_by_id[pipette_id].current_configuration
145
+
146
+ def get_virtual_pipette_static_config_by_model_string(
147
+ self, pipette_model_string: str, pipette_id: str, tip_overlap_version: str
148
+ ) -> LoadedStaticPipetteData:
149
+ """Get the config of a pipette when you know its model string (e.g. from state)."""
150
+ pipette_model = pipette_load_name.convert_pipette_model(
151
+ PipetteModel(pipette_model_string)
152
+ )
153
+ return self._get_virtual_pipette_static_config_by_model(
154
+ pipette_model, pipette_id, tip_overlap_version
155
+ )
156
+
157
+ def _get_virtual_pipette_full_config_by_model_string(
158
+ self, pipette_model_string: str
159
+ ) -> pipette_definition.PipetteConfigurations:
160
+ """Get the full pipette config from a model string."""
161
+ pipette_model = pipette_load_name.convert_pipette_model(
162
+ PipetteModel(pipette_model_string)
163
+ )
164
+ return load_pipette_data.load_definition(
165
+ pipette_model.pipette_type,
166
+ pipette_model.pipette_channels,
167
+ pipette_model.pipette_version,
168
+ pipette_model.oem_type,
169
+ )
170
+
171
+ def _get_virtual_pipette_static_config_by_model( # noqa: C901
172
+ self,
173
+ pipette_model: pipette_definition.PipetteModelVersionType,
174
+ pipette_id: str,
175
+ tip_overlap_version: str,
176
+ ) -> LoadedStaticPipetteData:
177
+ if pipette_id not in self._liquid_class_by_id:
178
+ self._liquid_class_by_id[pipette_id] = pip_types.LiquidClasses.default
179
+
180
+ liquid_class = self._liquid_class_by_id[pipette_id]
181
+ config = load_pipette_data.load_definition(
182
+ pipette_model.pipette_type,
183
+ pipette_model.pipette_channels,
184
+ pipette_model.pipette_version,
185
+ pipette_model.oem_type,
186
+ )
187
+ try:
188
+ tip_type = pip_types.PipetteTipType(
189
+ config.liquid_properties[liquid_class].max_volume
190
+ )
191
+ except ValueError:
192
+ tip_type = pipette_definition.default_tip_for_liquid_class(
193
+ config.liquid_properties[liquid_class]
194
+ )
195
+ tip_configuration = config.liquid_properties[liquid_class].supported_tips[
196
+ tip_type
197
+ ]
198
+ valid_nozzle_maps = load_pipette_data.load_valid_nozzle_maps(
199
+ pipette_model.pipette_type,
200
+ pipette_model.pipette_channels,
201
+ pipette_model.pipette_version,
202
+ pipette_model.oem_type,
203
+ )
204
+ if pipette_id not in self._nozzle_manager_layout_by_id:
205
+ nozzle_manager = NozzleConfigurationManager.build_from_config(
206
+ config, valid_nozzle_maps
207
+ )
208
+ else:
209
+ nozzle_manager = self._nozzle_manager_layout_by_id[pipette_id]
210
+
211
+ tip_overlap_dict_for_tip_type = None
212
+ for configuration in (
213
+ config.pick_up_tip_configurations.press_fit,
214
+ config.pick_up_tip_configurations.cam_action,
215
+ ):
216
+ if not config:
217
+ continue
218
+
219
+ approved_map = None
220
+ for map_key in valid_nozzle_maps.maps.keys():
221
+ if valid_nozzle_maps.maps[map_key] == list(
222
+ nozzle_manager.current_configuration.map_store.keys()
223
+ ):
224
+ approved_map = map_key
225
+ if approved_map is None:
226
+ raise MissingConfigurationData(
227
+ message="Virtual Static Nozzle Configuration does not match any approved map layout for the current pipette."
228
+ )
229
+
230
+ if configuration is not None:
231
+ try:
232
+ tip_overlap_dict_for_tip_type = (
233
+ get_latest_tip_overlap_before_version(
234
+ configuration.configuration_by_nozzle_map[
235
+ nozzle_manager.current_configuration.valid_map_key
236
+ ][tip_type.name].versioned_tip_overlap_dictionary,
237
+ tip_overlap_version,
238
+ )
239
+ )
240
+ break
241
+ except KeyError:
242
+ try:
243
+ default = configuration.configuration_by_nozzle_map[
244
+ nozzle_manager.current_configuration.valid_map_key
245
+ ].get("default")
246
+ if default is not None:
247
+ tip_overlap_dict_for_tip_type = (
248
+ get_latest_tip_overlap_before_version(
249
+ default.versioned_tip_overlap_dictionary,
250
+ tip_overlap_version,
251
+ )
252
+ )
253
+ break
254
+ except KeyError:
255
+ tip_overlap_dict_for_tip_type = None
256
+ if tip_overlap_dict_for_tip_type is None:
257
+ raise ValueError(
258
+ "Virtual Static Nozzle Configuration does not have a valid pick up tip configuration."
259
+ )
260
+
261
+ pip_back_left = config.pipette_bounding_box_offsets.back_left_corner
262
+ pip_front_right = config.pipette_bounding_box_offsets.front_right_corner
263
+ plunger_positions = config.plunger_positions_configurations[liquid_class]
264
+ return LoadedStaticPipetteData(
265
+ model=str(pipette_model),
266
+ display_name=config.display_name,
267
+ min_volume=config.liquid_properties[liquid_class].min_volume,
268
+ max_volume=config.liquid_properties[liquid_class].max_volume,
269
+ channels=config.channels,
270
+ home_position=config.mount_configurations.homePosition,
271
+ nozzle_offset_z=config.nozzle_offset[2],
272
+ tip_configuration_lookup_table={
273
+ k.value: v
274
+ for k, v in config.liquid_properties[
275
+ liquid_class
276
+ ].supported_tips.items()
277
+ },
278
+ flow_rates=FlowRates(
279
+ default_blow_out=tip_configuration.default_blowout_flowrate.values_by_api_level,
280
+ default_aspirate=tip_configuration.default_aspirate_flowrate.values_by_api_level,
281
+ default_dispense=tip_configuration.default_dispense_flowrate.values_by_api_level,
282
+ ),
283
+ nominal_tip_overlap=tip_overlap_dict_for_tip_type,
284
+ nozzle_map=nozzle_manager.current_configuration,
285
+ back_left_corner_offset=Point(
286
+ pip_back_left[0], pip_back_left[1], pip_back_left[2]
287
+ ),
288
+ front_right_corner_offset=Point(
289
+ pip_front_right[0], pip_front_right[1], pip_front_right[2]
290
+ ),
291
+ pipette_lld_settings=config.lld_settings,
292
+ plunger_positions={
293
+ "top": plunger_positions.top,
294
+ "bottom": plunger_positions.bottom,
295
+ "blow_out": plunger_positions.blow_out,
296
+ "drop_tip": plunger_positions.drop_tip,
297
+ },
298
+ shaft_ul_per_mm=config.shaft_ul_per_mm,
299
+ available_sensors=config.available_sensors
300
+ or pipette_definition.AvailableSensorDefinition(sensors=[]),
301
+ )
302
+
303
+ def get_virtual_pipette_static_config(
304
+ self, pipette_name: PipetteName, pipette_id: str, tip_overlap_version: str
305
+ ) -> LoadedStaticPipetteData:
306
+ """Get the config for a virtual pipette, given only the pipette name."""
307
+ pipette_model = pipette_load_name.convert_pipette_name(pipette_name)
308
+ return self._get_virtual_pipette_static_config_by_model(
309
+ pipette_model, pipette_id, tip_overlap_version
310
+ )
311
+
312
+
313
+ def get_pipette_static_config(
314
+ pipette_dict: PipetteDict, tip_overlap_version: str
315
+ ) -> LoadedStaticPipetteData:
316
+ """Get the config for a pipette, given the state/config object from the HW API."""
317
+ back_left_offset = pipette_dict["pipette_bounding_box_offsets"].back_left_corner
318
+ front_right_offset = pipette_dict["pipette_bounding_box_offsets"].front_right_corner
319
+ available_sensors = (
320
+ pipette_dict["available_sensors"]
321
+ if "available_sensors" in pipette_dict.keys()
322
+ else pipette_definition.AvailableSensorDefinition(sensors=[])
323
+ )
324
+ return LoadedStaticPipetteData(
325
+ model=pipette_dict["model"],
326
+ display_name=pipette_dict["display_name"],
327
+ min_volume=pipette_dict["min_volume"],
328
+ max_volume=pipette_dict["max_volume"],
329
+ channels=pipette_dict["channels"],
330
+ flow_rates=FlowRates(
331
+ default_blow_out=pipette_dict["default_blow_out_flow_rates"],
332
+ default_aspirate=pipette_dict["default_aspirate_flow_rates"],
333
+ default_dispense=pipette_dict["default_dispense_flow_rates"],
334
+ ),
335
+ tip_configuration_lookup_table={
336
+ k.value: v for k, v in pipette_dict["supported_tips"].items()
337
+ },
338
+ nominal_tip_overlap=get_latest_tip_overlap_before_version(
339
+ pipette_dict["versioned_tip_overlap"], tip_overlap_version
340
+ ),
341
+ # TODO(mc, 2023-02-28): these two values are not present in PipetteDict
342
+ # https://opentrons.atlassian.net/browse/RCORE-655
343
+ home_position=0,
344
+ nozzle_offset_z=0,
345
+ nozzle_map=pipette_dict["current_nozzle_map"],
346
+ back_left_corner_offset=Point(
347
+ back_left_offset[0], back_left_offset[1], back_left_offset[2]
348
+ ),
349
+ front_right_corner_offset=Point(
350
+ front_right_offset[0], front_right_offset[1], front_right_offset[2]
351
+ ),
352
+ pipette_lld_settings=pipette_dict["lld_settings"],
353
+ plunger_positions=pipette_dict["plunger_positions"],
354
+ shaft_ul_per_mm=pipette_dict["shaft_ul_per_mm"],
355
+ available_sensors=available_sensors,
356
+ )
357
+
358
+
359
+ def get_latest_tip_overlap_before_version(
360
+ overlap: Dict[str, Dict[str, float]], version: str
361
+ ) -> Dict[str, float]:
362
+ """Get the latest tip overlap definitions that are equal or older than the version."""
363
+ # TODO: make this less awful
364
+ def _numeric(versionstr: str) -> int:
365
+ return int(versionstr[1:])
366
+
367
+ def _latest(versions: Sequence[int], target: int) -> int:
368
+ last = 0
369
+ for version in versions:
370
+ if version > target:
371
+ return last
372
+ last = version
373
+ return last
374
+
375
+ numeric_target = _numeric(version)
376
+ numeric_versions = sorted([_numeric(k) for k in overlap.keys()])
377
+ found_numeric_version = _latest(numeric_versions, numeric_target)
378
+ found_version = f"v{found_numeric_version}"
379
+ return overlap[found_version]
@@ -0,0 +1,128 @@
1
+ """Convert deck slots into the preferred style for a robot.
2
+
3
+ The deck slots on an OT-2 are labeled like "1", "2", ..., and on an OT-3 they're labeled like
4
+ "D1," "D2", ....
5
+
6
+ When Protocol Engine takes a deck slot as input, we generally want it to accept either style
7
+ of label. This helps make protocols more portable across robot types.
8
+
9
+ But, Protocol Engine should then immediately convert it to the "correct" style for the robot that
10
+ it's controlling or simulating. This makes it simpler to consume the robot's HTTP API,
11
+ and it makes it easier for us to reason about Protocol Engine's internal state.
12
+
13
+ This module does that conversion, for any Protocol Engine input that contains a reference to a
14
+ deck slot.
15
+ """
16
+
17
+ from typing import Any, Callable, Dict, Type
18
+
19
+ from opentrons_shared_data.robot.types import RobotType
20
+
21
+ from . import commands
22
+ from .types import (
23
+ OFF_DECK_LOCATION,
24
+ SYSTEM_LOCATION,
25
+ DeckSlotLocation,
26
+ LoadableLabwareLocation,
27
+ AddressableAreaLocation,
28
+ ModuleLocation,
29
+ OnLabwareLocation,
30
+ )
31
+
32
+
33
+ def standardize_command(
34
+ original: commands.CommandCreate, robot_type: RobotType
35
+ ) -> commands.CommandCreate:
36
+ """Convert any deck slots in the given `CommandCreate` to match the given robot type."""
37
+ try:
38
+ standardize = _standardize_command_functions[type(original)]
39
+ except KeyError:
40
+ return original
41
+ else:
42
+ return standardize(original, robot_type)
43
+
44
+
45
+ # Command-specific standardization:
46
+ #
47
+ # Our use of .copy(update=...) in these implementations, instead of .construct(...), is a tradeoff.
48
+ # .construct() would give us better type-checking for the fields that we set,
49
+ # but .copy(update=...) avoids the hazard of forgetting to set fields that have defaults.
50
+
51
+
52
+ def _standardize_load_labware(
53
+ original: commands.LoadLabwareCreate, robot_type: RobotType
54
+ ) -> commands.LoadLabwareCreate:
55
+ params = original.params.model_copy(
56
+ update={
57
+ "location": _standardize_labware_location(
58
+ original.params.location, robot_type
59
+ )
60
+ }
61
+ )
62
+ return original.model_copy(update={"params": params})
63
+
64
+
65
+ def _standardize_load_module(
66
+ original: commands.LoadModuleCreate, robot_type: RobotType
67
+ ) -> commands.LoadModuleCreate:
68
+ params = original.params.model_copy(
69
+ update={
70
+ "location": _standardize_deck_slot_location(
71
+ original.params.location, robot_type
72
+ )
73
+ }
74
+ )
75
+ return original.model_copy(update={"params": params})
76
+
77
+
78
+ def _standardize_move_labware(
79
+ original: commands.MoveLabwareCreate, robot_type: RobotType
80
+ ) -> commands.MoveLabwareCreate:
81
+ params = original.params.model_copy(
82
+ update={
83
+ "newLocation": _standardize_labware_location(
84
+ original.params.newLocation, robot_type
85
+ )
86
+ }
87
+ )
88
+ return original.model_copy(update={"params": params})
89
+
90
+
91
+ _standardize_command_functions: Dict[
92
+ Type[commands.CommandCreate], Callable[[Any, RobotType], commands.CommandCreate]
93
+ ] = {
94
+ commands.LoadLabwareCreate: _standardize_load_labware,
95
+ commands.LoadModuleCreate: _standardize_load_module,
96
+ commands.MoveLabwareCreate: _standardize_move_labware,
97
+ }
98
+
99
+
100
+ # Helpers:
101
+
102
+
103
+ def _standardize_labware_location(
104
+ original: LoadableLabwareLocation, robot_type: RobotType
105
+ ) -> LoadableLabwareLocation:
106
+ if isinstance(original, DeckSlotLocation):
107
+ return _standardize_deck_slot_location(original, robot_type)
108
+ elif (
109
+ isinstance(
110
+ original,
111
+ (
112
+ ModuleLocation,
113
+ OnLabwareLocation,
114
+ AddressableAreaLocation,
115
+ ),
116
+ )
117
+ or original == OFF_DECK_LOCATION
118
+ or original == SYSTEM_LOCATION
119
+ ):
120
+ return original
121
+
122
+
123
+ def _standardize_deck_slot_location(
124
+ original: DeckSlotLocation, robot_type: RobotType
125
+ ) -> DeckSlotLocation:
126
+ return original.model_copy(
127
+ update={"slotName": original.slotName.to_equivalent_for_robot_type(robot_type)}
128
+ )
@@ -0,0 +1 @@
1
+ """Protocol engine state module."""