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,37 +1,52 @@
1
1
  from sys import modules
2
- import uasyncio as asyncio
3
2
  import urequests
4
3
  from Notify import Notify
5
- from Config import cfgget
6
- from Common import micro_task, syslog, console_write
4
+ from Common import micro_task, syslog, console_write, data_dir, conf_dir
7
5
  from LM_system import ifconfig
6
+ from utime import localtime
7
+
8
+
9
+ def _timestamp():
10
+ _time = [str(k) for k in localtime()[3:6]]
11
+ return ':'.join(_time)
8
12
 
9
13
 
10
14
  class Telegram(Notify):
15
+ INSTANCE = None
11
16
  # Telegram bot token and chat ID
12
17
  # https://core.telegram.org/bots/api
13
18
  _TOKEN = None # Telegram token
14
19
  _CHAT_IDS = set() # Telegram bot chat IDs - multi group support - persistent caching
15
20
  _API_PARAMS = "?offset=-1&limit=1&timeout=2" # Generic API params - optimization
16
21
  _IN_MSG_ID = None
22
+ _FILE_CACHE = data_dir('telegram.cache')
23
+
24
+ def __init__(self, token:str):
25
+ """
26
+ :param token: bot token
27
+ """
28
+ # Subscribe to the notification system - provide send_msg method (over self)
29
+ super().add_subscriber(self)
30
+ Telegram._TOKEN = token
31
+ Telegram.INSTANCE = self
17
32
 
18
33
  @staticmethod
19
- def __id_cache(mode):
34
+ def __id_cache(mode:str):
20
35
  """
21
- pds - persistent data structure
36
+ File cache
22
37
  modes:
23
38
  r - recover, s - save
24
39
  """
25
40
  if mode == 's':
26
41
  # SAVE CACHE
27
42
  console_write("[NTFY] Save chatIDs cache...")
28
- with open('telegram.pds', 'w') as f:
43
+ with open(Telegram._FILE_CACHE, 'w') as f:
29
44
  f.write(','.join([str(k) for k in Telegram._CHAT_IDS]))
30
45
  return
31
46
  try:
32
47
  # RESTORE CACHE
33
48
  console_write("[NTFY] Restore chatIDs cache...")
34
- with open('telegram.pds', 'r') as f:
49
+ with open(Telegram._FILE_CACHE, 'r') as f:
35
50
  # set() comprehension
36
51
  Telegram._CHAT_IDS = {int(k) for k in f.read().strip().split(',')}
37
52
  except:
@@ -41,14 +56,11 @@ class Telegram(Notify):
41
56
  def __bot_token():
42
57
  """Get bot token"""
43
58
  if Telegram._TOKEN is None:
44
- token = cfgget('telegram')
45
- if token is None or token == 'n/a':
46
- return None
47
- Telegram._TOKEN = token
59
+ return None
48
60
  return Telegram._TOKEN
49
61
 
50
62
  @staticmethod
51
- def send_msg(text, reply_to=None, chat_id=None):
63
+ def send_msg(text:str, *args, **kwargs):
52
64
  """
53
65
  Send a message to the Telegram chat by chat_id
54
66
  :param text: text to send
@@ -56,6 +68,8 @@ class Telegram(Notify):
56
68
  :param chat_id: chat_id to reply on, if None, reply to all known
57
69
  RETURN None when telegram bot token is missing
58
70
  """
71
+ reply_to = kwargs.get("reply_to", args[0] if len(args) > 0 else None)
72
+ chat_id = kwargs.get("chat_id", args[1] if len(args) > 1 else None)
59
73
 
60
74
  def _send(chid):
61
75
  """Send message to chat_id (chid)"""
@@ -97,79 +111,104 @@ class Telegram(Notify):
97
111
  verdict = f'Sent{chat_id}' if resp_json['ok'] else str(resp_json)
98
112
  return verdict
99
113
 
114
+ @staticmethod
115
+ def __update_chat_ids(resp_json:dict):
116
+ """
117
+ Update known chat_id-s and cache them
118
+ - return active chat_id frm resp_json
119
+ """
120
+ _cid = None
121
+ if resp_json.get("ok", None) and len(resp_json["result"]) > 0:
122
+ _cid = resp_json["result"][-1]["message"]["chat"]["id"]
123
+ # LIMIT Telegram._CHAT_IDS NOTIFICATION CACHE TO 3 IDs
124
+ if len(Telegram._CHAT_IDS) < 4 and _cid not in Telegram._CHAT_IDS:
125
+ console_write("[NTFY GET] update chatIDs")
126
+ _ids = len(Telegram._CHAT_IDS)
127
+ Telegram._CHAT_IDS.add(_cid)
128
+ if len(Telegram._CHAT_IDS) - _ids > 0: # optimized save (slow storage access)
129
+ Telegram.__id_cache('s')
130
+ else:
131
+ Telegram.__id_cache('r')
132
+ if len(Telegram._CHAT_IDS) == 0:
133
+ error_message = resp_json.get("description", "Unknown error")
134
+ raise Exception(f"Error retrieving chat ID: {error_message}")
135
+ return _cid
136
+
100
137
  @staticmethod
101
138
  def get_msg():
102
139
  """
103
140
  Get the last message from the Telegram chat.
104
141
  RETURN None when telegram bot token is missing
105
142
  """
143
+ console_write("[NTFY] GET MESSAGE")
144
+ bot_token = Telegram.__bot_token()
145
+ if bot_token is None:
146
+ return None
147
+ response = {'sender': None, 'text': None, 'm_id': -1, 'c_id': None}
148
+ url = f"https://api.telegram.org/bot{bot_token}/getUpdates{Telegram._API_PARAMS}"
149
+ console_write(f"\t[GET] request: {url}")
106
150
 
107
- def _update_chat_ids():
108
- """
109
- Update known chat_id-s and cache them
110
- - return active chat_id frm resp_json
111
- """
112
- console_write("[NTFY GET] update chatIDs")
113
- _cid = None
114
- if resp_json.get("ok", None) and len(resp_json["result"]) > 0:
115
- _cid = resp_json["result"][-1]["message"]["chat"]["id"]
116
- # LIMIT Telegram._CHAT_IDS NOTIFICATION CACHE TO 3 IDs
117
- if len(Telegram._CHAT_IDS) < 4:
118
- _ids = len(Telegram._CHAT_IDS)
119
- Telegram._CHAT_IDS.add(_cid)
120
- if len(Telegram._CHAT_IDS) - _ids > 0: # optimized save (slow storage access)
121
- Telegram.__id_cache('s')
122
- else:
123
- Telegram.__id_cache('r')
124
- if len(Telegram._CHAT_IDS) == 0:
125
- error_message = resp_json.get("description", "Unknown error")
126
- raise Exception(f"Error retrieving chat ID: {error_message}")
127
- return _cid
151
+ _, resp_json = urequests.get(url, jsonify=True, sock_size=128)
128
152
 
129
- # --------------------- FUNCTION MAIN ------------------------ #
153
+ if len(resp_json["result"]) > 0:
154
+ response['c_id'] = Telegram.__update_chat_ids(resp_json)
155
+ resp = resp_json["result"][-1]["message"]
156
+ response['sender'] = f"{resp['chat']['first_name']}{resp['chat']['last_name']}" if resp['chat'].get(
157
+ 'username', None) is None else resp['chat']['username']
158
+ response['text'], response['m_id'] = resp['text'], resp['message_id']
159
+ console_write(f"\t\t[GET] response: {response}")
160
+ return response
161
+
162
+ @staticmethod
163
+ async def aget_msg():
164
+ """
165
+ Async: Get the last message from the Telegram chat.
166
+ RETURN None when telegram bot token is missing
167
+ """
130
168
  console_write("[NTFY] GET MESSAGE")
131
169
  bot_token = Telegram.__bot_token()
132
170
  if bot_token is None:
133
171
  return None
134
172
  response = {'sender': None, 'text': None, 'm_id': -1, 'c_id': None}
135
173
  url = f"https://api.telegram.org/bot{bot_token}/getUpdates{Telegram._API_PARAMS}"
136
- console_write(f"\t1/2[GET] request: {url}")
137
- _, resp_json = urequests.get(url, jsonify=True, sock_size=128)
174
+ console_write(f"\t[aGET] request: {url}")
175
+
176
+ _, resp_json = await urequests.aget(url, jsonify=True, sock_size=128)
177
+
138
178
  if len(resp_json["result"]) > 0:
139
- response['c_id'] = _update_chat_ids()
179
+ response['c_id'] = Telegram.__update_chat_ids(resp_json)
140
180
  resp = resp_json["result"][-1]["message"]
141
181
  response['sender'] = f"{resp['chat']['first_name']}{resp['chat']['last_name']}" if resp['chat'].get(
142
182
  'username', None) is None else resp['chat']['username']
143
183
  response['text'], response['m_id'] = resp['text'], resp['message_id']
144
- console_write(f"\t2/2[GET] response: {response}")
184
+ console_write(f"\t\t[aGET] response: {response}")
145
185
  return response
146
186
 
147
187
  @staticmethod
148
- def receive_eval():
188
+ async def receive_eval():
149
189
  """
150
190
  READ - VALIDATE - EXECUTE - REPLY LOOP
151
191
  - can be used in async loop
152
192
  RETURN None when telegram bot token is missing
153
193
  """
154
-
155
- console_write("[NTFY] REC&EVAL sequence")
156
-
157
- # Return data structure template
194
+ console_write("[NTFY] EVAL sequence")
158
195
  verdict = None
159
196
 
160
- def lm_execute(cmd_args):
197
+ def _lm_execute(cmd_args):
161
198
  nonlocal verdict, m_id
162
- access, output = Telegram.lm_execute(cmd_args)
199
+ status, output = Telegram.lm_execute(cmd_args)
200
+ access = "NotAllowed" not in str(output)
201
+ status = "OK" if status else "NOK"
163
202
  if access:
164
- verdict = f'[UP] Exec: {" ".join(cmd_args[0])}'
203
+ verdict = f'{_timestamp()} [UP][{status}] Exec: {" ".join(cmd_args[0])}'
165
204
  Telegram.send_msg(output, reply_to=m_id)
166
205
  else:
167
- verdict = f'[UP] NoAccess: {cmd_args[0]}'
206
+ verdict = f'{_timestamp()} [UP][{status}] NoAccess: {cmd_args[0]}'
168
207
  Telegram._IN_MSG_ID = m_id
169
208
 
170
209
  # -------------------------- FUNCTION MAIN -------------------------- #
171
- # Poll telegram chat
172
- data = Telegram.get_msg()
210
+ # Async Poll telegram chat
211
+ data = await Telegram.aget_msg()
173
212
  if data is None:
174
213
  return data
175
214
  # Get msg, msg_id, chat_id as main input data source
@@ -185,24 +224,54 @@ class Telegram(Notify):
185
224
  cmd_lm = msg_in.strip().split()[1:]
186
225
  # [Compare] cmd selected device param with DEVFID (device/prompt name)
187
226
  if cmd_lm[0] in Telegram._DEVFID:
188
- lm_execute(cmd_lm[1:])
227
+ _lm_execute(cmd_lm[1:])
189
228
  else:
190
- verdict = f'[UP] NoSelected: {cmd_lm[0]}'
229
+ verdict = f'{_timestamp()} [UP] NoSelected: {cmd_lm[0]}'
191
230
  elif msg_in.startswith('/cmd'):
192
231
  cmd_lm = msg_in.strip().split()[1:]
193
- lm_execute(cmd_lm)
232
+ _lm_execute(cmd_lm)
194
233
  elif msg_in.startswith('/notify'):
195
234
  param = msg_in.strip().split()[1:]
196
235
  if len(param) > 0:
197
236
  verdict = Telegram.notifications(not param[0].strip().lower() in ("disable", "off", 'false'))
198
237
  else:
199
238
  verdict = Telegram.notifications()
239
+ # Send is still synchronous (OK)
200
240
  Telegram.send_msg(verdict, reply_to=m_id)
201
241
  else:
202
- verdict = "[UP] NoExec"
203
- console_write(f"\tREC&EVAL: {verdict}")
242
+ verdict = f"{_timestamp()} [UP] NoExec"
204
243
  return verdict
205
244
 
245
+ @staticmethod
246
+ async def server_bot(tag:str, period:int=3):
247
+ """
248
+ BOT - ReceiveEvalPrintLoop
249
+ :param tag: task tag (access)
250
+ :param period: polling period in sec, default: 3
251
+ """
252
+ cancel_cnt = 0
253
+ period = period if period > 0 else 1
254
+ period_ms = period * 1000
255
+ with micro_task(tag=tag) as my_task:
256
+ my_task.out = f"{_timestamp()} [UP] Running"
257
+ while True:
258
+ # Normal task period
259
+ await my_task.feed(sleep_ms=period_ms)
260
+ try:
261
+ # await asyncio.wait_for(Telegram.receive_eval(), 5) # 5 sec timeout???
262
+ v = await Telegram.receive_eval()
263
+ my_task.out = "Missing bot token" if v is None else f"{v} ({period}s)"
264
+ cancel_cnt = 0
265
+ except Exception as e:
266
+ my_task.out = str(e)
267
+ # Auto scale - blocking nature - in case of serial failures (5) - hibernate task (increase async sleep)
268
+ cancel_cnt += 1
269
+ if cancel_cnt > 5:
270
+ my_task.out = f"{_timestamp()} [DOWN] {e} (wait 1min)"
271
+ cancel_cnt = 5
272
+ # SLOW DOWN - hibernate task
273
+ await my_task.feed(sleep_ms=60_000)
274
+
206
275
  @staticmethod
207
276
  def set_commands():
208
277
  """
@@ -228,57 +297,58 @@ class Telegram(Notify):
228
297
  #########################################
229
298
  # micrOS Notifications #
230
299
  #########################################
231
- TELEGRAM_OBJ = None
232
300
 
233
- def __init():
234
- global TELEGRAM_OBJ
235
- if TELEGRAM_OBJ is None:
301
+ def __init(token:str=None):
302
+ token_cache = conf_dir("telegram.token")
303
+ token_refresh = True
304
+ if Telegram.INSTANCE is None:
236
305
  # ENABLE TELEGRAM IF NW IS STA - CONNECTED TO THE WEB
237
- _sta_available = True if ifconfig()[0] == "STA" else False
238
- if _sta_available:
239
- TELEGRAM_OBJ = Telegram()
240
- Notify.add_subscriber(TELEGRAM_OBJ)
306
+ if ifconfig()[0] == "STA":
307
+ if token is None:
308
+ token_refresh = False
309
+ # Attempt to load token from config folder
310
+ try:
311
+ with open(token_cache, "r") as f:
312
+ token = f.read()
313
+ except Exception as e:
314
+ err = f"Telegram: cannot load {token_cache}: {e}"
315
+ syslog(err)
316
+ raise Exception(err)
317
+ # Initialize telegram with token
318
+ Telegram(token)
319
+ if token_refresh:
320
+ # Save token
321
+ with open(token_cache, "w") as f:
322
+ f.write(token)
241
323
  else:
242
324
  syslog("No STA: cannot init telegram")
325
+ return Telegram.INSTANCE
243
326
 
244
- # Auto INIT Telegram at load time (legacy)
245
- __init()
246
327
 
247
- def load():
328
+ def load(token:str=None):
248
329
  """
249
330
  Set custom chat commands for Telegram
250
331
  - /ping
251
332
  - /cmd module function (params)
333
+ :param token: telegram bot token
252
334
  """
253
- __init()
254
- if TELEGRAM_OBJ is None:
335
+ if __init(token) is None:
255
336
  return "Network unavailable."
256
- verdict = TELEGRAM_OBJ.set_commands()
337
+ verdict = Telegram.set_commands()
257
338
  return "Missing telegram bot token" if verdict is None else verdict
258
339
 
259
340
 
260
- def send(text):
341
+ def send(text:str):
261
342
  """
262
343
  Send Telegram message - micrOS notification
263
344
  :param text: text to send
264
345
  return verdict
265
346
  """
266
- if TELEGRAM_OBJ is None:
347
+ if Telegram.INSTANCE is None:
267
348
  return "Network unavailable."
268
- verdict = TELEGRAM_OBJ.send_msg(text)
349
+ verdict = Telegram.send_msg(text)
269
350
  return "Missing telegram bot token" if verdict is None else verdict
270
351
 
271
- def notify(text):
272
- """
273
- Notify function with system global enable/disable function
274
- Control with:
275
- telegram notification enable=True
276
- telegram notification enable=False
277
- """
278
- if TELEGRAM_OBJ is None:
279
- return "Network unavailable."
280
- return TELEGRAM_OBJ.notify(text)
281
-
282
352
 
283
353
  def receive():
284
354
  """
@@ -286,44 +356,22 @@ def receive():
286
356
  - if all value None, then no incoming messages
287
357
  One successful msg receive is necessary to get chat_id for msg send as well!
288
358
  """
289
- if TELEGRAM_OBJ is None:
359
+ if Telegram.INSTANCE is None:
290
360
  return "Network unavailable."
291
- verdict = TELEGRAM_OBJ.get_msg()
361
+ verdict = Telegram.get_msg()
292
362
  return "Missing telegram bot token" if verdict is None else verdict
293
363
 
294
364
 
295
- async def __task():
296
- cancel_cnt = 0
297
- with micro_task(tag='telegram._loop') as my_task:
298
- my_task.out = "[UP] Running"
299
- while True:
300
- # Normal task period
301
- await asyncio.sleep(5)
302
- try:
303
- v = TELEGRAM_OBJ.receive_eval()
304
- my_task.out = "Missing bot token" if v is None else v
305
- cancel_cnt = 0
306
- except Exception as e:
307
- my_task.out = str(e)
308
- # Auto scale - blocking nature - in case of serial failures (5) - hibernate task (increase async sleep)
309
- cancel_cnt += 1
310
- if cancel_cnt > 5:
311
- my_task.out = f"[DOWN] {e}"
312
- cancel_cnt = 5
313
- # SLOW DOWN - hibernate task
314
- asyncio.sleep(115)
315
-
316
-
317
- def receiver_loop():
365
+ def receiver_loop(period=3):
318
366
  """
319
- Telegram msg receiver loop - automatic LM execution
367
+ Telegram BOT (repl) - ReadEvalPrintLoop for Load Modules
320
368
  - Only executes module (function) if the module is already loaded
321
- on the endpoint / micrOS node
369
+ :param period: polling period in sec, default: 3
322
370
  """
323
- if TELEGRAM_OBJ is None:
324
- return "Network unavailable."
325
- state = micro_task(tag='telegram._loop', task=__task())
326
- return "Starting" if state else "Already running"
371
+ if Telegram.INSTANCE is None:
372
+ return "Network unavailable or Telegram uninitialized"
373
+ tag = 'telegram.server_bot'
374
+ return micro_task(tag=tag, task=Telegram.server_bot(tag=tag, period=period))
327
375
 
328
376
 
329
377
  def help(widgets=False):
@@ -335,6 +383,6 @@ def help(widgets=False):
335
383
  """
336
384
  return ('send "text"',
337
385
  'receive',
338
- 'receiver_loop',
339
- 'notify "message"',
340
- 'load', 'INFO: Send & Receive messages with Telegram bot')
386
+ 'receiver_loop period=3',
387
+ 'load token=<your-bot-token>',
388
+ 'INFO: Send & Receive messages with Telegram bot')
@@ -8,7 +8,7 @@ https://github.com/mchobby/esp8266-upy/blob/master/trackball/examples/test_color
8
8
  from utime import sleep, ticks_ms, ticks_diff
9
9
  from struct import unpack
10
10
  from machine import SoftI2C, Pin
11
- from microIO import resolve_pin, pinmap_search
11
+ from microIO import bind_pin, pinmap_search
12
12
  from Common import syslog
13
13
  from micropython import schedule
14
14
 
@@ -179,7 +179,7 @@ def load(width=100, height=100, irq_sampling=50, sensitivity=5, reload=False):
179
179
  """
180
180
  global TRACKBALL
181
181
  if TRACKBALL is None or reload:
182
- i2c = SoftI2C(scl=Pin(resolve_pin('i2c_scl')), sda=Pin(resolve_pin('i2c_sda')))
182
+ i2c = SoftI2C(scl=Pin(bind_pin('i2c_scl')), sda=Pin(bind_pin('i2c_sda')))
183
183
  TRACKBALL = Trackball(i2c, max_x=width, max_y=height, irq_sampling=irq_sampling, sensitivity=sensitivity)
184
184
  _craft_event_interrupt()
185
185
  ready_color()
@@ -253,7 +253,7 @@ def _craft_event_interrupt():
253
253
  syslog(f"[ERR] Trackball user callback: {e}")
254
254
 
255
255
  try:
256
- pin = resolve_pin("trackball_int")
256
+ pin = bind_pin("trackball_int")
257
257
  except Exception as e:
258
258
  pin = None
259
259
  syslog(f'[ERR] trackball_int IRQ: {e}')
@@ -5,7 +5,7 @@
5
5
  from machine import SoftI2C, Pin
6
6
  from time import sleep
7
7
  from micropython import const
8
- from microIO import resolve_pin, pinmap_search
8
+ from microIO import bind_pin, pinmap_search
9
9
  from Types import resolve
10
10
 
11
11
  # start const
@@ -134,7 +134,7 @@ def load():
134
134
  VEML7700 Digital light intensity sensor
135
135
  """
136
136
  if VEML7700.INSTANCE is None:
137
- i2c = SoftI2C(Pin(resolve_pin('i2c_scl')), Pin(resolve_pin('i2c_sda')))
137
+ i2c = SoftI2C(Pin(bind_pin('i2c_scl')), Pin(bind_pin('i2c_sda')))
138
138
  VEML7700.INSTANCE = VEML7700(address=0x10, i2c=i2c, it=100, gain=1/8)
139
139
  return VEML7700.INSTANCE
140
140
 
@@ -0,0 +1,38 @@
1
+ """
2
+ Web backend loader
3
+ - Dynamic application dashboard
4
+ - Fileserver
5
+ """
6
+
7
+ from Common import web_endpoint, web_mounts
8
+
9
+
10
+ def load(dashboard=True, fileserver:bool=False, fs_explore:bool=False):
11
+ """
12
+ Centralized Web Backend Services Loader
13
+ - Dynamic application dashboard
14
+ - Fileserver
15
+ :param dashboard: bool - enable*/disable application dashboard
16
+ :param fileserver: bool - enable/disable* fileserver
17
+ :param fs_explore: bool - enable all shared web mounts: modules, data
18
+ """
19
+ endpoints = []
20
+ if dashboard:
21
+ web_endpoint('dashboard', 'dashboard.html')
22
+ endpoints.append("Dashboard initialized, endpoint: /dashboard")
23
+ if fileserver:
24
+ import LM_fileserver
25
+ endpoints.append(LM_fileserver.load())
26
+ endpoints.append(web_mounts(fs_explore, fs_explore, fs_explore))
27
+ return endpoints
28
+
29
+
30
+ def help(widgets=False):
31
+ """
32
+ [i] micrOS LM naming convention - built-in help message
33
+ :return tuple:
34
+ (widgets=False) list of functions implemented by this application
35
+ (widgets=True) list of widget json for UI generation
36
+ """
37
+ return ('load dashboard=True fileserver=False fsdir=None fs_explore=False',
38
+ 'help')
@@ -1,10 +1,17 @@
1
+ """
2
+ This module implements an optimized version of requests module
3
+ for async and sync http get and post requests.
4
+
5
+ Designed by Marcell Ban aka BxNxM GitHub
6
+ """
7
+
8
+ from json import loads, dumps
1
9
  from usocket import socket, getaddrinfo
2
10
  try:
3
- from ussl import wrap_socket # Legacy micropython ssl usage
11
+ from ussl import wrap_socket # Legacy micropython ssl usage (+simulator mode)
4
12
  except ImportError:
5
13
  from ssl import wrap_socket # From micropython 1.23...
6
- from json import loads, dumps
7
- from Debug import errlog_add
14
+ from Debug import syslog
8
15
  import uasyncio as asyncio
9
16
 
10
17
 
@@ -39,7 +46,7 @@ def _chunked(_body):
39
46
  chunk_size_str = _body[:line_end]
40
47
  try:
41
48
  chunk_size = int(chunk_size_str, 16)
42
- except ValueError as e:
49
+ except ValueError:
43
50
  chunk_size = 0
44
51
 
45
52
  # Check chunk size
@@ -109,7 +116,7 @@ def _parse_response(response):
109
116
  # micropython HTTP request #
110
117
  #############################################
111
118
 
112
- def request(method, url, data=None, json=None, headers=None, sock_size=256, jsonify=False):
119
+ def request(method:str, url:str, data:str=None, json=None, headers:dict=None, sock_size=256, jsonify=False):
113
120
  """
114
121
  Micropython syncronous HTTP request function for REST API handling
115
122
  :param method: GET/POST
@@ -140,7 +147,7 @@ def request(method, url, data=None, json=None, headers=None, sock_size=256, json
140
147
  try:
141
148
  sock = wrap_socket(sock) if proto == 'https:' else sock
142
149
  except Exception as e:
143
- errlog_add(f'[ERR] https soc-wrap: {e}')
150
+ syslog(f'[ERR] https soc-wrap: {e}')
144
151
 
145
152
  # [1] BUILD REQUEST
146
153
  http_request = _build_request(host, method, path, headers, data, json)
@@ -174,7 +181,7 @@ def request(method, url, data=None, json=None, headers=None, sock_size=256, json
174
181
  # async micropython HTTP request #
175
182
  #############################################
176
183
 
177
- async def arequest(method, url, data=None, json=None, headers=None, sock_size=256, jsonify=False):
184
+ async def arequest(method:str, url:str, data:str=None, json=None, headers:dict=None, sock_size=256, jsonify=False):
178
185
  """
179
186
  Micropython asynchronous HTTP request function for REST API handling
180
187
  :param method: GET/POST
@@ -190,10 +197,19 @@ async def arequest(method, url, data=None, json=None, headers=None, sock_size=25
190
197
  addr = _host_to_addr(host, port)
191
198
  reader, writer = None, None
192
199
 
200
+ # Open a connection
193
201
  try:
194
- # Open a connection
195
202
  reader, writer = await asyncio.open_connection(addr[0], port, ssl=(proto == 'https:'))
203
+ except Exception as e:
204
+ # Refresh host address & reconnect
205
+ if "EHOSTUNREACH" in str(e):
206
+ addr = _host_to_addr(host, port, force=True)
207
+ reader, writer = await asyncio.open_connection(addr[0], port, ssl=(proto == 'https:'))
208
+ else:
209
+ syslog(f"[ERR] arequest connection: {e}")
196
210
 
211
+ # Send request + Wait for the response
212
+ try:
197
213
  # Build the HTTP request
198
214
  http_request = _build_request(host, method, path, headers, data, json)
199
215
 
@@ -213,8 +229,14 @@ async def arequest(method, url, data=None, json=None, headers=None, sock_size=25
213
229
  status_code, body = _parse_response(response)
214
230
  except Exception as e:
215
231
  status_code = 500
216
- body = f'[ERR] arequest failed: {e}'
217
- errlog_add(body)
232
+ # https://github.com/micropython/micropython/blob/8785645a952c03315dbf93667b5f7c7eec49762f/cc3200/simplelink/include/device.h
233
+ if "-104" == str(e):
234
+ body = "[WARN] arequest: ASSOC_REJECT"
235
+ elif "ECONNABORTED" in str(e):
236
+ body = f"[WARN] arequest: {e}"
237
+ else:
238
+ body = f"[ERR] arequest: {e}"
239
+ syslog(body)
218
240
  finally:
219
241
  if writer:
220
242
  writer.close()
@@ -226,14 +248,16 @@ async def arequest(method, url, data=None, json=None, headers=None, sock_size=25
226
248
  # Implement http get/post functions #
227
249
  #############################################
228
250
 
229
- def get(url, headers={}, sock_size=256, jsonify=False):
251
+ def get(url:str, headers:dict=None, sock_size=256, jsonify=False):
230
252
  """
231
253
  GENERIC HTTP GET FUNCTION
232
254
  """
255
+ if headers is None:
256
+ headers = {}
233
257
  return request('GET', url, headers=headers, sock_size=sock_size, jsonify=jsonify)
234
258
 
235
259
 
236
- def post(url, data=None, json=None, headers={}, sock_size=256, jsonify=False):
260
+ def post(url:str, data=None, json=None, headers:dict=None, sock_size=256, jsonify=False):
237
261
  """
238
262
  GENERIC HTTP POST FUNCTION
239
263
  :param data: string body (handle bare string as data for POST method)
@@ -242,14 +266,14 @@ def post(url, data=None, json=None, headers={}, sock_size=256, jsonify=False):
242
266
  return request('POST', url, data=data, json=json, headers=headers, sock_size=sock_size, jsonify=jsonify)
243
267
 
244
268
 
245
- async def aget(url, headers={}, sock_size=256, jsonify=False):
269
+ async def aget(url:str, headers:dict=None, sock_size=256, jsonify=False):
246
270
  """
247
271
  GENERIC ASYNC HTTP GET FUNCTION
248
272
  """
249
273
  return await arequest('GET', url, headers=headers, sock_size=sock_size, jsonify=jsonify)
250
274
 
251
275
 
252
- async def apost(url, data=None, json=None, headers={}, sock_size=256, jsonify=False):
276
+ async def apost(url, data=None, json=None, headers:dict=None, sock_size=256, jsonify=False):
253
277
  """
254
278
  GENERIC ASYNC HTTP POST FUNCTION
255
279
  :param data: string body (handle bare string as data for POST method)
@@ -258,7 +282,7 @@ async def apost(url, data=None, json=None, headers={}, sock_size=256, jsonify=Fa
258
282
  return await arequest('POST', url, data=data, json=json, headers=headers, sock_size=sock_size, jsonify=jsonify)
259
283
 
260
284
 
261
- def host_cache():
285
+ def host_cache() -> dict:
262
286
  """
263
287
  Return address cache
264
288
  """
@@ -38,6 +38,9 @@
38
38
  </head>
39
39
  <body>
40
40
  <h1> micrOS dashboard </h1>
41
+ <div id="restInfo">
42
+ <div id="restInfoHeader"></div>
43
+ </div>
41
44
  <!-- Container for the dynamically generated list -->
42
45
  <section id="widgets-section"></section>
43
46
  <br><br><br>
@@ -54,6 +57,7 @@
54
57
  <script>
55
58
  document.addEventListener("DOMContentLoaded", function() {
56
59
  // Init basic info from board after DOM is fully loaded
60
+ restInfo(showPages=false);
57
61
 
58
62
  // INIT DASHBOARD (load active modules -> build page)
59
63
  DynamicWidgetLoad();