micrOSDevToolKit 2.9.1__py3-none-any.whl → 2.26.1__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.
Files changed (368) hide show
  1. env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
  2. env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +17 -1
  3. micrOS/micropython/esp32-20251209-v1.27.0.bin +0 -0
  4. micrOS/micropython/esp32c3-20251209-v1.27.0.bin +0 -0
  5. micrOS/micropython/esp32c6-20251209-v1.27.0.bin +0 -0
  6. micrOS/micropython/esp32s2-20251209-v1.27.0.bin +0 -0
  7. micrOS/micropython/esp32s2-LOLIN_MINI-20251209-v1.27.0.bin +0 -0
  8. micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-4MBflash-20241129-v1.24.1.bin} +0 -0
  9. micrOS/micropython/esp32s3-8MBflash-20251209-v1.27.0.bin +0 -0
  10. micrOS/micropython/esp32s3_spiram_oct-20251209-v1.27.0.bin +0 -0
  11. micrOS/micropython/rpi-pico-w-20251209-v1.27.0.uf2 +0 -0
  12. micrOS/micropython/tinypico-20251209-v1.27.0.bin +0 -0
  13. micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +167 -163
  14. micrOS/source/Auth.py +37 -0
  15. micrOS/source/Common.py +361 -116
  16. micrOS/source/Config.py +32 -22
  17. micrOS/source/Debug.py +50 -94
  18. micrOS/source/Espnow.py +377 -100
  19. micrOS/source/Files.py +207 -0
  20. micrOS/source/Hooks.py +48 -20
  21. micrOS/source/InterConnect.py +126 -42
  22. micrOS/source/Interrupts.py +6 -6
  23. micrOS/source/Logger.py +63 -26
  24. micrOS/source/Network.py +41 -21
  25. micrOS/source/Notify.py +48 -22
  26. micrOS/source/Pacman.py +326 -0
  27. micrOS/source/Scheduler.py +14 -54
  28. micrOS/source/Server.py +67 -69
  29. micrOS/source/Shell.py +99 -91
  30. micrOS/source/Tasks.py +141 -95
  31. micrOS/source/Time.py +19 -18
  32. micrOS/source/Types.py +53 -9
  33. micrOS/source/Web.py +381 -76
  34. micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
  35. micrOS/source/__pycache__/Debug.cpython-312.pyc +0 -0
  36. micrOS/source/__pycache__/Files.cpython-312.pyc +0 -0
  37. micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
  38. micrOS/source/__pycache__/Scheduler.cpython-312.pyc +0 -0
  39. micrOS/source/__pycache__/Server.cpython-312.pyc +0 -0
  40. micrOS/source/__pycache__/Shell.cpython-312.pyc +0 -0
  41. micrOS/source/__pycache__/replhelper.cpython-312.pyc +0 -0
  42. micrOS/source/config/_git.keep +0 -0
  43. micrOS/source/helpers.py +132 -0
  44. micrOS/source/micrOS.py +17 -7
  45. micrOS/source/micrOSloader.py +5 -12
  46. micrOS/source/microIO.py +44 -20
  47. micrOS/source/modules/IO_esp32c6.py +38 -0
  48. micrOS/source/{IO_esp32s3.py → modules/IO_esp32s3.py} +37 -1
  49. micrOS/source/{IO_m5stamp.py → modules/IO_m5stamp.py} +35 -1
  50. micrOS/source/{IO_qtpy.py → modules/IO_qtpy.py} +22 -17
  51. micrOS/source/{IO_tinypico.py → modules/IO_tinypico.py} +38 -0
  52. micrOS/source/modules/LM_L298N.py +161 -0
  53. {toolkit/workspace/precompiled → micrOS/source/modules}/LM_L9110_DCmotor.py +3 -3
  54. micrOS/source/{LM_OV2640.py → modules/LM_OV2640.py} +45 -27
  55. micrOS/source/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +3 -3
  56. micrOS/source/{LM_aht10.py → modules/LM_aht10.py} +2 -2
  57. micrOS/source/{LM_bme280.py → modules/LM_bme280.py} +3 -3
  58. micrOS/source/{LM_buzzer.py → modules/LM_buzzer.py} +18 -25
  59. micrOS/source/{LM_cct.py → modules/LM_cct.py} +17 -21
  60. micrOS/source/modules/LM_cluster.py +255 -0
  61. micrOS/source/{LM_co2.py → modules/LM_co2.py} +3 -3
  62. micrOS/source/{LM_dht11.py → modules/LM_dht11.py} +2 -2
  63. micrOS/source/{LM_dht22.py → modules/LM_dht22.py} +2 -2
  64. micrOS/source/{LM_dimmer.py → modules/LM_dimmer.py} +9 -9
  65. micrOS/source/{LM_distance.py → modules/LM_distance.py} +4 -6
  66. micrOS/source/{LM_ds18.py → modules/LM_ds18.py} +2 -2
  67. micrOS/source/{LM_esp32.py → modules/LM_esp32.py} +5 -0
  68. micrOS/source/modules/LM_espnow.py +53 -0
  69. micrOS/source/modules/LM_fileserver.py +265 -0
  70. micrOS/source/{LM_genIO.py → modules/LM_genIO.py} +52 -37
  71. micrOS/source/{LM_haptic.py → modules/LM_haptic.py} +2 -2
  72. {toolkit/workspace/precompiled → micrOS/source/modules}/LM_i2c.py +5 -4
  73. micrOS/source/{LM_i2s_mic.py → modules/LM_i2s_mic.py} +6 -7
  74. micrOS/source/{LM_ld2410.py → modules/LM_ld2410.py} +2 -2
  75. micrOS/source/{LM_light_sensor.py → modules/LM_light_sensor.py} +10 -21
  76. micrOS/source/modules/LM_mh_z19c.py +198 -0
  77. micrOS/source/modules/LM_neoeffects.py +284 -0
  78. micrOS/source/{LM_neopixel.py → modules/LM_neopixel.py} +19 -23
  79. micrOS/source/{LM_oled.py → modules/LM_oled.py} +2 -2
  80. micrOS/source/{LM_oled_sh1106.py → modules/LM_oled_sh1106.py} +3 -3
  81. micrOS/source/{LM_oled_ui.py → modules/LM_oled_ui.py} +72 -64
  82. micrOS/source/modules/LM_pacman.py +320 -0
  83. micrOS/source/{LM_presence.py → modules/LM_presence.py} +11 -15
  84. micrOS/source/modules/LM_qmi8658.py +204 -0
  85. micrOS/source/{LM_rencoder.py → modules/LM_rencoder.py} +2 -2
  86. micrOS/source/{LM_rest.py → modules/LM_rest.py} +4 -6
  87. micrOS/source/{LM_rgb.py → modules/LM_rgb.py} +21 -29
  88. micrOS/source/{LM_roboarm.py → modules/LM_roboarm.py} +8 -8
  89. micrOS/source/modules/LM_robustness.py +137 -0
  90. micrOS/source/{LM_servo.py → modules/LM_servo.py} +3 -3
  91. micrOS/source/{LM_stepper.py → modules/LM_stepper.py} +5 -5
  92. micrOS/source/{LM_switch.py → modules/LM_switch.py} +11 -9
  93. micrOS/source/{LM_system.py → modules/LM_system.py} +38 -32
  94. micrOS/source/modules/LM_tcs3472.py +187 -0
  95. micrOS/source/{LM_telegram.py → modules/LM_telegram.py} +164 -116
  96. micrOS/source/{LM_trackball.py → modules/LM_trackball.py} +3 -3
  97. micrOS/source/{LM_veml7700.py → modules/LM_veml7700.py} +2 -2
  98. micrOS/source/modules/LM_web.py +38 -0
  99. micrOS/source/urequests.py +39 -15
  100. {toolkit/workspace/precompiled → micrOS/source/web}/dashboard.html +4 -0
  101. micrOS/source/web/editor.js +440 -0
  102. micrOS/source/web/filesui.html +178 -0
  103. micrOS/source/web/filesui.js +338 -0
  104. {toolkit/workspace/precompiled → micrOS/source/web}/index.html +44 -2
  105. micrOS/source/{uapi.js → web/uapi.js} +48 -7
  106. micrOS/source/{ustyle.css → web/ustyle.css} +6 -3
  107. micrOS/utests/__init__.py +0 -0
  108. micrOS/utests/test_scheduler.py +435 -0
  109. {micrOSDevToolKit-2.9.1.data → microsdevtoolkit-2.26.1.data}/scripts/devToolKit.py +33 -3
  110. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/METADATA +327 -268
  111. microsdevtoolkit-2.26.1.dist-info/RECORD +396 -0
  112. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/WHEEL +1 -1
  113. toolkit/DevEnvCompile.py +63 -33
  114. toolkit/DevEnvOTA.py +58 -22
  115. toolkit/DevEnvUSB.py +110 -55
  116. toolkit/Gateway.py +6 -6
  117. toolkit/LM_to_compile.dat +6 -4
  118. toolkit/MicrOSDevEnv.py +127 -57
  119. toolkit/WebRepl.py +73 -0
  120. toolkit/dashboard_apps/BackupRestore.py +20 -35
  121. toolkit/dashboard_apps/CCTDemo.py +12 -17
  122. toolkit/dashboard_apps/CCTTest.py +20 -24
  123. toolkit/dashboard_apps/CamStream.py +2 -6
  124. toolkit/dashboard_apps/CatGame.py +14 -16
  125. toolkit/dashboard_apps/Dimmer.py +11 -21
  126. toolkit/dashboard_apps/GetVersion.py +11 -19
  127. toolkit/dashboard_apps/MicrophoneTest.py +1 -6
  128. toolkit/dashboard_apps/NeoEffectsDemo.py +22 -35
  129. toolkit/dashboard_apps/NeopixelTest.py +20 -25
  130. toolkit/dashboard_apps/PresenceTest.py +2 -8
  131. toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
  132. toolkit/dashboard_apps/RGBTest.py +20 -24
  133. toolkit/dashboard_apps/RoboArm.py +24 -32
  134. toolkit/dashboard_apps/SED_test.py +10 -14
  135. toolkit/dashboard_apps/SensorsTest.py +61 -0
  136. toolkit/dashboard_apps/SystemTest.py +202 -105
  137. toolkit/dashboard_apps/Template_app.py +11 -23
  138. toolkit/dashboard_apps/_app_base.py +34 -0
  139. toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
  140. toolkit/dashboard_apps/uLightDemo.py +15 -24
  141. toolkit/index.html +4 -4
  142. toolkit/lib/LocalMachine.py +6 -1
  143. toolkit/lib/MicrosFiles.py +46 -0
  144. toolkit/lib/Repository.py +64 -0
  145. toolkit/lib/TerminalColors.py +4 -0
  146. toolkit/lib/macroScript.py +6 -0
  147. toolkit/lib/micrOSClient.py +123 -50
  148. toolkit/lib/micrOSClientHistory.py +156 -0
  149. toolkit/lib/pip_package_installer.py +5 -2
  150. toolkit/micrOSdashboard.py +12 -17
  151. toolkit/micrOSlint.py +20 -8
  152. toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
  153. toolkit/simulator_lib/__pycache__/aioespnow.cpython-312.pyc +0 -0
  154. toolkit/simulator_lib/__pycache__/framebuf.cpython-312.pyc +0 -0
  155. toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
  156. toolkit/simulator_lib/__pycache__/micropython.cpython-312.pyc +0 -0
  157. toolkit/simulator_lib/__pycache__/mip.cpython-312.pyc +0 -0
  158. toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
  159. toolkit/simulator_lib/__pycache__/network.cpython-312.pyc +0 -0
  160. toolkit/simulator_lib/__pycache__/sim_common.cpython-312.pyc +0 -0
  161. toolkit/simulator_lib/__pycache__/simgc.cpython-312.pyc +0 -0
  162. toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
  163. toolkit/simulator_lib/__pycache__/uasyncio.cpython-312.pyc +0 -0
  164. toolkit/simulator_lib/__pycache__/uos.cpython-312.pyc +0 -0
  165. toolkit/simulator_lib/__pycache__/urandom.cpython-312.pyc +0 -0
  166. toolkit/simulator_lib/__pycache__/usocket.cpython-312.pyc +0 -0
  167. toolkit/simulator_lib/__pycache__/ussl.cpython-312.pyc +0 -0
  168. toolkit/simulator_lib/aioespnow.py +28 -0
  169. toolkit/simulator_lib/dht.py +1 -1
  170. toolkit/simulator_lib/framebuf.py +49 -1
  171. toolkit/simulator_lib/machine.py +17 -2
  172. toolkit/simulator_lib/micropython.py +3 -3
  173. toolkit/simulator_lib/mip.py +165 -0
  174. toolkit/simulator_lib/neopixel.py +3 -2
  175. toolkit/simulator_lib/network.py +2 -1
  176. toolkit/simulator_lib/node_config.json +2 -3
  177. toolkit/simulator_lib/ntptime.py +1 -1
  178. toolkit/simulator_lib/{sim_console.py → sim_common.py} +2 -3
  179. toolkit/simulator_lib/simgc.py +6 -2
  180. toolkit/simulator_lib/simulator.py +137 -59
  181. toolkit/simulator_lib/uasyncio.py +33 -2
  182. toolkit/simulator_lib/uos.py +147 -0
  183. toolkit/simulator_lib/urandom.py +4 -0
  184. toolkit/socketClient.py +43 -23
  185. toolkit/user_data/webhooks/generic.py +1 -1
  186. toolkit/user_data/webhooks/macro.py +1 -1
  187. toolkit/user_data/webhooks/template.py +1 -1
  188. toolkit/workspace/precompiled/Auth.mpy +0 -0
  189. toolkit/workspace/precompiled/Common.mpy +0 -0
  190. toolkit/workspace/precompiled/Config.mpy +0 -0
  191. toolkit/workspace/precompiled/Debug.mpy +0 -0
  192. toolkit/workspace/precompiled/Espnow.mpy +0 -0
  193. toolkit/workspace/precompiled/Files.mpy +0 -0
  194. toolkit/workspace/precompiled/Hooks.mpy +0 -0
  195. toolkit/workspace/precompiled/InterConnect.mpy +0 -0
  196. toolkit/workspace/precompiled/Interrupts.mpy +0 -0
  197. toolkit/workspace/precompiled/Logger.mpy +0 -0
  198. toolkit/workspace/precompiled/Network.mpy +0 -0
  199. toolkit/workspace/precompiled/Notify.mpy +0 -0
  200. toolkit/workspace/precompiled/Pacman.mpy +0 -0
  201. toolkit/workspace/precompiled/Scheduler.mpy +0 -0
  202. toolkit/workspace/precompiled/Server.mpy +0 -0
  203. toolkit/workspace/precompiled/Shell.mpy +0 -0
  204. toolkit/workspace/precompiled/Tasks.mpy +0 -0
  205. toolkit/workspace/precompiled/Time.mpy +0 -0
  206. toolkit/workspace/precompiled/Types.mpy +0 -0
  207. toolkit/workspace/precompiled/Web.mpy +0 -0
  208. toolkit/workspace/precompiled/_mpy.version +1 -1
  209. toolkit/workspace/precompiled/config/_git.keep +0 -0
  210. toolkit/workspace/precompiled/helpers.mpy +0 -0
  211. toolkit/workspace/precompiled/micrOS.mpy +0 -0
  212. toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
  213. toolkit/workspace/precompiled/microIO.mpy +0 -0
  214. toolkit/workspace/precompiled/{IO_esp32.mpy → modules/IO_esp32.mpy} +0 -0
  215. toolkit/workspace/precompiled/{IO_esp32c3.mpy → modules/IO_esp32c3.mpy} +0 -0
  216. toolkit/workspace/precompiled/modules/IO_esp32c6.mpy +0 -0
  217. toolkit/workspace/precompiled/{IO_esp32s2.mpy → modules/IO_esp32s2.mpy} +0 -0
  218. toolkit/workspace/precompiled/modules/IO_esp32s3.mpy +0 -0
  219. toolkit/workspace/precompiled/modules/IO_m5stamp.mpy +0 -0
  220. toolkit/workspace/precompiled/modules/IO_qtpy.mpy +0 -0
  221. toolkit/workspace/precompiled/modules/IO_rp2.mpy +0 -0
  222. toolkit/workspace/precompiled/modules/IO_tinypico.mpy +0 -0
  223. toolkit/workspace/precompiled/modules/LM_L298N.mpy +0 -0
  224. {micrOS/source → toolkit/workspace/precompiled/modules}/LM_L9110_DCmotor.py +3 -3
  225. toolkit/workspace/precompiled/modules/LM_OV2640.mpy +0 -0
  226. toolkit/workspace/precompiled/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +3 -3
  227. toolkit/workspace/precompiled/{LM_aht10.mpy → modules/LM_aht10.mpy} +0 -0
  228. toolkit/workspace/precompiled/{LM_bme280.mpy → modules/LM_bme280.mpy} +0 -0
  229. toolkit/workspace/precompiled/{LM_buzzer.mpy → modules/LM_buzzer.mpy} +0 -0
  230. toolkit/workspace/precompiled/modules/LM_cct.mpy +0 -0
  231. toolkit/workspace/precompiled/modules/LM_cluster.mpy +0 -0
  232. toolkit/workspace/precompiled/{LM_co2.mpy → modules/LM_co2.mpy} +0 -0
  233. toolkit/workspace/precompiled/{LM_dht11.mpy → modules/LM_dht11.mpy} +0 -0
  234. toolkit/workspace/precompiled/{LM_dht22.mpy → modules/LM_dht22.mpy} +0 -0
  235. toolkit/workspace/precompiled/modules/LM_dimmer.mpy +0 -0
  236. toolkit/workspace/precompiled/modules/LM_distance.mpy +0 -0
  237. toolkit/workspace/precompiled/{LM_ds18.mpy → modules/LM_ds18.mpy} +0 -0
  238. toolkit/workspace/precompiled/{LM_esp32.py → modules/LM_esp32.py} +5 -0
  239. toolkit/workspace/precompiled/modules/LM_espnow.py +53 -0
  240. toolkit/workspace/precompiled/modules/LM_fileserver.mpy +0 -0
  241. toolkit/workspace/precompiled/{LM_gameOfLife.mpy → modules/LM_gameOfLife.mpy} +0 -0
  242. toolkit/workspace/precompiled/modules/LM_genIO.mpy +0 -0
  243. toolkit/workspace/precompiled/{LM_haptic.mpy → modules/LM_haptic.mpy} +0 -0
  244. {micrOS/source → toolkit/workspace/precompiled/modules}/LM_i2c.py +5 -4
  245. toolkit/workspace/precompiled/modules/LM_i2s_mic.mpy +0 -0
  246. toolkit/workspace/precompiled/{LM_ld2410.mpy → modules/LM_ld2410.mpy} +0 -0
  247. toolkit/workspace/precompiled/modules/LM_light_sensor.mpy +0 -0
  248. toolkit/workspace/precompiled/modules/LM_mh_z19c.py +198 -0
  249. toolkit/workspace/precompiled/modules/LM_neoeffects.mpy +0 -0
  250. toolkit/workspace/precompiled/modules/LM_neopixel.mpy +0 -0
  251. toolkit/workspace/precompiled/{LM_oled.mpy → modules/LM_oled.mpy} +0 -0
  252. toolkit/workspace/precompiled/{LM_oled_sh1106.mpy → modules/LM_oled_sh1106.mpy} +0 -0
  253. toolkit/workspace/precompiled/modules/LM_oled_ui.mpy +0 -0
  254. toolkit/workspace/precompiled/modules/LM_pacman.mpy +0 -0
  255. toolkit/workspace/precompiled/modules/LM_presence.mpy +0 -0
  256. toolkit/workspace/precompiled/modules/LM_qmi8658.py +204 -0
  257. toolkit/workspace/precompiled/{LM_rencoder.py → modules/LM_rencoder.py} +2 -2
  258. toolkit/workspace/precompiled/modules/LM_rest.mpy +0 -0
  259. toolkit/workspace/precompiled/modules/LM_rgb.mpy +0 -0
  260. toolkit/workspace/precompiled/{LM_rgbcct.mpy → modules/LM_rgbcct.mpy} +0 -0
  261. toolkit/workspace/precompiled/modules/LM_roboarm.mpy +0 -0
  262. toolkit/workspace/precompiled/modules/LM_robustness.py +137 -0
  263. toolkit/workspace/precompiled/{LM_servo.mpy → modules/LM_servo.mpy} +0 -0
  264. toolkit/workspace/precompiled/{LM_sound_event.mpy → modules/LM_sound_event.mpy} +0 -0
  265. toolkit/workspace/precompiled/{LM_stepper.mpy → modules/LM_stepper.mpy} +0 -0
  266. toolkit/workspace/precompiled/modules/LM_switch.mpy +0 -0
  267. toolkit/workspace/precompiled/modules/LM_system.mpy +0 -0
  268. toolkit/workspace/precompiled/modules/LM_tcs3472.py +187 -0
  269. toolkit/workspace/precompiled/modules/LM_telegram.mpy +0 -0
  270. toolkit/workspace/precompiled/{LM_tinyrgb.mpy → modules/LM_tinyrgb.mpy} +0 -0
  271. toolkit/workspace/precompiled/{LM_trackball.mpy → modules/LM_trackball.mpy} +0 -0
  272. toolkit/workspace/precompiled/{LM_veml7700.mpy → modules/LM_veml7700.mpy} +0 -0
  273. toolkit/workspace/precompiled/modules/LM_web.mpy +0 -0
  274. toolkit/workspace/precompiled/urequests.mpy +0 -0
  275. {micrOS/source → toolkit/workspace/precompiled/web}/dashboard.html +4 -0
  276. toolkit/workspace/precompiled/web/editor.js +440 -0
  277. toolkit/workspace/precompiled/web/filesui.html +178 -0
  278. toolkit/workspace/precompiled/web/filesui.js +338 -0
  279. {micrOS/source → toolkit/workspace/precompiled/web}/index.html +44 -2
  280. toolkit/workspace/precompiled/{uapi.js → web/uapi.js} +48 -7
  281. toolkit/workspace/precompiled/{ustyle.css → web/ustyle.css} +6 -3
  282. micrOS/micropython/esp32-20241129-v1.24.1.bin +0 -0
  283. micrOS/micropython/esp32c3-20240222-v1.22.2.bin +0 -0
  284. micrOS/micropython/esp32s2-20240602-v1.23.0.bin +0 -0
  285. micrOS/micropython/esp32s2-LOLIN_MINI-20220618-v1.19.1.bin +0 -0
  286. micrOS/micropython/esp32s2-LOLIN_MINI-20240602-v1.23.0.bin +0 -0
  287. micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
  288. micrOS/micropython/esp32s3_spiram_oct-20231005-v1.21.0.bin +0 -0
  289. micrOS/micropython/esp32s3_spiram_oct-20241129-v1.24.1.bin +0 -0
  290. micrOS/micropython/rpi-pico-w-20241129-v1.24.1.uf2 +0 -0
  291. micrOS/micropython/tinypico-20241129-v1.24.1.bin +0 -0
  292. micrOS/source/LM_L298N_DCmotor.py +0 -86
  293. micrOS/source/LM_catgame.py +0 -75
  294. micrOS/source/LM_dashboard_be.py +0 -37
  295. micrOS/source/LM_demo.py +0 -97
  296. micrOS/source/LM_espnow.py +0 -23
  297. micrOS/source/LM_intercon.py +0 -57
  298. micrOS/source/LM_keychain.py +0 -322
  299. micrOS/source/LM_lmpacman.py +0 -126
  300. micrOS/source/LM_neoeffects.py +0 -331
  301. micrOS/source/LM_oledui.py +0 -972
  302. micrOS/source/LM_pet_feeder.py +0 -78
  303. micrOS/source/LM_ph_sensor.py +0 -51
  304. micrOS/source/LM_robustness.py +0 -74
  305. micrOS/source/reset.py +0 -11
  306. micrOSDevToolKit-2.9.1.dist-info/RECORD +0 -365
  307. toolkit/dashboard_apps/AirQualityBME280.py +0 -36
  308. toolkit/dashboard_apps/AirQualityDHT22_CO2.py +0 -36
  309. toolkit/lib/file_extensions.py +0 -16
  310. toolkit/simulator_lib/__pycache__/sim_console.cpython-312.pyc +0 -0
  311. toolkit/simulator_lib/__pycache__/sim_console.cpython-38.pyc +0 -0
  312. toolkit/simulator_lib/__pycache__/sim_console.cpython-39.pyc +0 -0
  313. toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
  314. toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
  315. toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
  316. toolkit/workspace/precompiled/IO_rp2.mpy +0 -0
  317. toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
  318. toolkit/workspace/precompiled/LM_L298N_DCmotor.mpy +0 -0
  319. toolkit/workspace/precompiled/LM_OV2640.mpy +0 -0
  320. toolkit/workspace/precompiled/LM_catgame.py +0 -75
  321. toolkit/workspace/precompiled/LM_cct.mpy +0 -0
  322. toolkit/workspace/precompiled/LM_dashboard_be.py +0 -37
  323. toolkit/workspace/precompiled/LM_demo.py +0 -97
  324. toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
  325. toolkit/workspace/precompiled/LM_distance.mpy +0 -0
  326. toolkit/workspace/precompiled/LM_espnow.py +0 -23
  327. toolkit/workspace/precompiled/LM_genIO.mpy +0 -0
  328. toolkit/workspace/precompiled/LM_i2s_mic.mpy +0 -0
  329. toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
  330. toolkit/workspace/precompiled/LM_keychain.mpy +0 -0
  331. toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
  332. toolkit/workspace/precompiled/LM_lmpacman.mpy +0 -0
  333. toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
  334. toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
  335. toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
  336. toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
  337. toolkit/workspace/precompiled/LM_pet_feeder.py +0 -78
  338. toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
  339. toolkit/workspace/precompiled/LM_presence.mpy +0 -0
  340. toolkit/workspace/precompiled/LM_rest.mpy +0 -0
  341. toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
  342. toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
  343. toolkit/workspace/precompiled/LM_robustness.py +0 -74
  344. toolkit/workspace/precompiled/LM_switch.mpy +0 -0
  345. toolkit/workspace/precompiled/LM_system.mpy +0 -0
  346. toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
  347. toolkit/workspace/precompiled/node_config.json +0 -1
  348. toolkit/workspace/precompiled/reset.mpy +0 -0
  349. /micrOS/source/{IO_esp32.py → modules/IO_esp32.py} +0 -0
  350. /micrOS/source/{IO_esp32c3.py → modules/IO_esp32c3.py} +0 -0
  351. /micrOS/source/{IO_esp32s2.py → modules/IO_esp32s2.py} +0 -0
  352. /micrOS/source/{IO_rp2.py → modules/IO_rp2.py} +0 -0
  353. /micrOS/source/{LM_gameOfLife.py → modules/LM_gameOfLife.py} +0 -0
  354. /micrOS/source/{LM_rgbcct.py → modules/LM_rgbcct.py} +0 -0
  355. /micrOS/source/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
  356. /micrOS/source/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
  357. /micrOS/source/{LM_sound_event.py → modules/LM_sound_event.py} +0 -0
  358. /micrOS/source/{LM_tinyrgb.py → modules/LM_tinyrgb.py} +0 -0
  359. /micrOS/source/{udashboard.js → web/udashboard.js} +0 -0
  360. /micrOS/source/{uwidgets.js → web/uwidgets.js} +0 -0
  361. /micrOS/source/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
  362. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info/licenses}/LICENSE +0 -0
  363. {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/top_level.txt +0 -0
  364. /toolkit/workspace/precompiled/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
  365. /toolkit/workspace/precompiled/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
  366. /toolkit/workspace/precompiled/{udashboard.js → web/udashboard.js} +0 -0
  367. /toolkit/workspace/precompiled/{uwidgets.js → web/uwidgets.js} +0 -0
  368. /toolkit/workspace/precompiled/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
@@ -1,6 +1,4 @@
1
1
  import socket
2
- import sys
3
-
4
2
  import select
5
3
  import re
6
4
  import time
@@ -10,6 +8,25 @@ except:
10
8
  from TerminalColors import Colors as color
11
9
 
12
10
 
11
+ ANSI_ESCAPE_RE = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
12
+
13
+ def load_command_history(prompt_getter):
14
+ """Optional command history feature"""
15
+ try:
16
+ try:
17
+ from .micrOSClientHistory import CommandInterface
18
+ except:
19
+ from micrOSClientHistory import CommandInterface
20
+ except Exception as e:
21
+ print(f"Command history - disabled (readline module error): {e}")
22
+ return None
23
+ try:
24
+ return CommandInterface(prompt=prompt_getter)
25
+ except Exception as e:
26
+ print(f"Command history error: {e}")
27
+ return None
28
+
29
+
13
30
  class micrOSClient:
14
31
  CONN_MAP = {}
15
32
 
@@ -35,6 +52,10 @@ class micrOSClient:
35
52
  # Validate and resolve host (IP/Hostname)
36
53
  self.__address_manager()
37
54
 
55
+ @property
56
+ def telnet_prompt(self):
57
+ return f"{color.BOLD}{self.preprompt}{self.prompt}{color.NC} "
58
+
38
59
  def __address_manager(self):
39
60
  self.dbg_print("[INIT] micrOSClient")
40
61
  # Host is valid IP address - self.host is ip address OK
@@ -67,10 +88,22 @@ class micrOSClient:
67
88
 
68
89
  @staticmethod
69
90
  def validate_ipv4(str_in):
70
- pattern = "^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"
71
- if bool(re.match(pattern, str_in)):
72
- return True
73
- return False
91
+ parts = str_in.split(".")
92
+ # An IPv4 address must have exactly 4 parts
93
+ if len(parts) != 4:
94
+ return False
95
+ for part in parts:
96
+ # Each part must be a number and not empty
97
+ if not part.isdigit():
98
+ return False
99
+ num = int(part)
100
+ # Each number must be in the valid range (0-255)
101
+ if num < 0 or num > 255:
102
+ return False
103
+ # Prevents leading zeros (e.g., "01" is invalid)
104
+ if part != str(num):
105
+ return False
106
+ return True
74
107
 
75
108
  def __connect(self, timeout):
76
109
  # Server connection - create socket
@@ -143,24 +176,35 @@ class micrOSClient:
143
176
 
144
177
  def __filter_preprompt(self, _data):
145
178
  if len(_data) == 0:
146
- return
147
- last_line = _data.strip().split('\n')[-1]
148
- # get pre-prompt: >[configure]< prompt $
179
+ return _data
180
+
181
+ has_trailing_newline = _data.endswith('\n')
182
+ working = _data.rstrip('\n')
183
+ lines = working.split('\n') if working else ['']
184
+ last_line = lines[-1]
185
+
149
186
  if self.prompt is not None:
150
- # Check prompt is in last line
151
- if self.prompt in last_line:
152
- # Check pre-prompt - remove prompt
153
- x = last_line.replace(self.prompt, '')
154
- # SET preprompt if preprompt exists
155
- self.preprompt = x if len(x) > 0 else self.preprompt
156
- # Pre-prompt remove and cancel preprompt modes
157
- if self.preprompt in last_line:
158
- _data = _data.replace(self.preprompt, "")
159
- else:
160
- self.preprompt = ""
161
- return _data
187
+ prompt_index = last_line.find(self.prompt)
188
+ if prompt_index != -1:
189
+ raw_prefix = last_line[:prompt_index]
190
+ plain_prefix = ANSI_ESCAPE_RE.sub('', raw_prefix)
191
+
192
+ plain_prefix = plain_prefix.rstrip()
193
+ if plain_prefix:
194
+ if not plain_prefix.endswith(' '):
195
+ plain_prefix += ' '
196
+ self.preprompt = plain_prefix
197
+ else:
198
+ self.preprompt = ""
199
+
200
+ lines[-1] = last_line[prompt_index:]
162
201
 
163
- def __receive_data(self, read_timeout=20):
202
+ rebuilt = '\n'.join(lines)
203
+ if has_trailing_newline:
204
+ rebuilt += '\n'
205
+ return rebuilt
206
+
207
+ def __receive_data(self, read_timeout=20, stream=False):
164
208
  """
165
209
  Client Receiver Loop
166
210
  - read_timeout - wait for server to reply (should be <15, avoid msg queue-ing)
@@ -173,7 +217,11 @@ class micrOSClient:
173
217
  # Collect answer data
174
218
  if select.select([self.conn], [], [], read_timeout)[0]:
175
219
  while True:
176
- data_buffer += self.conn.recv(4096).decode('utf-8')
220
+ incoming_data = self.conn.recv(4096).decode('utf-8')
221
+ if stream:
222
+ incoming_data = incoming_data.replace(self.prompt, f"{color.NC}{color.BOLD}{self.prompt}{color.NC}")
223
+ print(f"\r{color.LIGHT_GRAY}{incoming_data}{color.NC}", end="")
224
+ data_buffer += incoming_data
177
225
  # Last line from data_buffer (handle fragmented messages - prompt detection)
178
226
  last_line = data_buffer.strip().split("\n")[-1]
179
227
  # Wait for prompt or special cases (exit/prompt)
@@ -200,7 +248,7 @@ class micrOSClient:
200
248
  self.isconn = False
201
249
  self.spacer = 0
202
250
 
203
- def __run_command(self, cmd):
251
+ def __run_command(self, cmd, stream=False):
204
252
  """
205
253
  Run command on server tcp/ip connection
206
254
  - prompt check - validate device ("hostname $" = "prompt")
@@ -218,14 +266,14 @@ class micrOSClient:
218
266
  # Workaround for reboot command - micrOS async server cannot send Bye! msg before reboot.
219
267
  if reboot_request:
220
268
  return 'Bye!'
221
- data = self.__receive_data()
269
+ data = self.__receive_data(stream=stream)
222
270
  return data
223
271
  # Skip command run: prompt and host not the same!
224
272
  print(f"[micrOSClient] {color.ERR}prompt mismatch{color.NC}, hostname: {check_hostname} prompt: {check_prompt} ")
225
273
  # Check UID?
226
274
  return None
227
275
 
228
- def send_cmd(self, cmd, timeout=3, retry=5):
276
+ def send_cmd(self, cmd, timeout=3, retry=5, stream=False):
229
277
  """
230
278
  Send command function - main usage for non interactive mode
231
279
  """
@@ -244,7 +292,7 @@ class micrOSClient:
244
292
 
245
293
  # @ Run command
246
294
  try:
247
- out = self.__run_command(cmd)
295
+ out = self.__run_command(cmd, stream=stream)
248
296
  except Exception as e:
249
297
  self.dbg_print("{}[ERR]{} send_cmd error: {}".format(color.ERR, color.NC, e))
250
298
  self.dbg_print("Auto deinit connection")
@@ -258,14 +306,14 @@ class micrOSClient:
258
306
  f_delta_t = "{}[{:.2f}]{}".format(color.OKGREEN, delta_time, color.NC)
259
307
  self.dbg_print("{}[⏰] {} {}reply: {}{}".format(f_delta_t, cmd, color.BOLD, out, color.NC))
260
308
 
261
- # return output list
309
+ # return output list or None
262
310
  return out
263
311
 
264
- def send_cmd_retry(self, cmd, timeout=6, retry=5):
312
+ def send_cmd_retry(self, cmd, timeout=6, retry=5, stream=False):
265
313
  out = None
266
314
  for cnt in range(0, retry):
267
315
  try:
268
- out = self.send_cmd(cmd, timeout)
316
+ out = self.send_cmd(cmd, timeout, stream=stream)
269
317
  if out is None or isinstance(out, list):
270
318
  break
271
319
  except OSError as e:
@@ -277,7 +325,7 @@ class micrOSClient:
277
325
  time.sleep(0.2)
278
326
  return out
279
327
 
280
- def telnet(self, timeout=4):
328
+ def telnet(self, timeout=5):
281
329
  """
282
330
  Implements interactive mode for socket communication.
283
331
  """
@@ -287,18 +335,41 @@ class micrOSClient:
287
335
  print("Telnet connect: {}".format(e))
288
336
  if "busy" in str(e) or "timed out" in str(e) or "No route to host" in str(e) or "Host is down" in str(e):
289
337
  return
338
+
339
+ history = load_command_history(self.telnet_prompt) # History: Beta feature
340
+ if history is not None:
341
+ history.prompt = self.telnet_prompt
342
+ print(self.telnet_prompt, end="")
343
+ is_empty = False # Empty input support
290
344
  while True:
291
- cmd = input("{}{} ".format(self.preprompt, self.prompt))
292
- # send command
293
- output = self.send_cmd(cmd)
294
- # Format output to human readable
295
- output = '\n'.join(output) if isinstance(output, list) else output
296
- # output to STDOUT
297
- if not (cmd.strip() == '' and output is None):
298
- print(output)
299
- # Close session
300
- if 'Bye!' in str(output):
345
+ try:
346
+ # INPUT HANDLING
347
+ if history is not None:
348
+ history.prompt = self.telnet_prompt
349
+ cmd = input(self.telnet_prompt if is_empty else '') # CANNOT contain prompt - it is coming back from response data
350
+ if len(cmd.strip()) == 0:
351
+ is_empty = True
352
+ if history is not None:
353
+ history.prompt = self.telnet_prompt
354
+ continue
355
+ is_empty = False
356
+ # SEND COMMAND
357
+ output = self.send_cmd(cmd, timeout=timeout, stream=True)
358
+ if history is not None:
359
+ history.prompt = self.telnet_prompt
360
+ if not (history is None or output is None) and "Shell: for hints type help." not in output: # History: Beta feature
361
+ history.add_history(cmd)
362
+ # OUTPUT HANDLING
363
+ if 'Bye!' in str(output):
364
+ break
365
+ if output is None:
366
+ print("Exiting... client disconnected")
367
+ break
368
+ except KeyboardInterrupt:
369
+ print("Exiting...")
301
370
  break
371
+ if history is not None: # History: Beta feature
372
+ history.save_history()
302
373
  self.close()
303
374
 
304
375
  def dbg_print(self, msg, end='\n'):
@@ -325,8 +396,9 @@ class micrOSClient:
325
396
  verdict.append(console_msg)
326
397
  print(f"===>\t\t{console_msg}")
327
398
  self.close()
328
- verdict.append(f"SINGLE CONNECTION LOAD TEST X{cnt}, AVERAGE REPLY TIME: {round(delta_t_all/cnt, 3)} sec\n")
329
- return verdict
399
+ delta_t_result = round(delta_t_all / cnt, 3)
400
+ verdict.append(f"SINGLE CONNECTION LOAD TEST X{cnt}, AVERAGE REPLY TIME: {delta_t_result} sec\n")
401
+ return verdict, delta_t_result
330
402
 
331
403
  def __del__(self):
332
404
  if self.dbg and self.avg_reply[1] > 0:
@@ -355,9 +427,10 @@ def micros_connection_metrics(address):
355
427
  print(f"\t\t{_console_msg}")
356
428
  all_reply.append(_console_msg)
357
429
  success_rate = int(round(_success / cnt, 2) * 100)
358
- all_reply.append(f"MULTI CONNECTION LOAD TEST X{cnt}, AVERAGE REPLY TIME: {round(_all_delta_t/cnt, 3)}s, "
359
- f"SERVER AVAILABILITY: {success_rate}% ({round(_all_delta_t/_success, 3)}s)")
360
- return all_reply
430
+ delta_t_result = round(_all_delta_t/cnt, 3)
431
+ all_reply.append(f"MULTI CONNECTION LOAD TEST X{cnt}, AVERAGE REPLY TIME: {delta_t_result}s, "
432
+ f"SERVER AVAILABILITY: {success_rate}% ({int((_all_delta_t/_success)*1000)} ms)")
433
+ return all_reply, delta_t_result
361
434
 
362
435
  # ---------------------------------------------------- #
363
436
  high_level_verdict = []
@@ -365,12 +438,12 @@ def micros_connection_metrics(address):
365
438
  # [1] Create micrOSClient object + Run LOAD tests
366
439
  com_obj = micrOSClient(host=address, port=9008, pwd="ADmin123", dbg=True)
367
440
  # [1.1] Run load test in one connection
368
- verdict_list = com_obj.load_test()
441
+ verdict_list, delta_t_single_session = com_obj.load_test()
369
442
  com_obj.close()
370
443
  high_level_verdict.append(verdict_list[-1])
371
444
 
372
445
  # [2] Run multi connection load test - reconnect - raw connection (without retry)
373
- verdict_multi = multi_conn_load(address)
446
+ verdict_multi, delta_t_multi_session = multi_conn_load(address)
374
447
  high_level_verdict.append((verdict_multi[-1]))
375
448
 
376
449
  ############################################################################
@@ -382,7 +455,7 @@ def micros_connection_metrics(address):
382
455
  for k in verdict_multi:
383
456
  print(f"\t{k}")
384
457
 
385
- return high_level_verdict
458
+ return high_level_verdict, delta_t_single_session, delta_t_multi_session
386
459
 
387
460
 
388
461
  if __name__ == "__main__":
@@ -416,7 +489,7 @@ if __name__ == "__main__":
416
489
  print(f"noconf out: {noconf_mode}")
417
490
  if force_close: com_obj.close()
418
491
 
419
- verdict = micros_connection_metrics(address=address)
492
+ verdict, delta_t_single, delta_t_multi = micros_connection_metrics(address=address)
420
493
  for k in verdict:
421
494
  print(f"+\t\t{k}")
422
495
 
@@ -0,0 +1,156 @@
1
+ import sys
2
+ import os
3
+ import re
4
+
5
+ try:
6
+ import readline # Linux/macOS
7
+ except ImportError:
8
+ import pyreadline3 as readline # Windows (PowerShell, CMD)
9
+
10
+ try:
11
+ from .TerminalColors import Colors as color
12
+ except:
13
+ from TerminalColors import Colors as color
14
+
15
+
16
+ ANSI_ESCAPE_RE = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
17
+
18
+
19
+ class CommandInterface:
20
+ def __init__(self, prompt):
21
+ self._prompt = ""
22
+ self._prompt_plain = ""
23
+ self._last_rendered_length = 0
24
+ self.prompt = prompt
25
+ self.command_history = ["help"]
26
+ self.history_file = os.path.expanduser("~/.micrOS_cmd_history") # History file (Linux/macOS)
27
+
28
+ # Configure readline
29
+ self.load_history()
30
+ readline.set_completer_delims("") # Ensure entire command is considered
31
+ readline.set_completer(self.autocomplete)
32
+ # Check if we're running on macOS using libedit
33
+ if "libedit" in readline.__doc__:
34
+ readline.parse_and_bind("bind ^I rl_complete") # macOS alternative
35
+ else:
36
+ readline.parse_and_bind("tab: complete") # Linux/GNU readline
37
+ readline.set_pre_input_hook(self.pre_input_hook)
38
+ readline.set_completion_display_matches_hook(self.completion_display)
39
+
40
+ def __auto_clear_history(self):
41
+ cmd_history = []
42
+ # Load file history in order - skip duplicates
43
+ if os.path.exists(self.history_file):
44
+ with open(self.history_file, "r") as f:
45
+ for line in reversed(f.readlines()):
46
+ if line in cmd_history:
47
+ continue
48
+ cmd_history.append(line)
49
+ # Save cleaned history to file
50
+ with open(self.history_file, "w") as f:
51
+ f.writelines(f"{item}\n" for item in reversed(cmd_history))
52
+
53
+ def load_history(self):
54
+ """Loads command history from a file if available."""
55
+ print(f"Command history: {self.history_file}")
56
+ try:
57
+ self.__auto_clear_history()
58
+ except Exception as e:
59
+ print(f"Auto clean history error: {e}")
60
+ if os.path.exists(self.history_file):
61
+ with open(self.history_file, "r") as f:
62
+ for line in f:
63
+ clean_line = line.strip()
64
+ if clean_line: # Avoid empty lines
65
+ self.command_history.append(clean_line)
66
+ readline.add_history(clean_line)
67
+
68
+ def save_history(self):
69
+ """Saves command history to a file."""
70
+ with open(self.history_file, "w") as f:
71
+ for cmd in self.command_history:
72
+ f.write(cmd + "\n")
73
+
74
+ def add_history(self, cmd):
75
+ """Updates readline history and command_history."""
76
+ cmd = cmd.strip()
77
+ if cmd and cmd != self.command_history[-1]: # Avoid duplicate last command
78
+ self.command_history.append(cmd)
79
+ readline.add_history(cmd)
80
+
81
+ def autocomplete(self, text, state):
82
+ """Autocomplete function: suggests previous commands."""
83
+ matches = list(dict.fromkeys(cmd for cmd in self.command_history if cmd.startswith(text)))
84
+ return matches[state] if state < len(matches) else None
85
+
86
+ @staticmethod
87
+ def _strip_ansi(value):
88
+ if not value:
89
+ return ""
90
+ return ANSI_ESCAPE_RE.sub("", value)
91
+
92
+ @property
93
+ def prompt(self):
94
+ return self._prompt
95
+
96
+ @prompt.setter
97
+ def prompt(self, value):
98
+ self._prompt = value
99
+ self._prompt_plain = self._strip_ansi(value)
100
+
101
+ def pre_input_hook(self):
102
+ """Ensures prompt visibility when scrolling through history."""
103
+ buffer = readline.get_line_buffer()
104
+ sys.stdout.write("\r")
105
+ rendered = f"{self.prompt}{buffer}"
106
+ sys.stdout.write(rendered)
107
+
108
+ visible_length = len(self._prompt_plain) + len(buffer)
109
+ if visible_length < self._last_rendered_length:
110
+ padding = " " * (self._last_rendered_length - visible_length)
111
+ sys.stdout.write(padding)
112
+ sys.stdout.write("\r")
113
+ sys.stdout.write(rendered)
114
+
115
+ sys.stdout.flush()
116
+ self._last_rendered_length = visible_length
117
+ readline.redisplay() # Ensures history navigation does not erase prompt
118
+
119
+ def completion_display(self, substitutions, matches, longest_match_length):
120
+ print("\nSuggestions:", ", ".join(matches))
121
+
122
+ #####################################
123
+ # STANDALONE TEST METHODS #
124
+ #####################################
125
+
126
+ def dummy_send_cmd(self, cmd, stream):
127
+ """TEST FUNCTION - OUTPUT STRUCTURE SIMULATION (Must remain unchanged)."""
128
+ dummy_reply = "Bye!" if cmd.strip() in ["exit", "reboot"] else f"Dummy reply for {cmd}"
129
+ if stream:
130
+ print(dummy_reply) # micrOS protocol: return response data
131
+ print(self.prompt, end="") # micrOS protocol: return prompt -> indicating ready state
132
+ else:
133
+ dummy_reply = f"{dummy_reply}\n{self.prompt}"
134
+ return dummy_reply
135
+
136
+ def dummy_run(self):
137
+ """TEST FUNCTION - Simulated interactive terminal."""
138
+ print(f"{self.prompt}", end="", flush=True)
139
+ while True:
140
+ try:
141
+ cmd = input()
142
+ output = self.dummy_send_cmd(cmd, stream=True)
143
+ self.add_history(cmd)
144
+ if 'Bye!' in str(output):
145
+ break
146
+ except KeyboardInterrupt:
147
+ print("\nExiting...")
148
+ break
149
+
150
+ self.save_history()
151
+ print("Session closed.")
152
+
153
+
154
+ if __name__ == "__main__":
155
+ shell = CommandInterface(prompt="<prompt_placeholder>$ ")
156
+ shell.dummy_run()
@@ -66,8 +66,11 @@ def install_package(name, additional_pip_param=None):
66
66
  print(f"{TerminalColors.Colors.OK}[PIP] install {name} OK{TerminalColors.Colors.NC}")
67
67
  else:
68
68
  print(f"{TerminalColors.Colors.WARN}[PIP] install {name} NOK{TerminalColors.Colors.NC}")
69
- # Support brew installed python
70
- if "This environment is externally managed" in out:
69
+ if "--break-system-packages" in out:
70
+ # (Retry) Support system wide package install
71
+ install_package(name, additional_pip_param="--break-system-packages")
72
+ elif "This environment is externally managed" in out:
73
+ # (Retry-Fallback) Support brew installed python
71
74
  if "brew install" in out:
72
75
  print(f"Install optional dependency (brew): {name}")
73
76
  state, out = run_subprocess(["brew", "install", name])
@@ -6,17 +6,12 @@ import os
6
6
  import threading
7
7
  import subprocess
8
8
  import time
9
- from PyQt5.QtWidgets import QPushButton
10
- import PyQt5.QtCore as QtCore
11
- from PyQt5.QtCore import pyqtSlot
12
- from PyQt5.QtWidgets import *
13
- from PyQt5.QtGui import QIcon
14
- from PyQt5.QtGui import QTextCursor
15
- from PyQt5.QtWidgets import QApplication, QPlainTextEdit
16
- from PyQt5.QtCore import QThread, pyqtSignal
17
- from PyQt5.QtGui import QFont
18
- from PyQt5 import QtGui
19
- from PyQt5.QtGui import QPixmap
9
+
10
+ from PyQt5.QtWidgets import (QApplication, QPlainTextEdit, QPushButton, QProgressBar, QComboBox, QLabel, QCheckBox,
11
+ QLineEdit, QMessageBox, QWidget, QToolTip)
12
+ from PyQt5.QtCore import pyqtSlot, QThread, QSize, pyqtSignal
13
+ from PyQt5.QtGui import QIcon, QTextCursor, QFont, QPixmap
14
+
20
15
  import concurrent.futures
21
16
 
22
17
  MYPATH = os.path.dirname(__file__)
@@ -29,14 +24,14 @@ try:
29
24
  from . import socketClient
30
25
  from . import dashboard_apps
31
26
  from .lib import LocalMachine
32
- from .lib.file_extensions import check_all_extensions
27
+ from .lib.MicrosFiles import check_all_extensions
33
28
  except Exception as e:
34
29
  print("Import warning: {}".format(e))
35
30
  import MicrOSDevEnv
36
31
  import socketClient
37
32
  import dashboard_apps
38
33
  from lib import LocalMachine
39
- from lib.file_extensions import check_all_extensions
34
+ from lib.MicrosFiles import check_all_extensions
40
35
 
41
36
  APP_DIR = os.path.join(MYPATH, 'dashboard_apps')
42
37
 
@@ -454,7 +449,7 @@ class HeaderInfo:
454
449
  logo_path = os.path.join(MYPATH, '../media/logo_mini.png')
455
450
  button = QPushButton('', self.parent_obj)
456
451
  button.setIcon(QIcon(logo_path))
457
- button.setIconSize(QtCore.QSize(50, 50))
452
+ button.setIconSize(QSize(50, 50))
458
453
  button.setGeometry(20, 5, 50, 50)
459
454
  button.setToolTip(f"Open micrOS repo documentation\n{self.url}")
460
455
  button.setStyleSheet('border: 0px solid black;')
@@ -581,7 +576,7 @@ class ClusterStatus:
581
576
  except:
582
577
  hwuid = hello
583
578
  status = '🟢' if status else '🔴'
584
- msg = f"{status}{hwuid}|{devip}🏷{fuid} v:️{version}"
579
+ msg = f"{status}{hwuid} | {devip}🏷{fuid} v:{version}"
585
580
  return msg
586
581
 
587
582
  with concurrent.futures.ThreadPoolExecutor() as executor:
@@ -954,7 +949,7 @@ class micrOSGUI(QWidget):
954
949
  self.devenv_usb_deployment_is_active = True
955
950
  # Create a Thread with a function without any arguments
956
951
  self.console.append_output('[usb_deploy] |- start usb_deploy job')
957
- th = threading.Thread(target=self.devtool_obj.deploy_micros, kwargs={'restore': False, 'purge_conf': True},
952
+ th = threading.Thread(target=self.devtool_obj.deploy_micros, kwargs={'restore_config': False, "cleanup_workdir": True},
958
953
  daemon=DAEMON)
959
954
  th.start()
960
955
  self.bgjob_thread_obj_dict['usb_deploy'] = th
@@ -1219,7 +1214,7 @@ class micrOSGUI(QWidget):
1219
1214
 
1220
1215
  def main():
1221
1216
  app = QApplication(sys.argv)
1222
- app.setWindowIcon(QtGui.QIcon(os.path.join(MYPATH, '../media/logo.png')))
1217
+ app.setWindowIcon(QIcon(os.path.join(MYPATH, '../media/logo.png')))
1223
1218
  ex = micrOSGUI()
1224
1219
  ex.draw()
1225
1220
  sys.exit(app.exec_())
toolkit/micrOSlint.py CHANGED
@@ -18,7 +18,7 @@ MICROS_SOURCE_DIR = os.path.join(MYPATH, '../micrOS/source')
18
18
  RELEASE_INFO_PATH = os.path.join(MYPATH, '../micrOS/release_info/micrOS_ReleaseInfo')
19
19
 
20
20
  # MICROS LINTER CONFIG
21
- ALLOWED_LM_DEP_WARNS = 6 # ALLOWED NUMBER OF LM CORE DEPENDENCY (less is better)
21
+ ALLOWED_LM_DEP_WARNS = 3 # ALLOWED NUMBER OF LM CORE DEPENDENCY (less is better)
22
22
 
23
23
  def parse_micros_file_categories(verbose=True):
24
24
  """
@@ -27,11 +27,17 @@ def parse_micros_file_categories(verbose=True):
27
27
  file_ignore_list = ['.DS_Store']
28
28
  # micrOS file categories
29
29
  categories = {'core': [], 'load_module': [], 'pin_maps': [], 'other': []}
30
- files = [f for f in LocalMachine.FileHandler.list_dir(MICROS_SOURCE_DIR) if f not in file_ignore_list]
30
+ modules_path = os.path.join(MICROS_SOURCE_DIR, "modules")
31
+ web_path = os.path.join(MICROS_SOURCE_DIR, "web")
32
+ check_file = lambda _b, _f: os.path.isfile(os.path.join(_b, _f)) and _f not in file_ignore_list
33
+ root_files = [f for f in LocalMachine.FileHandler.list_dir(MICROS_SOURCE_DIR) if check_file(MICROS_SOURCE_DIR, f)]
34
+ module_files = [f"modules/{f}" for f in LocalMachine.FileHandler.list_dir(modules_path) if check_file(modules_path, f)]
35
+ web_files = [f"web/{f}" for f in LocalMachine.FileHandler.list_dir(web_path) if check_file(web_path, f)]
36
+ files = root_files + module_files + web_files
31
37
  for f in files:
32
- if f.startswith('LM_') and f.endswith('.py'):
38
+ if f.endswith('.py') and "LM_" in f:
33
39
  categories['load_module'].append(f)
34
- elif f.startswith('IO_') and f.endswith('.py'):
40
+ elif f.endswith('.py') and "IO_" in f:
35
41
  categories['pin_maps'].append(f)
36
42
  elif f.endswith('.py'):
37
43
  categories['core'].append(f)
@@ -172,14 +178,15 @@ def core_dep_checker(categories, verbose=True):
172
178
  def load_module_checker(categories, verbose=True):
173
179
 
174
180
  def _is_allowed(_relation):
175
- _allowed_whitelist = ['Common', 'microIO', 'Types']
181
+ _allowed_whitelist = ['Common', 'microIO', 'Types', 'urequests', 'Auth']
176
182
  _allowed = []
177
183
  for _allow in _relation:
178
184
  if _allow in _allowed_whitelist:
179
185
  _allowed.append(_allow)
180
186
  return _relation, _allowed
181
187
 
182
- lm_god_mode = ['LM_system.py', 'LM_lmpacman.py', 'LM_intercon.py']
188
+ lm_god_mode = ['modules/LM_system.py', 'modules/LM_pacman.py',
189
+ 'modules/LM_espnow.py', 'modules/LM_cluster.py']
183
190
  state_lm_dep = True
184
191
  verdict = []
185
192
  lm_resources = categories['load_module']
@@ -222,7 +229,12 @@ def _run_pylint(file_name):
222
229
  '--disable=broad-exception-caught', # Disable BROAD exception
223
230
  '--disable=broad-exception-raised', # Disable BROAD exception
224
231
  '--disable=too-many-return-statements', # :D I don't think so :D
225
- '--disable=too-many-branches' # :D I don't think so :D
232
+ '--disable=too-many-branches', # :D I don't think so :D
233
+ '--disable=too-many-positional-arguments', # :D I don't think so :D
234
+ '--disable=too-many-instance-attributes', # :D I don't think so :D
235
+ '--disable=wrong-import-position', # :D I don't think so :D !!! It is needed due to optimizations
236
+ '--disable=too-many-arguments', # :D I know what I am doing...
237
+ '--disable=multiple-statements', # :D I line oneliners
226
238
  ]
227
239
  if file_name in ['Tasks.py', 'microIO.py', 'Types.py']:
228
240
  pylint_opts.append('--disable=exec-used') # Disable micrOS execution core exec/eval warning
@@ -239,7 +251,7 @@ def _run_pylint(file_name):
239
251
 
240
252
  def run_pylint(categories, verbose=True, dry_run=False):
241
253
  # ERROR CONFIG: drop error if this is in pylint output
242
- error_msg_core = ['syntax-error', 'undefined-variable', 'no-member']
254
+ error_msg_core = ['syntax-error', 'undefined-variable', 'bad-indentation'] # 'no-member' ?
243
255
  # BYPASS 'no-member' due to duty and sleep_ms micropython functions is drops false alarm, etc.
244
256
  error_msg_lm = ['syntax-error', 'undefined-variable']
245
257