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
opentrons/__init__.py ADDED
@@ -0,0 +1,150 @@
1
+ import os
2
+
3
+ from pathlib import Path
4
+ import logging
5
+ import re
6
+ from typing import Any, List, Tuple
7
+
8
+ from opentrons.drivers.serial_communication import get_ports_by_name
9
+ from opentrons.hardware_control import (
10
+ API as HardwareAPI,
11
+ ThreadManager,
12
+ ThreadManagedHardware,
13
+ types as hw_types,
14
+ )
15
+
16
+ from opentrons.config import (
17
+ feature_flags as ff,
18
+ name,
19
+ robot_configs,
20
+ IS_ROBOT,
21
+ ROBOT_FIRMWARE_DIR,
22
+ )
23
+ from opentrons.util import logging_config
24
+ from opentrons.protocols.types import ApiDeprecationError
25
+ from opentrons.protocols.api_support.types import APIVersion
26
+
27
+ from ._version import version
28
+
29
+ HERE = os.path.abspath(os.path.dirname(__file__))
30
+ __version__ = version
31
+
32
+
33
+ LEGACY_MODULES = ["robot", "reset", "instruments", "containers", "labware", "modules"]
34
+
35
+
36
+ __all__ = ["version", "__version__", "HERE", "config"]
37
+
38
+
39
+ def __getattr__(attrname: str) -> None:
40
+ """
41
+ Prevent import of legacy modules from global to officially
42
+ deprecate Python API Version 1.0.
43
+ """
44
+ if attrname in LEGACY_MODULES:
45
+ raise ApiDeprecationError(APIVersion(1, 0))
46
+ raise AttributeError(attrname)
47
+
48
+
49
+ def __dir__() -> List[str]:
50
+ return sorted(__all__ + LEGACY_MODULES)
51
+
52
+
53
+ log = logging.getLogger(__name__)
54
+
55
+
56
+ SMOOTHIE_HEX_RE = re.compile("smoothie-(.*).hex")
57
+
58
+
59
+ def _find_smoothie_file() -> Tuple[Path, str]:
60
+ resources: List[Path] = []
61
+
62
+ # Search for smoothie files in /usr/lib/firmware first then fall back to
63
+ # value packed in wheel
64
+ if IS_ROBOT:
65
+ resources.extend(ROBOT_FIRMWARE_DIR.iterdir()) # type: ignore
66
+
67
+ resources_path = Path(HERE) / "resources"
68
+ resources.extend(resources_path.iterdir())
69
+
70
+ for path in resources:
71
+ matches = SMOOTHIE_HEX_RE.search(path.name)
72
+ if matches:
73
+ branch_plus_ref = matches.group(1)
74
+ return path, branch_plus_ref
75
+ raise OSError(f"Could not find smoothie firmware file in {resources_path}")
76
+
77
+
78
+ def _get_motor_control_serial_port() -> Any:
79
+ port = os.environ.get("OT_SMOOTHIE_EMULATOR_URI")
80
+
81
+ if port is None:
82
+ smoothie_id = os.environ.get("OT_SMOOTHIE_ID", "AMA")
83
+ # TODO(mc, 2021-08-01): raise a more informative exception than
84
+ # IndexError if a valid serial port is not found
85
+ port = get_ports_by_name(device_name=smoothie_id)[0]
86
+
87
+ log.info(f"Connecting to motor controller at port {port}")
88
+ return port
89
+
90
+
91
+ def should_use_ot3() -> bool:
92
+ """Return true if ot3 hardware controller should be used."""
93
+ if ff.enable_ot3_hardware_controller():
94
+ try:
95
+ from opentrons_hardware.drivers.can_bus import CanDriver # noqa: F401
96
+
97
+ return True
98
+ except ModuleNotFoundError:
99
+ log.exception("Cannot use OT3 Hardware controller.")
100
+ return False
101
+
102
+
103
+ async def _create_thread_manager() -> ThreadManagedHardware:
104
+ """Build the hardware controller wrapped in a ThreadManager.
105
+
106
+ .. deprecated:: 4.6
107
+ ThreadManager is on its way out.
108
+ """
109
+ if os.environ.get("ENABLE_VIRTUAL_SMOOTHIE"):
110
+ log.info("Initialized robot using virtual Smoothie")
111
+ thread_manager: ThreadManagedHardware = ThreadManager(
112
+ HardwareAPI.build_hardware_simulator
113
+ )
114
+ elif should_use_ot3():
115
+ from opentrons.hardware_control.ot3api import OT3API
116
+
117
+ thread_manager = ThreadManager(
118
+ ThreadManager.nonblocking_builder(OT3API.build_hardware_controller),
119
+ use_usb_bus=ff.rear_panel_integration(),
120
+ status_bar_enabled=ff.status_bar_enabled(),
121
+ feature_flags=hw_types.HardwareFeatureFlags.build_from_ff(),
122
+ )
123
+ else:
124
+ thread_manager = ThreadManager(
125
+ ThreadManager.nonblocking_builder(HardwareAPI.build_hardware_controller),
126
+ port=_get_motor_control_serial_port(),
127
+ firmware=_find_smoothie_file(),
128
+ feature_flags=hw_types.HardwareFeatureFlags.build_from_ff(),
129
+ )
130
+
131
+ try:
132
+ await thread_manager.managed_thread_ready_async()
133
+ except RuntimeError:
134
+ log.exception("Could not build hardware controller, forcing virtual")
135
+ thread_manager = ThreadManager(HardwareAPI.build_hardware_simulator)
136
+
137
+ return thread_manager
138
+
139
+
140
+ async def initialize() -> ThreadManagedHardware:
141
+ """
142
+ Initialize the Opentrons hardware returning a hardware instance.
143
+ """
144
+ robot_conf = robot_configs.load()
145
+ logging_config.log_init(robot_conf.log_level)
146
+
147
+ log.info(f"API server version: {version}")
148
+ log.info(f"Robot Name: {name()}")
149
+
150
+ return await _create_thread_manager()
opentrons/_version.py ADDED
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '8.6.0'
32
+ __version_tuple__ = version_tuple = (8, 6, 0)
33
+
34
+ __commit_id__ = commit_id = None
@@ -0,0 +1,54 @@
1
+ from .ot3 import gripper_offset
2
+ from .ot2 import mark_bad_calibration
3
+
4
+ from .deck_configuration import (
5
+ serialize_deck_configuration,
6
+ deserialize_deck_configuration,
7
+ )
8
+
9
+ # TODO these functions are only used in robot server. We should think about moving them and/or
10
+ # abstracting it away from a robot specific function. We should also check if the tip rack
11
+ # definition information is still needed.
12
+ from .ot2.tip_length import (
13
+ get_custom_tiprack_definition_for_tlc,
14
+ get_all_tip_length_calibrations,
15
+ _save_custom_tiprack_definition,
16
+ )
17
+ from .ot2.pipette_offset import get_all_pipette_offset_calibrations
18
+ from .ot3.deck_attitude import (
19
+ save_robot_belt_attitude,
20
+ get_robot_belt_attitude,
21
+ delete_robot_belt_attitude,
22
+ )
23
+ from .ot2.deck_attitude import (
24
+ save_robot_deck_attitude,
25
+ get_robot_deck_attitude,
26
+ delete_robot_deck_attitude,
27
+ )
28
+
29
+ from . import ot2, ot3, helpers
30
+
31
+ __all__ = [
32
+ "helpers",
33
+ # deck calibration functions
34
+ "save_robot_deck_attitude",
35
+ "get_robot_deck_attitude",
36
+ "delete_robot_deck_attitude",
37
+ "save_robot_belt_attitude",
38
+ "get_robot_belt_attitude",
39
+ "delete_robot_belt_attitude",
40
+ # deck configuration functions
41
+ "serialize_deck_configuration",
42
+ "deserialize_deck_configuration",
43
+ # functions only used in robot server
44
+ "_save_custom_tiprack_definition",
45
+ "get_custom_tiprack_definition_for_tlc",
46
+ "get_all_pipette_offset_calibrations",
47
+ "get_all_tip_length_calibrations",
48
+ # file exports
49
+ "gripper_offset",
50
+ "mark_bad_calibration",
51
+ # Platform specific submodules
52
+ "ot2",
53
+ "ot3",
54
+ ]
@@ -0,0 +1,62 @@
1
+ from datetime import datetime
2
+ from typing import List, Optional, Tuple
3
+
4
+ import pydantic
5
+
6
+ from .types import CutoutFixturePlacement
7
+ from . import file_operators as io
8
+
9
+
10
+ class _CutoutFixturePlacementModel(pydantic.BaseModel):
11
+ cutoutId: str
12
+ cutoutFixtureId: str
13
+ opentronsModuleSerialNumber: Optional[str] = None
14
+
15
+
16
+ class _DeckConfigurationModel(pydantic.BaseModel):
17
+ """The on-filesystem representation of a deck configuration."""
18
+
19
+ cutoutFixtures: List[_CutoutFixturePlacementModel]
20
+ lastModified: datetime
21
+
22
+
23
+ def serialize_deck_configuration(
24
+ cutout_fixture_placements: List[CutoutFixturePlacement], last_modified: datetime
25
+ ) -> bytes:
26
+ """Serialize a deck configuration for storing on the filesystem."""
27
+ data = _DeckConfigurationModel.model_construct(
28
+ cutoutFixtures=[
29
+ _CutoutFixturePlacementModel.model_construct(
30
+ cutoutId=e.cutout_id,
31
+ cutoutFixtureId=e.cutout_fixture_id,
32
+ opentronsModuleSerialNumber=e.opentrons_module_serial_number,
33
+ )
34
+ for e in cutout_fixture_placements
35
+ ],
36
+ lastModified=last_modified,
37
+ )
38
+ return io.serialize_pydantic_model(data)
39
+
40
+
41
+ # TODO(mm, 2023-11-21): If the data is corrupt, we should propagate the underlying error.
42
+ # And there should be an enumerated "corrupt storage" error in shared-data.
43
+ def deserialize_deck_configuration(
44
+ serialized: bytes,
45
+ ) -> Optional[Tuple[List[CutoutFixturePlacement], datetime]]:
46
+ """Deserialize bytes previously serialized by `serialize_deck_configuration()`.
47
+
48
+ Returns a tuple `(deck_configuration, last_modified_time)`, or `None` if the data is corrupt.
49
+ """
50
+ parsed = io.deserialize_pydantic_model(serialized, _DeckConfigurationModel)
51
+ if parsed is None:
52
+ return None
53
+ else:
54
+ cutout_fixture_placements = [
55
+ CutoutFixturePlacement(
56
+ cutout_id=e.cutoutId,
57
+ cutout_fixture_id=e.cutoutFixtureId,
58
+ opentrons_module_serial_number=e.opentronsModuleSerialNumber,
59
+ )
60
+ for e in parsed.cutoutFixtures
61
+ ]
62
+ return cutout_fixture_placements, parsed.lastModified
@@ -0,0 +1,31 @@
1
+ """ opentrons.calibration_storage.encoder_decoder: classes that
2
+ allow you to customize serialization to/from json.
3
+ """
4
+ import json
5
+ import datetime
6
+ from typing import Any, cast
7
+
8
+
9
+ class DateTimeEncoder(json.JSONEncoder):
10
+ def default(self, obj: object) -> Any:
11
+ if isinstance(obj, datetime.datetime):
12
+ return obj.isoformat()
13
+ return json.JSONEncoder.default(self, obj)
14
+
15
+
16
+ class DateTimeDecoder(json.JSONDecoder):
17
+ def __init__(self) -> None:
18
+ super().__init__(object_hook=self.dict_to_obj)
19
+
20
+ def dict_to_obj(self, d: object) -> Any:
21
+ if isinstance(d, dict):
22
+ d = {k: self._decode_datetime(v) for k, v in d.items()}
23
+ return d
24
+
25
+ def _decode_datetime(self, obj: object) -> Any:
26
+ try:
27
+ return datetime.datetime.fromisoformat(cast(str, obj))
28
+ except ValueError:
29
+ return obj
30
+ except TypeError:
31
+ return self.dict_to_obj(obj)
@@ -0,0 +1,142 @@
1
+ """ opentrons.calibration_storage.file_operators: functions that
2
+ manipulate the file system.
3
+
4
+ These methods should only be imported inside the calibration_storage
5
+ module, except in the special case of v2 labware support in
6
+ the v1 API.
7
+ """
8
+ import datetime
9
+ import json
10
+ import logging
11
+ import typing
12
+ from pathlib import Path
13
+
14
+ import pydantic
15
+
16
+ from .encoder_decoder import DateTimeEncoder, DateTimeDecoder
17
+
18
+
19
+ _log = logging.getLogger(__name__)
20
+
21
+
22
+ DecoderType = typing.Type[json.JSONDecoder]
23
+ EncoderType = typing.Type[json.JSONEncoder]
24
+
25
+
26
+ # TODO(mc, 2022-06-07): replace with Path.unlink(missing_ok=True)
27
+ # when we are on Python >= 3.8
28
+ def delete_file(path: Path) -> None:
29
+ try:
30
+ path.unlink()
31
+ except FileNotFoundError:
32
+ pass
33
+
34
+
35
+ # TODO: This is private but used by other files.
36
+ def _remove_json_files_in_directories(p: Path) -> None:
37
+ """Delete .json files in the given directory and its subdirectories."""
38
+ for item in p.iterdir():
39
+ if item.is_dir():
40
+ _remove_json_files_in_directories(item)
41
+ elif item.suffix == ".json":
42
+ delete_file(item)
43
+
44
+
45
+ def _assert_last_modified_value(calibration_dict: typing.Dict[str, typing.Any]) -> None:
46
+ last_modified = calibration_dict.get("lastModified")
47
+ if last_modified:
48
+ assert isinstance(calibration_dict["lastModified"], datetime.datetime), (
49
+ "invalid decoded value type for lastModified: got "
50
+ f"{type(calibration_dict['lastModified']).__name__},"
51
+ "expected datetime"
52
+ )
53
+
54
+
55
+ def read_cal_file(
56
+ file_path: Path, decoder: DecoderType = DateTimeDecoder
57
+ ) -> typing.Dict[str, typing.Any]:
58
+ """
59
+ Function used to read data from a file
60
+
61
+ :param file_path: path to look for data at
62
+ :param decoder: if there is any specialized decoder needed.
63
+ The default decoder is the date time decoder.
64
+ :return: Data from the file
65
+ """
66
+ # TODO(6/16): We should use tagged unions for
67
+ # both the calibration and tip length dicts to better
68
+ # categorize the Typed Dicts used here.
69
+ # This can be done when the labware endpoints
70
+ # are refactored to grab tip length calibration
71
+ # from the correct locations.
72
+ with open(file_path, "r", encoding="utf-8") as f:
73
+ calibration_data = typing.cast(
74
+ typing.Dict[str, typing.Any],
75
+ json.load(f, cls=decoder),
76
+ )
77
+ if isinstance(calibration_data.values(), dict):
78
+ _assert_last_modified_value(dict(calibration_data.values()))
79
+ else:
80
+ _assert_last_modified_value(calibration_data)
81
+ return calibration_data
82
+
83
+
84
+ def save_to_file(
85
+ directory_path: Path,
86
+ # todo(mm, 2023-11-15): This file_name argument does not include the file
87
+ # extension, which is inconsistent with read_cal_file(). The two should match.
88
+ file_name: str,
89
+ data: typing.Union[pydantic.BaseModel, typing.Dict[str, typing.Any], typing.Any],
90
+ encoder: EncoderType = DateTimeEncoder,
91
+ ) -> None:
92
+ """
93
+ Function used to save data to a file
94
+
95
+ :param directory_path: path to the directory in which to save the data
96
+ :param file_name: name of the file within the directory, *without the extension*.
97
+ :param data: The data to save. Either a Pydantic model, or a JSON-like dict to pass to
98
+ `json.dumps()`. If you're storing a Pydantic model, prefer `save_pydantic_model_to_file()`
99
+ and `read_pydantic_model_from_file()` for new code.
100
+ :param encoder: if there is any specialized encoder needed.
101
+ The default encoder is the date time encoder.
102
+ """
103
+ directory_path.mkdir(parents=True, exist_ok=True)
104
+ file_path = directory_path / f"{file_name}.json"
105
+ json_data = (
106
+ data.model_dump_json()
107
+ if isinstance(data, pydantic.BaseModel)
108
+ else json.dumps(data, cls=encoder)
109
+ )
110
+ file_path.write_text(json_data, encoding="utf-8")
111
+
112
+
113
+ def serialize_pydantic_model(data: pydantic.BaseModel) -> bytes:
114
+ """Safely serialize data from a Pydantic model into a form suitable for storing on disk."""
115
+ return data.model_dump_json(by_alias=True).encode("utf-8")
116
+
117
+
118
+ _ModelT = typing.TypeVar("_ModelT", bound=pydantic.BaseModel)
119
+
120
+
121
+ # TODO(mm, 2023-11-20): We probably want to distinguish "missing file" from "corrupt file."
122
+ # The caller needs to deal with those cases separately because the appropriate action depends on
123
+ # context. For example, when running protocols through robot-server, if the file is corrupt, it's
124
+ # safe-ish to fall back to a default because the Opentrons App will let the user confirm everything
125
+ # before starting the run. But when running protocols through the non-interactive
126
+ # `opentrons_execute`, we don't want it to silently use default data if the file is corrupt.
127
+ def deserialize_pydantic_model(
128
+ serialized: bytes,
129
+ model: typing.Type[_ModelT],
130
+ ) -> typing.Optional[_ModelT]:
131
+ """Safely read bytes from `serialize_pydantic_model()` back into a Pydantic model.
132
+
133
+ Returns `None` if the file is missing or corrupt.
134
+ """
135
+ try:
136
+ return model.model_validate_json(serialized)
137
+ except json.JSONDecodeError:
138
+ _log.warning("Data is not valid JSON.", exc_info=True)
139
+ return None
140
+ except pydantic.ValidationError:
141
+ _log.warning(f"Data is malformed as a {model}.", exc_info=True)
142
+ return None
@@ -0,0 +1,103 @@
1
+ """ opentrons.calibration_storage.helpers: various miscellaneous
2
+ functions
3
+
4
+ This module has functions that you can import to save robot or
5
+ labware calibration to its designated file location.
6
+ """
7
+ import json
8
+ from typing import Any, Union, List, Dict, TYPE_CHECKING, cast, Tuple
9
+ from dataclasses import is_dataclass, asdict
10
+
11
+
12
+ from hashlib import sha256
13
+
14
+ from . import types as local_types
15
+
16
+ if TYPE_CHECKING:
17
+ from opentrons_shared_data.labware.types import LabwareDefinition
18
+ from opentrons_shared_data.pipette.types import LabwareUri
19
+
20
+
21
+ def dict_filter_none(data: List[Tuple[str, Any]]) -> Dict[str, Any]:
22
+ """
23
+ Helper function to filter out None keys from a dataclass
24
+ before saving to file.
25
+ """
26
+ return dict(item for item in data if item[1] is not None)
27
+
28
+
29
+ def convert_to_dict(obj: Any) -> Dict[str, Any]:
30
+ # The correct way to type this is described here:
31
+ # https://github.com/python/mypy/issues/6568
32
+ # Unfortunately, since it's not currently supported I have an
33
+ # assert check instead.
34
+ assert is_dataclass(obj) and not isinstance(
35
+ obj, type
36
+ ), "This function is intended for dataclasses only"
37
+ return asdict(obj, dict_factory=dict_filter_none)
38
+
39
+
40
+ # TODO(mc, 2021-11-09): this hashing function may produce different hashes
41
+ # for semantically identical labware defs. For example, a value of `10` will
42
+ # produce a different hash than a value of `10.0`. Hashing should be produce
43
+ # identical hashes for `==` values. This could be done by running defs through
44
+ # Pydantic or similar rather via json.dumps
45
+ def hash_labware_def(labware_def: "LabwareDefinition") -> str:
46
+ """
47
+ Helper function to take in a labware definition and return
48
+ a hashed string of key elements from the labware definition
49
+ to make it a unique identifier.
50
+
51
+ :param labware_def: Full labware definition
52
+ :returns: sha256 string
53
+ """
54
+ # remove keys that do not affect run
55
+ blocklist = ["metadata", "brand", "groups"]
56
+ def_no_metadata = {k: v for k, v in labware_def.items() if k not in blocklist}
57
+ sorted_def_str = json.dumps(def_no_metadata, sort_keys=True, separators=(",", ":"))
58
+
59
+ return sha256(sorted_def_str.encode("utf-8")).hexdigest()
60
+
61
+
62
+ def details_from_uri(uri: str, delimiter: str = "/") -> local_types.UriDetails:
63
+ """
64
+ Unpack a labware URI to get the namespace, loadname and version
65
+ """
66
+ try:
67
+ info = uri.split(delimiter)
68
+ return local_types.UriDetails(
69
+ namespace=info[0], load_name=info[1], version=int(info[2])
70
+ )
71
+ except IndexError:
72
+ # Here we are assuming that the 'uri' passed in is actually
73
+ # the loadname, though sometimes it may be an empty string.
74
+ return local_types.UriDetails(namespace="", load_name=uri, version=1)
75
+
76
+
77
+ def uri_from_details(
78
+ namespace: str, load_name: str, version: Union[str, int], delimiter: str = "/"
79
+ ) -> "LabwareUri":
80
+ """Build a labware URI from its details.
81
+
82
+ A labware URI is a string that uniquely specifies a labware definition.
83
+
84
+ :returns str: The URI.
85
+ """
86
+ return cast("LabwareUri", f"{namespace}{delimiter}{load_name}{delimiter}{version}")
87
+
88
+
89
+ def uri_from_definition(
90
+ definition: "LabwareDefinition", delimiter: str = "/"
91
+ ) -> "LabwareUri":
92
+ """Build a labware URI from its definition.
93
+
94
+ A labware URI is a string that uniquely specifies a labware definition.
95
+
96
+ :returns str: The URI.
97
+ """
98
+ return uri_from_details(
99
+ namespace=definition["namespace"],
100
+ load_name=definition["parameters"]["loadName"],
101
+ version=definition["version"],
102
+ delimiter=delimiter,
103
+ )
@@ -0,0 +1,34 @@
1
+ from . import (
2
+ models,
3
+ mark_bad_calibration,
4
+ )
5
+ from .pipette_offset import (
6
+ save_pipette_calibration,
7
+ clear_pipette_offset_calibrations,
8
+ get_pipette_offset,
9
+ delete_pipette_offset_file,
10
+ )
11
+
12
+ from .tip_length import (
13
+ clear_tip_length_calibration,
14
+ create_tip_length_data,
15
+ save_tip_length_calibration,
16
+ tip_lengths_for_pipette,
17
+ load_tip_length_calibration,
18
+ delete_tip_length_calibration,
19
+ )
20
+
21
+ __all__ = [
22
+ "models",
23
+ "mark_bad_calibration",
24
+ "save_pipette_calibration",
25
+ "clear_pipette_offset_calibrations",
26
+ "get_pipette_offset",
27
+ "delete_pipette_offset_file",
28
+ "clear_tip_length_calibration",
29
+ "create_tip_length_data",
30
+ "save_tip_length_calibration",
31
+ "tip_lengths_for_pipette",
32
+ "load_tip_length_calibration",
33
+ "delete_tip_length_calibration",
34
+ ]
@@ -0,0 +1,85 @@
1
+ import json
2
+ import logging
3
+ from pydantic import ValidationError
4
+ from typing import Optional, Union
5
+ from dataclasses import asdict
6
+
7
+ from opentrons import config
8
+ from opentrons.util.helpers import utc_now
9
+
10
+
11
+ from .. import file_operators as io, types as local_types
12
+
13
+ from .models import v1
14
+
15
+ log = logging.getLogger(__name__)
16
+
17
+ # Delete Deck Calibration
18
+
19
+
20
+ def delete_robot_deck_attitude() -> None:
21
+ """
22
+ Delete the robot deck attitude calibration.
23
+ """
24
+ legacy_deck_calibration_file = config.get_opentrons_path("deck_calibration_file")
25
+
26
+ robot_dir = config.get_opentrons_path("robot_calibration_dir")
27
+ gantry_path = robot_dir / "deck_calibration.json"
28
+
29
+ # TODO(mc, 2022-06-08): this leaves legacy deck calibration backup files in place
30
+ # we should eventually clean them up, too, because they can really crowd /data/
31
+ io.delete_file(legacy_deck_calibration_file)
32
+ io.delete_file(gantry_path)
33
+
34
+
35
+ # Save Deck Calibration
36
+
37
+
38
+ def save_robot_deck_attitude(
39
+ transform: local_types.AttitudeMatrix,
40
+ pip_id: Optional[str],
41
+ lw_hash: Optional[str],
42
+ source: Optional[local_types.SourceType] = None,
43
+ cal_status: Optional[
44
+ Union[local_types.CalibrationStatus, v1.CalibrationStatus]
45
+ ] = None,
46
+ ) -> None:
47
+ robot_dir = config.get_opentrons_path("robot_calibration_dir")
48
+
49
+ if isinstance(cal_status, local_types.CalibrationStatus):
50
+ cal_status_model = v1.CalibrationStatus(**asdict(cal_status))
51
+ elif isinstance(cal_status, v1.CalibrationStatus):
52
+ cal_status_model = cal_status
53
+ else:
54
+ cal_status_model = v1.CalibrationStatus()
55
+
56
+ gantry_calibration = v1.DeckCalibrationModel(
57
+ attitude=transform,
58
+ pipette_calibrated_with=pip_id,
59
+ last_modified=utc_now(),
60
+ tiprack=lw_hash,
61
+ source=source or local_types.SourceType.user,
62
+ status=cal_status_model,
63
+ )
64
+ # convert to schema + validate json conversion
65
+ io.save_to_file(robot_dir, "deck_calibration", gantry_calibration)
66
+
67
+
68
+ # Get Deck Calibration
69
+
70
+
71
+ def get_robot_deck_attitude() -> Optional[v1.DeckCalibrationModel]:
72
+ deck_calibration_path = (
73
+ config.get_opentrons_path("robot_calibration_dir") / "deck_calibration.json"
74
+ )
75
+ try:
76
+ return v1.DeckCalibrationModel(**io.read_cal_file(deck_calibration_path))
77
+ except FileNotFoundError:
78
+ log.warning("Deck calibration not found.")
79
+ pass
80
+ except (json.JSONDecodeError, ValidationError):
81
+ log.warning(
82
+ "Deck calibration is malformed. Please factory reset your calibrations.",
83
+ exc_info=True,
84
+ )
85
+ return None