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
micrOS/source/Tasks.py CHANGED
@@ -10,18 +10,19 @@ Designed by Marcell Ban aka BxNxM
10
10
  #################################################################
11
11
  from sys import modules
12
12
  from json import dumps
13
+ from re import match
13
14
  import uasyncio as asyncio
14
15
  from micropython import schedule
15
16
  from utime import ticks_ms, ticks_diff
16
- from Debug import console_write, errlog_add
17
+ from Debug import console_write, syslog
17
18
  from Config import cfgget
18
19
  from Network import sta_high_avail
19
20
 
20
21
  try:
21
- from gc import collect
22
+ from gc import collect as gcollect
22
23
  except ImportError:
23
24
  console_write("[SIMULATOR MODE GC IMPORT]")
24
- from simgc import collect
25
+ from simgc import collect as gcollect
25
26
 
26
27
  #################################################################
27
28
  # Implement custom task class #
@@ -43,18 +44,20 @@ class TaskBase:
43
44
  self.done = asyncio.Event() # Store task done state
44
45
  self.out = "" # Store task output
45
46
 
46
- @staticmethod
47
- def is_busy(tag) -> bool:
47
+ ###### BASE METHODS FOR CHILD CLASSES ####
48
+ def _create(self, callback:callable) -> dict:
48
49
  """
49
- Check task is busy by tag
50
- :param tag: for task selection
50
+ Create async task and register it to TASKS dict by tag
51
+ :param callback: coroutine function
51
52
  """
52
- task = TaskBase.TASKS.get(tag, None)
53
- # return True: busy OR False: not busy (inactive)
54
- return bool(task is not None and not task.done.is_set())
53
+ # Create async task from coroutine function
54
+ self.task = asyncio.get_event_loop().create_task(callback)
55
+ # Store Task object by key - for task control
56
+ TaskBase.TASKS[self.tag] = self
57
+ return {self.tag: "Starting"}
55
58
 
56
59
  @staticmethod
57
- def task_gc():
60
+ def _task_gc():
58
61
  """
59
62
  Automatic passive task deletion over QUEUE_SIZE
60
63
  """
@@ -63,7 +66,18 @@ class TaskBase:
63
66
  if len(passive) >= keep:
64
67
  for i in range(0, len(passive)-keep+1):
65
68
  del TaskBase.TASKS[passive[i]]
66
- collect() # GC collect
69
+ gcollect()
70
+
71
+ ###### PUBLIC TASK METHODS #####
72
+ @staticmethod
73
+ def is_busy(tag:str) -> bool:
74
+ """
75
+ Check task is busy by tag
76
+ :param tag: for task selection
77
+ """
78
+ task = TaskBase.TASKS.get(tag, None)
79
+ # return True: busy OR False: not busy (inactive) OR None: not exists
80
+ return bool(task is not None and not task.done.is_set())
67
81
 
68
82
  def cancel(self) -> bool:
69
83
  """
@@ -75,15 +89,38 @@ class TaskBase:
75
89
  self.task.cancel() # Try to cancel task by asyncio
76
90
  except Exception as e:
77
91
  if "can't cancel self" != str(e):
78
- errlog_add(f"[WARN] IRQ Task cancel: {e}")
92
+ syslog(f"[WARN] IRQ Task cancel: {e}")
79
93
  self.__task_del()
80
94
  else:
81
95
  return False
82
96
  except Exception as e:
83
- errlog_add(f"[ERR] Task kill: {e}")
97
+ syslog(f"[ERR] Task kill: {e}")
84
98
  return False
85
99
  return True
86
100
 
101
+ @staticmethod
102
+ async def feed(sleep_ms=1):
103
+ """
104
+ Feed event loop
105
+ :param sleep_ms: in millisecond
106
+ """
107
+ # TODO?: feed WDT - auto restart when system is frozen
108
+ if sleep_ms <= 0:
109
+ return await asyncio.sleep(0.000_000_1) # 0 means: 100ns (Absolute minimum)
110
+ return await asyncio.sleep_ms(sleep_ms)
111
+
112
+ async def await_result(self, timeout:int=5):
113
+ """
114
+ Wait for task completion with timeout
115
+ :param timeout: in seconds
116
+ """
117
+ try:
118
+ await asyncio.wait_for(self.done.wait(), timeout)
119
+ except asyncio.TimeoutError:
120
+ return "Timeout has beed exceeded"
121
+ return self.out
122
+
123
+ ###### PRIVATE LCM METHODS #####
87
124
  def __task_del(self, keep_cache=False):
88
125
  """
89
126
  Delete task from TASKS
@@ -92,22 +129,13 @@ class TaskBase:
92
129
  if self.tag in TaskBase.TASKS:
93
130
  if not keep_cache: # True - In case of destructor
94
131
  del TaskBase.TASKS[self.tag]
95
- collect() # GC collect
96
-
97
- @staticmethod
98
- async def feed(sleep_ms=1):
99
- """
100
- Feed event loop
101
- :param sleep_ms: in millisecond (min: 1)
102
- """
103
- # TODO: feed WDT - preemptive cooperative multitasking aka reboot if no feed until X time period
104
- return await asyncio.sleep_ms(sleep_ms)
132
+ gcollect()
105
133
 
106
134
  def __del__(self):
107
135
  try:
108
136
  self.__task_del(keep_cache=True)
109
137
  except Exception as e:
110
- errlog_add(f"[ERR] TaskBase.__del__: {e}")
138
+ syslog(f"[ERR] TaskBase.__del__: {e}")
111
139
 
112
140
 
113
141
  class NativeTask(TaskBase):
@@ -116,7 +144,7 @@ class NativeTask(TaskBase):
116
144
  - could be built in function or custom code from load modules
117
145
  """
118
146
 
119
- def create(self, callback=None, tag=None):
147
+ def create(self, callback:callable=None, tag:str=None) -> dict:
120
148
  """
121
149
  Create async task with coroutine callback (no queue limit check!)
122
150
  + async socket server task
@@ -125,15 +153,11 @@ class NativeTask(TaskBase):
125
153
  """
126
154
  # Create task tag
127
155
  self.tag = f"aio.{ticks_ms()}" if tag is None else tag
128
- if TaskBase.is_busy(self.tag):
156
+ if self.is_busy(self.tag):
129
157
  # Skip task if already running
130
- return False
131
-
132
- # Start task with coroutine callback
133
- self.task = asyncio.get_event_loop().create_task(callback)
134
- # Store Task object by key - for task control
135
- TaskBase.TASKS[self.tag] = self
136
- return True
158
+ return {self.tag: "Already running"}
159
+ # Create task with coroutine callback
160
+ return super()._create(callback)
137
161
 
138
162
  def __enter__(self):
139
163
  """
@@ -150,7 +174,7 @@ class NativeTask(TaskBase):
150
174
  Helper function for Task creation in Load Modules
151
175
  [HINT] Use python with feature to utilize this feature
152
176
  """
153
- self.task_gc() # Task pool cleanup
177
+ self._task_gc() # Task pool cleanup
154
178
  self.done.set()
155
179
 
156
180
 
@@ -166,7 +190,7 @@ class MagicTask(TaskBase):
166
190
  self.__inloop = False # [LM] Task while loop for LM callback
167
191
  self.__sleep = 20 # [LM] Task while loop - async wait (proc feed) [ms]
168
192
 
169
- def create(self, callback=None, loop=None, sleep=None):
193
+ def create(self, callback:list=None, loop:bool=None, sleep:int=None) -> dict:
170
194
  """
171
195
  Create async task with function callback (with queue limit check)
172
196
  - wrap (sync) function into async task (task_wrapper)
@@ -176,20 +200,16 @@ class MagicTask(TaskBase):
176
200
  """
177
201
  # Create task tag
178
202
  self.tag = '.'.join(callback[0:2])
179
- if TaskBase.is_busy(self.tag):
203
+ if self.is_busy(self.tag):
180
204
  # Skip task if already running
181
- return False
182
-
205
+ return {self.tag: "Already running"}
183
206
  # Set parameters for async wrapper
184
207
  self.__callback = callback
185
208
  self.__inloop = self.__inloop if loop is None else loop
186
209
  # Set sleep value for async loop - optional parameter with min sleep limit check (20ms)
187
210
  self.__sleep = self.__sleep if sleep is None else sleep if sleep > 19 else self.__sleep
188
-
189
- self.task = asyncio.get_event_loop().create_task(self.__task_wrapper())
190
- # Store Task object by key - for task control
191
- TaskBase.TASKS[self.tag] = self
192
- return True
211
+ # Create task with coroutine callback
212
+ return super()._create(self.__task_wrapper())
193
213
 
194
214
  async def __task_wrapper(self):
195
215
  """
@@ -199,15 +219,12 @@ class MagicTask(TaskBase):
199
219
  - self.__inloop: lm call type - one-shot (False) / looped (True)
200
220
  - self.__msg_buf: lm msg object redirect to variable - store lm output
201
221
  """
202
- jsonify = self.__callback[-1] == '>json'
203
- if jsonify:
204
- self.__callback = self.__callback[:-1]
205
222
  while True:
206
223
  await self.feed(self.__sleep)
207
- state, self.out = _exec_lm_core(self.__callback, jsonify)
224
+ state, self.out = _exec_lm_core(self.__callback)
208
225
  if not state or not self.__inloop:
209
226
  break
210
- self.task_gc() # Task pool cleanup
227
+ self._task_gc() # Task pool cleanup
211
228
  self.done.set()
212
229
 
213
230
  def cancel(self):
@@ -227,6 +244,7 @@ class Manager:
227
244
  __slots__ = ['_initialized', 'idle_counter']
228
245
  INSTANCE = None # Manager object
229
246
  LOAD = 0 # CPU overload measure
247
+ INTERCON = None # Dynamic ref. for interconnect calls
230
248
 
231
249
  def __new__(cls):
232
250
  """
@@ -240,7 +258,7 @@ class Manager:
240
258
  cls.INSTANCE._initialized = False
241
259
  # Set async event loop exception handler
242
260
  asyncio.get_event_loop().set_exception_handler(lambda loop=None, context=None:
243
- errlog_add(f"[aio] exception: {loop}:{context}"))
261
+ syslog(f"[aio] exception: {loop}:{context}"))
244
262
  return cls.INSTANCE
245
263
 
246
264
  def __init__(self):
@@ -265,7 +283,7 @@ class Manager:
265
283
  """
266
284
  if Manager._queue_len() >= TaskBase.QUEUE_SIZE:
267
285
  msg = f"[aio] Task queue full: {TaskBase.QUEUE_SIZE}"
268
- errlog_add(msg)
286
+ syslog(msg)
269
287
  raise Exception(msg)
270
288
 
271
289
  async def idle_task(self):
@@ -287,21 +305,26 @@ class Manager:
287
305
  delta_rate = int(((ticks_diff(ticks_ms(), t) / 300) - 1) * 100)
288
306
  Manager.LOAD = int((Manager.LOAD + delta_rate) / 2) # Average - smooth
289
307
  # [2] NETWORK AUTO REPAIR
290
- if self.idle_counter > 200: # ~120 sec
308
+ if self.idle_counter > 300: # ~ 3 min
291
309
  self.idle_counter = 0 # Reset counter
292
- # Check and fix STA network (example: after power outage - micrOS boards boots faster then router)
310
+ # Check and fix STA network (reboot if target ssid is available not yet connected)
293
311
  sta_high_avail()
294
312
  self.idle_counter += 1 # Increase counter
295
313
  except Exception as e:
296
- errlog_add(f"[ERR] Idle task exists: {e}")
314
+ syslog(f"[ERR] Idle task exists: {e}")
297
315
  my_task.done.set()
298
316
 
299
317
  @staticmethod
300
- def create_task(callback, tag=None, loop=False, delay=None):
318
+ def create_task(callback, tag:str=None, loop:bool=False, delay:int=None) -> dict:
301
319
  """
302
- Primary interface
303
- Generic task creator method
304
- Create async Task with coroutine/list(lm call) callback
320
+ Primary interface of micrOS Generic task creator method
321
+ :param tag: task unique identifier
322
+ NativeTask:
323
+ :param callback: callable, coroutine to start a task
324
+ MagicTask with queue limiter:
325
+ :param callback: list of staring (command)
326
+ :param loop: MagicTask looping parameter
327
+ :param delay: MagicTask delay parameter
305
328
  """
306
329
  if isinstance(callback, list):
307
330
  # Check queue if task is Load Module
@@ -337,7 +360,7 @@ class Manager:
337
360
  _tasks = []
338
361
  tag_parts = tag.split('.')
339
362
  for t in TaskBase.TASKS:
340
- if t.startswith(tag_parts[0]) and len(tag_parts) > 1 and tag_parts[1] == '*':
363
+ if len(tag_parts) > 1 and t.startswith('.'.join(tag_parts[0:-1])) and tag_parts[-1] == '*':
341
364
  _tasks.append(t)
342
365
  if len(_tasks) == 0:
343
366
  return []
@@ -361,7 +384,7 @@ class Manager:
361
384
  return '\n'.join(output)
362
385
 
363
386
  @staticmethod
364
- def kill(tag):
387
+ def kill(tag:str) -> (bool, str):
365
388
  """
366
389
  Primary interface
367
390
  Kill/terminate async task
@@ -373,7 +396,7 @@ class Manager:
373
396
  try:
374
397
  return False if to_kill is None else to_kill.cancel()
375
398
  except Exception as e:
376
- errlog_add(f"[ERR] Task kill: {e}")
399
+ syslog(f"[ERR] Task kill: {e}")
377
400
  return False
378
401
 
379
402
  # Handle task group kill (module.*)
@@ -399,15 +422,23 @@ class Manager:
399
422
  try:
400
423
  asyncio.get_event_loop().run_forever()
401
424
  except Exception as e:
402
- errlog_add(f"[aio] loop stopped: {e}")
425
+ syslog(f"[aio] loop stopped: {e}")
403
426
  asyncio.get_event_loop().close()
404
427
 
405
428
  @staticmethod
406
- def server_task_msg(msg):
407
- server_task = TaskBase.TASKS.get('server', None)
408
- if server_task is None:
409
- return
410
- server_task.out = msg
429
+ def task_msg(tag:str, msg:str=None) -> bool|str:
430
+ """
431
+ Set/Get task message (for server virtual task, etc.)
432
+ """
433
+ _task = TaskBase.TASKS.get(tag, None)
434
+ if _task is None:
435
+ return False
436
+ # Get task output
437
+ if tag is None:
438
+ return _task.out
439
+ # Set task output
440
+ _task.out = msg
441
+ return True
411
442
 
412
443
 
413
444
  #################################################################
@@ -415,23 +446,40 @@ class Manager:
415
446
  #################################################################
416
447
  def exec_builtins(func):
417
448
  """
418
- Module execution built-in commands and modifiers
449
+ [Decorator] Module execution built-in commands and modifiers
419
450
  - modules - show active modules list
420
451
  - task kill ... - task termination
421
452
  show ... - task output dump
422
- - ... >json - postfix to "jsonize" the output
453
+ - ... >json - postfix to jsonify the output
423
454
  """
424
- def wrapper(arg_list, jsonify=None):
455
+ def wrapper(arg_list:list, jsonify=None):
425
456
  # Ensure the parameter is a list of strings
426
457
  if isinstance(arg_list, list) and arg_list:
427
- # JSONIFY: [1] >json in arg_list or [2] jsonify True/False
428
- json_flag = arg_list[-1] == '>json'
429
- if json_flag:
430
- arg_list = arg_list[:-1]
458
+ # Postfix operator handling
459
+ # ... >json - command output format option
460
+ # ... >>node01.local - intercon: command execution on remote device by hostname/IP address
461
+ arg_list, json_flag = (arg_list[:-1], True) if arg_list[-1] == '>json' else (arg_list, False)
431
462
  json_flag = jsonify if isinstance(jsonify, bool) else json_flag
463
+ arg_list, intercon_target = ((arg_list[:-1], arg_list[-1].replace(">>", ""))
464
+ if match(r'^>>[A-Za-z0-9._-]+$', arg_list[-1])
465
+ else (arg_list, None))
466
+
467
+ # INTERCONNECT
468
+ if intercon_target:
469
+ if Manager.INTERCON is None:
470
+ from InterConnect import send_cmd
471
+ Manager.INTERCON = send_cmd
472
+ try:
473
+ out = Manager.INTERCON(host=intercon_target, cmd=arg_list)
474
+ except Exception as e:
475
+ out = {}
476
+ syslog(f"[ERR] Intercon: {e}")
477
+ return True, out
478
+
432
479
  # MODULES
433
480
  if arg_list[0] == 'modules':
434
481
  return True, list((m.strip().replace('LM_', '') for m in modules if m.startswith('LM_'))) + ['task']
482
+
435
483
  # Handle task manipulation commands: list, kill, show - return True -> Command handled
436
484
  if 'task' == arg_list[0]:
437
485
  arg_len = len(arg_list)
@@ -439,22 +487,24 @@ def exec_builtins(func):
439
487
  if arg_len > 1 and 'list' == arg_list[1]:
440
488
  on, off = Manager.list_tasks(json=json_flag)
441
489
  # RETURN: JSON mode Human readable mode with cpu & queue info
442
- return (True, {'active': on[3:], 'inactive': off}) if json_flag else (True, '\n'.join(on) + '\n' + '\n'.join(off) + '\n')
490
+ return (True, dumps({'active': on[3:], 'inactive': off})) if json_flag else (True, '\n'.join(on) + '\n' + '\n'.join(off) + '\n')
443
491
  # task kill <taskID> / task show <taskID>
444
492
  if arg_len > 2:
445
493
  if 'kill' == arg_list[1]:
446
- state, msg = Manager.kill(tag=arg_list[2])
494
+ _, msg = Manager.kill(tag=arg_list[2])
447
495
  return True, msg
448
496
  if 'show' == arg_list[1]:
449
497
  return True, Manager.show(tag=arg_list[2])
450
498
  return True, "Invalid task cmd! Help: task list / kill <taskID> / show <taskID>"
499
+
451
500
  # Call the decorated function with the additional flag
452
501
  return func(arg_list, json_flag)
502
+ return False, None
503
+
453
504
  return wrapper
454
505
 
455
506
 
456
- @exec_builtins
457
- def lm_exec(arg_list, jsonify):
507
+ def lm_exec(arg_list:list, jsonify:bool=None):
458
508
  """
459
509
  Main LM executor function with
460
510
  - async (background)
@@ -474,21 +524,16 @@ def lm_exec(arg_list, jsonify):
474
524
  delay = int(delay) if delay.isdigit() else None
475
525
  # Create and start async lm task
476
526
  try:
477
- state = Manager.create_task(arg_list, loop=loop, delay=delay)
527
+ return True, Manager.create_task(arg_list, loop=loop, delay=delay)
478
528
  except Exception as e:
479
- # Valid & handled task command
480
- return True, str(e)
481
- tag = '.'.join(arg_list[0:2])
482
- # Valid & handled task command
483
- if state:
484
- return True, f"Start {tag}"
485
- return True, f"{tag} is Busy"
529
+ return False, {".".join(arg_list[0:2]): str(e)}
486
530
 
487
531
  # [2] Sync "realtime" task execution
488
532
  state, out = _exec_lm_core(arg_list, jsonify)
489
533
  return state, out
490
534
 
491
535
 
536
+ @exec_builtins
492
537
  def _exec_lm_core(cmd_list, jsonify):
493
538
  """
494
539
  [CORE] Single command executor: MODULE.FUNCTION...
@@ -497,7 +542,7 @@ def _exec_lm_core(cmd_list, jsonify):
497
542
  [2] function
498
543
  [3...] parameters (separator: space)
499
544
  :param jsonify: request json output
500
- Return Bool(OK/NOK), STR(Command output)
545
+ Return Bool(OK/NOK), Str(Command output)
501
546
  """
502
547
 
503
548
  def _func_params(param):
@@ -535,11 +580,12 @@ def _exec_lm_core(cmd_list, jsonify):
535
580
  # ------------ LM output format: dict(jsonify) / str(raw) ------------- #
536
581
  # Handle LM output data
537
582
  if isinstance(lm_output, dict):
538
- # json True: output->json else Format dict output "human readable"
583
+ # jsonify (True) json output, (False) default, "human readable" output)
539
584
  lm_output = dumps(lm_output) if jsonify else '\n'.join(
540
585
  [f" {key}: {value}" for key, value in lm_output.items()])
541
586
  if lm_func == 'help':
542
- # Special case for help command: json True: output->json else Format dict output "human readable"
587
+ # Special case:
588
+ # jsonify (True) json output, (False) default, "human readable" formatted output)
543
589
  lm_output = dumps(lm_output) if jsonify else '\n'.join([f" {out}," for out in lm_output])
544
590
  # Return LM exec result
545
591
  return True, str(lm_output)
@@ -549,7 +595,7 @@ def _exec_lm_core(cmd_list, jsonify):
549
595
  # UNLOAD MODULE IF MEMORY ERROR HAPPENED + gc.collect
550
596
  if lm_mod in modules:
551
597
  del modules[lm_mod]
552
- collect()
598
+ gcollect()
553
599
  # LM EXECUTION ERROR
554
600
  return False, f"Core error: {lm_mod}->{lm_func}: {e}"
555
601
  return False, "Shell: for hints type help.\nShell: for LM exec: [1](LM)module [2]function [3...]optional params"
@@ -580,13 +626,13 @@ def exec_lm_pipe(taskstr):
580
626
  return True
581
627
  # Execute individual commands - msgobj->"/dev/null"
582
628
  for cmd in (cmd.strip().split() for cmd in taskstr.split(';') if len(cmd) > 0):
583
- if len(cmd) > 0 and cmd[0].startswith("#"):
629
+ if cmd[0].startswith("#"):
584
630
  console_write(f"[SKIP] exec_lm_pipe: {' '.join(cmd)}")
585
- return True
631
+ continue
586
632
  if not lm_exec(cmd)[0]:
587
- errlog_add(f"[WARN] exec_lm_pipe: {cmd}")
633
+ syslog(f"[WARN] exec_lm_pipe: {' '.join(cmd)}")
588
634
  except Exception as e:
589
- errlog_add(f"[ERR] exec_lm_pipe {taskstr}: {e}")
635
+ syslog(f"[ERR] exec_lm_pipe {taskstr}: {e}")
590
636
  return False
591
637
  return True
592
638
 
@@ -599,5 +645,5 @@ def exec_lm_pipe_schedule(taskstr):
599
645
  schedule(exec_lm_pipe, taskstr)
600
646
  return True
601
647
  except Exception as e:
602
- errlog_add(f"[ERR] exec_lm_pipe_schedule: {e}")
648
+ syslog(f"[ERR] exec_lm_pipe_schedule: {e}")
603
649
  return False
micrOS/source/Time.py CHANGED
@@ -14,27 +14,29 @@ from network import WLAN, STA_IF
14
14
  from utime import sleep_ms, time, mktime, localtime
15
15
 
16
16
  from Config import cfgput, cfgget
17
- from Debug import errlog_add, console_write
17
+ from Debug import syslog, console_write
18
18
  from urequests import get as http_get
19
+ from Files import OSPath, path_join
19
20
 
20
21
 
21
22
  class Sun:
22
23
  TIME = {}
23
24
  UTC = cfgget('utc') # STORED IN MINUTE
24
25
  BOOTIME = None # Initialize BOOTIME: Not SUN, but for system uptime
26
+ FILE_CACHE = path_join(OSPath.DATA, 'sun.cache')
25
27
 
26
28
 
27
- def set_time(year, month, mday, hour, min, sec):
29
+ def set_time(year, month, mday, hour, minute, sec):
28
30
  """
29
31
  Set Localtime + RTC Clock manually + update BOOTIME/uptime
30
32
  https://docs.micropython.org/en/latest/library/machine.RTC.html
31
33
  """
32
34
  # Make time from tuple to sec
33
- time_sec = mktime((year, month, mday, hour, min, sec, 0, 0))
35
+ time_sec = mktime((year, month, mday, hour, minute, sec, 0, 0))
34
36
  # Set localtime
35
37
  localtime(time_sec)
36
38
  # Set RTC
37
- RTC().datetime((year, month, mday, 0, hour, min, sec, 0))
39
+ RTC().datetime((year, month, mday, 0, hour, minute, sec, 0))
38
40
  # (re)set uptime when settime - normally at boot time
39
41
  if Sun.BOOTIME is None:
40
42
  Sun.BOOTIME = time()
@@ -47,7 +49,7 @@ def ntp_time():
47
49
  :return: ntp date struct
48
50
  """
49
51
  if not WLAN(STA_IF).isconnected():
50
- errlog_add("STA not connected: ntptime")
52
+ syslog("[WARN] STA not connected: ntptime")
51
53
  return False
52
54
 
53
55
  def get_ntp():
@@ -83,31 +85,30 @@ def ntp_time():
83
85
  console_write(f"ntptime error.:{e}")
84
86
  err = e
85
87
  sleep_ms(100)
86
- errlog_add(f"[ERR] ntptime: {err}")
88
+ syslog(f"[ERR] ntptime: {err}")
87
89
  return False
88
90
 
89
91
 
90
92
  def __sun_cache(mode):
91
93
  """
92
- pds - persistent data structure
94
+ File cache
93
95
  modes:
94
96
  r - recover, s - save
95
97
  """
96
98
  if mode == 's':
97
99
  # SAVE CACHE
98
- temp = {}
99
100
  try:
100
- with open('sun.pds', 'w') as f:
101
- for k, v in Sun.TIME.items():
102
- temp[k] = tuple([str(t) for t in v])
103
- f.write(';'.join([f'{k}:{"-".join(v)}' for k, v in temp.items()]))
101
+ with open(Sun.FILE_CACHE, 'w') as f:
102
+ cache = {k:tuple([str(t) for t in v]) for k, v in Sun.TIME.items()}
103
+ f.write(';'.join([f'{k}:{"-".join(v)}' for k, v in cache.items()]))
104
104
  except:
105
- errlog_add("[ERR] Cannot write sun cache")
105
+ syslog("[ERR] Cannot write sun cache")
106
106
  return
107
107
  try:
108
108
  # RESTORE CACHE
109
- with open('sun.pds', 'r') as f:
110
- buff = {data.split(':')[0]: data.split(':')[1].split('-') for data in f.read().strip().split(';')}
109
+ with open(Sun.FILE_CACHE, 'r') as f:
110
+ buff = {data.split(':')[0]: data.split(':')[1].split('-')
111
+ for data in f.read().strip().split(';')}
111
112
  for k, v in buff.items():
112
113
  Sun.TIME[k] = tuple([int(e) for e in v])
113
114
  except:
@@ -140,7 +141,7 @@ def suntime():
140
141
  Sun.UTC = int(response.get('offset') / 60) # IN MINUTE
141
142
  cfgput('utc', Sun.UTC, True)
142
143
  except Exception as e:
143
- errlog_add(f'[ERR] ip-api: {e} data: {response}')
144
+ syslog(f'[ERR] ip-api: {e} data: {response}')
144
145
  return Sun.TIME
145
146
 
146
147
  # SUNSET-SUNRISE API REQUEST HANDLING
@@ -155,7 +156,7 @@ def suntime():
155
156
  sun = {'sunrise': time_regex.search(results.get('sunrise')).group(1).split(':'),
156
157
  'sunset': time_regex.search(results.get('sunset')).group(1).split(':')}
157
158
  except Exception as e:
158
- errlog_add(f'[ERR] sunrise-api: {e} data: {response}')
159
+ syslog(f'[ERR] sunrise-api: {e} data: {response}')
159
160
  # Try to parse response by expected sun_keys
160
161
  try:
161
162
  for key in sun:
@@ -163,7 +164,7 @@ def suntime():
163
164
  sun[key][0] += int(Sun.UTC / 60)
164
165
  sun[key] = tuple(sun[key])
165
166
  except Exception as e:
166
- errlog_add(f'sunrise-api parse error: {e} sun: {sun}')
167
+ syslog(f'[WARN] sunrise-api parse error: {e} sun: {sun}')
167
168
  # Retrieve cached data and return
168
169
  __sun_cache('r') # Using Sun.TIME
169
170
  console_write('[suntime] loaded from cache')