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,552 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ from typing import Optional, List, Type
6
+
7
+ from opentrons.drivers.command_builder import CommandBuilder
8
+
9
+ from .errors import (
10
+ NoResponse,
11
+ AlarmResponse,
12
+ ErrorResponse,
13
+ BaseErrorCode,
14
+ DefaultErrorCodes,
15
+ )
16
+ from .async_serial import AsyncSerial
17
+
18
+ log = logging.getLogger(__name__)
19
+
20
+
21
+ class SerialConnection:
22
+ @classmethod
23
+ async def _build_serial(
24
+ cls,
25
+ port: str,
26
+ baud_rate: int,
27
+ timeout: float,
28
+ loop: Optional[asyncio.AbstractEventLoop],
29
+ reset_buffer_before_write: bool,
30
+ ) -> AsyncSerial:
31
+ return await AsyncSerial.create(
32
+ port=port,
33
+ baud_rate=baud_rate,
34
+ timeout=timeout,
35
+ loop=loop,
36
+ reset_buffer_before_write=reset_buffer_before_write,
37
+ )
38
+
39
+ @classmethod
40
+ async def create(
41
+ cls,
42
+ port: str,
43
+ baud_rate: int,
44
+ timeout: float,
45
+ ack: str,
46
+ name: Optional[str] = None,
47
+ retry_wait_time_seconds: float = 0.1,
48
+ loop: Optional[asyncio.AbstractEventLoop] = None,
49
+ error_keyword: Optional[str] = None,
50
+ alarm_keyword: Optional[str] = None,
51
+ reset_buffer_before_write: bool = False,
52
+ error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
53
+ ) -> "SerialConnection":
54
+ """
55
+ Create a connection.
56
+
57
+ Args:
58
+ port: url or port to connect to
59
+ baud_rate: baud rate
60
+ timeout: timeout in seconds
61
+ ack: the command response ack
62
+ name: the connection name
63
+ retry_wait_time_seconds: how long to wait between retries.
64
+ loop: optional event loop.
65
+ error_keyword: optional string that will cause an
66
+ ErrorResponse exception when detected
67
+ (default: error)
68
+ alarm_keyword: optional string that will cause an
69
+ AlarmResponse exception when detected
70
+ (default: alarm)
71
+ reset_buffer_before_write: whether to reset the read buffer before
72
+ every write
73
+ error_codes: Enum class for error codes
74
+ (default: DefaultErrorCodes)
75
+
76
+ Returns: SerialConnection
77
+ """
78
+ serial = await cls._build_serial(
79
+ port=port,
80
+ baud_rate=baud_rate,
81
+ timeout=timeout,
82
+ loop=loop,
83
+ reset_buffer_before_write=reset_buffer_before_write,
84
+ )
85
+ name = name or port
86
+ obj = cls(
87
+ serial=serial,
88
+ port=port,
89
+ name=name,
90
+ ack=ack,
91
+ retry_wait_time_seconds=retry_wait_time_seconds,
92
+ error_keyword=error_keyword or "error",
93
+ alarm_keyword=alarm_keyword or "alarm",
94
+ error_codes=error_codes,
95
+ )
96
+ await obj.flush_input()
97
+ return obj
98
+
99
+ def __init__(
100
+ self,
101
+ serial: AsyncSerial,
102
+ port: str,
103
+ name: str,
104
+ ack: str,
105
+ retry_wait_time_seconds: float,
106
+ error_keyword: str,
107
+ alarm_keyword: str,
108
+ error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
109
+ ) -> None:
110
+ """
111
+ Constructor
112
+
113
+ Args:
114
+ serial: AsyncSerial object
115
+ port: url or port to connect to
116
+ ack: the command response ack
117
+ name: the connection name
118
+ retry_wait_time_seconds: how long to wait between retries.
119
+ error_keyword: string that will cause an ErrorResponse
120
+ exception when detected
121
+ alarm_keyword: string that will cause an AlarmResponse
122
+ exception when detected
123
+ error_codes: Enum class for error codes
124
+ """
125
+ self._serial = serial
126
+ self._port = port
127
+ self._name = name
128
+ self._ack = ack.encode()
129
+ self._retry_wait_time_seconds = retry_wait_time_seconds
130
+ self._send_data_lock = asyncio.Lock()
131
+ self._error_keyword = error_keyword.lower()
132
+ self._alarm_keyword = alarm_keyword.lower()
133
+ self._error_codes = error_codes
134
+
135
+ async def send_command(
136
+ self, command: CommandBuilder, retries: int = 0, timeout: Optional[float] = None
137
+ ) -> str:
138
+ """
139
+ Send a command and return the response.
140
+
141
+ Args:
142
+ command: A command builder.
143
+ retries: number of times to retry in case of timeout
144
+ timeout: optional override of default timeout in seconds
145
+
146
+ Returns: The command response
147
+
148
+ Raises: SerialException
149
+ """
150
+ return await self.send_data(
151
+ data=command.build(), retries=retries, timeout=timeout
152
+ )
153
+
154
+ async def send_dfu_command(self, command: CommandBuilder) -> None:
155
+ """
156
+ Send a dfu command to enter device bootloader.
157
+
158
+ This method doesn't wait for a response after sending the command since the
159
+ module port gets disconnected once it enters its bootloader.
160
+ """
161
+ encoded_command = command.build().encode()
162
+
163
+ async with self._send_data_lock:
164
+ log.debug(f"{self.name}: Write -> {encoded_command!r}")
165
+ await self._serial.write(data=encoded_command)
166
+
167
+ async def send_data(
168
+ self, data: str, retries: int = 0, timeout: Optional[float] = None
169
+ ) -> str:
170
+ """
171
+ Send data and return the response.
172
+
173
+ Args:
174
+ data: The data to send.
175
+ retries: number of times to retry in case of timeout
176
+ timeout: optional override of default timeout in seconds
177
+
178
+ Returns: The command response
179
+
180
+ Raises: SerialException
181
+ """
182
+ async with self._send_data_lock, self._serial.timeout_override(
183
+ "timeout", timeout
184
+ ):
185
+ return await self._send_data(data=data, retries=retries)
186
+
187
+ async def _send_data(self, data: str, retries: int = 0) -> str:
188
+ """
189
+ Send data and return the response.
190
+
191
+ Args:
192
+ data: The data to send.
193
+ retries: number of times to retry in case of timeout
194
+
195
+ Returns: The command response
196
+
197
+ Raises: SerialException
198
+ """
199
+ data_encode = data.encode()
200
+
201
+ for retry in range(retries + 1):
202
+ log.debug(f"{self.name}: Write -> {data_encode!r}")
203
+ await self._serial.write(data=data_encode)
204
+
205
+ response = await self._serial.read_until(match=self._ack)
206
+ log.debug(f"{self.name}: Read <- {response!r}")
207
+
208
+ if (
209
+ self._ack in response
210
+ or self._error_keyword.encode() in response.lower()
211
+ ):
212
+ # Remove ack from response
213
+ response = response.replace(self._ack, b"")
214
+ str_response = self.process_raw_response(
215
+ command=data, response=response.decode()
216
+ )
217
+ self.raise_on_error(response=str_response, request=data)
218
+ return str_response
219
+
220
+ log.info(f"{self.name}: retry number {retry}/{retries}")
221
+
222
+ await self.on_retry()
223
+
224
+ raise NoResponse(port=self._port, command=data)
225
+
226
+ async def open(self) -> None:
227
+ """Open the connection."""
228
+ await self._serial.open()
229
+
230
+ async def close(self) -> None:
231
+ """Close the connection."""
232
+ await self._serial.close()
233
+
234
+ async def is_open(self) -> bool:
235
+ """Check if connection is open."""
236
+ return await self._serial.is_open()
237
+
238
+ @property
239
+ def port(self) -> str:
240
+ return self._port
241
+
242
+ @property
243
+ def name(self) -> str:
244
+ return self._name
245
+
246
+ @property
247
+ def send_data_lock(self) -> asyncio.Lock:
248
+ return self._send_data_lock
249
+
250
+ def raise_on_error(self, response: str, request: str) -> None:
251
+ """
252
+ Raise an error if the response contains an error
253
+
254
+ Args:
255
+ response: response
256
+ request: the requesting command
257
+
258
+ Returns: None
259
+
260
+ Raises: SerialException
261
+ """
262
+ if not response or not request:
263
+ return
264
+
265
+ lower = response.lower()
266
+ res_gcode = response.split()[0]
267
+ req_gcode = request.split()[0]
268
+
269
+ # Make sure this is not just a normal response that happens to contain the
270
+ # `err` or `alarm` keyword in the message body by checking the gcode values
271
+ # for both the request and response. If the gcodes are the same then this
272
+ # is not an error response.
273
+ if res_gcode == req_gcode:
274
+ return
275
+
276
+ if self._alarm_keyword in lower:
277
+ raise AlarmResponse(port=self._port, response=response)
278
+
279
+ if self._error_keyword.lower() in lower:
280
+ # Check for specific error codes
281
+ error_codes_dict = self._error_codes.get_error_codes()
282
+ for code, error_code in error_codes_dict.items():
283
+ if code in lower:
284
+ error_code.raise_exception(
285
+ port=self._port, response=response, command=request
286
+ )
287
+
288
+ # If no specific error code was found, raise a generic ErrorResponse
289
+ raise ErrorResponse(port=self._port, response=response)
290
+
291
+ async def on_retry(self) -> None:
292
+ """
293
+ Opportunity for derived classes to perform action between retries. Default
294
+ behaviour is to wait then re-open the connection.
295
+
296
+ Returns: None
297
+ """
298
+ await asyncio.sleep(self._retry_wait_time_seconds)
299
+ await self._serial.close()
300
+ await self._serial.open()
301
+
302
+ def process_raw_response(self, command: str, response: str) -> str:
303
+ """
304
+ Opportunity for derived classes to process the raw response. Default
305
+ strips white space.
306
+
307
+ Args:
308
+ command: The sent command.
309
+ response: The raw read response minus ack.
310
+
311
+ Returns:
312
+ processed response.
313
+ """
314
+ return response.strip()
315
+
316
+ async def flush_input(self) -> None:
317
+ """Empty the input buffer.
318
+
319
+ This is a pretty gross utility that may take a while and is intended to consume
320
+ blocks of text printed by the other side, for instance on boot.
321
+ """
322
+ self._serial.reset_input_buffer()
323
+ log.info("flushing input")
324
+ consecutive_empties = 0
325
+ async with self._serial.timeout_override("timeout", 0.1):
326
+ while True:
327
+ try:
328
+ inp = await self._serial.read_until(b"\r\n")
329
+ log.info(f"flush_input read: {inp!r}")
330
+ if not inp:
331
+ consecutive_empties += 1
332
+ if consecutive_empties >= 5:
333
+ return
334
+ else:
335
+ consecutive_empties = 0
336
+ except Exception:
337
+ log.exception("timeout exception is")
338
+ return
339
+
340
+
341
+ class AsyncResponseSerialConnection(SerialConnection):
342
+ @classmethod
343
+ async def create(
344
+ cls,
345
+ port: str,
346
+ baud_rate: int,
347
+ timeout: float,
348
+ ack: str,
349
+ name: Optional[str] = None,
350
+ retry_wait_time_seconds: float = 0.1,
351
+ loop: Optional[asyncio.AbstractEventLoop] = None,
352
+ error_keyword: Optional[str] = None,
353
+ alarm_keyword: Optional[str] = None,
354
+ reset_buffer_before_write: bool = False,
355
+ error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
356
+ async_error_ack: Optional[str] = None,
357
+ number_of_retries: int = 0,
358
+ ) -> AsyncResponseSerialConnection:
359
+ """
360
+ Create a connection.
361
+
362
+ Args:
363
+ port: url or port to connect to
364
+ baud_rate: baud rate
365
+ timeout: timeout in seconds
366
+ ack: the command response ack
367
+ name: the connection name
368
+ retry_wait_time_seconds: how long to wait between retries.
369
+ loop: optional event loop.
370
+ error_keyword: optional string that will cause an
371
+ ErrorResponse exception when detected
372
+ (default: error)
373
+ alarm_keyword: optional string that will cause an
374
+ AlarmResponse exception when detected
375
+ (default: alarm)
376
+ reset_buffer_before_write: whether to reset the read buffer before
377
+ every write
378
+ async_error_ack: optional string that will indicate an asynchronous
379
+ error when detected (default: async)
380
+ number_of_retries: default number of retries
381
+ error_codes: Enum class for error codes
382
+ (default: DefaultErrorCodes)
383
+
384
+ Returns: AsyncResponseSerialConnection
385
+ """
386
+ serial = await super()._build_serial(
387
+ port=port,
388
+ baud_rate=baud_rate,
389
+ timeout=timeout,
390
+ loop=loop,
391
+ reset_buffer_before_write=reset_buffer_before_write,
392
+ )
393
+ name = name or port
394
+ obj = cls(
395
+ serial=serial,
396
+ port=port,
397
+ name=name,
398
+ ack=ack,
399
+ retry_wait_time_seconds=retry_wait_time_seconds,
400
+ error_keyword=error_keyword or "err",
401
+ alarm_keyword=alarm_keyword or "alarm",
402
+ async_error_ack=async_error_ack or "async",
403
+ number_of_retries=number_of_retries,
404
+ error_codes=error_codes,
405
+ )
406
+ return obj
407
+
408
+ def __init__(
409
+ self,
410
+ serial: AsyncSerial,
411
+ port: str,
412
+ name: str,
413
+ ack: str,
414
+ retry_wait_time_seconds: float,
415
+ error_keyword: str,
416
+ alarm_keyword: str,
417
+ async_error_ack: str,
418
+ number_of_retries: int = 0,
419
+ error_codes: Type[BaseErrorCode] = DefaultErrorCodes,
420
+ ) -> None:
421
+ """
422
+ Constructor
423
+
424
+ Args:
425
+ serial: AsyncSerial object
426
+ port: url or port to connect to
427
+ ack: the command response ack
428
+ name: the connection name
429
+ retry_wait_time_seconds: how long to wait between retries.
430
+ error_keyword: string that will cause an ErrorResponse
431
+ exception when detected
432
+ alarm_keyword: string that will cause an AlarmResponse
433
+ exception when detected
434
+ async_error_ack: string that will indicate an asynchronous
435
+ error when detected
436
+ number_of_retries: default number of retries
437
+ error_codes: Enum class for error codes
438
+ """
439
+ super().__init__(
440
+ serial=serial,
441
+ port=port,
442
+ name=name,
443
+ ack=ack,
444
+ retry_wait_time_seconds=retry_wait_time_seconds,
445
+ error_keyword=error_keyword,
446
+ alarm_keyword=alarm_keyword,
447
+ error_codes=error_codes,
448
+ )
449
+ self._serial = serial
450
+ self._port = port
451
+ self._name = name
452
+ self._ack = ack.encode()
453
+ self._retry_wait_time_seconds = retry_wait_time_seconds
454
+ self._number_of_retries = number_of_retries
455
+ self._error_keyword = error_keyword.lower()
456
+ self._alarm_keyword = alarm_keyword.lower()
457
+ self._async_error_ack = async_error_ack.lower()
458
+
459
+ async def send_command(
460
+ self, command: CommandBuilder, retries: int = 0, timeout: Optional[float] = None
461
+ ) -> str:
462
+ """
463
+ Send a command and return the response.
464
+
465
+ Args:
466
+ command: A command builder.
467
+ retries: number of times to retry in case of timeout
468
+ timeout: optional override of default timeout in seconds
469
+
470
+ Returns: The command response
471
+
472
+ Raises: SerialException
473
+ """
474
+ return await self.send_data(
475
+ data=command.build(),
476
+ retries=retries or self._number_of_retries,
477
+ timeout=timeout,
478
+ )
479
+
480
+ async def send_data(
481
+ self, data: str, retries: int = 0, timeout: Optional[float] = None
482
+ ) -> str:
483
+ """
484
+ Send data and return the response.
485
+
486
+ Args:
487
+ data: The data to send.
488
+ retries: number of times to retry in case of timeout
489
+ timeout: optional override of default timeout in seconds
490
+
491
+ Returns: The command response
492
+
493
+ Raises: SerialException
494
+ """
495
+ async with super().send_data_lock, self._serial.timeout_override(
496
+ "timeout", timeout
497
+ ):
498
+ return await self._send_data(
499
+ data=data, retries=retries or self._number_of_retries
500
+ )
501
+
502
+ async def _send_data(self, data: str, retries: int = 0) -> str:
503
+ """
504
+ Send data and return the response.
505
+
506
+ Args:
507
+ data: The data to send.
508
+ retries: number of times to retry in case of timeout
509
+
510
+ Returns: The command response
511
+
512
+ Raises: SerialException
513
+ """
514
+ data_encode = data.encode()
515
+ retries = retries or self._number_of_retries
516
+
517
+ for retry in range(retries + 1):
518
+ log.debug(f"{self._name}: Write -> {data_encode!r}")
519
+ await self._serial.write(data=data_encode)
520
+
521
+ response: List[bytes] = []
522
+ response.append(await self._serial.read_until(match=self._ack))
523
+ log.debug(f"{self._name}: Read <- {response[-1]!r}")
524
+
525
+ while self._async_error_ack.encode() in response[-1].lower():
526
+ # check for multiple a priori async errors
527
+ response.append(await self._serial.read_until(match=self._ack))
528
+ log.debug(f"{self._name}: Read <- {response[-1]!r}")
529
+
530
+ for r in response:
531
+ if self._async_error_ack.encode() in r:
532
+ # Remove ack from response
533
+ ackless_response = r.replace(self._ack, b"")
534
+ str_response = self.process_raw_response(
535
+ command=data, response=ackless_response.decode()
536
+ )
537
+ self.raise_on_error(response=str_response, request=data)
538
+
539
+ if self._ack in response[-1]:
540
+ # Remove ack from response
541
+ ackless_response = response[-1].replace(self._ack, b"")
542
+ str_response = self.process_raw_response(
543
+ command=data, response=ackless_response.decode()
544
+ )
545
+ self.raise_on_error(response=str_response, request=data)
546
+ return str_response
547
+
548
+ log.info(f"{self._name}: retry number {retry}/{retries}")
549
+
550
+ await self.on_retry()
551
+
552
+ raise NoResponse(port=self._port, command=data)
@@ -0,0 +1,102 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import List, Optional, Iterator
4
+
5
+
6
+ class CommandBuilder:
7
+ """Class used to build GCODE commands."""
8
+
9
+ def __init__(self, terminator: str = "\n") -> None:
10
+ """
11
+ Construct a command builder.
12
+
13
+ Args:
14
+ terminator: The command terminator.
15
+ """
16
+ self._terminator = terminator
17
+ self._elements: List[str] = []
18
+
19
+ def add_float(
20
+ self, prefix: str, value: float, precision: Optional[int] = None
21
+ ) -> CommandBuilder:
22
+ """
23
+ Add a float value.
24
+
25
+ Args:
26
+ prefix: The value prefix.
27
+ value: The float value.
28
+ precision: Rounding precision. If None, there will be no rounding.
29
+
30
+ Returns: self
31
+ """
32
+ value = round(value, precision) if precision is not None else value
33
+ return self.add_element(f"{prefix}{value}")
34
+
35
+ def add_int(self, prefix: str, value: int) -> CommandBuilder:
36
+ """
37
+ Add an integer value.
38
+
39
+ Args:
40
+ prefix: The value prefix
41
+ value: The integer value
42
+
43
+ Returns: self
44
+ """
45
+ return self.add_element(f"{prefix}{value}")
46
+
47
+ def add_gcode(self, gcode: str) -> CommandBuilder:
48
+ """
49
+ Add a GCODE.
50
+
51
+ Args:
52
+ gcode: The gcode
53
+
54
+ Returns: self
55
+ """
56
+ return self.add_element(gcode)
57
+
58
+ def add_builder(self, builder: CommandBuilder) -> CommandBuilder:
59
+ """
60
+ Add all elements from builder
61
+
62
+ Args:
63
+ builder: a command builder
64
+
65
+ Returns: self
66
+ """
67
+ self._elements += builder._elements
68
+ return self
69
+
70
+ def add_element(self, element: str) -> CommandBuilder:
71
+ """
72
+ Add an element to the command builder
73
+
74
+ Args:
75
+ element: an element as a string
76
+
77
+ Returns: self
78
+ """
79
+ self._elements.append(element)
80
+ return self
81
+
82
+ def build(self) -> str:
83
+ """
84
+ Build command as a string.
85
+
86
+ Returns: string
87
+ """
88
+ return " ".join(self._elements + [self._terminator])
89
+
90
+ def __str__(self) -> str:
91
+ return self.build()
92
+
93
+ def __iter__(self) -> Iterator[str]:
94
+ return iter(self._elements)
95
+
96
+ def __bool__(self) -> bool:
97
+ return len(self._elements) != 0
98
+
99
+ def __eq__(self, other: object) -> bool:
100
+ if isinstance(other, CommandBuilder):
101
+ return self.build() == other.build()
102
+ return False
@@ -0,0 +1,13 @@
1
+ from .abstract import AbstractFlexStackerDriver
2
+ from .driver import FlexStackerDriver
3
+ from .simulator import SimulatingDriver
4
+ from . import types as FlexStackerTypes
5
+ from . import utils as FlexStackerUtils
6
+
7
+ __all__ = [
8
+ "AbstractFlexStackerDriver",
9
+ "FlexStackerDriver",
10
+ "SimulatingDriver",
11
+ "FlexStackerTypes",
12
+ "FlexStackerUtils",
13
+ ]