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,183 @@
1
+ from enum import Enum
2
+ from dataclasses import dataclass, asdict, fields
3
+ from typing import Dict, Tuple, TypeVar, Generic, List, cast
4
+ from typing_extensions import TypedDict, Literal
5
+ from opentrons.hardware_control.types import OT3AxisKind
6
+
7
+
8
+ class AxisDict(TypedDict):
9
+ X: float
10
+ Y: float
11
+ Z: float
12
+ A: float
13
+ B: float
14
+ C: float
15
+
16
+
17
+ Vt = TypeVar("Vt")
18
+
19
+
20
+ class GantryLoad(Enum):
21
+ HIGH_THROUGHPUT_1000 = "high_throughput_1000"
22
+ HIGH_THROUGHPUT_200 = "high_throughput_200"
23
+ LOW_THROUGHPUT = "low_throughput"
24
+
25
+
26
+ @dataclass
27
+ class ByGantryLoad(Generic[Vt]):
28
+ high_throughput_1000: Vt
29
+ high_throughput_200: Vt
30
+ low_throughput: Vt
31
+
32
+ def __getitem__(self, key: GantryLoad) -> Vt:
33
+ return cast(Vt, asdict(self)[key.value])
34
+
35
+
36
+ PerPipetteAxisSettings = ByGantryLoad[Dict[OT3AxisKind, float]]
37
+
38
+
39
+ class CurrentDictDefault(TypedDict):
40
+ default: AxisDict
41
+
42
+
43
+ CurrentDictModelEntries = TypedDict(
44
+ "CurrentDictModelEntries",
45
+ {"2.1": AxisDict, "A": AxisDict, "B": AxisDict, "C": AxisDict},
46
+ total=False,
47
+ )
48
+
49
+
50
+ class CurrentDict(CurrentDictDefault, CurrentDictModelEntries):
51
+ pass
52
+
53
+
54
+ Offset = Tuple[float, float, float]
55
+
56
+
57
+ @dataclass
58
+ class RobotConfig:
59
+ model: Literal["OT-2 Standard"]
60
+ name: str
61
+ version: int
62
+ gantry_steps_per_mm: Dict[str, float]
63
+ acceleration: Dict[str, float]
64
+ serial_speed: int
65
+ default_pipette_configs: Dict[str, float]
66
+ default_current: CurrentDict
67
+ low_current: CurrentDict
68
+ high_current: CurrentDict
69
+ default_max_speed: AxisDict
70
+ log_level: str
71
+ z_retract_distance: float
72
+ left_mount_offset: Offset
73
+
74
+
75
+ OT3Transform = List[List[float]]
76
+
77
+
78
+ @dataclass(frozen=True)
79
+ class OT3MotionSettings:
80
+ default_max_speed: PerPipetteAxisSettings
81
+ acceleration: PerPipetteAxisSettings
82
+ max_speed_discontinuity: PerPipetteAxisSettings
83
+ direction_change_speed_discontinuity: PerPipetteAxisSettings
84
+
85
+ def by_gantry_load(
86
+ self, gantry_load: GantryLoad
87
+ ) -> Dict[str, Dict[OT3AxisKind, float]]:
88
+ return dict(
89
+ (field.name, getattr(self, field.name)[gantry_load])
90
+ for field in fields(self)
91
+ )
92
+
93
+
94
+ @dataclass(frozen=True)
95
+ class OT3CurrentSettings:
96
+ hold_current: PerPipetteAxisSettings
97
+ run_current: PerPipetteAxisSettings
98
+
99
+ def by_gantry_load(
100
+ self, gantry_load: GantryLoad
101
+ ) -> Dict[str, Dict[OT3AxisKind, float]]:
102
+ return dict(
103
+ (field.name, getattr(self, field.name)[gantry_load])
104
+ for field in fields(self)
105
+ )
106
+
107
+
108
+ @dataclass(frozen=True)
109
+ class CapacitivePassSettings:
110
+ prep_distance_mm: float
111
+ max_overrun_distance_mm: float
112
+ speed_mm_per_s: float
113
+ sensor_threshold_pf: float
114
+
115
+
116
+ @dataclass(frozen=True)
117
+ class ZSenseSettings:
118
+ pass_settings: CapacitivePassSettings
119
+
120
+
121
+ @dataclass
122
+ class LiquidProbeSettings:
123
+ mount_speed: float
124
+ plunger_speed: float
125
+ plunger_impulse_time: float
126
+ sensor_threshold_pascals: float
127
+ aspirate_while_sensing: bool
128
+ z_overlap_between_passes_mm: float
129
+ plunger_reset_offset: float
130
+ samples_for_baselining: int
131
+ sample_time_sec: float
132
+
133
+
134
+ @dataclass(frozen=True)
135
+ class EdgeSenseSettings:
136
+ overrun_tolerance_mm: float
137
+ early_sense_tolerance_mm: float
138
+ pass_settings: CapacitivePassSettings
139
+ search_initial_tolerance_mm: float
140
+ search_iteration_limit: int
141
+
142
+ def __init__(
143
+ self,
144
+ overrun_tolerance_mm: float,
145
+ early_sense_tolerance_mm: float,
146
+ pass_settings: CapacitivePassSettings,
147
+ search_initial_tolerance_mm: float,
148
+ search_iteration_limit: int,
149
+ ) -> None:
150
+ if overrun_tolerance_mm > pass_settings.max_overrun_distance_mm:
151
+ raise ValueError("Overrun tolerance and pass setting distance do not match")
152
+ object.__setattr__(self, "overrun_tolerance_mm", overrun_tolerance_mm)
153
+ object.__setattr__(self, "early_sense_tolerance_mm", early_sense_tolerance_mm)
154
+ object.__setattr__(self, "pass_settings", pass_settings)
155
+ object.__setattr__(
156
+ self, "search_initial_tolerance_mm", search_initial_tolerance_mm
157
+ )
158
+ object.__setattr__(self, "search_iteration_limit", search_iteration_limit)
159
+
160
+
161
+ @dataclass(frozen=True)
162
+ class OT3CalibrationSettings:
163
+ z_offset: ZSenseSettings
164
+ edge_sense: EdgeSenseSettings
165
+ probe_length: float
166
+
167
+
168
+ @dataclass
169
+ class OT3Config:
170
+ model: Literal["OT-3 Standard"]
171
+ name: str
172
+ version: int
173
+ log_level: str
174
+ motion_settings: OT3MotionSettings
175
+ current_settings: OT3CurrentSettings
176
+ safe_home_distance: float
177
+ deck_transform: OT3Transform
178
+ carriage_offset: Offset
179
+ left_mount_offset: Offset
180
+ right_mount_offset: Offset
181
+ gripper_mount_offset: Offset
182
+ calibration: OT3CalibrationSettings
183
+ liquid_sense: LiquidProbeSettings
File without changes
@@ -0,0 +1,11 @@
1
+ from .abstract import AbstractAbsorbanceReaderDriver
2
+ from .driver import AbsorbanceReaderDriver
3
+ from .simulator import SimulatingDriver
4
+ from .hid_protocol import AbsorbanceHidInterface
5
+
6
+ __all__ = [
7
+ "AbstractAbsorbanceReaderDriver",
8
+ "AbsorbanceReaderDriver",
9
+ "SimulatingDriver",
10
+ "AbsorbanceHidInterface",
11
+ ]
@@ -0,0 +1,72 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Dict, List, Optional, Tuple
3
+ from opentrons.drivers.types import (
4
+ ABSMeasurementMode,
5
+ AbsorbanceReaderLidStatus,
6
+ AbsorbanceReaderDeviceState,
7
+ AbsorbanceReaderPlatePresence,
8
+ )
9
+
10
+
11
+ class AbstractAbsorbanceReaderDriver(ABC):
12
+ @abstractmethod
13
+ async def connect(self) -> None:
14
+ """Connect to absorbance reader"""
15
+ ...
16
+
17
+ @abstractmethod
18
+ async def disconnect(self) -> None:
19
+ """Disconnect from absorbance reader"""
20
+ ...
21
+
22
+ @abstractmethod
23
+ async def is_connected(self) -> bool:
24
+ """Check connection to absorbance reader"""
25
+ ...
26
+
27
+ @abstractmethod
28
+ async def get_lid_status(self) -> AbsorbanceReaderLidStatus:
29
+ ...
30
+
31
+ @abstractmethod
32
+ async def get_available_wavelengths(self) -> List[int]:
33
+ ...
34
+
35
+ @abstractmethod
36
+ async def initialize_measurement(
37
+ self,
38
+ wavelengths: List[int],
39
+ mode: ABSMeasurementMode = ABSMeasurementMode.SINGLE,
40
+ reference_wavelength: Optional[int] = None,
41
+ ) -> None:
42
+ """Initialize measurement for the device in single or multi mode for the given wavelengths"""
43
+ ...
44
+
45
+ @abstractmethod
46
+ async def get_measurement(self) -> List[List[float]]:
47
+ """Gets one or more measurements based on the current configuration."""
48
+ ...
49
+
50
+ @abstractmethod
51
+ async def get_status(self) -> AbsorbanceReaderDeviceState:
52
+ ...
53
+
54
+ @abstractmethod
55
+ async def get_device_info(self) -> Dict[str, str]:
56
+ """Get device info"""
57
+ ...
58
+
59
+ @abstractmethod
60
+ async def get_uptime(self) -> int:
61
+ """Get device uptime"""
62
+ ...
63
+
64
+ @abstractmethod
65
+ async def get_plate_presence(self) -> AbsorbanceReaderPlatePresence:
66
+ """Check if there is a plate in the reader."""
67
+ ...
68
+
69
+ @abstractmethod
70
+ async def update_firmware(self, firmware_file_path: str) -> Tuple[bool, str]:
71
+ """Updates the firmware on the device."""
72
+ ...
@@ -0,0 +1,352 @@
1
+ import asyncio
2
+ import os
3
+ import re
4
+ from concurrent.futures.thread import ThreadPoolExecutor
5
+ from functools import partial
6
+ from typing import Any, Optional, List, Dict, Tuple
7
+
8
+ from .hid_protocol import (
9
+ AbsorbanceHidInterface as AbsProtocol,
10
+ ErrorCodeNames,
11
+ DeviceStateNames,
12
+ SlotStateNames,
13
+ MeasurementConfig,
14
+ )
15
+ from opentrons.drivers.types import (
16
+ AbsorbanceReaderLidStatus,
17
+ AbsorbanceReaderPlatePresence,
18
+ AbsorbanceReaderDeviceState,
19
+ ABSMeasurementMode,
20
+ )
21
+ from opentrons.drivers.rpi_drivers.types import USBPort
22
+ from opentrons.hardware_control.modules.errors import AbsorbanceReaderDisconnectedError
23
+
24
+
25
+ SN_PARSER = re.compile(r'ATTRS{serial}=="(?P<serial>.+?)"')
26
+ # match semver V0.0.0 (old format) or one integer (latest format)
27
+ VERSION_PARSER = re.compile(r"(?P<version>(V\d+\.\d+\.\d+|^\d+$))")
28
+ SERIAL_PARSER = re.compile(r"(?P<serial>(OPT|BYO)[A-Z]{3}[0-9]+)")
29
+
30
+
31
+ class AsyncByonoy:
32
+ """Async wrapper around Byonoy Device Library."""
33
+
34
+ @staticmethod
35
+ def match_device_with_sn(
36
+ sn: str, devices: List[AbsProtocol.Device]
37
+ ) -> AbsProtocol.Device:
38
+ for device in devices:
39
+ if device.sn == sn:
40
+ return device
41
+ raise RuntimeError(f"Unavailble module with serial number: {sn}")
42
+
43
+ @staticmethod
44
+ def serial_number_from_port(name: str) -> str:
45
+ """
46
+ Get the serial number from a port using pyusb.
47
+ """
48
+ import usb.core as usb_core # type: ignore[import-untyped]
49
+
50
+ port_numbers = tuple(int(s) for s in name.split("-")[1].split("."))
51
+ device = usb_core.find(port_numbers=port_numbers)
52
+ if device:
53
+ return str(device.serial_number)
54
+ raise RuntimeError(f"Could not find serial number for port: {name}")
55
+
56
+ @classmethod
57
+ async def create(
58
+ cls,
59
+ port: str,
60
+ usb_port: USBPort,
61
+ loop: Optional[asyncio.AbstractEventLoop] = None,
62
+ ) -> "AsyncByonoy":
63
+ """
64
+ Create an AsyncByonoy instance.
65
+
66
+ Args:
67
+ port: url or port name
68
+ baud_rate: the baud rate
69
+ timeout: optional timeout in seconds
70
+ write_timeout: optional write timeout in seconds
71
+ loop: optional event loop. if None get_running_loop will be used
72
+ reset_buffer_before_write: reset the serial input buffer before
73
+ writing to it
74
+ """
75
+ loop = loop or asyncio.get_running_loop()
76
+ executor = ThreadPoolExecutor(max_workers=1)
77
+
78
+ import byonoy_devices as byonoy # type: ignore[import-not-found]
79
+
80
+ interface: AbsProtocol = byonoy
81
+
82
+ device_sn = cls.serial_number_from_port(usb_port.name)
83
+ found: List[AbsProtocol.Device] = await loop.run_in_executor(
84
+ executor=executor, func=byonoy.available_devices
85
+ )
86
+ device = cls.match_device_with_sn(device_sn, found)
87
+
88
+ return cls(
89
+ interface=interface,
90
+ device=device,
91
+ executor=executor,
92
+ loop=loop,
93
+ )
94
+
95
+ def __init__(
96
+ self,
97
+ interface: AbsProtocol,
98
+ device: AbsProtocol.Device,
99
+ executor: ThreadPoolExecutor,
100
+ loop: asyncio.AbstractEventLoop,
101
+ ) -> None:
102
+ """
103
+ Constructor
104
+
105
+ Args:
106
+ serial: connected Serial object
107
+ executor: a thread pool executor
108
+ loop: event loop
109
+ """
110
+ self._interface = interface
111
+ self._device = device
112
+ self._executor = executor
113
+ self._loop = loop
114
+ self._supported_wavelengths: Optional[list[int]] = None
115
+ self._device_handle: Optional[int] = None
116
+ self._current_config: Optional[MeasurementConfig] = None
117
+
118
+ async def open(self) -> bool:
119
+ """
120
+ Open the connection.
121
+
122
+ Returns: boolean denoting connection success.
123
+ """
124
+
125
+ err, device_handle = await self._loop.run_in_executor(
126
+ executor=self._executor,
127
+ func=partial(self._interface.open_device, self._device),
128
+ )
129
+ self._raise_if_error(err.name, f"Error opening device: {err}")
130
+ self._device_handle = device_handle
131
+ return bool(device_handle)
132
+
133
+ async def close(self) -> None:
134
+ """Close the connection."""
135
+ handle = self._verify_device_handle()
136
+ await self._loop.run_in_executor(
137
+ executor=self._executor,
138
+ func=partial(self._interface.free_device, handle),
139
+ )
140
+ self._device_handle = None
141
+
142
+ async def is_open(self) -> bool:
143
+ """True if connection is open."""
144
+ if self._device_handle is None:
145
+ return False
146
+ handle = self._verify_device_handle()
147
+ return await self._loop.run_in_executor(
148
+ executor=self._executor,
149
+ func=partial(self._interface.device_open, handle),
150
+ )
151
+
152
+ async def get_device_information(self) -> Dict[str, str]:
153
+ """Get serial number and version info."""
154
+ handle = self._verify_device_handle()
155
+ err, device_info = await self._loop.run_in_executor(
156
+ executor=self._executor,
157
+ func=partial(self._interface.get_device_information, handle),
158
+ )
159
+ self._raise_if_error(err.name, f"Error getting device information: {err}")
160
+ serial_match = SERIAL_PARSER.match(device_info.sn)
161
+ version_match = VERSION_PARSER.search(device_info.version)
162
+ serial = serial_match["serial"].strip() if serial_match else "OPTMAA00000"
163
+ version = version_match["version"].lower() if version_match else "v0"
164
+ info = {
165
+ "serial": serial,
166
+ "version": version,
167
+ "model": "ABS96",
168
+ }
169
+ return info
170
+
171
+ async def get_device_status(self) -> AbsorbanceReaderDeviceState:
172
+ """Get state information of the device."""
173
+ handle = self._verify_device_handle()
174
+ err, status = await self._loop.run_in_executor(
175
+ executor=self._executor,
176
+ func=partial(self._interface.get_device_status, handle),
177
+ )
178
+ self._raise_if_error(err.name, f"Error getting device status: {err}")
179
+ return self.convert_device_state(status.name)
180
+
181
+ async def update_firmware(self, firmware_file_path: str) -> Tuple[bool, str]:
182
+ """Updates the firmware of the device."""
183
+ handle = self._verify_device_handle()
184
+ if not os.path.exists(firmware_file_path):
185
+ return False, f"Firmware file not found: {firmware_file_path}"
186
+ err = await self._loop.run_in_executor(
187
+ executor=self._executor,
188
+ func=partial(self._interface.update_device, handle, firmware_file_path),
189
+ )
190
+ if err.name != "NO_ERROR":
191
+ return False, f"Byonoy update failed with error: {err}"
192
+ return True, ""
193
+
194
+ async def get_device_uptime(self) -> int:
195
+ """Get how long in seconds the device has been running for."""
196
+ handle = self._verify_device_handle()
197
+ err, uptime = await self._loop.run_in_executor(
198
+ executor=self._executor,
199
+ func=partial(self._interface.get_device_uptime, handle),
200
+ )
201
+ self._raise_if_error(err.name, "Error getting device uptime: ")
202
+ return uptime
203
+
204
+ async def get_lid_status(self) -> AbsorbanceReaderLidStatus:
205
+ """Get the state of the absorbance lid."""
206
+ handle = self._verify_device_handle()
207
+ err, lid_info = await self._loop.run_in_executor(
208
+ executor=self._executor,
209
+ func=partial(self._interface.get_device_parts_aligned, handle),
210
+ )
211
+ self._raise_if_error(err.name, f"Error getting lid status: {err}")
212
+ return (
213
+ AbsorbanceReaderLidStatus.ON if lid_info else AbsorbanceReaderLidStatus.OFF
214
+ )
215
+
216
+ async def get_supported_wavelengths(self) -> list[int]:
217
+ """Get a list of the wavelength readings this device supports."""
218
+ handle = self._verify_device_handle()
219
+ err, wavelengths = await self._loop.run_in_executor(
220
+ executor=self._executor,
221
+ func=partial(self._interface.abs96_get_available_wavelengths, handle),
222
+ )
223
+ self._raise_if_error(err.name, "Error getting available wavelengths: ")
224
+ self._supported_wavelengths = wavelengths
225
+ return wavelengths
226
+
227
+ async def get_measurement(self) -> List[List[float]]:
228
+ """Gets one or more measurements based on the current configuration."""
229
+ handle = self._verify_device_handle()
230
+ assert (
231
+ self._current_config is not None
232
+ ), "Cannot get measurement without initializing."
233
+ measure_func: Any = self._interface.abs96_single_measure
234
+ if isinstance(self._current_config, AbsProtocol.MultiMeasurementConfig):
235
+ measure_func = self._interface.abs96_multiple_measure
236
+ err, measurements = await self._loop.run_in_executor(
237
+ executor=self._executor,
238
+ func=partial(
239
+ measure_func,
240
+ handle,
241
+ self._current_config,
242
+ ),
243
+ )
244
+ self._raise_if_error(err.name, f"Error getting measurement: {err}")
245
+ return measurements if isinstance(measurements[0], List) else [measurements] # type: ignore
246
+
247
+ async def get_plate_presence(self) -> AbsorbanceReaderPlatePresence:
248
+ """Get the state of the plate for the reader."""
249
+ handle = self._verify_device_handle()
250
+ err, presence = await self._loop.run_in_executor(
251
+ executor=self._executor,
252
+ func=partial(self._interface.get_device_slot_status, handle),
253
+ )
254
+ self._raise_if_error(err.name, f"Error getting slot status: {err}")
255
+ return self.convert_plate_presence(presence.name)
256
+
257
+ def _get_supported_wavelengths(self) -> List[int]:
258
+ handle = self._verify_device_handle()
259
+ wavelengths: List[int]
260
+ err, wavelengths = self._interface.abs96_get_available_wavelengths(handle)
261
+ self._raise_if_error(err.name, f"Error getting available wavelengths: {err}")
262
+ self._supported_wavelengths = wavelengths
263
+ return wavelengths
264
+
265
+ def _initialize_measurement(self, conf: MeasurementConfig) -> None:
266
+ handle = self._verify_device_handle()
267
+ if isinstance(conf, AbsProtocol.SingleMeasurementConfig):
268
+ err = self._interface.abs96_initialize_single_measurement(handle, conf)
269
+ else:
270
+ err = self._interface.abs96_initialize_multiple_measurement(handle, conf)
271
+ self._raise_if_error(err.name, f"Error initializing measurement: {err}")
272
+ self._current_config = conf
273
+
274
+ def _initialize(
275
+ self,
276
+ mode: ABSMeasurementMode,
277
+ wavelengths: List[int],
278
+ reference_wavelength: Optional[int] = None,
279
+ ) -> None:
280
+ if not self._supported_wavelengths:
281
+ self._get_supported_wavelengths()
282
+ assert self._supported_wavelengths
283
+ conf: MeasurementConfig
284
+ if set(wavelengths).issubset(self._supported_wavelengths):
285
+ if mode == ABSMeasurementMode.SINGLE:
286
+ conf = self._interface.Abs96SingleMeasurementConfig()
287
+ conf.sample_wavelength = wavelengths[0] or 0
288
+ conf.reference_wavelength = reference_wavelength or 0
289
+ else:
290
+ conf = self._interface.Abs96MultipleMeasurementConfig()
291
+ conf.sample_wavelengths = wavelengths
292
+ else:
293
+ raise ValueError(
294
+ f"Unsupported wavelength: {wavelengths}, expected: {self._supported_wavelengths}"
295
+ )
296
+ self._initialize_measurement(conf)
297
+
298
+ async def initialize(
299
+ self,
300
+ mode: ABSMeasurementMode,
301
+ wavelengths: List[int],
302
+ reference_wavelength: Optional[int] = None,
303
+ ) -> None:
304
+ """initialize the device so we can start reading samples from it."""
305
+ await self._loop.run_in_executor(
306
+ executor=self._executor,
307
+ func=partial(self._initialize, mode, wavelengths, reference_wavelength),
308
+ )
309
+
310
+ def _verify_device_handle(self) -> int:
311
+ assert self._device_handle is not None, RuntimeError(
312
+ "Device handle not set up."
313
+ )
314
+ return self._device_handle
315
+
316
+ def _raise_if_error(
317
+ self,
318
+ err_name: ErrorCodeNames,
319
+ msg: str = "Error occurred: ",
320
+ ) -> None:
321
+ if err_name in [
322
+ "DEVICE_CLOSED",
323
+ "DEVICE_COMMUNICATION_FAILURE",
324
+ "UNSUPPORTED_OPERATION",
325
+ ]:
326
+ raise AbsorbanceReaderDisconnectedError(self._device.sn)
327
+ if err_name != "NO_ERROR":
328
+ raise RuntimeError(msg, err_name)
329
+
330
+ @staticmethod
331
+ def convert_device_state(
332
+ device_state: DeviceStateNames,
333
+ ) -> AbsorbanceReaderDeviceState:
334
+ state_map: Dict[DeviceStateNames, AbsorbanceReaderDeviceState] = {
335
+ "UNKNOWN": AbsorbanceReaderDeviceState.UNKNOWN,
336
+ "OK": AbsorbanceReaderDeviceState.OK,
337
+ "BROKEN_FW": AbsorbanceReaderDeviceState.BROKEN_FW,
338
+ "ERROR": AbsorbanceReaderDeviceState.ERROR,
339
+ }
340
+ return state_map[device_state]
341
+
342
+ @staticmethod
343
+ def convert_plate_presence(
344
+ slot_state: SlotStateNames,
345
+ ) -> AbsorbanceReaderPlatePresence:
346
+ state_map: Dict[SlotStateNames, AbsorbanceReaderPlatePresence] = {
347
+ "UNKNOWN": AbsorbanceReaderPlatePresence.UNKNOWN,
348
+ "EMPTY": AbsorbanceReaderPlatePresence.ABSENT,
349
+ "OCCUPIED": AbsorbanceReaderPlatePresence.PRESENT,
350
+ "UNDETERMINED": AbsorbanceReaderPlatePresence.UNKNOWN,
351
+ }
352
+ return state_map[slot_state]
@@ -0,0 +1,81 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from typing import Dict, Optional, List, Tuple, TYPE_CHECKING
5
+
6
+ from opentrons.drivers.types import (
7
+ ABSMeasurementMode,
8
+ AbsorbanceReaderLidStatus,
9
+ AbsorbanceReaderDeviceState,
10
+ AbsorbanceReaderPlatePresence,
11
+ )
12
+ from opentrons.drivers.absorbance_reader.abstract import (
13
+ AbstractAbsorbanceReaderDriver,
14
+ )
15
+ from opentrons.drivers.rpi_drivers.types import USBPort
16
+
17
+ if TYPE_CHECKING:
18
+ from .async_byonoy import AsyncByonoy as AsyncByonoyType
19
+
20
+
21
+ class AbsorbanceReaderDriver(AbstractAbsorbanceReaderDriver):
22
+ @classmethod
23
+ async def create(
24
+ cls,
25
+ port: str,
26
+ usb_port: USBPort,
27
+ loop: Optional[asyncio.AbstractEventLoop],
28
+ ) -> AbsorbanceReaderDriver:
29
+ """Create an absorbance reader driver."""
30
+ from .async_byonoy import AsyncByonoy
31
+
32
+ connection = await AsyncByonoy.create(port=port, usb_port=usb_port, loop=loop)
33
+ return cls(connection=connection)
34
+
35
+ def __init__(self, connection: AsyncByonoyType) -> None:
36
+ self._connection = connection
37
+
38
+ async def connect(self) -> None:
39
+ """Connect to absorbance reader"""
40
+ await self._connection.open()
41
+
42
+ async def disconnect(self) -> None:
43
+ """Disconnect from absorbance reader"""
44
+ await self._connection.close()
45
+
46
+ async def is_connected(self) -> bool:
47
+ """Check connection to absorbance reader"""
48
+ return await self._connection.is_open()
49
+
50
+ async def get_device_info(self) -> Dict[str, str]:
51
+ """Get device info"""
52
+ return await self._connection.get_device_information()
53
+
54
+ async def update_firmware(self, firmware_file_path: str) -> Tuple[bool, str]:
55
+ return await self._connection.update_firmware(firmware_file_path)
56
+
57
+ async def get_uptime(self) -> int:
58
+ return await self._connection.get_device_uptime()
59
+
60
+ async def get_lid_status(self) -> AbsorbanceReaderLidStatus:
61
+ return await self._connection.get_lid_status()
62
+
63
+ async def get_available_wavelengths(self) -> List[int]:
64
+ return await self._connection.get_supported_wavelengths()
65
+
66
+ async def initialize_measurement(
67
+ self,
68
+ wavelengths: List[int],
69
+ mode: ABSMeasurementMode = ABSMeasurementMode.SINGLE,
70
+ reference_wavelength: Optional[int] = None,
71
+ ) -> None:
72
+ await self._connection.initialize(mode, wavelengths, reference_wavelength)
73
+
74
+ async def get_measurement(self) -> List[List[float]]:
75
+ return await self._connection.get_measurement()
76
+
77
+ async def get_status(self) -> AbsorbanceReaderDeviceState:
78
+ return await self._connection.get_device_status()
79
+
80
+ async def get_plate_presence(self) -> AbsorbanceReaderPlatePresence:
81
+ return await self._connection.get_plate_presence()