opentrons 8.6.0a1__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (600) hide show
  1. opentrons/__init__.py +150 -0
  2. opentrons/_version.py +34 -0
  3. opentrons/calibration_storage/__init__.py +54 -0
  4. opentrons/calibration_storage/deck_configuration.py +62 -0
  5. opentrons/calibration_storage/encoder_decoder.py +31 -0
  6. opentrons/calibration_storage/file_operators.py +142 -0
  7. opentrons/calibration_storage/helpers.py +103 -0
  8. opentrons/calibration_storage/ot2/__init__.py +34 -0
  9. opentrons/calibration_storage/ot2/deck_attitude.py +85 -0
  10. opentrons/calibration_storage/ot2/mark_bad_calibration.py +27 -0
  11. opentrons/calibration_storage/ot2/models/__init__.py +0 -0
  12. opentrons/calibration_storage/ot2/models/v1.py +149 -0
  13. opentrons/calibration_storage/ot2/pipette_offset.py +129 -0
  14. opentrons/calibration_storage/ot2/tip_length.py +281 -0
  15. opentrons/calibration_storage/ot3/__init__.py +31 -0
  16. opentrons/calibration_storage/ot3/deck_attitude.py +83 -0
  17. opentrons/calibration_storage/ot3/gripper_offset.py +156 -0
  18. opentrons/calibration_storage/ot3/models/__init__.py +0 -0
  19. opentrons/calibration_storage/ot3/models/v1.py +122 -0
  20. opentrons/calibration_storage/ot3/module_offset.py +138 -0
  21. opentrons/calibration_storage/ot3/pipette_offset.py +95 -0
  22. opentrons/calibration_storage/types.py +45 -0
  23. opentrons/cli/__init__.py +21 -0
  24. opentrons/cli/__main__.py +5 -0
  25. opentrons/cli/analyze.py +501 -0
  26. opentrons/config/__init__.py +631 -0
  27. opentrons/config/advanced_settings.py +871 -0
  28. opentrons/config/defaults_ot2.py +214 -0
  29. opentrons/config/defaults_ot3.py +499 -0
  30. opentrons/config/feature_flags.py +86 -0
  31. opentrons/config/gripper_config.py +55 -0
  32. opentrons/config/reset.py +203 -0
  33. opentrons/config/robot_configs.py +187 -0
  34. opentrons/config/types.py +183 -0
  35. opentrons/drivers/__init__.py +0 -0
  36. opentrons/drivers/absorbance_reader/__init__.py +11 -0
  37. opentrons/drivers/absorbance_reader/abstract.py +72 -0
  38. opentrons/drivers/absorbance_reader/async_byonoy.py +352 -0
  39. opentrons/drivers/absorbance_reader/driver.py +81 -0
  40. opentrons/drivers/absorbance_reader/hid_protocol.py +161 -0
  41. opentrons/drivers/absorbance_reader/simulator.py +84 -0
  42. opentrons/drivers/asyncio/__init__.py +0 -0
  43. opentrons/drivers/asyncio/communication/__init__.py +22 -0
  44. opentrons/drivers/asyncio/communication/async_serial.py +183 -0
  45. opentrons/drivers/asyncio/communication/errors.py +88 -0
  46. opentrons/drivers/asyncio/communication/serial_connection.py +552 -0
  47. opentrons/drivers/command_builder.py +102 -0
  48. opentrons/drivers/flex_stacker/__init__.py +13 -0
  49. opentrons/drivers/flex_stacker/abstract.py +214 -0
  50. opentrons/drivers/flex_stacker/driver.py +768 -0
  51. opentrons/drivers/flex_stacker/errors.py +68 -0
  52. opentrons/drivers/flex_stacker/simulator.py +309 -0
  53. opentrons/drivers/flex_stacker/types.py +367 -0
  54. opentrons/drivers/flex_stacker/utils.py +19 -0
  55. opentrons/drivers/heater_shaker/__init__.py +5 -0
  56. opentrons/drivers/heater_shaker/abstract.py +76 -0
  57. opentrons/drivers/heater_shaker/driver.py +204 -0
  58. opentrons/drivers/heater_shaker/simulator.py +94 -0
  59. opentrons/drivers/mag_deck/__init__.py +6 -0
  60. opentrons/drivers/mag_deck/abstract.py +44 -0
  61. opentrons/drivers/mag_deck/driver.py +208 -0
  62. opentrons/drivers/mag_deck/simulator.py +63 -0
  63. opentrons/drivers/rpi_drivers/__init__.py +33 -0
  64. opentrons/drivers/rpi_drivers/dev_types.py +94 -0
  65. opentrons/drivers/rpi_drivers/gpio.py +282 -0
  66. opentrons/drivers/rpi_drivers/gpio_simulator.py +127 -0
  67. opentrons/drivers/rpi_drivers/interfaces.py +15 -0
  68. opentrons/drivers/rpi_drivers/types.py +364 -0
  69. opentrons/drivers/rpi_drivers/usb.py +102 -0
  70. opentrons/drivers/rpi_drivers/usb_simulator.py +22 -0
  71. opentrons/drivers/serial_communication.py +151 -0
  72. opentrons/drivers/smoothie_drivers/__init__.py +4 -0
  73. opentrons/drivers/smoothie_drivers/connection.py +51 -0
  74. opentrons/drivers/smoothie_drivers/constants.py +121 -0
  75. opentrons/drivers/smoothie_drivers/driver_3_0.py +1933 -0
  76. opentrons/drivers/smoothie_drivers/errors.py +49 -0
  77. opentrons/drivers/smoothie_drivers/parse_utils.py +143 -0
  78. opentrons/drivers/smoothie_drivers/simulator.py +99 -0
  79. opentrons/drivers/smoothie_drivers/types.py +16 -0
  80. opentrons/drivers/temp_deck/__init__.py +10 -0
  81. opentrons/drivers/temp_deck/abstract.py +54 -0
  82. opentrons/drivers/temp_deck/driver.py +197 -0
  83. opentrons/drivers/temp_deck/simulator.py +57 -0
  84. opentrons/drivers/thermocycler/__init__.py +12 -0
  85. opentrons/drivers/thermocycler/abstract.py +99 -0
  86. opentrons/drivers/thermocycler/driver.py +395 -0
  87. opentrons/drivers/thermocycler/simulator.py +126 -0
  88. opentrons/drivers/types.py +107 -0
  89. opentrons/drivers/utils.py +222 -0
  90. opentrons/execute.py +742 -0
  91. opentrons/hardware_control/__init__.py +65 -0
  92. opentrons/hardware_control/__main__.py +77 -0
  93. opentrons/hardware_control/adapters.py +98 -0
  94. opentrons/hardware_control/api.py +1347 -0
  95. opentrons/hardware_control/backends/__init__.py +7 -0
  96. opentrons/hardware_control/backends/controller.py +400 -0
  97. opentrons/hardware_control/backends/errors.py +9 -0
  98. opentrons/hardware_control/backends/estop_state.py +164 -0
  99. opentrons/hardware_control/backends/flex_protocol.py +497 -0
  100. opentrons/hardware_control/backends/ot3controller.py +1930 -0
  101. opentrons/hardware_control/backends/ot3simulator.py +900 -0
  102. opentrons/hardware_control/backends/ot3utils.py +664 -0
  103. opentrons/hardware_control/backends/simulator.py +442 -0
  104. opentrons/hardware_control/backends/status_bar_state.py +240 -0
  105. opentrons/hardware_control/backends/subsystem_manager.py +431 -0
  106. opentrons/hardware_control/backends/tip_presence_manager.py +173 -0
  107. opentrons/hardware_control/backends/types.py +14 -0
  108. opentrons/hardware_control/constants.py +6 -0
  109. opentrons/hardware_control/dev_types.py +125 -0
  110. opentrons/hardware_control/emulation/__init__.py +0 -0
  111. opentrons/hardware_control/emulation/abstract_emulator.py +21 -0
  112. opentrons/hardware_control/emulation/app.py +56 -0
  113. opentrons/hardware_control/emulation/connection_handler.py +38 -0
  114. opentrons/hardware_control/emulation/heater_shaker.py +150 -0
  115. opentrons/hardware_control/emulation/magdeck.py +60 -0
  116. opentrons/hardware_control/emulation/module_server/__init__.py +8 -0
  117. opentrons/hardware_control/emulation/module_server/client.py +78 -0
  118. opentrons/hardware_control/emulation/module_server/helpers.py +130 -0
  119. opentrons/hardware_control/emulation/module_server/models.py +31 -0
  120. opentrons/hardware_control/emulation/module_server/server.py +110 -0
  121. opentrons/hardware_control/emulation/parser.py +74 -0
  122. opentrons/hardware_control/emulation/proxy.py +241 -0
  123. opentrons/hardware_control/emulation/run_emulator.py +68 -0
  124. opentrons/hardware_control/emulation/scripts/__init__.py +0 -0
  125. opentrons/hardware_control/emulation/scripts/run_app.py +54 -0
  126. opentrons/hardware_control/emulation/scripts/run_module_emulator.py +72 -0
  127. opentrons/hardware_control/emulation/scripts/run_smoothie.py +37 -0
  128. opentrons/hardware_control/emulation/settings.py +119 -0
  129. opentrons/hardware_control/emulation/simulations.py +133 -0
  130. opentrons/hardware_control/emulation/smoothie.py +192 -0
  131. opentrons/hardware_control/emulation/tempdeck.py +69 -0
  132. opentrons/hardware_control/emulation/thermocycler.py +128 -0
  133. opentrons/hardware_control/emulation/types.py +10 -0
  134. opentrons/hardware_control/emulation/util.py +38 -0
  135. opentrons/hardware_control/errors.py +43 -0
  136. opentrons/hardware_control/execution_manager.py +164 -0
  137. opentrons/hardware_control/instruments/__init__.py +5 -0
  138. opentrons/hardware_control/instruments/instrument_abc.py +39 -0
  139. opentrons/hardware_control/instruments/ot2/__init__.py +0 -0
  140. opentrons/hardware_control/instruments/ot2/instrument_calibration.py +152 -0
  141. opentrons/hardware_control/instruments/ot2/pipette.py +777 -0
  142. opentrons/hardware_control/instruments/ot2/pipette_handler.py +995 -0
  143. opentrons/hardware_control/instruments/ot3/__init__.py +0 -0
  144. opentrons/hardware_control/instruments/ot3/gripper.py +420 -0
  145. opentrons/hardware_control/instruments/ot3/gripper_handler.py +173 -0
  146. opentrons/hardware_control/instruments/ot3/instrument_calibration.py +214 -0
  147. opentrons/hardware_control/instruments/ot3/pipette.py +858 -0
  148. opentrons/hardware_control/instruments/ot3/pipette_handler.py +1030 -0
  149. opentrons/hardware_control/module_control.py +332 -0
  150. opentrons/hardware_control/modules/__init__.py +69 -0
  151. opentrons/hardware_control/modules/absorbance_reader.py +373 -0
  152. opentrons/hardware_control/modules/errors.py +7 -0
  153. opentrons/hardware_control/modules/flex_stacker.py +948 -0
  154. opentrons/hardware_control/modules/heater_shaker.py +426 -0
  155. opentrons/hardware_control/modules/lid_temp_status.py +35 -0
  156. opentrons/hardware_control/modules/magdeck.py +233 -0
  157. opentrons/hardware_control/modules/mod_abc.py +245 -0
  158. opentrons/hardware_control/modules/module_calibration.py +93 -0
  159. opentrons/hardware_control/modules/plate_temp_status.py +61 -0
  160. opentrons/hardware_control/modules/tempdeck.py +299 -0
  161. opentrons/hardware_control/modules/thermocycler.py +731 -0
  162. opentrons/hardware_control/modules/types.py +417 -0
  163. opentrons/hardware_control/modules/update.py +255 -0
  164. opentrons/hardware_control/modules/utils.py +73 -0
  165. opentrons/hardware_control/motion_utilities.py +318 -0
  166. opentrons/hardware_control/nozzle_manager.py +422 -0
  167. opentrons/hardware_control/ot3_calibration.py +1171 -0
  168. opentrons/hardware_control/ot3api.py +3227 -0
  169. opentrons/hardware_control/pause_manager.py +31 -0
  170. opentrons/hardware_control/poller.py +112 -0
  171. opentrons/hardware_control/protocols/__init__.py +106 -0
  172. opentrons/hardware_control/protocols/asyncio_configurable.py +11 -0
  173. opentrons/hardware_control/protocols/calibratable.py +45 -0
  174. opentrons/hardware_control/protocols/chassis_accessory_manager.py +90 -0
  175. opentrons/hardware_control/protocols/configurable.py +48 -0
  176. opentrons/hardware_control/protocols/event_sourcer.py +18 -0
  177. opentrons/hardware_control/protocols/execution_controllable.py +33 -0
  178. opentrons/hardware_control/protocols/flex_calibratable.py +96 -0
  179. opentrons/hardware_control/protocols/flex_instrument_configurer.py +52 -0
  180. opentrons/hardware_control/protocols/gripper_controller.py +55 -0
  181. opentrons/hardware_control/protocols/hardware_manager.py +51 -0
  182. opentrons/hardware_control/protocols/identifiable.py +16 -0
  183. opentrons/hardware_control/protocols/instrument_configurer.py +206 -0
  184. opentrons/hardware_control/protocols/liquid_handler.py +266 -0
  185. opentrons/hardware_control/protocols/module_provider.py +16 -0
  186. opentrons/hardware_control/protocols/motion_controller.py +243 -0
  187. opentrons/hardware_control/protocols/position_estimator.py +45 -0
  188. opentrons/hardware_control/protocols/simulatable.py +10 -0
  189. opentrons/hardware_control/protocols/stoppable.py +9 -0
  190. opentrons/hardware_control/protocols/types.py +27 -0
  191. opentrons/hardware_control/robot_calibration.py +224 -0
  192. opentrons/hardware_control/scripts/README.md +28 -0
  193. opentrons/hardware_control/scripts/__init__.py +1 -0
  194. opentrons/hardware_control/scripts/gripper_control.py +208 -0
  195. opentrons/hardware_control/scripts/ot3gripper +7 -0
  196. opentrons/hardware_control/scripts/ot3repl +7 -0
  197. opentrons/hardware_control/scripts/repl.py +187 -0
  198. opentrons/hardware_control/scripts/tc_control.py +97 -0
  199. opentrons/hardware_control/simulator_setup.py +260 -0
  200. opentrons/hardware_control/thread_manager.py +431 -0
  201. opentrons/hardware_control/threaded_async_lock.py +97 -0
  202. opentrons/hardware_control/types.py +792 -0
  203. opentrons/hardware_control/util.py +234 -0
  204. opentrons/legacy_broker.py +53 -0
  205. opentrons/legacy_commands/__init__.py +1 -0
  206. opentrons/legacy_commands/commands.py +483 -0
  207. opentrons/legacy_commands/helpers.py +153 -0
  208. opentrons/legacy_commands/module_commands.py +215 -0
  209. opentrons/legacy_commands/protocol_commands.py +54 -0
  210. opentrons/legacy_commands/publisher.py +155 -0
  211. opentrons/legacy_commands/robot_commands.py +51 -0
  212. opentrons/legacy_commands/types.py +1115 -0
  213. opentrons/motion_planning/__init__.py +32 -0
  214. opentrons/motion_planning/adjacent_slots_getters.py +168 -0
  215. opentrons/motion_planning/deck_conflict.py +396 -0
  216. opentrons/motion_planning/errors.py +35 -0
  217. opentrons/motion_planning/types.py +42 -0
  218. opentrons/motion_planning/waypoints.py +218 -0
  219. opentrons/ordered_set.py +138 -0
  220. opentrons/protocol_api/__init__.py +105 -0
  221. opentrons/protocol_api/_liquid.py +157 -0
  222. opentrons/protocol_api/_liquid_properties.py +814 -0
  223. opentrons/protocol_api/_nozzle_layout.py +31 -0
  224. opentrons/protocol_api/_parameter_context.py +300 -0
  225. opentrons/protocol_api/_parameters.py +31 -0
  226. opentrons/protocol_api/_transfer_liquid_validation.py +108 -0
  227. opentrons/protocol_api/_types.py +43 -0
  228. opentrons/protocol_api/config.py +23 -0
  229. opentrons/protocol_api/core/__init__.py +23 -0
  230. opentrons/protocol_api/core/common.py +33 -0
  231. opentrons/protocol_api/core/core_map.py +74 -0
  232. opentrons/protocol_api/core/engine/__init__.py +22 -0
  233. opentrons/protocol_api/core/engine/_default_labware_versions.py +179 -0
  234. opentrons/protocol_api/core/engine/deck_conflict.py +348 -0
  235. opentrons/protocol_api/core/engine/exceptions.py +19 -0
  236. opentrons/protocol_api/core/engine/instrument.py +2391 -0
  237. opentrons/protocol_api/core/engine/labware.py +238 -0
  238. opentrons/protocol_api/core/engine/load_labware_params.py +73 -0
  239. opentrons/protocol_api/core/engine/module_core.py +1025 -0
  240. opentrons/protocol_api/core/engine/overlap_versions.py +20 -0
  241. opentrons/protocol_api/core/engine/pipette_movement_conflict.py +358 -0
  242. opentrons/protocol_api/core/engine/point_calculations.py +64 -0
  243. opentrons/protocol_api/core/engine/protocol.py +1153 -0
  244. opentrons/protocol_api/core/engine/robot.py +139 -0
  245. opentrons/protocol_api/core/engine/stringify.py +74 -0
  246. opentrons/protocol_api/core/engine/transfer_components_executor.py +990 -0
  247. opentrons/protocol_api/core/engine/well.py +241 -0
  248. opentrons/protocol_api/core/instrument.py +459 -0
  249. opentrons/protocol_api/core/labware.py +151 -0
  250. opentrons/protocol_api/core/legacy/__init__.py +11 -0
  251. opentrons/protocol_api/core/legacy/_labware_geometry.py +37 -0
  252. opentrons/protocol_api/core/legacy/deck.py +369 -0
  253. opentrons/protocol_api/core/legacy/labware_offset_provider.py +108 -0
  254. opentrons/protocol_api/core/legacy/legacy_instrument_core.py +709 -0
  255. opentrons/protocol_api/core/legacy/legacy_labware_core.py +235 -0
  256. opentrons/protocol_api/core/legacy/legacy_module_core.py +592 -0
  257. opentrons/protocol_api/core/legacy/legacy_protocol_core.py +612 -0
  258. opentrons/protocol_api/core/legacy/legacy_well_core.py +162 -0
  259. opentrons/protocol_api/core/legacy/load_info.py +67 -0
  260. opentrons/protocol_api/core/legacy/module_geometry.py +547 -0
  261. opentrons/protocol_api/core/legacy/well_geometry.py +148 -0
  262. opentrons/protocol_api/core/legacy_simulator/__init__.py +16 -0
  263. opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +624 -0
  264. opentrons/protocol_api/core/legacy_simulator/legacy_protocol_core.py +85 -0
  265. opentrons/protocol_api/core/module.py +484 -0
  266. opentrons/protocol_api/core/protocol.py +311 -0
  267. opentrons/protocol_api/core/robot.py +51 -0
  268. opentrons/protocol_api/core/well.py +116 -0
  269. opentrons/protocol_api/core/well_grid.py +45 -0
  270. opentrons/protocol_api/create_protocol_context.py +177 -0
  271. opentrons/protocol_api/deck.py +223 -0
  272. opentrons/protocol_api/disposal_locations.py +244 -0
  273. opentrons/protocol_api/instrument_context.py +3212 -0
  274. opentrons/protocol_api/labware.py +1579 -0
  275. opentrons/protocol_api/module_contexts.py +1425 -0
  276. opentrons/protocol_api/module_validation_and_errors.py +61 -0
  277. opentrons/protocol_api/protocol_context.py +1688 -0
  278. opentrons/protocol_api/robot_context.py +303 -0
  279. opentrons/protocol_api/validation.py +761 -0
  280. opentrons/protocol_engine/__init__.py +155 -0
  281. opentrons/protocol_engine/actions/__init__.py +65 -0
  282. opentrons/protocol_engine/actions/action_dispatcher.py +30 -0
  283. opentrons/protocol_engine/actions/action_handler.py +13 -0
  284. opentrons/protocol_engine/actions/actions.py +302 -0
  285. opentrons/protocol_engine/actions/get_state_update.py +38 -0
  286. opentrons/protocol_engine/clients/__init__.py +5 -0
  287. opentrons/protocol_engine/clients/sync_client.py +174 -0
  288. opentrons/protocol_engine/clients/transports.py +197 -0
  289. opentrons/protocol_engine/commands/__init__.py +757 -0
  290. opentrons/protocol_engine/commands/absorbance_reader/__init__.py +61 -0
  291. opentrons/protocol_engine/commands/absorbance_reader/close_lid.py +154 -0
  292. opentrons/protocol_engine/commands/absorbance_reader/common.py +6 -0
  293. opentrons/protocol_engine/commands/absorbance_reader/initialize.py +151 -0
  294. opentrons/protocol_engine/commands/absorbance_reader/open_lid.py +154 -0
  295. opentrons/protocol_engine/commands/absorbance_reader/read.py +226 -0
  296. opentrons/protocol_engine/commands/air_gap_in_place.py +162 -0
  297. opentrons/protocol_engine/commands/aspirate.py +244 -0
  298. opentrons/protocol_engine/commands/aspirate_in_place.py +184 -0
  299. opentrons/protocol_engine/commands/aspirate_while_tracking.py +211 -0
  300. opentrons/protocol_engine/commands/blow_out.py +146 -0
  301. opentrons/protocol_engine/commands/blow_out_in_place.py +119 -0
  302. opentrons/protocol_engine/commands/calibration/__init__.py +60 -0
  303. opentrons/protocol_engine/commands/calibration/calibrate_gripper.py +166 -0
  304. opentrons/protocol_engine/commands/calibration/calibrate_module.py +117 -0
  305. opentrons/protocol_engine/commands/calibration/calibrate_pipette.py +96 -0
  306. opentrons/protocol_engine/commands/calibration/move_to_maintenance_position.py +156 -0
  307. opentrons/protocol_engine/commands/command.py +308 -0
  308. opentrons/protocol_engine/commands/command_unions.py +974 -0
  309. opentrons/protocol_engine/commands/comment.py +57 -0
  310. opentrons/protocol_engine/commands/configure_for_volume.py +108 -0
  311. opentrons/protocol_engine/commands/configure_nozzle_layout.py +115 -0
  312. opentrons/protocol_engine/commands/custom.py +67 -0
  313. opentrons/protocol_engine/commands/dispense.py +194 -0
  314. opentrons/protocol_engine/commands/dispense_in_place.py +179 -0
  315. opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
  316. opentrons/protocol_engine/commands/drop_tip.py +232 -0
  317. opentrons/protocol_engine/commands/drop_tip_in_place.py +205 -0
  318. opentrons/protocol_engine/commands/flex_stacker/__init__.py +64 -0
  319. opentrons/protocol_engine/commands/flex_stacker/common.py +900 -0
  320. opentrons/protocol_engine/commands/flex_stacker/empty.py +293 -0
  321. opentrons/protocol_engine/commands/flex_stacker/fill.py +281 -0
  322. opentrons/protocol_engine/commands/flex_stacker/retrieve.py +339 -0
  323. opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +328 -0
  324. opentrons/protocol_engine/commands/flex_stacker/store.py +326 -0
  325. opentrons/protocol_engine/commands/generate_command_schema.py +61 -0
  326. opentrons/protocol_engine/commands/get_next_tip.py +134 -0
  327. opentrons/protocol_engine/commands/get_tip_presence.py +87 -0
  328. opentrons/protocol_engine/commands/hash_command_params.py +38 -0
  329. opentrons/protocol_engine/commands/heater_shaker/__init__.py +102 -0
  330. opentrons/protocol_engine/commands/heater_shaker/close_labware_latch.py +83 -0
  331. opentrons/protocol_engine/commands/heater_shaker/deactivate_heater.py +82 -0
  332. opentrons/protocol_engine/commands/heater_shaker/deactivate_shaker.py +84 -0
  333. opentrons/protocol_engine/commands/heater_shaker/open_labware_latch.py +110 -0
  334. opentrons/protocol_engine/commands/heater_shaker/set_and_wait_for_shake_speed.py +125 -0
  335. opentrons/protocol_engine/commands/heater_shaker/set_target_temperature.py +90 -0
  336. opentrons/protocol_engine/commands/heater_shaker/wait_for_temperature.py +102 -0
  337. opentrons/protocol_engine/commands/home.py +100 -0
  338. opentrons/protocol_engine/commands/identify_module.py +86 -0
  339. opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
  340. opentrons/protocol_engine/commands/liquid_probe.py +464 -0
  341. opentrons/protocol_engine/commands/load_labware.py +210 -0
  342. opentrons/protocol_engine/commands/load_lid.py +154 -0
  343. opentrons/protocol_engine/commands/load_lid_stack.py +272 -0
  344. opentrons/protocol_engine/commands/load_liquid.py +95 -0
  345. opentrons/protocol_engine/commands/load_liquid_class.py +144 -0
  346. opentrons/protocol_engine/commands/load_module.py +223 -0
  347. opentrons/protocol_engine/commands/load_pipette.py +167 -0
  348. opentrons/protocol_engine/commands/magnetic_module/__init__.py +32 -0
  349. opentrons/protocol_engine/commands/magnetic_module/disengage.py +97 -0
  350. opentrons/protocol_engine/commands/magnetic_module/engage.py +119 -0
  351. opentrons/protocol_engine/commands/move_labware.py +546 -0
  352. opentrons/protocol_engine/commands/move_relative.py +102 -0
  353. opentrons/protocol_engine/commands/move_to_addressable_area.py +176 -0
  354. opentrons/protocol_engine/commands/move_to_addressable_area_for_drop_tip.py +198 -0
  355. opentrons/protocol_engine/commands/move_to_coordinates.py +107 -0
  356. opentrons/protocol_engine/commands/move_to_well.py +119 -0
  357. opentrons/protocol_engine/commands/movement_common.py +338 -0
  358. opentrons/protocol_engine/commands/pick_up_tip.py +241 -0
  359. opentrons/protocol_engine/commands/pipetting_common.py +443 -0
  360. opentrons/protocol_engine/commands/prepare_to_aspirate.py +121 -0
  361. opentrons/protocol_engine/commands/pressure_dispense.py +155 -0
  362. opentrons/protocol_engine/commands/reload_labware.py +90 -0
  363. opentrons/protocol_engine/commands/retract_axis.py +75 -0
  364. opentrons/protocol_engine/commands/robot/__init__.py +70 -0
  365. opentrons/protocol_engine/commands/robot/close_gripper_jaw.py +96 -0
  366. opentrons/protocol_engine/commands/robot/common.py +18 -0
  367. opentrons/protocol_engine/commands/robot/move_axes_relative.py +101 -0
  368. opentrons/protocol_engine/commands/robot/move_axes_to.py +100 -0
  369. opentrons/protocol_engine/commands/robot/move_to.py +94 -0
  370. opentrons/protocol_engine/commands/robot/open_gripper_jaw.py +86 -0
  371. opentrons/protocol_engine/commands/save_position.py +109 -0
  372. opentrons/protocol_engine/commands/seal_pipette_to_tip.py +353 -0
  373. opentrons/protocol_engine/commands/set_rail_lights.py +67 -0
  374. opentrons/protocol_engine/commands/set_status_bar.py +89 -0
  375. opentrons/protocol_engine/commands/temperature_module/__init__.py +46 -0
  376. opentrons/protocol_engine/commands/temperature_module/deactivate.py +86 -0
  377. opentrons/protocol_engine/commands/temperature_module/set_target_temperature.py +97 -0
  378. opentrons/protocol_engine/commands/temperature_module/wait_for_temperature.py +104 -0
  379. opentrons/protocol_engine/commands/thermocycler/__init__.py +152 -0
  380. opentrons/protocol_engine/commands/thermocycler/close_lid.py +87 -0
  381. opentrons/protocol_engine/commands/thermocycler/deactivate_block.py +80 -0
  382. opentrons/protocol_engine/commands/thermocycler/deactivate_lid.py +80 -0
  383. opentrons/protocol_engine/commands/thermocycler/open_lid.py +87 -0
  384. opentrons/protocol_engine/commands/thermocycler/run_extended_profile.py +171 -0
  385. opentrons/protocol_engine/commands/thermocycler/run_profile.py +124 -0
  386. opentrons/protocol_engine/commands/thermocycler/set_target_block_temperature.py +140 -0
  387. opentrons/protocol_engine/commands/thermocycler/set_target_lid_temperature.py +100 -0
  388. opentrons/protocol_engine/commands/thermocycler/wait_for_block_temperature.py +93 -0
  389. opentrons/protocol_engine/commands/thermocycler/wait_for_lid_temperature.py +89 -0
  390. opentrons/protocol_engine/commands/touch_tip.py +189 -0
  391. opentrons/protocol_engine/commands/unsafe/__init__.py +161 -0
  392. opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +100 -0
  393. opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +121 -0
  394. opentrons/protocol_engine/commands/unsafe/unsafe_engage_axes.py +82 -0
  395. opentrons/protocol_engine/commands/unsafe/unsafe_place_labware.py +208 -0
  396. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_close_latch.py +94 -0
  397. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_manual_retrieve.py +295 -0
  398. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_open_latch.py +91 -0
  399. opentrons/protocol_engine/commands/unsafe/unsafe_stacker_prepare_shuttle.py +136 -0
  400. opentrons/protocol_engine/commands/unsafe/unsafe_ungrip_labware.py +77 -0
  401. opentrons/protocol_engine/commands/unsafe/update_position_estimators.py +90 -0
  402. opentrons/protocol_engine/commands/unseal_pipette_from_tip.py +153 -0
  403. opentrons/protocol_engine/commands/verify_tip_presence.py +100 -0
  404. opentrons/protocol_engine/commands/wait_for_duration.py +76 -0
  405. opentrons/protocol_engine/commands/wait_for_resume.py +75 -0
  406. opentrons/protocol_engine/create_protocol_engine.py +193 -0
  407. opentrons/protocol_engine/engine_support.py +28 -0
  408. opentrons/protocol_engine/error_recovery_policy.py +81 -0
  409. opentrons/protocol_engine/errors/__init__.py +191 -0
  410. opentrons/protocol_engine/errors/error_occurrence.py +182 -0
  411. opentrons/protocol_engine/errors/exceptions.py +1308 -0
  412. opentrons/protocol_engine/execution/__init__.py +50 -0
  413. opentrons/protocol_engine/execution/command_executor.py +216 -0
  414. opentrons/protocol_engine/execution/create_queue_worker.py +102 -0
  415. opentrons/protocol_engine/execution/door_watcher.py +119 -0
  416. opentrons/protocol_engine/execution/equipment.py +819 -0
  417. opentrons/protocol_engine/execution/error_recovery_hardware_state_synchronizer.py +101 -0
  418. opentrons/protocol_engine/execution/gantry_mover.py +686 -0
  419. opentrons/protocol_engine/execution/hardware_stopper.py +147 -0
  420. opentrons/protocol_engine/execution/heater_shaker_movement_flagger.py +207 -0
  421. opentrons/protocol_engine/execution/labware_movement.py +297 -0
  422. opentrons/protocol_engine/execution/movement.py +349 -0
  423. opentrons/protocol_engine/execution/pipetting.py +607 -0
  424. opentrons/protocol_engine/execution/queue_worker.py +86 -0
  425. opentrons/protocol_engine/execution/rail_lights.py +25 -0
  426. opentrons/protocol_engine/execution/run_control.py +33 -0
  427. opentrons/protocol_engine/execution/status_bar.py +34 -0
  428. opentrons/protocol_engine/execution/thermocycler_movement_flagger.py +188 -0
  429. opentrons/protocol_engine/execution/thermocycler_plate_lifter.py +81 -0
  430. opentrons/protocol_engine/execution/tip_handler.py +550 -0
  431. opentrons/protocol_engine/labware_offset_standardization.py +194 -0
  432. opentrons/protocol_engine/notes/__init__.py +17 -0
  433. opentrons/protocol_engine/notes/notes.py +59 -0
  434. opentrons/protocol_engine/plugins.py +104 -0
  435. opentrons/protocol_engine/protocol_engine.py +683 -0
  436. opentrons/protocol_engine/resources/__init__.py +26 -0
  437. opentrons/protocol_engine/resources/deck_configuration_provider.py +232 -0
  438. opentrons/protocol_engine/resources/deck_data_provider.py +94 -0
  439. opentrons/protocol_engine/resources/file_provider.py +161 -0
  440. opentrons/protocol_engine/resources/fixture_validation.py +58 -0
  441. opentrons/protocol_engine/resources/labware_data_provider.py +106 -0
  442. opentrons/protocol_engine/resources/labware_validation.py +73 -0
  443. opentrons/protocol_engine/resources/model_utils.py +32 -0
  444. opentrons/protocol_engine/resources/module_data_provider.py +44 -0
  445. opentrons/protocol_engine/resources/ot3_validation.py +21 -0
  446. opentrons/protocol_engine/resources/pipette_data_provider.py +379 -0
  447. opentrons/protocol_engine/slot_standardization.py +128 -0
  448. opentrons/protocol_engine/state/__init__.py +1 -0
  449. opentrons/protocol_engine/state/_abstract_store.py +27 -0
  450. opentrons/protocol_engine/state/_axis_aligned_bounding_box.py +50 -0
  451. opentrons/protocol_engine/state/_labware_origin_math.py +636 -0
  452. opentrons/protocol_engine/state/_move_types.py +83 -0
  453. opentrons/protocol_engine/state/_well_math.py +193 -0
  454. opentrons/protocol_engine/state/addressable_areas.py +699 -0
  455. opentrons/protocol_engine/state/command_history.py +309 -0
  456. opentrons/protocol_engine/state/commands.py +1158 -0
  457. opentrons/protocol_engine/state/config.py +39 -0
  458. opentrons/protocol_engine/state/files.py +57 -0
  459. opentrons/protocol_engine/state/fluid_stack.py +138 -0
  460. opentrons/protocol_engine/state/geometry.py +2359 -0
  461. opentrons/protocol_engine/state/inner_well_math_utils.py +548 -0
  462. opentrons/protocol_engine/state/labware.py +1459 -0
  463. opentrons/protocol_engine/state/liquid_classes.py +82 -0
  464. opentrons/protocol_engine/state/liquids.py +73 -0
  465. opentrons/protocol_engine/state/module_substates/__init__.py +45 -0
  466. opentrons/protocol_engine/state/module_substates/absorbance_reader_substate.py +35 -0
  467. opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +112 -0
  468. opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +115 -0
  469. opentrons/protocol_engine/state/module_substates/magnetic_block_substate.py +17 -0
  470. opentrons/protocol_engine/state/module_substates/magnetic_module_substate.py +65 -0
  471. opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +67 -0
  472. opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +163 -0
  473. opentrons/protocol_engine/state/modules.py +1500 -0
  474. opentrons/protocol_engine/state/motion.py +373 -0
  475. opentrons/protocol_engine/state/pipettes.py +905 -0
  476. opentrons/protocol_engine/state/state.py +421 -0
  477. opentrons/protocol_engine/state/state_summary.py +36 -0
  478. opentrons/protocol_engine/state/tips.py +420 -0
  479. opentrons/protocol_engine/state/update_types.py +904 -0
  480. opentrons/protocol_engine/state/wells.py +290 -0
  481. opentrons/protocol_engine/types/__init__.py +308 -0
  482. opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
  483. opentrons/protocol_engine/types/command_annotations.py +53 -0
  484. opentrons/protocol_engine/types/deck_configuration.py +81 -0
  485. opentrons/protocol_engine/types/execution.py +96 -0
  486. opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
  487. opentrons/protocol_engine/types/instrument.py +47 -0
  488. opentrons/protocol_engine/types/instrument_sensors.py +47 -0
  489. opentrons/protocol_engine/types/labware.py +131 -0
  490. opentrons/protocol_engine/types/labware_movement.py +22 -0
  491. opentrons/protocol_engine/types/labware_offset_location.py +111 -0
  492. opentrons/protocol_engine/types/labware_offset_vector.py +16 -0
  493. opentrons/protocol_engine/types/liquid.py +40 -0
  494. opentrons/protocol_engine/types/liquid_class.py +59 -0
  495. opentrons/protocol_engine/types/liquid_handling.py +13 -0
  496. opentrons/protocol_engine/types/liquid_level_detection.py +191 -0
  497. opentrons/protocol_engine/types/location.py +194 -0
  498. opentrons/protocol_engine/types/module.py +303 -0
  499. opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
  500. opentrons/protocol_engine/types/run_time_parameters.py +133 -0
  501. opentrons/protocol_engine/types/tip.py +18 -0
  502. opentrons/protocol_engine/types/util.py +21 -0
  503. opentrons/protocol_engine/types/well_position.py +124 -0
  504. opentrons/protocol_reader/__init__.py +37 -0
  505. opentrons/protocol_reader/extract_labware_definitions.py +66 -0
  506. opentrons/protocol_reader/file_format_validator.py +152 -0
  507. opentrons/protocol_reader/file_hasher.py +27 -0
  508. opentrons/protocol_reader/file_identifier.py +284 -0
  509. opentrons/protocol_reader/file_reader_writer.py +90 -0
  510. opentrons/protocol_reader/input_file.py +16 -0
  511. opentrons/protocol_reader/protocol_files_invalid_error.py +6 -0
  512. opentrons/protocol_reader/protocol_reader.py +188 -0
  513. opentrons/protocol_reader/protocol_source.py +124 -0
  514. opentrons/protocol_reader/role_analyzer.py +86 -0
  515. opentrons/protocol_runner/__init__.py +26 -0
  516. opentrons/protocol_runner/create_simulating_orchestrator.py +118 -0
  517. opentrons/protocol_runner/json_file_reader.py +55 -0
  518. opentrons/protocol_runner/json_translator.py +314 -0
  519. opentrons/protocol_runner/legacy_command_mapper.py +848 -0
  520. opentrons/protocol_runner/legacy_context_plugin.py +116 -0
  521. opentrons/protocol_runner/protocol_runner.py +530 -0
  522. opentrons/protocol_runner/python_protocol_wrappers.py +179 -0
  523. opentrons/protocol_runner/run_orchestrator.py +496 -0
  524. opentrons/protocol_runner/task_queue.py +95 -0
  525. opentrons/protocols/__init__.py +6 -0
  526. opentrons/protocols/advanced_control/__init__.py +0 -0
  527. opentrons/protocols/advanced_control/common.py +38 -0
  528. opentrons/protocols/advanced_control/mix.py +60 -0
  529. opentrons/protocols/advanced_control/transfers/__init__.py +0 -0
  530. opentrons/protocols/advanced_control/transfers/common.py +180 -0
  531. opentrons/protocols/advanced_control/transfers/transfer.py +972 -0
  532. opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +231 -0
  533. opentrons/protocols/api_support/__init__.py +0 -0
  534. opentrons/protocols/api_support/constants.py +8 -0
  535. opentrons/protocols/api_support/deck_type.py +110 -0
  536. opentrons/protocols/api_support/definitions.py +18 -0
  537. opentrons/protocols/api_support/instrument.py +151 -0
  538. opentrons/protocols/api_support/labware_like.py +233 -0
  539. opentrons/protocols/api_support/tip_tracker.py +175 -0
  540. opentrons/protocols/api_support/types.py +32 -0
  541. opentrons/protocols/api_support/util.py +403 -0
  542. opentrons/protocols/bundle.py +89 -0
  543. opentrons/protocols/duration/__init__.py +4 -0
  544. opentrons/protocols/duration/errors.py +5 -0
  545. opentrons/protocols/duration/estimator.py +628 -0
  546. opentrons/protocols/execution/__init__.py +0 -0
  547. opentrons/protocols/execution/dev_types.py +181 -0
  548. opentrons/protocols/execution/errors.py +40 -0
  549. opentrons/protocols/execution/execute.py +84 -0
  550. opentrons/protocols/execution/execute_json_v3.py +275 -0
  551. opentrons/protocols/execution/execute_json_v4.py +359 -0
  552. opentrons/protocols/execution/execute_json_v5.py +28 -0
  553. opentrons/protocols/execution/execute_python.py +169 -0
  554. opentrons/protocols/execution/json_dispatchers.py +87 -0
  555. opentrons/protocols/execution/types.py +7 -0
  556. opentrons/protocols/geometry/__init__.py +0 -0
  557. opentrons/protocols/geometry/planning.py +297 -0
  558. opentrons/protocols/labware.py +312 -0
  559. opentrons/protocols/models/__init__.py +0 -0
  560. opentrons/protocols/models/json_protocol.py +679 -0
  561. opentrons/protocols/parameters/__init__.py +0 -0
  562. opentrons/protocols/parameters/csv_parameter_definition.py +77 -0
  563. opentrons/protocols/parameters/csv_parameter_interface.py +96 -0
  564. opentrons/protocols/parameters/exceptions.py +34 -0
  565. opentrons/protocols/parameters/parameter_definition.py +272 -0
  566. opentrons/protocols/parameters/types.py +17 -0
  567. opentrons/protocols/parameters/validation.py +267 -0
  568. opentrons/protocols/parse.py +671 -0
  569. opentrons/protocols/types.py +159 -0
  570. opentrons/py.typed +0 -0
  571. opentrons/resources/scripts/lpc21isp +0 -0
  572. opentrons/resources/smoothie-edge-8414642.hex +23010 -0
  573. opentrons/simulate.py +1065 -0
  574. opentrons/system/__init__.py +6 -0
  575. opentrons/system/camera.py +51 -0
  576. opentrons/system/log_control.py +59 -0
  577. opentrons/system/nmcli.py +856 -0
  578. opentrons/system/resin.py +24 -0
  579. opentrons/system/smoothie_update.py +15 -0
  580. opentrons/system/wifi.py +204 -0
  581. opentrons/tools/__init__.py +0 -0
  582. opentrons/tools/args_handler.py +22 -0
  583. opentrons/tools/write_pipette_memory.py +157 -0
  584. opentrons/types.py +618 -0
  585. opentrons/util/__init__.py +1 -0
  586. opentrons/util/async_helpers.py +166 -0
  587. opentrons/util/broker.py +84 -0
  588. opentrons/util/change_notifier.py +47 -0
  589. opentrons/util/entrypoint_util.py +278 -0
  590. opentrons/util/get_union_elements.py +26 -0
  591. opentrons/util/helpers.py +6 -0
  592. opentrons/util/linal.py +178 -0
  593. opentrons/util/logging_config.py +265 -0
  594. opentrons/util/logging_queue_handler.py +61 -0
  595. opentrons/util/performance_helpers.py +157 -0
  596. opentrons-8.6.0a1.dist-info/METADATA +37 -0
  597. opentrons-8.6.0a1.dist-info/RECORD +600 -0
  598. opentrons-8.6.0a1.dist-info/WHEEL +4 -0
  599. opentrons-8.6.0a1.dist-info/entry_points.txt +3 -0
  600. opentrons-8.6.0a1.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,245 @@
1
+ import abc
2
+ import asyncio
3
+ import logging
4
+ import re
5
+ from typing import Any, ClassVar, Mapping, Optional, TypeVar
6
+ from packaging.version import InvalidVersion, parse, Version
7
+ from opentrons.config import IS_ROBOT, ROBOT_FIRMWARE_DIR
8
+ from opentrons.drivers.rpi_drivers.types import USBPort
9
+
10
+ from ..execution_manager import ExecutionManager
11
+ from .types import (
12
+ BundledFirmware,
13
+ ModuleDisconnectedCallback,
14
+ UploadFunction,
15
+ LiveData,
16
+ ModuleType,
17
+ HopperDoorState,
18
+ )
19
+
20
+ mod_log = logging.getLogger(__name__)
21
+
22
+ TaskPayload = TypeVar("TaskPayload")
23
+
24
+
25
+ def parse_fw_version(version: str) -> Version:
26
+ try:
27
+ device_version = parse(version)
28
+ # This is a patch for older versions of packaging - they would try and parse old
29
+ # kidns of versions and return a LegacyVersion object. We can't check for that
30
+ # explicitly because they removed it in modern versions of packaging.
31
+ if not isinstance(device_version, Version):
32
+ raise InvalidVersion()
33
+ except InvalidVersion:
34
+ device_version = parse("v0.0.0")
35
+ return device_version
36
+
37
+
38
+ class AbstractModule(abc.ABC):
39
+ """Defines the common methods of a module."""
40
+
41
+ MODULE_TYPE: ClassVar[ModuleType]
42
+
43
+ @classmethod
44
+ @abc.abstractmethod
45
+ async def build(
46
+ cls,
47
+ port: str,
48
+ usb_port: USBPort,
49
+ hw_control_loop: asyncio.AbstractEventLoop,
50
+ execution_manager: Optional[ExecutionManager] = None,
51
+ poll_interval_seconds: Optional[float] = None,
52
+ simulating: bool = False,
53
+ sim_model: Optional[str] = None,
54
+ sim_serial_number: Optional[str] = None,
55
+ disconnected_callback: ModuleDisconnectedCallback = None,
56
+ ) -> "AbstractModule":
57
+ """Modules should always be created using this factory.
58
+
59
+ This lets the (perhaps blocking) work of connecting to and initializing
60
+ a module be in a place that can be async.
61
+ """
62
+
63
+ def __init__(
64
+ self,
65
+ port: str,
66
+ usb_port: USBPort,
67
+ hw_control_loop: asyncio.AbstractEventLoop,
68
+ execution_manager: Optional[ExecutionManager] = None,
69
+ disconnected_callback: ModuleDisconnectedCallback = None,
70
+ ) -> None:
71
+ self._port = port
72
+ self._usb_port = usb_port
73
+ self._loop = hw_control_loop
74
+ self._execution_manager = execution_manager
75
+ self._bundled_fw: Optional[BundledFirmware] = self.get_bundled_fw()
76
+ self._disconnected_callback = disconnected_callback
77
+ self._updating = False
78
+
79
+ @staticmethod
80
+ def sort_key(inst: "AbstractModule") -> int:
81
+ usb_port = inst.usb_port
82
+
83
+ primary_port = usb_port.port_number
84
+
85
+ if usb_port.hub_port is not None:
86
+ secondary_port = usb_port.hub_port
87
+ else:
88
+ secondary_port = 0
89
+
90
+ return primary_port * 1000 + secondary_port
91
+
92
+ @property
93
+ def loop(self) -> asyncio.AbstractEventLoop:
94
+ return self._loop
95
+
96
+ @property
97
+ def updating(self) -> bool:
98
+ """The device is updating is True."""
99
+ return self._updating
100
+
101
+ def disconnected_callback(self) -> None:
102
+ """Called from within the module object to signify the object is no longer connected"""
103
+ if self._disconnected_callback is not None:
104
+ self._disconnected_callback(self.port, self.serial_number)
105
+
106
+ def get_bundled_fw(self) -> Optional[BundledFirmware]:
107
+ """Get absolute path to bundled version of module fw if available."""
108
+ if not IS_ROBOT:
109
+ return None
110
+ file_prefix = self.firmware_prefix()
111
+
112
+ MODULE_FW_RE = re.compile(f"^{file_prefix}@v(.*)[.](hex|bin|byoup)$")
113
+ for fw_resource in ROBOT_FIRMWARE_DIR.iterdir(): # type: ignore
114
+ matches = MODULE_FW_RE.search(fw_resource.name)
115
+ if matches:
116
+ return BundledFirmware(version=matches.group(1), path=fw_resource)
117
+
118
+ mod_log.info(f"no available fw file found for: {file_prefix}")
119
+ return None
120
+
121
+ def has_available_update(self) -> bool:
122
+ """Return whether a newer firmware file is available"""
123
+ if self.device_info and self._bundled_fw:
124
+ device_version = parse_fw_version(self.device_info["version"])
125
+ available_version = parse_fw_version(self._bundled_fw.version)
126
+ return available_version > device_version
127
+ return False
128
+
129
+ async def wait_for_is_running(self) -> None:
130
+ if not self.is_simulated and self._execution_manager is not None:
131
+ await self._execution_manager.wait_for_is_running()
132
+
133
+ def make_cancellable(self, task: "asyncio.Task[TaskPayload]") -> None:
134
+ if self._execution_manager is not None:
135
+ self._execution_manager.register_cancellable_task(task)
136
+
137
+ @abc.abstractmethod
138
+ async def deactivate(self, must_be_running: bool = True) -> None:
139
+ """Deactivate the module.
140
+
141
+ Contains an override to the `wait_for_is_running` step in cases where the
142
+ module must be deactivated regardless of context."""
143
+ pass
144
+
145
+ @property
146
+ @abc.abstractmethod
147
+ def status(self) -> str:
148
+ """Return some string describing status."""
149
+ pass
150
+
151
+ @property
152
+ @abc.abstractmethod
153
+ def device_info(self) -> Mapping[str, str]:
154
+ """Return a dict of the module's static information (serial, etc)"""
155
+ pass
156
+
157
+ @property
158
+ @abc.abstractmethod
159
+ def live_data(self) -> LiveData:
160
+ """Return a dict of the module's dynamic information"""
161
+ pass
162
+
163
+ @property
164
+ @abc.abstractmethod
165
+ def is_simulated(self) -> bool:
166
+ """True if >this is a simulated module."""
167
+ pass
168
+
169
+ @property
170
+ def port(self) -> str:
171
+ """The virtual port where the module is connected."""
172
+ return self._port
173
+
174
+ @property
175
+ def usb_port(self) -> USBPort:
176
+ """The physical port where the module is connected."""
177
+ return self._usb_port
178
+
179
+ @property
180
+ def serial_number(self) -> Optional[str]:
181
+ """The usb serial number of this device."""
182
+ return self.device_info.get("serial")
183
+
184
+ @property
185
+ def hopper_door_state(self) -> Optional[HopperDoorState]:
186
+ """Return a Flex Stacker Hopper Module Door State"""
187
+ pass
188
+
189
+ @abc.abstractmethod
190
+ async def prep_for_update(self) -> str:
191
+ """Prepare for an update.
192
+
193
+ By the time this coroutine completes, the hardware should be ready
194
+ to take an update. This implicitly tears down the module instance;
195
+ it does not need to be either working or recoverable after this
196
+ coroutine completes.
197
+
198
+ :returns str: The port we're running on.
199
+ """
200
+ pass
201
+
202
+ @property
203
+ def bundled_fw(self) -> Optional[BundledFirmware]:
204
+ return self._bundled_fw
205
+
206
+ @abc.abstractmethod
207
+ def model(self) -> str:
208
+ """A name for this specific module, matching module defs"""
209
+ pass
210
+
211
+ @classmethod
212
+ @abc.abstractmethod
213
+ def name(cls) -> str:
214
+ """A shortname used for matching usb ports, among other things"""
215
+ pass
216
+
217
+ @abc.abstractmethod
218
+ def firmware_prefix(self) -> str:
219
+ """The prefix used for looking up firmware"""
220
+ pass
221
+
222
+ @abc.abstractmethod
223
+ def bootloader(self) -> UploadFunction:
224
+ """Method used to upload file to this module's bootloader."""
225
+ pass
226
+
227
+ async def cleanup(self) -> None:
228
+ """Clean up the module instance.
229
+
230
+ Clean up, i.e. stop pollers, disconnect serial, etc in preparation for
231
+ object destruction.
232
+ """
233
+ pass
234
+
235
+ def event_listener(self, event: Any) -> None:
236
+ """Listen for events and update the module state."""
237
+ pass
238
+
239
+ async def identify(self, start: bool, color_name: Optional[str] = None) -> None:
240
+ """Identify the module."""
241
+ pass
242
+
243
+ def cleanup_persistent(self) -> None:
244
+ """Reset any persistent data on the module that should not exist outside of a run."""
245
+ pass
@@ -0,0 +1,93 @@
1
+ from datetime import datetime
2
+
3
+ from dataclasses import dataclass
4
+ from typing import List, Optional
5
+ from opentrons.calibration_storage.ot3.models.v1 import CalibrationStatus
6
+ from opentrons.calibration_storage.ot3.module_offset import (
7
+ get_module_offset,
8
+ load_all_module_offsets,
9
+ save_module_calibration,
10
+ )
11
+ from opentrons.calibration_storage.types import SourceType
12
+ from opentrons.hardware_control.modules.types import ModuleType
13
+ from opentrons.hardware_control.types import OT3Mount
14
+
15
+
16
+ from opentrons.types import Point
17
+
18
+
19
+ @dataclass
20
+ class ModuleCalibrationOffset:
21
+ """Class to store module offset calibration data."""
22
+
23
+ offset: Point
24
+ module_id: str
25
+ module: ModuleType
26
+ source: SourceType
27
+ status: CalibrationStatus
28
+ slot: str
29
+ mount: Optional[OT3Mount] = None
30
+ instrument_id: Optional[str] = None
31
+ last_modified: Optional[datetime] = None
32
+
33
+
34
+ def load_module_calibration_offset(
35
+ module_type: ModuleType,
36
+ module_id: str,
37
+ ) -> Optional[ModuleCalibrationOffset]:
38
+ """Loads the calibration offset for a module."""
39
+ module_offset_data = get_module_offset(module_type, module_id)
40
+ if not module_offset_data:
41
+ return None
42
+ return ModuleCalibrationOffset(
43
+ module=module_type,
44
+ module_id=module_id,
45
+ slot=module_offset_data.slot,
46
+ mount=module_offset_data.mount,
47
+ offset=module_offset_data.offset,
48
+ last_modified=module_offset_data.lastModified,
49
+ instrument_id=module_offset_data.instrument_id,
50
+ source=module_offset_data.source,
51
+ status=CalibrationStatus(
52
+ markedAt=module_offset_data.status.markedAt,
53
+ markedBad=module_offset_data.status.markedBad,
54
+ source=module_offset_data.status.source,
55
+ ),
56
+ )
57
+
58
+
59
+ def save_module_calibration_offset(
60
+ offset: Point,
61
+ mount: OT3Mount,
62
+ slot: str,
63
+ module: ModuleType,
64
+ module_id: str,
65
+ instrument_id: Optional[str] = None,
66
+ ) -> None:
67
+ """Save the calibration offset for a given module."""
68
+ save_module_calibration(offset, mount, slot, module, module_id, instrument_id)
69
+
70
+
71
+ def load_all_module_calibrations() -> List[ModuleCalibrationOffset]:
72
+ """Loads all the module calibration stored on the robot."""
73
+ module_calibrations: List[ModuleCalibrationOffset] = []
74
+ module_offset_data = load_all_module_offsets()
75
+ for data in module_offset_data:
76
+ module_calibrations.append(
77
+ ModuleCalibrationOffset(
78
+ slot=data.slot,
79
+ module=data.module,
80
+ module_id=data.module_id,
81
+ mount=data.mount,
82
+ offset=data.offset,
83
+ last_modified=data.lastModified,
84
+ instrument_id=data.instrument_id,
85
+ source=data.source,
86
+ status=CalibrationStatus(
87
+ markedAt=data.status.markedAt,
88
+ markedBad=data.status.markedBad,
89
+ source=data.status.source,
90
+ ),
91
+ )
92
+ )
93
+ return module_calibrations
@@ -0,0 +1,61 @@
1
+ from collections import deque
2
+ from typing import Deque
3
+
4
+ from opentrons.drivers.types import PlateTemperature
5
+ from opentrons.hardware_control.modules.types import TemperatureStatus
6
+
7
+
8
+ class PlateTemperatureStatus:
9
+
10
+ TEMP_THRESHOLD = 0.3
11
+ """The threshold under which the difference between target and temperature
12
+ is considered `holding`."""
13
+
14
+ MIN_SAMPLES_UNDER_THRESHOLD = 10
15
+ """The number of temperature samples needed before determining that the
16
+ temperature is `holding`"""
17
+
18
+ def __init__(self) -> None:
19
+ """Construct."""
20
+ self._temp_history: Deque[float] = deque(
21
+ maxlen=self.MIN_SAMPLES_UNDER_THRESHOLD
22
+ )
23
+ self._status = TemperatureStatus.ERROR
24
+
25
+ @property
26
+ def status(self) -> TemperatureStatus:
27
+ """Return the current status."""
28
+ return self._status
29
+
30
+ def update(self, temperature: PlateTemperature) -> TemperatureStatus:
31
+ """Update the status based on the temperature."""
32
+ # Add to history
33
+ self._temp_history.append(temperature.current)
34
+
35
+ if temperature.target is None:
36
+ _status = TemperatureStatus.IDLE
37
+ else:
38
+ diff = temperature.target - temperature.current
39
+ if self._is_holding_at_target(temperature.target, self._temp_history):
40
+ _status = TemperatureStatus.HOLDING
41
+ elif diff < 0:
42
+ _status = TemperatureStatus.COOLING
43
+ else:
44
+ _status = TemperatureStatus.HEATING
45
+ self._status = _status
46
+ return self._status
47
+
48
+ @staticmethod
49
+ def _is_holding_at_target(target: float, history: Deque[float]) -> bool:
50
+ """
51
+ Checks block temp history to determine if block temp has stabilized at
52
+ the target temperature. Returns true only if all values in history are
53
+ within threshold range of target temperature.
54
+ """
55
+ if len(history) < PlateTemperatureStatus.MIN_SAMPLES_UNDER_THRESHOLD:
56
+ # Not enough temp history
57
+ return False
58
+ else:
59
+ return all(
60
+ abs(target - t) < PlateTemperatureStatus.TEMP_THRESHOLD for t in history
61
+ )
@@ -0,0 +1,299 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from typing import Dict, Optional
6
+
7
+ from opentrons.hardware_control.modules.types import (
8
+ ModuleDisconnectedCallback,
9
+ TemperatureStatus,
10
+ )
11
+ from opentrons.hardware_control.poller import Reader, Poller
12
+ from typing_extensions import Final
13
+ from opentrons.drivers.types import Temperature
14
+ from opentrons.drivers.temp_deck import (
15
+ SimulatingDriver,
16
+ AbstractTempDeckDriver,
17
+ TempDeckDriver,
18
+ )
19
+ from opentrons.drivers.rpi_drivers.types import USBPort
20
+ from opentrons.hardware_control.execution_manager import ExecutionManager
21
+ from opentrons.hardware_control.modules import update, mod_abc, types, errors
22
+
23
+ log = logging.getLogger(__name__)
24
+
25
+ TEMP_POLL_INTERVAL_SECS = 1.0
26
+ SIM_TEMP_POLL_INTERVAL_SECS = TEMP_POLL_INTERVAL_SECS / 20.0
27
+
28
+
29
+ class TempDeck(mod_abc.AbstractModule):
30
+ """Hardware control interface for an attached Temperature Module."""
31
+
32
+ MODULE_TYPE = types.ModuleType["TEMPERATURE"]
33
+ FIRST_GEN2_REVISION = 20
34
+
35
+ @classmethod
36
+ async def build(
37
+ cls,
38
+ port: str,
39
+ usb_port: USBPort,
40
+ hw_control_loop: asyncio.AbstractEventLoop,
41
+ execution_manager: Optional[ExecutionManager] = None,
42
+ poll_interval_seconds: Optional[float] = None,
43
+ simulating: bool = False,
44
+ sim_model: Optional[str] = None,
45
+ sim_serial_number: Optional[str] = None,
46
+ disconnected_callback: ModuleDisconnectedCallback = None,
47
+ ) -> "TempDeck":
48
+ """
49
+ Build a TempDeck
50
+
51
+ Args:
52
+ port: The port to connect to
53
+ usb_port: USB Port
54
+ hw_control_loop: The event loop running in the hardware control thread.
55
+ execution_manager: Execution manager.
56
+ poll_interval_seconds: Poll interval override.
57
+ simulating: whether to build a simulating driver
58
+ sim_model: The model name used by simulator
59
+ disconnected_callback: Callback to inform the module controller that the device was disconnected
60
+
61
+ Returns:
62
+ Tempdeck instance
63
+ """
64
+ driver: AbstractTempDeckDriver
65
+ if not simulating:
66
+ driver = await TempDeckDriver.create(port=port, loop=hw_control_loop)
67
+ poll_interval_seconds = poll_interval_seconds or TEMP_POLL_INTERVAL_SECS
68
+ else:
69
+ driver = SimulatingDriver(
70
+ sim_model=sim_model, serial_number=sim_serial_number
71
+ )
72
+ poll_interval_seconds = poll_interval_seconds or SIM_TEMP_POLL_INTERVAL_SECS
73
+
74
+ reader = TempDeckReader(driver=driver)
75
+ poller = Poller(reader=reader, interval=poll_interval_seconds)
76
+ module = cls(
77
+ port=port,
78
+ usb_port=usb_port,
79
+ execution_manager=execution_manager,
80
+ driver=driver,
81
+ reader=reader,
82
+ poller=poller,
83
+ device_info=await driver.get_device_info(),
84
+ hw_control_loop=hw_control_loop,
85
+ disconnected_callback=disconnected_callback,
86
+ )
87
+
88
+ try:
89
+ await poller.start()
90
+ except Exception:
91
+ log.exception(f"First read of Temperature Module on port {port} failed")
92
+
93
+ return module
94
+
95
+ def __init__(
96
+ self,
97
+ port: str,
98
+ usb_port: USBPort,
99
+ driver: AbstractTempDeckDriver,
100
+ reader: TempDeckReader,
101
+ poller: Poller,
102
+ device_info: Dict[str, str],
103
+ hw_control_loop: asyncio.AbstractEventLoop,
104
+ execution_manager: Optional[ExecutionManager] = None,
105
+ disconnected_callback: ModuleDisconnectedCallback = None,
106
+ ) -> None:
107
+ """Constructor"""
108
+ super().__init__(
109
+ port=port,
110
+ usb_port=usb_port,
111
+ hw_control_loop=hw_control_loop,
112
+ execution_manager=execution_manager,
113
+ disconnected_callback=disconnected_callback,
114
+ )
115
+ self._device_info = device_info
116
+ self._driver = driver
117
+ self._reader = reader
118
+ self._poller = poller
119
+
120
+ async def cleanup(self) -> None:
121
+ """Stop the poller task."""
122
+ await self._poller.stop()
123
+ await self._driver.disconnect()
124
+
125
+ @classmethod
126
+ def name(cls) -> str:
127
+ return "tempdeck"
128
+
129
+ def firmware_prefix(self) -> str:
130
+ """The prefix used for looking up firmware"""
131
+ return "temperature-module"
132
+
133
+ def model(self) -> str:
134
+ return self._model_from_revision(self._device_info.get("model"))
135
+
136
+ def bootloader(self) -> types.UploadFunction:
137
+ return update.upload_via_avrdude
138
+
139
+ async def start_set_temperature(self, celsius: float) -> None:
140
+ """Set the target temperature in degrees Celsius.
141
+
142
+ Range: 4 to 95 degrees Celsius (QA tested).
143
+
144
+ The internal temp range is -9 to 99 °C, which is limited by the two-digit
145
+ temperature display. Any input outside of this range will be clipped
146
+ to the nearest limit.
147
+ """
148
+ await self.wait_for_is_running()
149
+ await self._driver.set_temperature(celsius)
150
+ await self._reader.read()
151
+
152
+ async def await_temperature(self, awaiting_temperature: Optional[float]) -> None:
153
+ """Await a target temperature in degrees Celsius.
154
+
155
+ Polls Temperature Module's temperature until
156
+ the specified temperature is reached.
157
+
158
+ Args:
159
+ temperature: The temperature to wait for.
160
+ If `None` (recommended), the module's target will be used.
161
+ Specifying any value other than the current target
162
+ may produce unpredictable behavior.
163
+ """
164
+ if self.is_simulated:
165
+ return
166
+
167
+ await self.wait_for_is_running()
168
+ await self._reader.read()
169
+
170
+ async def _await_temperature() -> None:
171
+ if awaiting_temperature is None:
172
+ while self.status != TemperatureStatus.HOLDING:
173
+ await self._poller.wait_next_poll()
174
+ elif self.status == TemperatureStatus.HEATING:
175
+ while self.temperature < awaiting_temperature:
176
+ await self._poller.wait_next_poll()
177
+ elif self.status == TemperatureStatus.COOLING:
178
+ while self.temperature > awaiting_temperature:
179
+ await self._poller.wait_next_poll()
180
+
181
+ t = self._loop.create_task(_await_temperature())
182
+ self.make_cancellable(t)
183
+ await t
184
+
185
+ async def deactivate(self, must_be_running: bool = True) -> None:
186
+ """Stop heating/cooling and turn off the fan"""
187
+ if must_be_running:
188
+ await self.wait_for_is_running()
189
+ await self._driver.deactivate()
190
+ await self._reader.read()
191
+
192
+ @property
193
+ def device_info(self) -> Dict[str, str]:
194
+ return self._device_info
195
+
196
+ @property
197
+ def live_data(self) -> types.LiveData:
198
+ data: types.TemperatureModuleData = {
199
+ "currentTemp": self.temperature,
200
+ "targetTemp": self.target,
201
+ }
202
+ return {
203
+ "status": self.status,
204
+ "data": data,
205
+ }
206
+
207
+ @property
208
+ def temperature(self) -> float:
209
+ return self._reader.temperature.current
210
+
211
+ @property
212
+ def target(self) -> Optional[float]:
213
+ return self._reader.temperature.target
214
+
215
+ @property
216
+ def status(self) -> TemperatureStatus:
217
+ return self._get_status(self._reader.temperature)
218
+
219
+ @property
220
+ def is_simulated(self) -> bool:
221
+ return isinstance(self._driver, SimulatingDriver)
222
+
223
+ async def prep_for_update(self) -> str:
224
+ model = self._device_info and self._device_info.get("model")
225
+ if model in ("temp_deck_v1", "temp_deck_v1.1", "temp_deck_v2"):
226
+ raise errors.UpdateError(
227
+ "This Temperature Module can't be updated."
228
+ "Please contact Opentrons Support."
229
+ )
230
+ await self._poller.stop()
231
+ await self._driver.enter_programming_mode()
232
+ new_port = await update.find_bootloader_port()
233
+ return new_port or self.port
234
+
235
+ def has_available_update(self) -> bool:
236
+ """Override of abc implementation to suppress update notifications
237
+ for v1, v1.1, and v2 temperature modules which cannot be updated"""
238
+ if not self._device_info:
239
+ model = None
240
+ else:
241
+ model = self._device_info.get("model")
242
+ if model in {"temp_deck_v1", "temp_deck_v1.1", "temp_deck_v2", None}:
243
+ return False
244
+ return super().has_available_update()
245
+
246
+ @staticmethod
247
+ def _get_status(temperature: Temperature) -> TemperatureStatus:
248
+ """
249
+ Determine the status from the temperature.
250
+
251
+ Args:
252
+ temperature: A Temperature instance
253
+
254
+ Returns:
255
+ The status
256
+ """
257
+ DELTA: Final = 0.7
258
+ status = TemperatureStatus.IDLE
259
+ if temperature.target is not None:
260
+ diff = temperature.target - temperature.current
261
+ if abs(diff) < DELTA: # To avoid status fluctuation near target
262
+ status = TemperatureStatus.HOLDING
263
+ elif diff < 0:
264
+ status = TemperatureStatus.COOLING
265
+ else:
266
+ status = TemperatureStatus.HEATING
267
+ return status
268
+
269
+ @staticmethod
270
+ def _model_from_revision(revision: Optional[str]) -> str:
271
+ """Defines the revision -> model mapping"""
272
+ if not revision or "v" not in revision:
273
+ log.error(f"bad revision: {revision}")
274
+ return "temperatureModuleV1"
275
+ try:
276
+ revision_num = float(revision.split("v")[-1])
277
+ except (ValueError, TypeError):
278
+ # none or corrupt
279
+ log.exception("no revision")
280
+ return "temperatureModuleV1"
281
+
282
+ if revision_num < TempDeck.FIRST_GEN2_REVISION:
283
+ return "temperatureModuleV1"
284
+ else:
285
+ return "temperatureModuleV2"
286
+
287
+
288
+ class TempDeckReader(Reader):
289
+ """Reads data from an attached Temperature Module."""
290
+
291
+ temperature: Temperature
292
+
293
+ def __init__(self, driver: AbstractTempDeckDriver) -> None:
294
+ self.temperature = Temperature(current=25, target=None)
295
+ self._driver = driver
296
+
297
+ async def read(self) -> None:
298
+ """Read the module's current and target temperatures."""
299
+ self.temperature = await self._driver.get_temperature()