benchlab-pytools 3.0.0__tar.gz

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.
Files changed (206) hide show
  1. benchlab_pytools-3.0.0/.flake8 +2 -0
  2. benchlab_pytools-3.0.0/.gitignore +241 -0
  3. benchlab_pytools-3.0.0/CHANGELOG.md +44 -0
  4. benchlab_pytools-3.0.0/CONTRIBUTING.md +68 -0
  5. benchlab_pytools-3.0.0/LICENSE +21 -0
  6. benchlab_pytools-3.0.0/PKG-INFO +239 -0
  7. benchlab_pytools-3.0.0/README.md +149 -0
  8. benchlab_pytools-3.0.0/benchlab/__init__.py +14 -0
  9. benchlab_pytools-3.0.0/benchlab/__main__.py +21 -0
  10. benchlab_pytools-3.0.0/benchlab/config/README.md +325 -0
  11. benchlab_pytools-3.0.0/benchlab/config/__init__.py +9 -0
  12. benchlab_pytools-3.0.0/benchlab/config/config_client.py +631 -0
  13. benchlab_pytools-3.0.0/benchlab/config/config_manager.py +495 -0
  14. benchlab_pytools-3.0.0/benchlab/config/config_tool.py +358 -0
  15. benchlab_pytools-3.0.0/benchlab/config/diff.py +163 -0
  16. benchlab_pytools-3.0.0/benchlab/config/examples/complete_config.json +56 -0
  17. benchlab_pytools-3.0.0/benchlab/config/examples/rgb_lighting.json +24 -0
  18. benchlab_pytools-3.0.0/benchlab/config/examples/simple_fan.json +32 -0
  19. benchlab_pytools-3.0.0/benchlab/config/schema.py +138 -0
  20. benchlab_pytools-3.0.0/benchlab/config/test_config_client.py +107 -0
  21. benchlab_pytools-3.0.0/benchlab/config/test_config_manager.py +116 -0
  22. benchlab_pytools-3.0.0/benchlab/config/test_diff.py +208 -0
  23. benchlab_pytools-3.0.0/benchlab/core/README.md +154 -0
  24. benchlab_pytools-3.0.0/benchlab/core/__init__.py +78 -0
  25. benchlab_pytools-3.0.0/benchlab/core/config.py +145 -0
  26. benchlab_pytools-3.0.0/benchlab/core/datasource.py +1209 -0
  27. benchlab_pytools-3.0.0/benchlab/core/datasource_manager.py +418 -0
  28. benchlab_pytools-3.0.0/benchlab/core/device_registry.py +206 -0
  29. benchlab_pytools-3.0.0/benchlab/core/discovery.py +92 -0
  30. benchlab_pytools-3.0.0/benchlab/core/infrastructure.py +309 -0
  31. benchlab_pytools-3.0.0/benchlab/core/process_manager.py +356 -0
  32. benchlab_pytools-3.0.0/benchlab/core/retry.py +85 -0
  33. benchlab_pytools-3.0.0/benchlab/core/shared_serial.py +235 -0
  34. benchlab_pytools-3.0.0/benchlab/core/statistics.py +224 -0
  35. benchlab_pytools-3.0.0/benchlab/csv_log/README.md +206 -0
  36. benchlab_pytools-3.0.0/benchlab/csv_log/__init__.py +5 -0
  37. benchlab_pytools-3.0.0/benchlab/csv_log/csv_logger_enhanced.py +416 -0
  38. benchlab_pytools-3.0.0/benchlab/csv_log/message_batcher.py +361 -0
  39. benchlab_pytools-3.0.0/benchlab/csv_log/requirements.txt +3 -0
  40. benchlab_pytools-3.0.0/benchlab/csv_log/smart_retry.py +466 -0
  41. benchlab_pytools-3.0.0/benchlab/graph/README.md +117 -0
  42. benchlab_pytools-3.0.0/benchlab/graph/__init__.py +5 -0
  43. benchlab_pytools-3.0.0/benchlab/graph/app.py +353 -0
  44. benchlab_pytools-3.0.0/benchlab/graph/requirements.txt +2 -0
  45. benchlab_pytools-3.0.0/benchlab/graph/runner.py +42 -0
  46. benchlab_pytools-3.0.0/benchlab/graph/test_graph.py +154 -0
  47. benchlab_pytools-3.0.0/benchlab/graph/ui.py +288 -0
  48. benchlab_pytools-3.0.0/benchlab/hwinfo/README.md +135 -0
  49. benchlab_pytools-3.0.0/benchlab/hwinfo/__init__.py +5 -0
  50. benchlab_pytools-3.0.0/benchlab/hwinfo/hwinfo_export.py +386 -0
  51. benchlab_pytools-3.0.0/benchlab/hwinfo/requirements.txt +1 -0
  52. benchlab_pytools-3.0.0/benchlab/hwinfo/test_hwinfo_export.py +102 -0
  53. benchlab_pytools-3.0.0/benchlab/launcher.py +387 -0
  54. benchlab_pytools-3.0.0/benchlab/link/.env.EXAMPLE +10 -0
  55. benchlab_pytools-3.0.0/benchlab/link/README.md +172 -0
  56. benchlab_pytools-3.0.0/benchlab/link/__init__.py +1 -0
  57. benchlab_pytools-3.0.0/benchlab/link/link_main.py +479 -0
  58. benchlab_pytools-3.0.0/benchlab/link/test_link_main.py +151 -0
  59. benchlab_pytools-3.0.0/benchlab/main.py +462 -0
  60. benchlab_pytools-3.0.0/benchlab/menu.py +729 -0
  61. benchlab_pytools-3.0.0/benchlab/menu_classic.py +410 -0
  62. benchlab_pytools-3.0.0/benchlab/mqtt/README.md +201 -0
  63. benchlab_pytools-3.0.0/benchlab/mqtt/__init__.py +5 -0
  64. benchlab_pytools-3.0.0/benchlab/mqtt/mqtt.config_template +2 -0
  65. benchlab_pytools-3.0.0/benchlab/mqtt/mqtt_publisher.py +540 -0
  66. benchlab_pytools-3.0.0/benchlab/mqtt/requirements.txt +3 -0
  67. benchlab_pytools-3.0.0/benchlab/mqtt/test_mqtt_publisher.py +175 -0
  68. benchlab_pytools-3.0.0/benchlab/prefs.py +67 -0
  69. benchlab_pytools-3.0.0/benchlab/restapi/.env.example +17 -0
  70. benchlab_pytools-3.0.0/benchlab/restapi/__init__.py +5 -0
  71. benchlab_pytools-3.0.0/benchlab/restapi/favicon.ico +0 -0
  72. benchlab_pytools-3.0.0/benchlab/restapi/readme.md +202 -0
  73. benchlab_pytools-3.0.0/benchlab/restapi/requirements.txt +5 -0
  74. benchlab_pytools-3.0.0/benchlab/restapi/telemetry_api.py +808 -0
  75. benchlab_pytools-3.0.0/benchlab/restapi/test_server.py +209 -0
  76. benchlab_pytools-3.0.0/benchlab/sources.py +515 -0
  77. benchlab_pytools-3.0.0/benchlab/tools.py +147 -0
  78. benchlab_pytools-3.0.0/benchlab/tui/README.md +266 -0
  79. benchlab_pytools-3.0.0/benchlab/tui/__init__.py +5 -0
  80. benchlab_pytools-3.0.0/benchlab/tui/config.py +477 -0
  81. benchlab_pytools-3.0.0/benchlab/tui/requirements.txt +2 -0
  82. benchlab_pytools-3.0.0/benchlab/tui/test_tui_core.py +241 -0
  83. benchlab_pytools-3.0.0/benchlab/tui/test_tui_main.py +76 -0
  84. benchlab_pytools-3.0.0/benchlab/tui/tui_core.py +1298 -0
  85. benchlab_pytools-3.0.0/benchlab/tui/tui_main.py +418 -0
  86. benchlab_pytools-3.0.0/benchlab/vu/README.md +64 -0
  87. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/NOTICE.md +13 -0
  88. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/README.md +80 -0
  89. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/Running_from_source_on_linux.md +97 -0
  90. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/__init__.py +0 -0
  91. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/assets/vu1_hello_world.png +0 -0
  92. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/community_applications.md +13 -0
  93. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/config.yaml +9 -0
  94. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/database.py +256 -0
  95. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/dial_driver.py +534 -0
  96. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/dials/Comms_Hub_Gauge.py +78 -0
  97. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/dials/Comms_Hub_Server.py +100 -0
  98. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/dials/__init__.py +0 -0
  99. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/dials/base_logger.py +100 -0
  100. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/installer/inc/icon.ico +0 -0
  101. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/installer/install.nsi +148 -0
  102. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/make_version.py +40 -0
  103. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/pylintrc +628 -0
  104. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/requirements.txt +9 -0
  105. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/serial_driver.py +244 -0
  106. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/server.py +670 -0
  107. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/server_config.py +255 -0
  108. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/server_dial_handler.py +334 -0
  109. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/vu_notifications.py +24 -0
  110. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/android-chrome-192x192.png +0 -0
  111. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/android-chrome-512x512.png +0 -0
  112. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/apple-touch-icon.png +0 -0
  113. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/demo.css +291 -0
  114. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/demo.min.css +9 -0
  115. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/demo.rtl.css +276 -0
  116. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/demo.rtl.min.css +9 -0
  117. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-flags.css +1084 -0
  118. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-flags.min.css +9 -0
  119. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-flags.rtl.css +1084 -0
  120. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-flags.rtl.min.css +9 -0
  121. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-payments.css +528 -0
  122. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-payments.min.css +9 -0
  123. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-payments.rtl.css +528 -0
  124. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-payments.rtl.min.css +9 -0
  125. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-social.css +10 -0
  126. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-social.min.css +8 -0
  127. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-social.rtl.css +10 -0
  128. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-social.rtl.min.css +8 -0
  129. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-vendors.css +1504 -0
  130. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-vendors.min.css +9 -0
  131. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-vendors.rtl.css +1504 -0
  132. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler-vendors.rtl.min.css +9 -0
  133. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler.css +25813 -0
  134. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler.min.css +13 -0
  135. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler.rtl.css +25777 -0
  136. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/tabler.rtl.min.css +13 -0
  137. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/css/theme.min.css +261 -0
  138. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/img/header.png +0 -0
  139. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/img/logo.png +0 -0
  140. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/dark-theme.js +35 -0
  141. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/dark-theme.min.js +9 -0
  142. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/demo.js +132 -0
  143. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/demo.min.js +9 -0
  144. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/jquery.min.js +2 -0
  145. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/tabler.esm.js +7482 -0
  146. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/tabler.esm.min.js +15 -0
  147. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/tabler.js +7543 -0
  148. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/tabler.min.js +15 -0
  149. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/vu1_api.js +68 -0
  150. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/vu1_gui_api_key_settings.js +167 -0
  151. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/vu1_gui_api_keys.js +138 -0
  152. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/vu1_gui_dial.js +179 -0
  153. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/vu1_gui_home.js +60 -0
  154. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/assets/js/vu1_gui_root.js +125 -0
  155. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/favicon-16x16.png +0 -0
  156. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/favicon-32x32.png +0 -0
  157. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/favicon.ico +0 -0
  158. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/favicon.png +0 -0
  159. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/index.html +47 -0
  160. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/views/api_keys.html +151 -0
  161. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/views/dial.html +286 -0
  162. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/views/footer.html +27 -0
  163. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/views/header.html +86 -0
  164. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/views/key_settings.html +132 -0
  165. benchlab_pytools-3.0.0/benchlab/vu/VU-Server/www/views/start.html +124 -0
  166. benchlab_pytools-3.0.0/benchlab/vu/__init__.py +5 -0
  167. benchlab_pytools-3.0.0/benchlab/vu/assets/Barlow-Bold.ttf +0 -0
  168. benchlab_pytools-3.0.0/benchlab/vu/assets/bl_dial_144x200.png +0 -0
  169. benchlab_pytools-3.0.0/benchlab/vu/assets/bl_logo_144x200.png +0 -0
  170. benchlab_pytools-3.0.0/benchlab/vu/devices.py +166 -0
  171. benchlab_pytools-3.0.0/benchlab/vu/requirements.txt +24 -0
  172. benchlab_pytools-3.0.0/benchlab/vu/sensors.py +18 -0
  173. benchlab_pytools-3.0.0/benchlab/vu/test_devices.py +66 -0
  174. benchlab_pytools-3.0.0/benchlab/vu/test_vu_server_config.py +43 -0
  175. benchlab_pytools-3.0.0/benchlab/vu/test_vu_server_manager.py +212 -0
  176. benchlab_pytools-3.0.0/benchlab/vu/test_vu_tui.py +46 -0
  177. benchlab_pytools-3.0.0/benchlab/vu/vu_dial.config_template +90 -0
  178. benchlab_pytools-3.0.0/benchlab/vu/vu_logo_gen.py +97 -0
  179. benchlab_pytools-3.0.0/benchlab/vu/vu_server.config_template +5 -0
  180. benchlab_pytools-3.0.0/benchlab/vu/vu_server_config.py +40 -0
  181. benchlab_pytools-3.0.0/benchlab/vu/vu_server_manager.py +192 -0
  182. benchlab_pytools-3.0.0/benchlab/vu/vu_tui.py +919 -0
  183. benchlab_pytools-3.0.0/benchlab/vu/vu_updater.py +540 -0
  184. benchlab_pytools-3.0.0/benchlab/wigidash/README.md +182 -0
  185. benchlab_pytools-3.0.0/benchlab/wigidash/__init__.py +5 -0
  186. benchlab_pytools-3.0.0/benchlab/wigidash/assets/Inter-Bold.ttf +0 -0
  187. benchlab_pytools-3.0.0/benchlab/wigidash/assets/Inter.ttf +0 -0
  188. benchlab_pytools-3.0.0/benchlab/wigidash/assets/benchlab.png +0 -0
  189. benchlab_pytools-3.0.0/benchlab/wigidash/benchlab_fleet.py +150 -0
  190. benchlab_pytools-3.0.0/benchlab/wigidash/benchlab_graph.py +517 -0
  191. benchlab_pytools-3.0.0/benchlab/wigidash/benchlab_overview.py +426 -0
  192. benchlab_pytools-3.0.0/benchlab/wigidash/benchlab_telemetry.py +105 -0
  193. benchlab_pytools-3.0.0/benchlab/wigidash/benchlab_ui.py +190 -0
  194. benchlab_pytools-3.0.0/benchlab/wigidash/benchlab_utils.py +182 -0
  195. benchlab_pytools-3.0.0/benchlab/wigidash/requirements.txt +9 -0
  196. benchlab_pytools-3.0.0/benchlab/wigidash/test_wigidash.py +341 -0
  197. benchlab_pytools-3.0.0/benchlab/wigidash/wigidash_device.py +541 -0
  198. benchlab_pytools-3.0.0/benchlab/wigidash/wigidash_manager.py +342 -0
  199. benchlab_pytools-3.0.0/benchlab/wigidash/wigidash_session.py +355 -0
  200. benchlab_pytools-3.0.0/benchlab/wigidash/wigidash_usb.py +247 -0
  201. benchlab_pytools-3.0.0/benchlab/wigidash/wigidash_widget.py +88 -0
  202. benchlab_pytools-3.0.0/benchlab.py +41 -0
  203. benchlab_pytools-3.0.0/bootstrap.py +155 -0
  204. benchlab_pytools-3.0.0/pyproject.toml +126 -0
  205. benchlab_pytools-3.0.0/pytest.ini +4 -0
  206. benchlab_pytools-3.0.0/requirements.txt +25 -0
@@ -0,0 +1,2 @@
1
+ [flake8]
2
+ exclude = benchlab/vu/VU-Server,__pycache__,.git,.pytest_cache
@@ -0,0 +1,241 @@
1
+ # Benchlab specific files
2
+ *.db
3
+ *.db-journal
4
+ *.config
5
+ *.pid.lock
6
+ .benchlab_prefs.json
7
+ my_config.json
8
+ /logs/
9
+ benchlab/vu/generated/
10
+ benchlab/vu/VU-Server/upload/
11
+ benchlab/link/DEV_NOTES.md
12
+ benchlab/link/link.config
13
+ benchlab/link/.env
14
+
15
+ # Byte-compiled / optimized / DLL files
16
+ __pycache__/
17
+ *.py[codz]
18
+ *$py.class
19
+
20
+ # C extensions
21
+ *.so
22
+
23
+ # Distribution / packaging
24
+ .Python
25
+ build/
26
+ develop-eggs/
27
+ dist/
28
+ downloads/
29
+ eggs/
30
+ .eggs/
31
+ lib/
32
+ lib64/
33
+ parts/
34
+ sdist/
35
+ var/
36
+ wheels/
37
+ share/python-wheels/
38
+ *.egg-info/
39
+ .installed.cfg
40
+ *.egg
41
+ MANIFEST
42
+
43
+ # PyInstaller
44
+ # Usually these files are written by a python script from a template
45
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
46
+ *.manifest
47
+ *.spec
48
+
49
+ # Installer logs
50
+ pip-log.txt
51
+ pip-delete-this-directory.txt
52
+
53
+ # Unit test / coverage reports
54
+ htmlcov/
55
+ .tox/
56
+ .nox/
57
+ .coverage
58
+ .coverage.*
59
+ .cache
60
+ nosetests.xml
61
+ coverage.xml
62
+ *.cover
63
+ *.py.cover
64
+ .hypothesis/
65
+ .pytest_cache/
66
+ cover/
67
+
68
+ # Translations
69
+ *.mo
70
+ *.pot
71
+
72
+ # Django stuff:
73
+ *.log
74
+ local_settings.py
75
+ db.sqlite3
76
+ db.sqlite3-journal
77
+
78
+ # Flask stuff:
79
+ instance/
80
+ .webassets-cache
81
+
82
+ # Scrapy stuff:
83
+ .scrapy
84
+
85
+ # Sphinx documentation
86
+ docs/_build/
87
+
88
+ # PyBuilder
89
+ .pybuilder/
90
+ target/
91
+
92
+ # Jupyter Notebook
93
+ .ipynb_checkpoints
94
+
95
+ # IPython
96
+ profile_default/
97
+ ipython_config.py
98
+
99
+ # pyenv
100
+ # For a library or package, you might want to ignore these files since the code is
101
+ # intended to run in multiple environments; otherwise, check them in:
102
+ # .python-version
103
+
104
+ # pipenv
105
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
106
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
107
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
108
+ # install all needed dependencies.
109
+ #Pipfile.lock
110
+
111
+ # UV
112
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
113
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
114
+ # commonly ignored for libraries.
115
+ #uv.lock
116
+
117
+ # poetry
118
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
119
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
120
+ # commonly ignored for libraries.
121
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
122
+ #poetry.lock
123
+ #poetry.toml
124
+
125
+ # pdm
126
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
127
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
128
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
129
+ #pdm.lock
130
+ #pdm.toml
131
+ .pdm-python
132
+ .pdm-build/
133
+
134
+ # pixi
135
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
136
+ #pixi.lock
137
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
138
+ # in the .venv directory. It is recommended not to include this directory in version control.
139
+ .pixi
140
+
141
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
142
+ __pypackages__/
143
+
144
+ # Celery stuff
145
+ celerybeat-schedule
146
+ celerybeat.pid
147
+
148
+ # SageMath parsed files
149
+ *.sage.py
150
+
151
+ # Environments
152
+ .env
153
+ .envrc
154
+ .venv
155
+ env/
156
+ venv/
157
+ ENV/
158
+ env.bak/
159
+ venv.bak/
160
+
161
+ # Spyder project settings
162
+ .spyderproject
163
+ .spyproject
164
+
165
+ # Rope project settings
166
+ .ropeproject
167
+
168
+ # mkdocs documentation
169
+ /site
170
+
171
+ # mypy
172
+ .mypy_cache/
173
+ .dmypy.json
174
+ dmypy.json
175
+
176
+ # Pyre type checker
177
+ .pyre/
178
+
179
+ # pytype static type analyzer
180
+ .pytype/
181
+
182
+ # Cython debug symbols
183
+ cython_debug/
184
+
185
+ # PyCharm
186
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
187
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
188
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
189
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
190
+ #.idea/
191
+
192
+ # Abstra
193
+ # Abstra is an AI-powered process automation framework.
194
+ # Ignore directories containing user credentials, local state, and settings.
195
+ # Learn more at https://abstra.io/docs
196
+ .abstra/
197
+
198
+ # Visual Studio Code
199
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
200
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
201
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
202
+ # you could uncomment the following to ignore the entire vscode folder
203
+ .vscode/
204
+
205
+ # Ruff stuff:
206
+ .ruff_cache/
207
+
208
+ # PyPI configuration file
209
+ .pypirc
210
+
211
+ # Cursor
212
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
213
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
214
+ # refer to https://docs.cursor.com/context/ignore-files
215
+ .cursorignore
216
+ .cursorindexingignore
217
+
218
+ # Marimo
219
+ marimo/_static/
220
+ marimo/_lsp/
221
+ __marimo__/
222
+
223
+ #Cline Settings
224
+ ./clinerules/
225
+ clinerules.md
226
+ benchlab/vu/generated/Ambient_Temp_31adb92f7d8c50f2ef571b0e57623d4a_logo.png
227
+ benchlab/vu/generated/HPWR1_Current_3bdca09ec192687fe4737b7eab9b5a40_logo.png
228
+ benchlab/vu/generated/Humidity_5841b6aff86e7995ed175c5d6461a5cf_logo.png
229
+ benchlab/vu/generated/SYS_Power_7932c00b5744a5d26d25928e058c8231_logo.png
230
+ benchlab/vu/VU-Server/upload/img_4A0027000650564139323920
231
+ benchlab/vu/VU-Server/upload/img_4A0038000650564139323920
232
+ benchlab/vu/VU-Server/upload/img_35002F000650564139323920
233
+ benchlab/vu/VU-Server/upload/img_890024000650564139323920
234
+ benchlab/vu/VU-Server/upload/tmp_4A0027000650564139323920
235
+ benchlab/vu/VU-Server/upload/tmp_4A0038000650564139323920
236
+ benchlab/vu/VU-Server/upload/tmp_35002F000650564139323920
237
+ benchlab/vu/VU-Server/upload/tmp_890024000650564139323920
238
+ benchlab/vu/VU-Server/upload/img_4A0027000650564139323920
239
+ benchlab/vu/VU-Server/upload/img_4A0038000650564139323920
240
+ benchlab/vu/VU-Server/upload/img_35002F000650564139323920
241
+ benchlab/vu/VU-Server/upload/img_890024000650564139323920
@@ -0,0 +1,44 @@
1
+ # Changelog
2
+
3
+ All notable changes to BENCHLAB PyTools are documented here. Format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows
5
+ [SemVer](https://semver.org/).
6
+
7
+ ## [3.0.0] - 2026-08-15
8
+
9
+ ### Added
10
+ - Packaging: `pyproject.toml` for `pip install benchlab-pytools`, with
11
+ per-tool optional extras (`[tui]`, `[graph]`, `[vu]`, `[wigidash]`,
12
+ `[mqtt]`, `[restapi]`, `[csv_log]`, `[hwinfo]`, `[all]`) and a `benchlab`
13
+ console-script entry point.
14
+ - `--version` CLI flag.
15
+ - Tag-triggered release workflow: builds and tests the package, publishes
16
+ to PyPI, and attaches a source zip + wheel to a GitHub Release.
17
+ - `benchlab/vu/VU-Server/NOTICE.md` documenting redistribution permission
18
+ for the vendored VU-Server app.
19
+ - flake8 lint CI gate (`.flake8`, `.github/workflows/lint.yml`) for pull
20
+ requests targeting `main`.
21
+
22
+ ### Changed
23
+ - Link: `CloudMQTTClient` now pins paho-mqtt's `callback_api_version`
24
+ explicitly to `VERSION2` instead of relying on the deprecated implicit
25
+ default, with `on_connect`/`on_disconnect` updated to the matching
26
+ 5-arg signature.
27
+ - Link: MQTT topic pattern now also supports a `{client_uuid}` token
28
+ alongside `{uid}` (`LINK_TOPIC_PATTERN`), so deployments needing a
29
+ `clients/{client_uuid}/devices/{uid}/...` scheme are configurable
30
+ without code changes.
31
+ - Whole codebase now passes flake8's default ruleset (2,443 findings
32
+ fixed: unused imports/variables, an undefined-name issue in
33
+ `benchlab/core/datasource.py` resolved via a `TYPE_CHECKING`-guarded
34
+ import, and formatting/line-length cleanup — no behavior changes).
35
+
36
+ ## [0.8.2] - Unreleased (pre-packaging baseline)
37
+
38
+ Snapshot of the codebase at the point packaging work began. Interactive
39
+ menu (prompt_toolkit-based), TUI, CSV logger, FastAPI server, graph, HWiNFO
40
+ export, MQTT publisher, VU dials, WigiDash, and config import/export tools,
41
+ sharing a common data-source layer (direct serial, FastAPI, MQTT, named
42
+ pipe, service HTTP).
43
+
44
+ [3.0.0]: https://github.com/BenchLab-io/benchlab-pytools/compare/v0.8.2...v3.0.0
@@ -0,0 +1,68 @@
1
+ # Contributing to BENCHLAB PyTools
2
+
3
+ ## Development setup
4
+
5
+ ```bash
6
+ git clone https://github.com/BenchLab-io/benchlab-pytools.git
7
+ cd benchlab-pytools
8
+ pip install -r requirements.txt
9
+ pip install -r benchlab/csv_log/requirements.txt
10
+ pip install -r benchlab/graph/requirements.txt
11
+ pip install -r benchlab/wigidash/requirements.txt
12
+ pip install -r benchlab/vu/requirements.txt
13
+ pip install pytest
14
+ ```
15
+
16
+ Or install everything (including test tooling) via the package extras:
17
+
18
+ ```bash
19
+ pip install -e ".[all]"
20
+ pip install pytest
21
+ ```
22
+
23
+ Requires Python 3.10+.
24
+
25
+ ## Running tests
26
+
27
+ ```bash
28
+ pytest
29
+ ```
30
+
31
+ CI (`.github/workflows/pycore-compat.yml`) runs the full suite on
32
+ Windows against both the pinned `benchlab-pycore` version and the latest
33
+ release on PyPI, to catch drift between this repo and that package's
34
+ published API early (see issue #9).
35
+
36
+ ## Adding a new tool
37
+
38
+ 1. Add an entry to `CONSUMER_TOOLS` in `benchlab/tools.py` with `name`,
39
+ `flag`, `module`, `function`, and `requirements`.
40
+ 2. Implement the tool's entry function, accepting an `args` namespace (see
41
+ `benchlab/launcher.py::_build_args_namespace`).
42
+ 3. Add a CLI flag in `benchlab/main.py::get_parser()` and dispatch it in
43
+ `launch_mode()`.
44
+ 4. Add a `requirements.txt` in the tool's directory if it needs extra
45
+ dependencies, and a matching extra in `pyproject.toml`.
46
+ 5. Write a `README.md` in the tool's directory following the style of the
47
+ existing ones.
48
+ 6. Add tests and wire them into `.github/workflows/pycore-compat.yml`.
49
+
50
+ ## Versioning and releases
51
+
52
+ The version lives in `benchlab/__init__.py::__version__` and is the single
53
+ source of truth (`pyproject.toml` reads it dynamically). To cut a release:
54
+
55
+ 1. Bump `__version__` in `benchlab/__init__.py`.
56
+ 2. Move the `[Unreleased]` section in `CHANGELOG.md` to a new version
57
+ heading with today's date.
58
+ 3. Commit, then tag: `git tag vX.Y.Z && git push origin vX.Y.Z`.
59
+ 4. The `release` workflow builds, tests, publishes to PyPI, and creates a
60
+ GitHub Release with the wheel/sdist and a source zip attached.
61
+
62
+ ## Pull requests
63
+
64
+ - Keep changes scoped to one tool/concern where possible — this repo is
65
+ organized as independent subpackages under `benchlab/` sharing a common
66
+ core.
67
+ - Include or update tests for behavior changes.
68
+ - CI must pass before merge.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 BENCHLAB.io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,239 @@
1
+ Metadata-Version: 2.5
2
+ Name: benchlab-pytools
3
+ Version: 3.0.0
4
+ Summary: Python control suite for BENCHLAB telemetry devices
5
+ Project-URL: Homepage, https://benchlab.io/
6
+ Project-URL: Repository, https://github.com/BenchLab-io/benchlab-pytools
7
+ Project-URL: Issues, https://github.com/BenchLab-io/benchlab-pytools/issues
8
+ Author: BENCHLAB.io
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: benchlab,hardware-monitoring,telemetry
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: End Users/Desktop
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: System :: Hardware
23
+ Classifier: Topic :: System :: Monitoring
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: benchlab-pycore>=0.5.1
26
+ Requires-Dist: packaging<26.0,>=23.0
27
+ Requires-Dist: python-dotenv<2.0,>=1.0.0
28
+ Requires-Dist: textual<9.0,>=0.60
29
+ Requires-Dist: windows-curses>=2.4.1; platform_system == 'Windows'
30
+ Provides-Extra: all
31
+ Requires-Dist: amqtt<0.13.0,>=0.12.0; extra == 'all'
32
+ Requires-Dist: benchlab-pycore>=0.5.1; extra == 'all'
33
+ Requires-Dist: blessed>=1.20.0; extra == 'all'
34
+ Requires-Dist: dearpygui>=2.1.1; extra == 'all'
35
+ Requires-Dist: fastapi==0.111.1; extra == 'all'
36
+ Requires-Dist: libusb-package>=1.0.26.1; (sys_platform == 'win32') and extra == 'all'
37
+ Requires-Dist: matplotlib>=3.10.7; extra == 'all'
38
+ Requires-Dist: numpy; extra == 'all'
39
+ Requires-Dist: numpy>=2.2.0; extra == 'all'
40
+ Requires-Dist: paho-mqtt<3.0,>=2.0; extra == 'all'
41
+ Requires-Dist: pillow>=10.0.0; extra == 'all'
42
+ Requires-Dist: pillow>=11.3.0; extra == 'all'
43
+ Requires-Dist: pydantic>=2.0.0; extra == 'all'
44
+ Requires-Dist: pyserial>=3.5; extra == 'all'
45
+ Requires-Dist: python-dotenv==1.1.1; extra == 'all'
46
+ Requires-Dist: pyusb>=1.3.1; extra == 'all'
47
+ Requires-Dist: pyyaml<7.0,>=6.0; extra == 'all'
48
+ Requires-Dist: pyyaml>=6.0; extra == 'all'
49
+ Requires-Dist: requests>=2.31.0; extra == 'all'
50
+ Requires-Dist: ruamel-yaml; extra == 'all'
51
+ Requires-Dist: tornado; extra == 'all'
52
+ Requires-Dist: uvicorn[standard]==0.24.0; extra == 'all'
53
+ Provides-Extra: csv-log
54
+ Requires-Dist: benchlab-pycore>=0.5.1; extra == 'csv-log'
55
+ Requires-Dist: pyserial>=3.5; extra == 'csv-log'
56
+ Provides-Extra: graph
57
+ Requires-Dist: dearpygui>=2.1.1; extra == 'graph'
58
+ Requires-Dist: pyserial>=3.5; extra == 'graph'
59
+ Provides-Extra: hwinfo
60
+ Requires-Dist: pyserial>=3.5; extra == 'hwinfo'
61
+ Provides-Extra: mqtt
62
+ Requires-Dist: amqtt<0.13.0,>=0.12.0; extra == 'mqtt'
63
+ Requires-Dist: paho-mqtt<3.0,>=2.0; extra == 'mqtt'
64
+ Requires-Dist: pyyaml<7.0,>=6.0; extra == 'mqtt'
65
+ Provides-Extra: restapi
66
+ Requires-Dist: fastapi==0.111.1; extra == 'restapi'
67
+ Requires-Dist: pydantic>=2.0.0; extra == 'restapi'
68
+ Requires-Dist: pyserial>=3.5; extra == 'restapi'
69
+ Requires-Dist: python-dotenv==1.1.1; extra == 'restapi'
70
+ Requires-Dist: uvicorn[standard]==0.24.0; extra == 'restapi'
71
+ Provides-Extra: tui
72
+ Requires-Dist: pyserial>=3.5; extra == 'tui'
73
+ Provides-Extra: vu
74
+ Requires-Dist: blessed>=1.20.0; extra == 'vu'
75
+ Requires-Dist: numpy; extra == 'vu'
76
+ Requires-Dist: pillow>=10.0.0; extra == 'vu'
77
+ Requires-Dist: pyserial>=3.5; extra == 'vu'
78
+ Requires-Dist: pyyaml>=6.0; extra == 'vu'
79
+ Requires-Dist: requests>=2.31.0; extra == 'vu'
80
+ Requires-Dist: ruamel-yaml; extra == 'vu'
81
+ Requires-Dist: tornado; extra == 'vu'
82
+ Provides-Extra: wigidash
83
+ Requires-Dist: libusb-package>=1.0.26.1; (sys_platform == 'win32') and extra == 'wigidash'
84
+ Requires-Dist: matplotlib>=3.10.7; extra == 'wigidash'
85
+ Requires-Dist: numpy>=2.2.0; extra == 'wigidash'
86
+ Requires-Dist: pillow>=11.3.0; extra == 'wigidash'
87
+ Requires-Dist: pyserial>=3.5; extra == 'wigidash'
88
+ Requires-Dist: pyusb>=1.3.1; extra == 'wigidash'
89
+ Description-Content-Type: text/markdown
90
+
91
+ # BENCHLAB PyTools
92
+
93
+ BENCHLAB PyTools is the Python-based control suite for BENCHLAB telemetry devices. It provides a shared telemetry pipeline — device discovery, data sourcing, and process management — plus a set of consumer tools built on top of it:
94
+
95
+ - **TUI** — interactive terminal dashboard for live monitoring
96
+ - **CSV Logger** — fleet-wide telemetry logging for offline analysis
97
+ - **FastAPI Server** — REST API for telemetry, exposed for other tools/integrations
98
+ - **Graph** — DearPyGui-based real-time sensor graphing
99
+ - **HWiNFO Export** — exposes sensors as HWiNFO64 custom sensors
100
+ - **MQTT Publisher** — publishes telemetry to a local or remote MQTT broker
101
+ - **Link** — publishes telemetry to the BENCHLAB cloud (SaaS) MQTT broker
102
+ - **VU Dials** — analog-style VU meter dial display and configuration
103
+ - **WigiDash** — telemetry/graph display on a G.SKILL WigiDash panel
104
+ - **Config Tool** — import/export device configuration (fan curves, RGB, etc.) via JSON
105
+
106
+ All tools share a common data-source layer, so the same telemetry can be read directly from a device, through a FastAPI server, over MQTT, or via the Windows BENCHLAB service — locally or remotely — without changing the consumer tool.
107
+
108
+ ---
109
+
110
+ ## Installation
111
+
112
+ Requires Python 3.10+.
113
+
114
+ ```bash
115
+ pip install -r requirements.txt
116
+ ```
117
+
118
+ Each tool has its own `requirements.txt` (e.g. `benchlab/graph/requirements.txt`, `benchlab/vu/requirements.txt`). The launcher installs a tool's requirements automatically the first time it's run — you generally don't need to install them by hand.
119
+
120
+ ---
121
+
122
+ ## Usage
123
+
124
+ ### Interactive Menu
125
+
126
+ Run with no arguments to enter the interactive launcher:
127
+
128
+ ```bash
129
+ python benchlab.py
130
+ ```
131
+
132
+ or equivalently:
133
+
134
+ ```bash
135
+ python -m benchlab
136
+ ```
137
+
138
+ The interactive menu (prompt_toolkit-based, with a plain-input fallback if `prompt_toolkit` isn't installed) lets you pick a data source and one or more tools, then launches them — installing any missing per-tool dependencies along the way.
139
+
140
+ ### Command-Line Flags
141
+
142
+ Each tool can also be launched directly with a flag:
143
+
144
+ ```bash
145
+ python -m benchlab -tui # Interactive terminal dashboard
146
+ python -m benchlab -logfleet # CSV logger (no TUI)
147
+ python -m benchlab -fastapi # FastAPI telemetry server
148
+ python -m benchlab -graph # DearPyGui graph
149
+ python -m benchlab -hwinfo # HWiNFO custom sensor export
150
+ python -m benchlab -mqtt [broker] # MQTT publisher (default broker: localhost)
151
+ python -m benchlab -link # Publish telemetry to BENCHLAB cloud (Link)
152
+ python -m benchlab -vu # VU analog dials
153
+ python -m benchlab -vuconfig # VU dial configuration UI
154
+ python -m benchlab -wigidash # WigiDash display
155
+ python -m benchlab -config ... # Device configuration import/export
156
+ ```
157
+
158
+ Running with no flags is equivalent to launching the interactive menu.
159
+
160
+ ### Data Sources
161
+
162
+ Most tools accept `--source` to choose where telemetry comes from:
163
+
164
+ | Source | Description |
165
+ |---|---|
166
+ | `direct` (default) | Direct USB-serial connection via `benchlab-pycore` |
167
+ | `fastapi` | Local FastAPI server, started automatically if not already running |
168
+ | `fastapi_custom` | Remote FastAPI server — requires `--api-url` |
169
+ | `mqtt` | Local MQTT broker + publisher, started automatically if needed |
170
+ | `mqtt_custom` | Remote/existing MQTT broker — requires `--mqtt-broker`/`--mqtt-port` |
171
+ | `named_pipe` | Windows BENCHLAB service (`BL_Service`) via named pipes — Windows only |
172
+ | `service_http` | Windows BENCHLAB service HTTP API — requires `--service-url` (default `http://localhost:8585`) |
173
+
174
+ Common connection flags:
175
+
176
+ ```
177
+ --source SOURCE direct | fastapi | fastapi_custom | mqtt | mqtt_custom | named_pipe | service_http
178
+ --api-url URL FastAPI base URL (default: http://127.0.0.1:8000)
179
+ --api-port PORT FastAPI port (default: 8000)
180
+ --mqtt-broker HOST MQTT broker host (default: localhost)
181
+ --mqtt-port PORT MQTT broker port (default: 1883)
182
+ --service-url URL BENCHLAB Windows service HTTP API URL (default: http://localhost:8585)
183
+ -i, --interval SECONDS Refresh interval (default: 1.0)
184
+ ```
185
+
186
+ When a source needs a background service (`fastapi`, `mqtt`), the launcher starts and health-checks it automatically, and tears it down on exit. Not every tool supports every source — the config tool, for example, only supports `direct` and `named_pipe`. See each tool's README for specifics.
187
+
188
+ ### Launch Profiles
189
+
190
+ A named profile can bundle a data source and a set of tools to start together:
191
+
192
+ ```bash
193
+ python -m benchlab --profile gskill_ctex26
194
+ ```
195
+
196
+ Profiles are defined in `benchlab/tools.py` (`LAUNCH_PROFILES`). Each spawns its tools in separate terminal windows and manages them as a group.
197
+
198
+ ---
199
+
200
+ ## Architecture
201
+
202
+ - `benchlab/main.py` — CLI argument parsing and mode dispatch (`launch_mode()`)
203
+ - `benchlab/launcher.py` — in-process and multi-terminal tool launching, process lifecycle
204
+ - `benchlab/sources.py` — data-source detection, startup, and teardown for all supported sources
205
+ - `benchlab/tools.py` — the `CONSUMER_TOOLS` registry (tool metadata, module/function to invoke, dependencies) and `LAUNCH_PROFILES`
206
+ - `benchlab/menu.py` / `benchlab/menu_classic.py` — interactive terminal menu (prompt_toolkit, with a plain-input fallback)
207
+ - `benchlab/core/` — shared internals used by every tool: device discovery, the data-source abstraction, process management, retry logic. See [benchlab/core/README.md](benchlab/core/README.md).
208
+
209
+ Each consumer tool lives in its own subpackage under `benchlab/` with its own README, and (where needed) its own `requirements.txt`.
210
+
211
+ ### Adding a New Tool
212
+
213
+ 1. Add an entry to `CONSUMER_TOOLS` in `benchlab/tools.py` with `name`, `flag`, `module`, `function`, and `requirements`.
214
+ 2. Implement the tool's entry function in its module, accepting an `args` namespace (see `benchlab/launcher.py::_build_args_namespace`).
215
+ 3. Add a CLI flag for it in `benchlab/main.py::get_parser()` and dispatch it in `launch_mode()`.
216
+ 4. Add a `requirements.txt` in the tool's directory if it has extra dependencies.
217
+ 5. Write a `README.md` in the tool's directory following the style of the existing ones.
218
+
219
+ ---
220
+
221
+ ## Tool Documentation
222
+
223
+ - [Config Tool](benchlab/config/README.md) — device configuration import/export
224
+ - [Core](benchlab/core/README.md) — shared internals (data sources, process management, discovery)
225
+ - [CSV Logger](benchlab/csv_log/README.md)
226
+ - [FastAPI Server](benchlab/restapi/readme.md)
227
+ - [Graph](benchlab/graph/README.md)
228
+ - [HWiNFO Export](benchlab/hwinfo/README.md)
229
+ - [Link](benchlab/link/README.md) — publish telemetry to BENCHLAB cloud
230
+ - [MQTT Publisher](benchlab/mqtt/README.md)
231
+ - [TUI](benchlab/tui/README.md)
232
+ - [VU Dials](benchlab/vu/README.md)
233
+ - [WigiDash](benchlab/wigidash/README.md)
234
+
235
+ ---
236
+
237
+ ## License
238
+
239
+ Part of BENCHLAB PyTools. See main project license for details.