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,628 @@
1
+ import logging
2
+ from typing import Any, Optional, List, cast
3
+ from typing_extensions import Final
4
+ import math
5
+ import functools
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from opentrons.legacy_commands import types
10
+ from opentrons.protocols.api_support.deck_type import (
11
+ guess_from_global_config as guess_deck_type_from_global_config,
12
+ )
13
+ from opentrons.protocols.api_support.labware_like import LabwareLike
14
+ from opentrons.protocols.duration.errors import DurationEstimatorException
15
+ from opentrons.protocol_api.core.legacy.deck import Deck
16
+ from opentrons.types import Location
17
+
18
+
19
+ # We refer to page 3 of the GEN2 Temperature Module White-Paper
20
+ # https://blog.opentrons.com/opentrons-technical-documentation/
21
+ # Through the data we notice that there are different
22
+ # rates of Celsius/second depending on temperature range.
23
+ # These were all tested to be ~95% consistent with the data
24
+ TEMP_MOD_RATE_HIGH_AND_ABOVE: Final = 0.3611111111
25
+ TEMP_MOD_RATE_LOW_TO_HIGH: Final = 0.2
26
+ TEMP_MOD_RATE_ZERO_TO_LOW: Final = 0.0875
27
+ TEMP_MOD_LOW_THRESH: Final = 25.0
28
+ TEMP_MOD_HIGH_THRESH: Final = 37.0
29
+
30
+ THERMO_LOW_THRESH: Final = 23.0
31
+ THERMO_HIGH_THRESH: Final = 70.0
32
+
33
+ START_MODULE_TEMPERATURE: Final = 25.0
34
+
35
+ STARTING_SLOT: Final[str] = "12"
36
+
37
+
38
+ logger = logging.getLogger(__name__)
39
+
40
+
41
+ @dataclass
42
+ class TimerEntry:
43
+ command: types.CommandMessage
44
+ duration: float
45
+
46
+
47
+ # TODO (al, 2021-09-09): Write doc strings for each method detailing how the
48
+ # duration is computed.
49
+
50
+
51
+ class DurationEstimator:
52
+ """
53
+ Broker listener that calculates the duration of protocol steps.
54
+ """
55
+
56
+ def __init__(self) -> None:
57
+ # Which slot the last command was in.
58
+ self._last_deckslot = STARTING_SLOT
59
+ # todo(mm, 2021-09-08): Support protocols with more than one
60
+ # Temperature or Thermocycler Module.
61
+ self._last_temperature_module_temperature = START_MODULE_TEMPERATURE
62
+ self._last_thermocycler_module_temperature = START_MODULE_TEMPERATURE
63
+ # Per step time estimate.
64
+ self._increments: List[TimerEntry] = []
65
+
66
+ # TODO(mm, 2022-12-01): Allow the caller to configure the deck type.
67
+ self._deck = Deck(deck_type=guess_deck_type_from_global_config())
68
+
69
+ def get_total_duration(self) -> float:
70
+ """Return the total duration"""
71
+ return functools.reduce(
72
+ lambda acc, val: acc + val.duration, self._increments, 0.0
73
+ )
74
+
75
+ def on_message(self, message: types.CommandMessage) -> None:
76
+ """
77
+ Message handler for Broker events.
78
+
79
+ Args:
80
+ message: A protocol message
81
+
82
+ Returns:
83
+ None
84
+ """
85
+ # Whether this message comes before or after the command is being executed..
86
+ if message["$"] != "after":
87
+ # We only want to process the afters.
88
+ return
89
+
90
+ # Extract the message name
91
+ message_name = message["name"]
92
+ # The actual payload of the command that varies by message.
93
+ payload = message["payload"]
94
+
95
+ location = payload.get("location")
96
+
97
+ try:
98
+ duration = self.handle_message(message_name, payload)
99
+ except Exception as e:
100
+ raise DurationEstimatorException(str(e))
101
+
102
+ if location:
103
+ slot = self.get_slot(location)
104
+ self._last_deckslot = slot if slot else self._last_deckslot
105
+
106
+ self._increments.append(
107
+ TimerEntry(
108
+ command=message,
109
+ duration=duration,
110
+ )
111
+ )
112
+
113
+ def handle_message( # noqa: C901
114
+ self, message_name: str, payload: types.CommandPayload
115
+ ) -> float:
116
+ """
117
+ Handle the message payload
118
+
119
+ Args:
120
+ message_name: Name of message
121
+ payload: The command payload
122
+
123
+ Returns:
124
+ The duration in seconds
125
+ """
126
+ duration = 0.0
127
+ # TODO (al, 2021-09-09):
128
+ # - Make this into a map
129
+ # - Remove "noqa: C901"
130
+ if message_name == types.PICK_UP_TIP:
131
+ payload = cast(types.PickUpTipCommandPayload, payload)
132
+ duration = self.on_pick_up_tip(payload=payload)
133
+ elif message_name == types.DROP_TIP:
134
+ payload = cast(types.DropTipCommandPayload, payload)
135
+ duration = self.on_drop_tip(payload=payload)
136
+ elif message_name == types.ASPIRATE:
137
+ payload = cast(types.AspirateDispenseCommandPayload, payload)
138
+ duration = self.on_aspirate(payload=payload)
139
+ elif message_name == types.DISPENSE:
140
+ payload = cast(types.AspirateDispenseCommandPayload, payload)
141
+ duration = self.on_dispense(payload=payload)
142
+ elif message_name == types.BLOW_OUT:
143
+ payload = cast(types.BlowOutCommandPayload, payload)
144
+ duration = self.on_blow_out(payload=payload)
145
+ elif message_name == types.TOUCH_TIP:
146
+ payload = cast(types.TouchTipCommandPayload, payload)
147
+ duration = self.on_touch_tip()
148
+ elif message_name == types.DELAY:
149
+ payload = cast(types.DelayCommandPayload, payload)
150
+ duration = self.on_delay(payload=payload)
151
+ elif message_name == types.TEMPDECK_SET_TEMP:
152
+ payload = cast(types.TempdeckSetTempCommandPayload, payload)
153
+ duration = self.on_tempdeck_set_temp(payload=payload)
154
+ elif message_name == types.TEMPDECK_DEACTIVATE:
155
+ payload = cast(types.TempdeckDeactivateCommandPayload, payload)
156
+ duration = self.on_tempdeck_deactivate()
157
+ elif message_name == types.TEMPDECK_AWAIT_TEMP:
158
+ payload = cast(types.TempdeckAwaitTempCommandPayload, payload)
159
+ duration = self.on_tempdeck_await_temp()
160
+ elif message_name == types.THERMOCYCLER_SET_BLOCK_TEMP:
161
+ payload = cast(types.ThermocyclerSetBlockTempCommandPayload, payload)
162
+ duration = self.on_thermocycler_block_temp(payload=payload)
163
+ elif message_name == types.THERMOCYCLER_EXECUTE_PROFILE:
164
+ payload = cast(types.ThermocyclerExecuteProfileCommandPayload, payload)
165
+ duration = self.on_execute_profile(payload=payload)
166
+ elif message_name == types.THERMOCYCLER_SET_LID_TEMP:
167
+ duration = self.on_thermocycler_set_lid_temp()
168
+ elif message_name == types.THERMOCYCLER_CLOSE:
169
+ duration = self.on_thermocycler_lid_close()
170
+ elif message_name == types.THERMOCYCLER_DEACTIVATE_LID:
171
+ duration = self.on_thermocycler_deactivate_lid()
172
+ elif message_name == types.THERMOCYCLER_OPEN:
173
+ duration = self.on_thermocycler_lid_open()
174
+ elif message_name == types.TRANSFER:
175
+ # Already accounted for in other steps
176
+ pass
177
+ elif message_name == types.DISTRIBUTE:
178
+ pass
179
+ elif message_name == types.CONSOLIDATE:
180
+ pass
181
+ elif message_name == types.COMMENT:
182
+ pass
183
+ else:
184
+ logger.warning(
185
+ f"Command type '{message_name}' is not yet supported by the "
186
+ f"duration estimator."
187
+ )
188
+ return duration
189
+
190
+ def on_pick_up_tip(self, payload: types.PickUpTipCommandPayload) -> float:
191
+ """Handle a pick up tip event"""
192
+
193
+ instrument = payload["instrument"]
194
+ location = payload["location"]
195
+ prev_slot = self._last_deckslot
196
+ curr_slot = self.get_slot(location)
197
+
198
+ gantry_speed = instrument.default_speed
199
+
200
+ deck_travel_time = self.calc_deck_movement_time(
201
+ self._deck, curr_slot, prev_slot, gantry_speed
202
+ )
203
+
204
+ # The time to pick up tip is 4 seconds. Determined by testing on hardware.
205
+ duration = deck_travel_time + 4
206
+
207
+ logger.info(
208
+ f"{instrument.name} picked up tip from slot "
209
+ f"{curr_slot} the duration is {duration}"
210
+ )
211
+ return duration
212
+
213
+ def on_drop_tip(self, payload: types.DropTipCommandPayload) -> float:
214
+
215
+ instrument = payload["instrument"]
216
+ # We are going to once again use our "deck movement" set up. This should
217
+ # be in pickup, drop tip, aspirate, dispense
218
+ location = payload["location"]
219
+ curr_slot = self.get_slot(location)
220
+ # this one disagrees with me.
221
+ prev_slot = self._last_deckslot
222
+ gantry_speed = instrument.default_speed
223
+ deck_travel_time = self.calc_deck_movement_time(
224
+ self._deck, curr_slot, prev_slot, gantry_speed
225
+ )
226
+ # TODO (al, 2021-09-08): Should we be checking for drop tip home_after = False?
227
+
228
+ # The time to drop up tip is 10 seconds. Determined by testing on hardware.
229
+ duration = deck_travel_time + 10
230
+
231
+ # let's only log the message after the pick up tip is done.
232
+ logger.info(f"{instrument.name}, drop tip duration is {duration}")
233
+ return duration
234
+
235
+ def on_aspirate(self, payload: types.AspirateDispenseCommandPayload) -> float:
236
+ # General aspiration code
237
+ instrument = payload["instrument"]
238
+ volume = payload["volume"]
239
+ rate = payload["rate"] * instrument.flow_rate.aspirate
240
+
241
+ aspiration_time = volume / rate
242
+
243
+ # now lets handle the aspiration z-axis code.
244
+ location = payload["location"]
245
+ slot = self.get_slot(location)
246
+
247
+ gantry_speed = instrument.default_speed
248
+ z_total_time = self.z_time(
249
+ location.labware.parent.parent.is_module, gantry_speed
250
+ )
251
+
252
+ # We are going to once again use our "deck movement" set up.
253
+ # Might be changed in future PR if our travel
254
+ # calculations adjust
255
+ # This should be in pickup, drop tip, aspirate, dispense
256
+ location = payload["location"]
257
+ prev_slot = self._last_deckslot
258
+ curr_slot = self.get_slot(location)
259
+
260
+ gantry_speed = instrument.default_speed
261
+ deck_travel_time = self.calc_deck_movement_time(
262
+ self._deck, curr_slot, prev_slot, gantry_speed
263
+ )
264
+ assert isinstance(aspiration_time, float)
265
+ duration = deck_travel_time + z_total_time + aspiration_time
266
+ logger.info(
267
+ f"{instrument.name} aspirate from {slot}, " f"the duration is {duration}"
268
+ )
269
+ return duration
270
+
271
+ def on_dispense(self, payload: types.AspirateDispenseCommandPayload) -> float:
272
+ # General code for aspiration/dispense
273
+ instrument = payload["instrument"]
274
+ volume = payload["volume"]
275
+ rate = payload["rate"] * instrument.flow_rate.dispense
276
+ dispense_time = volume / rate
277
+
278
+ # define variables
279
+ location = payload["location"]
280
+ slot = self.get_slot(location)
281
+ gantry_speed = instrument.default_speed
282
+
283
+ z_total_time = self.z_time(
284
+ location.labware.parent.parent.is_module, gantry_speed
285
+ )
286
+ # We are going to once again use our "deck movement" set up.
287
+ # This should be in pickup, drop tip, aspirate, dispense
288
+ location = payload["location"]
289
+ prev_slot = self._last_deckslot
290
+ curr_slot = self.get_slot(location)
291
+
292
+ gantry_speed = instrument.default_speed
293
+ deck_travel_time = self.calc_deck_movement_time(
294
+ self._deck, curr_slot, prev_slot, gantry_speed
295
+ )
296
+
297
+ assert isinstance(dispense_time, float)
298
+ duration = deck_travel_time + z_total_time + dispense_time
299
+
300
+ logger.info(
301
+ f"{instrument.name} dispensed from {slot}, the duration is {duration}"
302
+ )
303
+ return duration
304
+
305
+ def on_blow_out(self, payload: types.BlowOutCommandPayload) -> float:
306
+ location = payload["location"]
307
+ curr_slot = self.get_slot(location)
308
+ # In theory, we could use instrument.flow_rate.blow_out, but we don't
309
+ # know how much is in the tip left to blow out
310
+ # So we are defaulting to 0.5 seconds
311
+ duration = 0.5
312
+ logger.info(f"blowing_out_for {duration} seconds, in slot {curr_slot}")
313
+ return duration
314
+
315
+ def on_touch_tip(self) -> float:
316
+ # base assumption. Touch_tip takes 0.5 seconds This is consistent with a
317
+ # ~7.5mm diameter (default 60mm/s, 4 sides)
318
+ # plate = protocol.load_labware('corning_96_wellplate_360ul_flat', '1')
319
+ # depth = plate['A1'].diameter
320
+ # Then use the speed of the touch tip
321
+ # ( plate = protocol.load_labware('corning_96_wellplate_360ul_flat', '1')
322
+ # depth = plate['A1'].diameter
323
+ duration = 0.5
324
+ logger.info(f"touch_tip for {duration} seconds")
325
+ return duration
326
+
327
+ def on_delay(self, payload: types.DelayCommandPayload) -> float:
328
+ # Explanation: we are gathering seconds and minutes here
329
+ seconds_delay = payload["seconds"]
330
+ minutes_delay = payload["minutes"]
331
+ duration = seconds_delay + minutes_delay * 60
332
+ duration = float(duration)
333
+ # Note will need to multiply minutes by 60
334
+ logger.info(f"delay for {seconds_delay} seconds and {minutes_delay} minutes")
335
+
336
+ return duration
337
+
338
+ def on_thermocycler_block_temp(
339
+ self, payload: types.ThermocyclerSetBlockTempCommandPayload
340
+ ) -> float:
341
+ temperature = payload["temperature"]
342
+ hold_time = payload["hold_time"]
343
+ temp0 = self._last_thermocycler_module_temperature
344
+ temp1 = temperature
345
+ # we are referring to a thermocycler_handler(temp0, temp1) function.
346
+ # Magic numbers come from testing and have been consistent
347
+ temperature_changing_time = self.thermocycler_handler(temp0, temp1)
348
+ if hold_time is None:
349
+ hold_time = 0
350
+ else:
351
+ hold_time = float(hold_time)
352
+
353
+ duration = temperature_changing_time + hold_time
354
+ # Note will need to multiply minutes by 60
355
+ logger.info(
356
+ f"hold for {hold_time} seconds and set temp for {temperature}"
357
+ f" C total duration {duration}"
358
+ )
359
+ duration = float(duration)
360
+
361
+ return duration
362
+
363
+ def on_execute_profile(
364
+ self, payload: types.ThermocyclerExecuteProfileCommandPayload
365
+ ) -> float:
366
+ # Overview We need to run each time a temperature change happens
367
+ # through thermocycler_handler and multiply
368
+ # By the cycle count. Then we also (in parallel) do the same with delays
369
+
370
+ profile_total_steps = payload["steps"]
371
+ thermocycler_temperatures = [self._last_thermocycler_module_temperature]
372
+ thermocycler_hold_times = []
373
+ cycle_count = float(payload["text"].split(" ")[2])
374
+
375
+ # We are going to need to treat this theromcycler part a bit differently
376
+ # for a bit and just send out total times
377
+ for step in profile_total_steps:
378
+ thermocycler_temperatures.append(float(step["temperature"]))
379
+ thermocycler_hold_times.append(float(step["hold_time_seconds"]))
380
+ # Initializing variable
381
+ total_hold_time = float(cycle_count) * float(sum(thermocycler_hold_times))
382
+ # This takes care of the cumulative hold time
383
+ # WE DON't Have a way to deal with this currently in the way we
384
+ # have things set up.
385
+ cycling_counter = []
386
+ thermocycler_temperatures.pop(0)
387
+ for thermocycler_counter in range(0, len(thermocycler_temperatures)):
388
+ cycling_counter.append(
389
+ self.thermocycler_handler(
390
+ float(thermocycler_temperatures[thermocycler_counter - 1]),
391
+ float(thermocycler_temperatures[thermocycler_counter]),
392
+ )
393
+ )
394
+
395
+ # Sum hold time and cycling temp time
396
+ duration = float(sum(cycling_counter) + total_hold_time)
397
+ self._last_thermocycler_module_temperature = thermocycler_temperatures[-1]
398
+
399
+ cycling_counter = []
400
+ # Note will need to multiply minutes by 60
401
+ logger.info(
402
+ f"temperatures {sum(cycling_counter)}, "
403
+ f"hold_times {total_hold_time} , cycles are {cycle_count}, "
404
+ f"{duration}"
405
+ )
406
+ return duration
407
+
408
+ def on_thermocycler_set_lid_temp(self) -> float:
409
+ # Hardware said ~1 minute
410
+ duration = 60
411
+ thermoaction = "set lid temperature"
412
+ logger.info(f"thermocation = {thermoaction}")
413
+ return duration
414
+
415
+ def on_thermocycler_lid_close(self) -> float:
416
+ # Hardware said ~24 seconds
417
+ duration = 24
418
+ thermoaction = "closing"
419
+ logger.info(f"thermocation = {thermoaction}")
420
+ return duration
421
+
422
+ def on_thermocycler_lid_open(self) -> float:
423
+ # Hardware said ~24 seconds
424
+ duration = 24
425
+ thermoaction = "opening"
426
+ logger.info(f"thermocation = {thermoaction}")
427
+ return duration
428
+
429
+ def on_thermocycler_deactivate_lid(self) -> float:
430
+ # Hardware said ~23 seconds
431
+ duration = 23
432
+ thermoaction = "Deactivating"
433
+ logger.info(f"thermocation = {thermoaction}")
434
+ return duration
435
+
436
+ def on_tempdeck_set_temp(
437
+ self, payload: types.TempdeckSetTempCommandPayload
438
+ ) -> float:
439
+ temperature_tempdeck = payload["celsius"]
440
+ temp0 = self._last_temperature_module_temperature
441
+ temp1 = float(temperature_tempdeck)
442
+ duration = self.temperature_module(temp0, temp1)
443
+ self._last_temperature_module_temperature = temp0
444
+ logger.info(f"tempdeck {duration} ")
445
+ return duration
446
+
447
+ def thermocycler_handler(self, temp0: float, temp1: float) -> float:
448
+ total = 0.0
449
+ if temp1 - temp0 > 0:
450
+ # heating up!
451
+ if temp1 > THERMO_HIGH_THRESH:
452
+ # the temp1 part that's over 70 is
453
+ total = abs(temp1 - THERMO_HIGH_THRESH) / 2
454
+ # the temp1 part that's under 70 is:
455
+ total += abs(THERMO_HIGH_THRESH - temp0) / 4
456
+ else:
457
+ total = abs(temp1 - temp0) / 4
458
+ # This is where the error is. if it's 10 and 94 this would not
459
+ # @Matt please look into this
460
+ elif temp1 - temp0 < 0:
461
+ if temp1 >= THERMO_HIGH_THRESH:
462
+ total = abs(temp1 - temp0) / 2
463
+ elif temp1 >= THERMO_LOW_THRESH:
464
+ total = abs(temp1 - temp0) / 1
465
+ else:
466
+ # 70 to 23 2 C/s
467
+ total = abs(temp0 - THERMO_LOW_THRESH) / 0.5
468
+ # 23 to temp1 0.1 C/s
469
+ total += abs(temp1 - THERMO_LOW_THRESH) / 0.1
470
+
471
+ return total
472
+
473
+ def temperature_module(self, temp0: float, temp1: float) -> float:
474
+ duration = 0.0
475
+ if temp1 != temp0:
476
+ if temp1 > TEMP_MOD_HIGH_THRESH:
477
+ duration = self.rate_high(temp0, temp1)
478
+ elif TEMP_MOD_LOW_THRESH <= temp1 <= TEMP_MOD_HIGH_THRESH:
479
+ duration = self.rate_mid(temp0, temp1)
480
+ elif temp1 < TEMP_MOD_LOW_THRESH:
481
+ duration = self.rate_low(temp0, temp1)
482
+ return duration
483
+
484
+ def on_tempdeck_deactivate(self) -> float:
485
+ # TODO (al, 2021-09-08: Find an answer for this value.
486
+ duration = 0.0
487
+ logger.info("tempdeck deactivating")
488
+ return duration
489
+
490
+ def on_tempdeck_await_temp(self) -> float:
491
+ # The duration is accounted for in set temperature
492
+ duration = 0.0
493
+ logger.info("tempdeck awaiting temperature")
494
+ return duration
495
+
496
+ @staticmethod
497
+ def get_slot(location: Any) -> Optional[str]:
498
+ """A utility function to extract the slot number from the location."""
499
+ if isinstance(location, Location):
500
+ return location.labware.first_parent()
501
+ else:
502
+ return LabwareLike(location).first_parent()
503
+
504
+ @staticmethod
505
+ def calc_deck_movement_time(
506
+ deck: Deck, current_slot: Optional[str], previous_slot: str, gantry_speed: float
507
+ ) -> float:
508
+ # Quick summary we set coordinates for each deck slot and found ways
509
+ # to move between deck slots.
510
+ # Each deck slot is a key for a coordinate value
511
+ # Moving between coordinate values
512
+ if not current_slot:
513
+ raise DurationEstimatorException(
514
+ f"Current slot '{current_slot}' is not valid."
515
+ )
516
+
517
+ previous_deck_center = deck.position_for(previous_slot)
518
+ if not previous_deck_center:
519
+ raise DurationEstimatorException(
520
+ f"Previous slot '{current_slot}' is not valid."
521
+ )
522
+ current_deck_center = deck.position_for(current_slot)
523
+
524
+ x_difference = abs(current_deck_center.point.x - previous_deck_center.point.x)
525
+ y_difference = abs(current_deck_center.point.y - previous_deck_center.point.y)
526
+
527
+ if x_difference == 0 and y_difference == 0:
528
+ # Inter slot movement defaults to half a second.
529
+ deck_movement_time = 0.5
530
+ else:
531
+ deck_distance = math.sqrt((x_difference**2) + (y_difference**2))
532
+ deck_movement_time = deck_distance / gantry_speed
533
+ return deck_movement_time
534
+
535
+ @staticmethod
536
+ def z_time(is_module: bool, gantry_speed: float) -> float:
537
+ # TODO (al, 2021-09-08): Use definitions from protocol context objects.
538
+ z_default_labware_height = 177.8
539
+ z_default_module_height = 95.25
540
+ # 177.8 - 82.55 Where did we get 177.8 from?
541
+ # Would it be better to just use
542
+ # protocol_api.labware.Well.top
543
+ # labware.top() ?
544
+
545
+ if is_module:
546
+ z_time = z_default_module_height / gantry_speed
547
+ else:
548
+ z_time = z_default_labware_height / gantry_speed
549
+
550
+ return z_time
551
+
552
+ @staticmethod
553
+ def rate_high(temp0: float, temp1: float) -> float:
554
+ """
555
+ Calculate temp deck temperature change to a high temperature.
556
+
557
+ Args:
558
+ temp0: Current
559
+ temp1: Target
560
+
561
+ Returns:
562
+ Duration in seconds.
563
+ """
564
+ val = 0.0
565
+ if temp0 >= TEMP_MOD_HIGH_THRESH:
566
+ val = abs(temp1 - temp0) / TEMP_MOD_RATE_HIGH_AND_ABOVE
567
+ elif TEMP_MOD_LOW_THRESH < temp0 < TEMP_MOD_HIGH_THRESH:
568
+ val = abs(temp0 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
569
+ val += abs(temp1 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_HIGH_AND_ABOVE
570
+ elif temp0 <= TEMP_MOD_LOW_THRESH:
571
+ # the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
572
+ val = abs(TEMP_MOD_LOW_THRESH - temp0) / TEMP_MOD_RATE_ZERO_TO_LOW
573
+ val += abs(TEMP_MOD_LOW_THRESH - temp1) / TEMP_MOD_RATE_HIGH_AND_ABOVE
574
+
575
+ return val
576
+
577
+ @staticmethod
578
+ def rate_mid(temp0: float, temp1: float) -> float:
579
+ """
580
+ Calculate temp deck temperature change to a medium temperature.
581
+
582
+ Args:
583
+ temp0: Current
584
+ temp1: Target
585
+
586
+ Returns:
587
+ Duration in seconds.
588
+ """
589
+ val = 0.0
590
+ if TEMP_MOD_LOW_THRESH <= temp0 <= TEMP_MOD_HIGH_THRESH:
591
+ val = abs(temp1 - temp0) / TEMP_MOD_RATE_LOW_TO_HIGH
592
+ elif temp0 < TEMP_MOD_LOW_THRESH:
593
+ # the temp1 part that's over TEMP_MOD_HIGH_THRESH is
594
+ val = abs(temp1 - TEMP_MOD_LOW_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
595
+ # the temp0 part that's under TEMP_MOD_HIGH_THRESH is:
596
+ val += abs(TEMP_MOD_LOW_THRESH - temp0) / TEMP_MOD_RATE_ZERO_TO_LOW
597
+ elif temp0 > TEMP_MOD_HIGH_THRESH:
598
+ val = abs(temp0 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_HIGH_AND_ABOVE
599
+ # the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
600
+ val += abs(TEMP_MOD_HIGH_THRESH - temp1) / TEMP_MOD_RATE_ZERO_TO_LOW
601
+ return val
602
+
603
+ # How to handle temperatures where one of them is low temp
604
+ @staticmethod
605
+ def rate_low(temp0: float, temp1: float) -> float:
606
+ """
607
+ Calculate temp deck temperature change to a low temperature.
608
+
609
+ Args:
610
+ temp0: Current
611
+ temp1: Target
612
+
613
+ Returns:
614
+ Duration in seconds.
615
+ """
616
+ val = 0.0
617
+ if temp0 <= TEMP_MOD_LOW_THRESH:
618
+ val = abs(temp1 - temp0) / TEMP_MOD_RATE_ZERO_TO_LOW
619
+ elif TEMP_MOD_LOW_THRESH < temp0 < TEMP_MOD_HIGH_THRESH:
620
+ # the temp0 part that's over TEMP_MOD_HIGH_THRESH is
621
+ val = abs(temp0 - TEMP_MOD_LOW_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
622
+ # the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
623
+ val += abs(TEMP_MOD_LOW_THRESH - temp1) / TEMP_MOD_RATE_ZERO_TO_LOW
624
+ elif temp0 >= TEMP_MOD_HIGH_THRESH:
625
+ val = abs(temp0 - TEMP_MOD_HIGH_THRESH) / TEMP_MOD_RATE_LOW_TO_HIGH
626
+ # the temp1 part that's under TEMP_MOD_HIGH_THRESH is:
627
+ val += abs(TEMP_MOD_HIGH_THRESH - temp1) / TEMP_MOD_RATE_ZERO_TO_LOW
628
+ return val
File without changes