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,417 @@
1
+ from __future__ import annotations
2
+ from enum import Enum
3
+ from dataclasses import dataclass
4
+ from typing import (
5
+ Dict,
6
+ List,
7
+ NamedTuple,
8
+ Callable,
9
+ Any,
10
+ Tuple,
11
+ Awaitable,
12
+ Union,
13
+ Optional,
14
+ cast,
15
+ TYPE_CHECKING,
16
+ TypeGuard,
17
+ )
18
+ from typing_extensions import TypedDict
19
+ from pathlib import Path
20
+
21
+ from opentrons.drivers.flex_stacker.types import (
22
+ LimitSwitchStatus,
23
+ PlatformStatus,
24
+ StackerAxis,
25
+ )
26
+ from opentrons.drivers.rpi_drivers.types import USBPort
27
+
28
+ if TYPE_CHECKING:
29
+ from opentrons_shared_data.module.types import (
30
+ ThermocyclerModuleType,
31
+ MagneticModuleType,
32
+ TemperatureModuleType,
33
+ HeaterShakerModuleType,
34
+ MagneticBlockType,
35
+ AbsorbanceReaderType,
36
+ FlexStackerModuleType,
37
+ )
38
+
39
+
40
+ class ThermocyclerStepBase(TypedDict):
41
+ temperature: float
42
+
43
+
44
+ class ThermocyclerStep(ThermocyclerStepBase, total=False):
45
+ hold_time_seconds: float
46
+ hold_time_minutes: float
47
+
48
+
49
+ class ThermocyclerCycle(TypedDict):
50
+ steps: List[ThermocyclerStep]
51
+ repetitions: int
52
+
53
+
54
+ UploadFunction = Callable[[str, str, Dict[str, Any]], Awaitable[Tuple[bool, str]]]
55
+
56
+
57
+ ModuleDisconnectedCallback = Optional[Callable[[str, str | None], None]]
58
+
59
+
60
+ class MagneticModuleData(TypedDict):
61
+ engaged: bool
62
+ height: float
63
+
64
+
65
+ class TemperatureModuleData(TypedDict):
66
+ currentTemp: float
67
+ targetTemp: float | None
68
+
69
+
70
+ class HeaterShakerData(TypedDict):
71
+ temperatureStatus: str
72
+ speedStatus: str
73
+ labwareLatchStatus: str
74
+ currentTemp: float
75
+ targetTemp: float | None
76
+ currentSpeed: int
77
+ targetSpeed: int | None
78
+ errorDetails: str | None
79
+
80
+
81
+ class ThermocyclerData(TypedDict):
82
+ lid: str
83
+ lidTarget: float | None
84
+ lidTemp: float
85
+ lidTempStatus: str
86
+ currentTemp: float | None
87
+ targetTemp: float | None
88
+ holdTime: float | None
89
+ rampRate: float | None
90
+ currentCycleIndex: int | None
91
+ totalCycleCount: int | None
92
+ currentStepIndex: int | None
93
+ totalStepCount: int | None
94
+
95
+
96
+ class AbsorbanceReaderData(TypedDict):
97
+ uptime: int
98
+ deviceStatus: str
99
+ lidStatus: str
100
+ platePresence: str
101
+ measureMode: str
102
+ sampleWavelengths: List[int]
103
+ referenceWavelength: int
104
+
105
+
106
+ class FlexStackerData(TypedDict):
107
+ latchState: str
108
+ platformState: str
109
+ hopperDoorState: str
110
+ installDetected: bool
111
+ errorDetails: str | None
112
+
113
+
114
+ ModuleData = Union[
115
+ Dict[Any, Any], # This allows an empty dict as module data
116
+ MagneticModuleData,
117
+ TemperatureModuleData,
118
+ HeaterShakerData,
119
+ ThermocyclerData,
120
+ AbsorbanceReaderData,
121
+ FlexStackerData,
122
+ ]
123
+
124
+
125
+ class ModuleDataValidator:
126
+ @classmethod
127
+ def is_magnetic_module_data(
128
+ cls, data: ModuleData | None
129
+ ) -> TypeGuard[MagneticModuleData]:
130
+ return data is not None and "engaged" in data.keys()
131
+
132
+ @classmethod
133
+ def is_temperature_module_data(
134
+ cls, data: ModuleData | None
135
+ ) -> TypeGuard[TemperatureModuleData]:
136
+ return data is not None and "targetTemp" in data.keys()
137
+
138
+ @classmethod
139
+ def is_heater_shaker_data(
140
+ cls, data: ModuleData | None
141
+ ) -> TypeGuard[HeaterShakerData]:
142
+ return data is not None and "labwareLatchStatus" in data.keys()
143
+
144
+ @classmethod
145
+ def is_thermocycler_data(
146
+ cls, data: ModuleData | None
147
+ ) -> TypeGuard[ThermocyclerData]:
148
+ return data is not None and "lid" in data.keys()
149
+
150
+ @classmethod
151
+ def is_absorbance_reader_data(
152
+ cls, data: ModuleData | None
153
+ ) -> TypeGuard[AbsorbanceReaderData]:
154
+ return data is not None and "uptime" in data.keys()
155
+
156
+ @classmethod
157
+ def is_flex_stacker_data(
158
+ cls, data: ModuleData | None
159
+ ) -> TypeGuard[FlexStackerData]:
160
+ return data is not None and "platformState" in data.keys()
161
+
162
+
163
+ class LiveData(TypedDict):
164
+ status: str
165
+ data: ModuleData | None
166
+
167
+
168
+ class ModuleType(str, Enum):
169
+ THERMOCYCLER: ThermocyclerModuleType = "thermocyclerModuleType"
170
+ TEMPERATURE: TemperatureModuleType = "temperatureModuleType"
171
+ MAGNETIC: MagneticModuleType = "magneticModuleType"
172
+ HEATER_SHAKER: HeaterShakerModuleType = "heaterShakerModuleType"
173
+ MAGNETIC_BLOCK: MagneticBlockType = "magneticBlockType"
174
+ ABSORBANCE_READER: AbsorbanceReaderType = "absorbanceReaderType"
175
+ FLEX_STACKER: FlexStackerModuleType = "flexStackerModuleType"
176
+
177
+ @classmethod
178
+ def from_model(cls, model: ModuleModel) -> ModuleType:
179
+ if isinstance(model, MagneticModuleModel):
180
+ return cls.MAGNETIC
181
+ if isinstance(model, TemperatureModuleModel):
182
+ return cls.TEMPERATURE
183
+ if isinstance(model, ThermocyclerModuleModel):
184
+ return cls.THERMOCYCLER
185
+ if isinstance(model, HeaterShakerModuleModel):
186
+ return cls.HEATER_SHAKER
187
+ if isinstance(model, MagneticBlockModel):
188
+ return cls.MAGNETIC_BLOCK
189
+ if isinstance(model, AbsorbanceReaderModel):
190
+ return cls.ABSORBANCE_READER
191
+ if isinstance(model, FlexStackerModuleModel):
192
+ return cls.FLEX_STACKER
193
+
194
+ @classmethod
195
+ def to_module_fixture_id(cls, module_type: ModuleType) -> str:
196
+ if module_type == ModuleType.THERMOCYCLER:
197
+ # Thermocyclers are "loaded" in B1 only
198
+ return "thermocyclerModuleV2Front"
199
+ if module_type == ModuleType.TEMPERATURE:
200
+ return "temperatureModuleV2"
201
+ if module_type == ModuleType.HEATER_SHAKER:
202
+ return "heaterShakerModuleV1"
203
+ if module_type == ModuleType.MAGNETIC_BLOCK:
204
+ return "magneticBlockV1"
205
+ if module_type == ModuleType.ABSORBANCE_READER:
206
+ return "absorbanceReaderV1"
207
+ if module_type == ModuleType.FLEX_STACKER:
208
+ return "flexStackerModuleV1"
209
+ else:
210
+ raise ValueError(
211
+ f"Module Type {module_type} does not have a related fixture ID."
212
+ )
213
+
214
+
215
+ class MagneticModuleModel(str, Enum):
216
+ MAGNETIC_V1: str = "magneticModuleV1"
217
+ MAGNETIC_V2: str = "magneticModuleV2"
218
+
219
+
220
+ class TemperatureModuleModel(str, Enum):
221
+ TEMPERATURE_V1: str = "temperatureModuleV1"
222
+ TEMPERATURE_V2: str = "temperatureModuleV2"
223
+
224
+
225
+ class ThermocyclerModuleModel(str, Enum):
226
+ THERMOCYCLER_V1: str = "thermocyclerModuleV1"
227
+ THERMOCYCLER_V2: str = "thermocyclerModuleV2"
228
+
229
+
230
+ class HeaterShakerModuleModel(str, Enum):
231
+ HEATER_SHAKER_V1: str = "heaterShakerModuleV1"
232
+
233
+
234
+ class MagneticBlockModel(str, Enum):
235
+ MAGNETIC_BLOCK_V1: str = "magneticBlockV1"
236
+
237
+
238
+ class AbsorbanceReaderModel(str, Enum):
239
+ ABSORBANCE_READER_V1: str = "absorbanceReaderV1"
240
+
241
+
242
+ class FlexStackerModuleModel(str, Enum):
243
+ FLEX_STACKER_V1: str = "flexStackerModuleV1"
244
+
245
+
246
+ def module_model_from_string(model_string: str) -> ModuleModel:
247
+ for model_enum in {
248
+ MagneticModuleModel,
249
+ TemperatureModuleModel,
250
+ ThermocyclerModuleModel,
251
+ HeaterShakerModuleModel,
252
+ MagneticBlockModel,
253
+ AbsorbanceReaderModel,
254
+ FlexStackerModuleModel,
255
+ }:
256
+ try:
257
+ return cast(ModuleModel, model_enum(model_string))
258
+ except ValueError:
259
+ pass
260
+ raise ValueError(f"No such module model {model_string}")
261
+
262
+
263
+ @dataclass(kw_only=True)
264
+ class ModuleAtPort:
265
+ port: str
266
+ name: str
267
+ serial: Optional[str] = None
268
+ usb_port: USBPort = USBPort(name="", port_number=0)
269
+
270
+
271
+ @dataclass(kw_only=True)
272
+ class SimulatingModule:
273
+ serial_number: str
274
+ model: Optional[str]
275
+
276
+
277
+ @dataclass(kw_only=True)
278
+ class SimulatingModuleAtPort(ModuleAtPort, SimulatingModule):
279
+ pass
280
+
281
+
282
+ class BundledFirmware(NamedTuple):
283
+ """Represents a versioned firmware file, generally bundled into the fs"""
284
+
285
+ version: str
286
+ path: Path
287
+
288
+ def __repr__(self) -> str:
289
+ return f"<BundledFirmware {self.version}, path={self.path}>"
290
+
291
+
292
+ class ModuleInfo(NamedTuple):
293
+ model: str # A module model such as "magneticModuleV2"
294
+ fw_version: str # The version of the firmware
295
+ hw_revision: str # the revision of the hardware
296
+ serial: str # the serial number
297
+
298
+
299
+ # TODO(mc, 2022-01-18): replace with enum
300
+ ModuleModel = Union[
301
+ MagneticModuleModel,
302
+ TemperatureModuleModel,
303
+ ThermocyclerModuleModel,
304
+ HeaterShakerModuleModel,
305
+ MagneticBlockModel,
306
+ AbsorbanceReaderModel,
307
+ FlexStackerModuleModel,
308
+ ]
309
+
310
+
311
+ class MagneticStatus(str, Enum):
312
+ ENGAGED = "engaged"
313
+ DISENGAGED = "disengaged"
314
+
315
+
316
+ class TemperatureStatus(str, Enum):
317
+ HOLDING = "holding at target"
318
+ COOLING = "cooling"
319
+ HEATING = "heating"
320
+ IDLE = "idle"
321
+ ERROR = "error"
322
+
323
+
324
+ class SpeedStatus(str, Enum):
325
+ HOLDING = "holding at target"
326
+ ACCELERATING = "speeding up"
327
+ DECELERATING = "slowing down"
328
+ IDLE = "idle"
329
+ ERROR = "error"
330
+
331
+
332
+ class HeaterShakerStatus(str, Enum):
333
+ IDLE = "idle"
334
+ RUNNING = "running"
335
+ ERROR = "error"
336
+
337
+
338
+ class AbsorbanceReaderStatus(str, Enum):
339
+ IDLE = "idle"
340
+ MEASURING = "measuring"
341
+ ERROR = "error"
342
+
343
+
344
+ class LidStatus(str, Enum):
345
+ ON = "on"
346
+ OFF = "off"
347
+ UNKNOWN = "unknown"
348
+ ERROR = "error"
349
+
350
+
351
+ class FlexStackerStatus(str, Enum):
352
+ IDLE = "idle"
353
+ DISPENSING = "dispensing"
354
+ STORING = "storing"
355
+ ERROR = "error"
356
+
357
+
358
+ class PlatformState(str, Enum):
359
+ UNKNOWN = "unknown"
360
+ EXTENDED = "extended"
361
+ RETRACTED = "retracted"
362
+ MISSING = "missing"
363
+
364
+ @classmethod
365
+ def from_status(cls, status: PlatformStatus) -> "PlatformState":
366
+ """Get the state from the platform status."""
367
+ if status.E and not status.R:
368
+ return cls.EXTENDED
369
+ if status.R and not status.E:
370
+ return cls.RETRACTED
371
+ return cls.UNKNOWN
372
+
373
+
374
+ class StackerAxisState(str, Enum):
375
+ UNKNOWN = "unknown"
376
+ EXTENDED = "extended"
377
+ RETRACTED = "retracted"
378
+
379
+ @classmethod
380
+ def from_status(
381
+ cls, status: LimitSwitchStatus, axis: StackerAxis
382
+ ) -> "StackerAxisState":
383
+ """Get the axis state from the limit switch status."""
384
+ match axis:
385
+ case StackerAxis.X:
386
+ if status.XE and not status.XR:
387
+ return cls.EXTENDED
388
+ if status.XR and not status.XE:
389
+ return cls.RETRACTED
390
+ case StackerAxis.Z:
391
+ if status.ZE and not status.ZR:
392
+ return cls.EXTENDED
393
+ if status.ZR and not status.ZE:
394
+ return cls.RETRACTED
395
+ case StackerAxis.L:
396
+ return cls.EXTENDED if status.LR else cls.RETRACTED
397
+ return cls.UNKNOWN
398
+
399
+
400
+ class LatchState(str, Enum):
401
+ CLOSED = "closed"
402
+ OPENED = "opened"
403
+
404
+ @classmethod
405
+ def from_state(cls, state: StackerAxisState) -> "LatchState":
406
+ """Get the latch state from the axis state."""
407
+ return cls.CLOSED if state == StackerAxisState.EXTENDED else cls.OPENED
408
+
409
+
410
+ class HopperDoorState(str, Enum):
411
+ CLOSED = "closed"
412
+ OPENED = "opened"
413
+
414
+ @classmethod
415
+ def from_state(cls, state: bool) -> "HopperDoorState":
416
+ """Get the hopper door state from the door state boolean."""
417
+ return cls.CLOSED if state else cls.OPENED
@@ -0,0 +1,255 @@
1
+ import asyncio
2
+ import logging
3
+ import os
4
+ from pathlib import Path
5
+ from glob import glob
6
+ from typing import Any, AsyncGenerator, Dict, Tuple, Union
7
+
8
+ from .errors import UpdateError
9
+ from .mod_abc import AbstractModule
10
+ from opentrons.hardware_control.threaded_async_lock import ThreadedAsyncLock
11
+ from contextlib import asynccontextmanager
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+ _update_transition_lock = ThreadedAsyncLock()
16
+
17
+
18
+ @asynccontextmanager
19
+ async def protect_update_transition() -> AsyncGenerator[None, None]:
20
+ async with _update_transition_lock.lock():
21
+ yield
22
+
23
+
24
+ async def update_firmware(
25
+ module: AbstractModule,
26
+ firmware_file: Union[str, Path],
27
+ ) -> None:
28
+ """Apply update of given firmware file to given module.
29
+
30
+ raises an UpdateError with the reason for the failure.
31
+ """
32
+ async with protect_update_transition():
33
+ flash_port_or_dfu_serial = await module.prep_for_update()
34
+ kwargs: Dict[str, Any] = {
35
+ "stdout": asyncio.subprocess.PIPE,
36
+ "stderr": asyncio.subprocess.PIPE,
37
+ "module": module,
38
+ }
39
+ successful, res = await module.bootloader()(
40
+ flash_port_or_dfu_serial, str(firmware_file), kwargs
41
+ )
42
+ if not successful:
43
+ log.info(f"Bootloader reponse: {res}")
44
+ raise UpdateError(res)
45
+
46
+
47
+ async def find_bootloader_port() -> str:
48
+ """
49
+ Finds the port of an Opentrons Module that has entered its bootloader.
50
+ The bootloader port shows up as 'ot_module_(avrdude|samba)_bootloader'
51
+ on the pi; return found port.
52
+ """
53
+
54
+ for attempt in range(3):
55
+ bootloader_ports = glob("/dev/ot_module_*_bootloader*")
56
+ if bootloader_ports:
57
+ if len(bootloader_ports) == 1:
58
+ log.info(f"Found bootloader at port {bootloader_ports[0]}")
59
+ return bootloader_ports[0]
60
+ elif len(bootloader_ports) > 1:
61
+ raise OSError("Multiple new bootloader ports" "found on mode switch")
62
+ await asyncio.sleep(2)
63
+ raise Exception("No ot_module bootloaders found in /dev. Try again")
64
+
65
+
66
+ async def find_dfu_device(pid: str, expected_device_count: int) -> str:
67
+ """
68
+ Find the dfu device and return its serial number (separate from module serial).
69
+
70
+ Args:
71
+ - pid: The USB Product ID of the device
72
+ - expected_device_count: The expected number of "devices" for dfu-util
73
+ to find for this PID. This is necessary because most STM32 MCU's
74
+ will enumerate with multiple DFU devices, representing the
75
+ separate programmable memory regions on the device. If more than
76
+ this many devices are found, it is assumed that either the wrong
77
+ module is in DFU mode *or* multiple modules are in DFU mode.
78
+ """
79
+ retries = 5
80
+ log.info(f"Searching for a dfu device with PID {pid}")
81
+ while retries != 0:
82
+ retries -= 1
83
+ await asyncio.sleep(1)
84
+ proc = await asyncio.create_subprocess_exec(
85
+ "dfu-util",
86
+ "-l",
87
+ stdout=asyncio.subprocess.PIPE,
88
+ stderr=asyncio.subprocess.PIPE,
89
+ )
90
+ await proc.wait()
91
+ stdout, stderr = await proc.communicate()
92
+
93
+ if stdout is None and stderr is None:
94
+ continue
95
+ if stderr:
96
+ raise RuntimeError(f"Error finding dfu device: {stderr.decode()}")
97
+
98
+ result = stdout.decode()
99
+ if pid not in result:
100
+ # It could take a few seconds for the device to show up
101
+ continue
102
+ devices_found = 0
103
+ for line in result.splitlines():
104
+ if pid in line:
105
+ log.info(f"Found device with PID {pid}")
106
+ devices_found += 1
107
+ serial = line[(line.find("serial=") + 7) :]
108
+ if devices_found == expected_device_count:
109
+ # Heater-Shaker has 2 unique endpoints, Thermocycler has 3
110
+ return serial
111
+ elif devices_found > expected_device_count:
112
+ raise OSError("Multiple new bootloader devices" "found on mode switch")
113
+
114
+ raise RuntimeError(
115
+ "Could not update firmware via dfu. Possible issues- dfu-util"
116
+ " not working or specified dfu device not found"
117
+ )
118
+
119
+
120
+ async def upload_via_avrdude(
121
+ port: str, firmware_file_path: str, kwargs: Dict[str, Any]
122
+ ) -> Tuple[bool, str]:
123
+ """
124
+ Run firmware upload command for hardware module with avrdude bootloader.
125
+
126
+ Returns tuple of success boolean and message from bootloader.
127
+ """
128
+ # avrdude_options
129
+ PART_NO = "atmega32u4"
130
+ PROGRAMMER_ID = "avr109"
131
+ BAUDRATE = "57600"
132
+
133
+ config_file_path = Path("/etc/avrdude.conf")
134
+ proc = await asyncio.create_subprocess_exec(
135
+ "avrdude",
136
+ "-C{}".format(config_file_path),
137
+ "-v",
138
+ "-p{}".format(PART_NO),
139
+ "-c{}".format(PROGRAMMER_ID),
140
+ "-P{}".format(port),
141
+ "-b{}".format(BAUDRATE),
142
+ "-D",
143
+ "-Uflash:w:{}:i".format(firmware_file_path),
144
+ stdout=kwargs["stdout"],
145
+ stderr=kwargs["stderr"],
146
+ )
147
+ await proc.wait()
148
+
149
+ _result = await proc.communicate()
150
+ result = _result[1].decode()
151
+ avrdude_res = _format_avrdude_response(result)
152
+ if avrdude_res[0]:
153
+ log.debug(result)
154
+ else:
155
+ log.error(
156
+ "Failed to update module firmware for {}: {}".format(port, avrdude_res[1])
157
+ )
158
+ return avrdude_res
159
+
160
+
161
+ def _format_avrdude_response(raw_response: str) -> Tuple[bool, str]:
162
+ avrdude_log = ""
163
+ for line in raw_response.splitlines():
164
+ if "avrdude:" in line and line != raw_response.splitlines()[1]:
165
+ avrdude_log += line.lstrip("avrdude:") + ".."
166
+ if "flash verified" in line:
167
+ return True, line.lstrip("avrdude: ")
168
+ return False, avrdude_log
169
+
170
+
171
+ async def upload_via_bossa(
172
+ port: str, firmware_file_path: str, kwargs: Dict[str, Any]
173
+ ) -> Tuple[bool, str]:
174
+ """
175
+ Run firmware upload command for hardware module with SAMBA bootloader.
176
+
177
+ Returns tuple of success boolean and message from bootloader.
178
+ """
179
+ # bossac -p/dev/ttyACM1 -e -w -v -R --offset=0x2000
180
+ # modules/thermo-cycler/production/firmware/thermo-cycler-arduino.ino.bin
181
+ # NOTE: bossac cannot traverse symlinks to port,
182
+ # so we resolve to real path
183
+ resolved_symlink = os.path.realpath(port)
184
+ log.info(
185
+ f"device at symlinked port: {port} " f"resolved to path: {resolved_symlink}"
186
+ )
187
+ bossa_args = [
188
+ "bossac",
189
+ f"-p{resolved_symlink}",
190
+ "-e",
191
+ "-w",
192
+ "-v",
193
+ "-R",
194
+ "--offset=0x2000",
195
+ f"{firmware_file_path}",
196
+ ]
197
+ proc = await asyncio.create_subprocess_exec(
198
+ *bossa_args, stdout=kwargs["stdout"], stderr=kwargs["stderr"]
199
+ )
200
+ stdout, stderr = await proc.communicate()
201
+ res = stdout.decode()
202
+ if "Verify successful" in res:
203
+ log.debug(res)
204
+ return True, res
205
+ elif stderr:
206
+ log.error(f"Failed to update module firmware for {port}: {res}")
207
+ log.error(f"Error given: {stderr.decode()}")
208
+ return False, res
209
+ return False, ""
210
+
211
+
212
+ async def upload_via_dfu(
213
+ dfu_serial: str, firmware_file_path: str, kwargs: Dict[str, Any]
214
+ ) -> Tuple[bool, str]:
215
+ """Run firmware upload command for DFU.
216
+
217
+ Unlike other firmware upload methods, this one doesn't take a `port` argument since
218
+ the module isn't recognized as a cdc device in dfu mode and hence doesn't get
219
+ a port. The firmware upload utility, dfu-util, looks for the specific module
220
+ by searching for available dfu devices. Since we check beforehand that only one
221
+ dfu device is available during the upload process, this check is sufficient for us.
222
+
223
+ In the future, if we want to make sure that the dfu device available is in fact
224
+ the one we seek, then we can ask dfu-util to check for available dfu devices with
225
+ a specific serial number (unrelated to Opentrons' module serial numbers).
226
+ Hence, this method takes a `dfu_serial` argument instead.
227
+
228
+ Returns tuple of success boolean and message from bootloader
229
+ """
230
+ log.info("Starting firmware upload via dfu util")
231
+ dfu_args = [
232
+ "dfu-util",
233
+ "-a 0",
234
+ "-s 0x08000000:leave",
235
+ f"-D{firmware_file_path}",
236
+ "-R",
237
+ ]
238
+ proc = await asyncio.create_subprocess_exec(
239
+ *dfu_args, stdout=kwargs["stdout"], stderr=kwargs["stderr"]
240
+ )
241
+ stdout, stderr = await proc.communicate()
242
+ res = stdout.decode()
243
+
244
+ if "File downloaded successfully" in res:
245
+ log.debug(res)
246
+ log.info("Firmware upload successful")
247
+ return True, res
248
+ else:
249
+ log.error(
250
+ f"Failed to update module firmware for {dfu_serial}. "
251
+ # It isn't easy to decipher the issue from stderror alone
252
+ f"stdout: {res} \n"
253
+ f"stderr: {stderr.decode()}"
254
+ )
255
+ return False, res