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.
- env/driver_cp210x/macOS_VCP_Driver/SiLabsUSBDriverDisk.dmg +0 -0
- env/driver_cp210x/macOS_VCP_Driver/macOS_VCP_Driver_Release_Notes.txt +17 -1
- micrOS/micropython/esp32-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/esp32c3-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/esp32c6-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/esp32s2-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/esp32s2-LOLIN_MINI-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/{esp32s3-20241129-v1.24.1.bin → esp32s3-4MBflash-20241129-v1.24.1.bin} +0 -0
- micrOS/micropython/esp32s3-8MBflash-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/esp32s3_spiram_oct-20251209-v1.27.0.bin +0 -0
- micrOS/micropython/rpi-pico-w-20251209-v1.27.0.uf2 +0 -0
- micrOS/micropython/tinypico-20251209-v1.27.0.bin +0 -0
- micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +167 -163
- micrOS/source/Auth.py +37 -0
- micrOS/source/Common.py +361 -116
- micrOS/source/Config.py +32 -22
- micrOS/source/Debug.py +50 -94
- micrOS/source/Espnow.py +377 -100
- micrOS/source/Files.py +207 -0
- micrOS/source/Hooks.py +48 -20
- micrOS/source/InterConnect.py +126 -42
- micrOS/source/Interrupts.py +6 -6
- micrOS/source/Logger.py +63 -26
- micrOS/source/Network.py +41 -21
- micrOS/source/Notify.py +48 -22
- micrOS/source/Pacman.py +326 -0
- micrOS/source/Scheduler.py +14 -54
- micrOS/source/Server.py +67 -69
- micrOS/source/Shell.py +99 -91
- micrOS/source/Tasks.py +141 -95
- micrOS/source/Time.py +19 -18
- micrOS/source/Types.py +53 -9
- micrOS/source/Web.py +381 -76
- micrOS/source/__pycache__/Common.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Debug.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Files.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Logger.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Scheduler.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Server.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/Shell.cpython-312.pyc +0 -0
- micrOS/source/__pycache__/replhelper.cpython-312.pyc +0 -0
- micrOS/source/config/_git.keep +0 -0
- micrOS/source/helpers.py +132 -0
- micrOS/source/micrOS.py +17 -7
- micrOS/source/micrOSloader.py +5 -12
- micrOS/source/microIO.py +44 -20
- micrOS/source/modules/IO_esp32c6.py +38 -0
- micrOS/source/{IO_esp32s3.py → modules/IO_esp32s3.py} +37 -1
- micrOS/source/{IO_m5stamp.py → modules/IO_m5stamp.py} +35 -1
- micrOS/source/{IO_qtpy.py → modules/IO_qtpy.py} +22 -17
- micrOS/source/{IO_tinypico.py → modules/IO_tinypico.py} +38 -0
- micrOS/source/modules/LM_L298N.py +161 -0
- {toolkit/workspace/precompiled → micrOS/source/modules}/LM_L9110_DCmotor.py +3 -3
- micrOS/source/{LM_OV2640.py → modules/LM_OV2640.py} +45 -27
- micrOS/source/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +3 -3
- micrOS/source/{LM_aht10.py → modules/LM_aht10.py} +2 -2
- micrOS/source/{LM_bme280.py → modules/LM_bme280.py} +3 -3
- micrOS/source/{LM_buzzer.py → modules/LM_buzzer.py} +18 -25
- micrOS/source/{LM_cct.py → modules/LM_cct.py} +17 -21
- micrOS/source/modules/LM_cluster.py +255 -0
- micrOS/source/{LM_co2.py → modules/LM_co2.py} +3 -3
- micrOS/source/{LM_dht11.py → modules/LM_dht11.py} +2 -2
- micrOS/source/{LM_dht22.py → modules/LM_dht22.py} +2 -2
- micrOS/source/{LM_dimmer.py → modules/LM_dimmer.py} +9 -9
- micrOS/source/{LM_distance.py → modules/LM_distance.py} +4 -6
- micrOS/source/{LM_ds18.py → modules/LM_ds18.py} +2 -2
- micrOS/source/{LM_esp32.py → modules/LM_esp32.py} +5 -0
- micrOS/source/modules/LM_espnow.py +53 -0
- micrOS/source/modules/LM_fileserver.py +265 -0
- micrOS/source/{LM_genIO.py → modules/LM_genIO.py} +52 -37
- micrOS/source/{LM_haptic.py → modules/LM_haptic.py} +2 -2
- {toolkit/workspace/precompiled → micrOS/source/modules}/LM_i2c.py +5 -4
- micrOS/source/{LM_i2s_mic.py → modules/LM_i2s_mic.py} +6 -7
- micrOS/source/{LM_ld2410.py → modules/LM_ld2410.py} +2 -2
- micrOS/source/{LM_light_sensor.py → modules/LM_light_sensor.py} +10 -21
- micrOS/source/modules/LM_mh_z19c.py +198 -0
- micrOS/source/modules/LM_neoeffects.py +284 -0
- micrOS/source/{LM_neopixel.py → modules/LM_neopixel.py} +19 -23
- micrOS/source/{LM_oled.py → modules/LM_oled.py} +2 -2
- micrOS/source/{LM_oled_sh1106.py → modules/LM_oled_sh1106.py} +3 -3
- micrOS/source/{LM_oled_ui.py → modules/LM_oled_ui.py} +72 -64
- micrOS/source/modules/LM_pacman.py +320 -0
- micrOS/source/{LM_presence.py → modules/LM_presence.py} +11 -15
- micrOS/source/modules/LM_qmi8658.py +204 -0
- micrOS/source/{LM_rencoder.py → modules/LM_rencoder.py} +2 -2
- micrOS/source/{LM_rest.py → modules/LM_rest.py} +4 -6
- micrOS/source/{LM_rgb.py → modules/LM_rgb.py} +21 -29
- micrOS/source/{LM_roboarm.py → modules/LM_roboarm.py} +8 -8
- micrOS/source/modules/LM_robustness.py +137 -0
- micrOS/source/{LM_servo.py → modules/LM_servo.py} +3 -3
- micrOS/source/{LM_stepper.py → modules/LM_stepper.py} +5 -5
- micrOS/source/{LM_switch.py → modules/LM_switch.py} +11 -9
- micrOS/source/{LM_system.py → modules/LM_system.py} +38 -32
- micrOS/source/modules/LM_tcs3472.py +187 -0
- micrOS/source/{LM_telegram.py → modules/LM_telegram.py} +164 -116
- micrOS/source/{LM_trackball.py → modules/LM_trackball.py} +3 -3
- micrOS/source/{LM_veml7700.py → modules/LM_veml7700.py} +2 -2
- micrOS/source/modules/LM_web.py +38 -0
- micrOS/source/urequests.py +39 -15
- {toolkit/workspace/precompiled → micrOS/source/web}/dashboard.html +4 -0
- micrOS/source/web/editor.js +440 -0
- micrOS/source/web/filesui.html +178 -0
- micrOS/source/web/filesui.js +338 -0
- {toolkit/workspace/precompiled → micrOS/source/web}/index.html +44 -2
- micrOS/source/{uapi.js → web/uapi.js} +48 -7
- micrOS/source/{ustyle.css → web/ustyle.css} +6 -3
- micrOS/utests/__init__.py +0 -0
- micrOS/utests/test_scheduler.py +435 -0
- {micrOSDevToolKit-2.9.1.data → microsdevtoolkit-2.26.1.data}/scripts/devToolKit.py +33 -3
- {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/METADATA +327 -268
- microsdevtoolkit-2.26.1.dist-info/RECORD +396 -0
- {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/WHEEL +1 -1
- toolkit/DevEnvCompile.py +63 -33
- toolkit/DevEnvOTA.py +58 -22
- toolkit/DevEnvUSB.py +110 -55
- toolkit/Gateway.py +6 -6
- toolkit/LM_to_compile.dat +6 -4
- toolkit/MicrOSDevEnv.py +127 -57
- toolkit/WebRepl.py +73 -0
- toolkit/dashboard_apps/BackupRestore.py +20 -35
- toolkit/dashboard_apps/CCTDemo.py +12 -17
- toolkit/dashboard_apps/CCTTest.py +20 -24
- toolkit/dashboard_apps/CamStream.py +2 -6
- toolkit/dashboard_apps/CatGame.py +14 -16
- toolkit/dashboard_apps/Dimmer.py +11 -21
- toolkit/dashboard_apps/GetVersion.py +11 -19
- toolkit/dashboard_apps/MicrophoneTest.py +1 -6
- toolkit/dashboard_apps/NeoEffectsDemo.py +22 -35
- toolkit/dashboard_apps/NeopixelTest.py +20 -25
- toolkit/dashboard_apps/PresenceTest.py +2 -8
- toolkit/dashboard_apps/QMI8685_GYRO.py +68 -0
- toolkit/dashboard_apps/RGBTest.py +20 -24
- toolkit/dashboard_apps/RoboArm.py +24 -32
- toolkit/dashboard_apps/SED_test.py +10 -14
- toolkit/dashboard_apps/SensorsTest.py +61 -0
- toolkit/dashboard_apps/SystemTest.py +202 -105
- toolkit/dashboard_apps/Template_app.py +11 -23
- toolkit/dashboard_apps/_app_base.py +34 -0
- toolkit/dashboard_apps/_gyro_visualizer.py +78 -0
- toolkit/dashboard_apps/uLightDemo.py +15 -24
- toolkit/index.html +4 -4
- toolkit/lib/LocalMachine.py +6 -1
- toolkit/lib/MicrosFiles.py +46 -0
- toolkit/lib/Repository.py +64 -0
- toolkit/lib/TerminalColors.py +4 -0
- toolkit/lib/macroScript.py +6 -0
- toolkit/lib/micrOSClient.py +123 -50
- toolkit/lib/micrOSClientHistory.py +156 -0
- toolkit/lib/pip_package_installer.py +5 -2
- toolkit/micrOSdashboard.py +12 -17
- toolkit/micrOSlint.py +20 -8
- toolkit/simulator_lib/__pycache__/IO_darwin.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/aioespnow.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/framebuf.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/machine.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/micropython.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/mip.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/neopixel.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/network.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/sim_common.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/simgc.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/uasyncio.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/uos.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/urandom.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/usocket.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/ussl.cpython-312.pyc +0 -0
- toolkit/simulator_lib/aioespnow.py +28 -0
- toolkit/simulator_lib/dht.py +1 -1
- toolkit/simulator_lib/framebuf.py +49 -1
- toolkit/simulator_lib/machine.py +17 -2
- toolkit/simulator_lib/micropython.py +3 -3
- toolkit/simulator_lib/mip.py +165 -0
- toolkit/simulator_lib/neopixel.py +3 -2
- toolkit/simulator_lib/network.py +2 -1
- toolkit/simulator_lib/node_config.json +2 -3
- toolkit/simulator_lib/ntptime.py +1 -1
- toolkit/simulator_lib/{sim_console.py → sim_common.py} +2 -3
- toolkit/simulator_lib/simgc.py +6 -2
- toolkit/simulator_lib/simulator.py +137 -59
- toolkit/simulator_lib/uasyncio.py +33 -2
- toolkit/simulator_lib/uos.py +147 -0
- toolkit/simulator_lib/urandom.py +4 -0
- toolkit/socketClient.py +43 -23
- toolkit/user_data/webhooks/generic.py +1 -1
- toolkit/user_data/webhooks/macro.py +1 -1
- toolkit/user_data/webhooks/template.py +1 -1
- toolkit/workspace/precompiled/Auth.mpy +0 -0
- toolkit/workspace/precompiled/Common.mpy +0 -0
- toolkit/workspace/precompiled/Config.mpy +0 -0
- toolkit/workspace/precompiled/Debug.mpy +0 -0
- toolkit/workspace/precompiled/Espnow.mpy +0 -0
- toolkit/workspace/precompiled/Files.mpy +0 -0
- toolkit/workspace/precompiled/Hooks.mpy +0 -0
- toolkit/workspace/precompiled/InterConnect.mpy +0 -0
- toolkit/workspace/precompiled/Interrupts.mpy +0 -0
- toolkit/workspace/precompiled/Logger.mpy +0 -0
- toolkit/workspace/precompiled/Network.mpy +0 -0
- toolkit/workspace/precompiled/Notify.mpy +0 -0
- toolkit/workspace/precompiled/Pacman.mpy +0 -0
- toolkit/workspace/precompiled/Scheduler.mpy +0 -0
- toolkit/workspace/precompiled/Server.mpy +0 -0
- toolkit/workspace/precompiled/Shell.mpy +0 -0
- toolkit/workspace/precompiled/Tasks.mpy +0 -0
- toolkit/workspace/precompiled/Time.mpy +0 -0
- toolkit/workspace/precompiled/Types.mpy +0 -0
- toolkit/workspace/precompiled/Web.mpy +0 -0
- toolkit/workspace/precompiled/_mpy.version +1 -1
- toolkit/workspace/precompiled/config/_git.keep +0 -0
- toolkit/workspace/precompiled/helpers.mpy +0 -0
- toolkit/workspace/precompiled/micrOS.mpy +0 -0
- toolkit/workspace/precompiled/micrOSloader.mpy +0 -0
- toolkit/workspace/precompiled/microIO.mpy +0 -0
- toolkit/workspace/precompiled/{IO_esp32.mpy → modules/IO_esp32.mpy} +0 -0
- toolkit/workspace/precompiled/{IO_esp32c3.mpy → modules/IO_esp32c3.mpy} +0 -0
- toolkit/workspace/precompiled/modules/IO_esp32c6.mpy +0 -0
- toolkit/workspace/precompiled/{IO_esp32s2.mpy → modules/IO_esp32s2.mpy} +0 -0
- toolkit/workspace/precompiled/modules/IO_esp32s3.mpy +0 -0
- toolkit/workspace/precompiled/modules/IO_m5stamp.mpy +0 -0
- toolkit/workspace/precompiled/modules/IO_qtpy.mpy +0 -0
- toolkit/workspace/precompiled/modules/IO_rp2.mpy +0 -0
- toolkit/workspace/precompiled/modules/IO_tinypico.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_L298N.mpy +0 -0
- {micrOS/source → toolkit/workspace/precompiled/modules}/LM_L9110_DCmotor.py +3 -3
- toolkit/workspace/precompiled/modules/LM_OV2640.mpy +0 -0
- toolkit/workspace/precompiled/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +3 -3
- toolkit/workspace/precompiled/{LM_aht10.mpy → modules/LM_aht10.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_bme280.mpy → modules/LM_bme280.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_buzzer.mpy → modules/LM_buzzer.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_cct.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_cluster.mpy +0 -0
- toolkit/workspace/precompiled/{LM_co2.mpy → modules/LM_co2.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_dht11.mpy → modules/LM_dht11.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_dht22.mpy → modules/LM_dht22.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_dimmer.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_distance.mpy +0 -0
- toolkit/workspace/precompiled/{LM_ds18.mpy → modules/LM_ds18.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_esp32.py → modules/LM_esp32.py} +5 -0
- toolkit/workspace/precompiled/modules/LM_espnow.py +53 -0
- toolkit/workspace/precompiled/modules/LM_fileserver.mpy +0 -0
- toolkit/workspace/precompiled/{LM_gameOfLife.mpy → modules/LM_gameOfLife.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_genIO.mpy +0 -0
- toolkit/workspace/precompiled/{LM_haptic.mpy → modules/LM_haptic.mpy} +0 -0
- {micrOS/source → toolkit/workspace/precompiled/modules}/LM_i2c.py +5 -4
- toolkit/workspace/precompiled/modules/LM_i2s_mic.mpy +0 -0
- toolkit/workspace/precompiled/{LM_ld2410.mpy → modules/LM_ld2410.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_light_sensor.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_mh_z19c.py +198 -0
- toolkit/workspace/precompiled/modules/LM_neoeffects.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_neopixel.mpy +0 -0
- toolkit/workspace/precompiled/{LM_oled.mpy → modules/LM_oled.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_oled_sh1106.mpy → modules/LM_oled_sh1106.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_oled_ui.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_pacman.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_presence.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_qmi8658.py +204 -0
- toolkit/workspace/precompiled/{LM_rencoder.py → modules/LM_rencoder.py} +2 -2
- toolkit/workspace/precompiled/modules/LM_rest.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_rgb.mpy +0 -0
- toolkit/workspace/precompiled/{LM_rgbcct.mpy → modules/LM_rgbcct.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_roboarm.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_robustness.py +137 -0
- toolkit/workspace/precompiled/{LM_servo.mpy → modules/LM_servo.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_sound_event.mpy → modules/LM_sound_event.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_stepper.mpy → modules/LM_stepper.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_switch.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_system.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_tcs3472.py +187 -0
- toolkit/workspace/precompiled/modules/LM_telegram.mpy +0 -0
- toolkit/workspace/precompiled/{LM_tinyrgb.mpy → modules/LM_tinyrgb.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_trackball.mpy → modules/LM_trackball.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_veml7700.mpy → modules/LM_veml7700.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_web.mpy +0 -0
- toolkit/workspace/precompiled/urequests.mpy +0 -0
- {micrOS/source → toolkit/workspace/precompiled/web}/dashboard.html +4 -0
- toolkit/workspace/precompiled/web/editor.js +440 -0
- toolkit/workspace/precompiled/web/filesui.html +178 -0
- toolkit/workspace/precompiled/web/filesui.js +338 -0
- {micrOS/source → toolkit/workspace/precompiled/web}/index.html +44 -2
- toolkit/workspace/precompiled/{uapi.js → web/uapi.js} +48 -7
- toolkit/workspace/precompiled/{ustyle.css → web/ustyle.css} +6 -3
- micrOS/micropython/esp32-20241129-v1.24.1.bin +0 -0
- micrOS/micropython/esp32c3-20240222-v1.22.2.bin +0 -0
- micrOS/micropython/esp32s2-20240602-v1.23.0.bin +0 -0
- micrOS/micropython/esp32s2-LOLIN_MINI-20220618-v1.19.1.bin +0 -0
- micrOS/micropython/esp32s2-LOLIN_MINI-20240602-v1.23.0.bin +0 -0
- micrOS/micropython/esp32s3-20240105-v1.22.1.bin +0 -0
- micrOS/micropython/esp32s3_spiram_oct-20231005-v1.21.0.bin +0 -0
- micrOS/micropython/esp32s3_spiram_oct-20241129-v1.24.1.bin +0 -0
- micrOS/micropython/rpi-pico-w-20241129-v1.24.1.uf2 +0 -0
- micrOS/micropython/tinypico-20241129-v1.24.1.bin +0 -0
- micrOS/source/LM_L298N_DCmotor.py +0 -86
- micrOS/source/LM_catgame.py +0 -75
- micrOS/source/LM_dashboard_be.py +0 -37
- micrOS/source/LM_demo.py +0 -97
- micrOS/source/LM_espnow.py +0 -23
- micrOS/source/LM_intercon.py +0 -57
- micrOS/source/LM_keychain.py +0 -322
- micrOS/source/LM_lmpacman.py +0 -126
- micrOS/source/LM_neoeffects.py +0 -331
- micrOS/source/LM_oledui.py +0 -972
- micrOS/source/LM_pet_feeder.py +0 -78
- micrOS/source/LM_ph_sensor.py +0 -51
- micrOS/source/LM_robustness.py +0 -74
- micrOS/source/reset.py +0 -11
- micrOSDevToolKit-2.9.1.dist-info/RECORD +0 -365
- toolkit/dashboard_apps/AirQualityBME280.py +0 -36
- toolkit/dashboard_apps/AirQualityDHT22_CO2.py +0 -36
- toolkit/lib/file_extensions.py +0 -16
- toolkit/simulator_lib/__pycache__/sim_console.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/sim_console.cpython-38.pyc +0 -0
- toolkit/simulator_lib/__pycache__/sim_console.cpython-39.pyc +0 -0
- toolkit/workspace/precompiled/IO_esp32s3.mpy +0 -0
- toolkit/workspace/precompiled/IO_m5stamp.mpy +0 -0
- toolkit/workspace/precompiled/IO_qtpy.mpy +0 -0
- toolkit/workspace/precompiled/IO_rp2.mpy +0 -0
- toolkit/workspace/precompiled/IO_tinypico.mpy +0 -0
- toolkit/workspace/precompiled/LM_L298N_DCmotor.mpy +0 -0
- toolkit/workspace/precompiled/LM_OV2640.mpy +0 -0
- toolkit/workspace/precompiled/LM_catgame.py +0 -75
- toolkit/workspace/precompiled/LM_cct.mpy +0 -0
- toolkit/workspace/precompiled/LM_dashboard_be.py +0 -37
- toolkit/workspace/precompiled/LM_demo.py +0 -97
- toolkit/workspace/precompiled/LM_dimmer.mpy +0 -0
- toolkit/workspace/precompiled/LM_distance.mpy +0 -0
- toolkit/workspace/precompiled/LM_espnow.py +0 -23
- toolkit/workspace/precompiled/LM_genIO.mpy +0 -0
- toolkit/workspace/precompiled/LM_i2s_mic.mpy +0 -0
- toolkit/workspace/precompiled/LM_intercon.mpy +0 -0
- toolkit/workspace/precompiled/LM_keychain.mpy +0 -0
- toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
- toolkit/workspace/precompiled/LM_lmpacman.mpy +0 -0
- toolkit/workspace/precompiled/LM_neoeffects.mpy +0 -0
- toolkit/workspace/precompiled/LM_neopixel.mpy +0 -0
- toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
- toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
- toolkit/workspace/precompiled/LM_pet_feeder.py +0 -78
- toolkit/workspace/precompiled/LM_ph_sensor.py +0 -51
- toolkit/workspace/precompiled/LM_presence.mpy +0 -0
- toolkit/workspace/precompiled/LM_rest.mpy +0 -0
- toolkit/workspace/precompiled/LM_rgb.mpy +0 -0
- toolkit/workspace/precompiled/LM_roboarm.mpy +0 -0
- toolkit/workspace/precompiled/LM_robustness.py +0 -74
- toolkit/workspace/precompiled/LM_switch.mpy +0 -0
- toolkit/workspace/precompiled/LM_system.mpy +0 -0
- toolkit/workspace/precompiled/LM_telegram.mpy +0 -0
- toolkit/workspace/precompiled/node_config.json +0 -1
- toolkit/workspace/precompiled/reset.mpy +0 -0
- /micrOS/source/{IO_esp32.py → modules/IO_esp32.py} +0 -0
- /micrOS/source/{IO_esp32c3.py → modules/IO_esp32c3.py} +0 -0
- /micrOS/source/{IO_esp32s2.py → modules/IO_esp32s2.py} +0 -0
- /micrOS/source/{IO_rp2.py → modules/IO_rp2.py} +0 -0
- /micrOS/source/{LM_gameOfLife.py → modules/LM_gameOfLife.py} +0 -0
- /micrOS/source/{LM_rgbcct.py → modules/LM_rgbcct.py} +0 -0
- /micrOS/source/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
- /micrOS/source/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
- /micrOS/source/{LM_sound_event.py → modules/LM_sound_event.py} +0 -0
- /micrOS/source/{LM_tinyrgb.py → modules/LM_tinyrgb.py} +0 -0
- /micrOS/source/{udashboard.js → web/udashboard.js} +0 -0
- /micrOS/source/{uwidgets.js → web/uwidgets.js} +0 -0
- /micrOS/source/{uwidgets_pro.js → web/uwidgets_pro.js} +0 -0
- {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info/licenses}/LICENSE +0 -0
- {micrOSDevToolKit-2.9.1.dist-info → microsdevtoolkit-2.26.1.dist-info}/top_level.txt +0 -0
- /toolkit/workspace/precompiled/{LM_rp2w.py → modules/LM_rp2w.py} +0 -0
- /toolkit/workspace/precompiled/{LM_sdcard.py → modules/LM_sdcard.py} +0 -0
- /toolkit/workspace/precompiled/{udashboard.js → web/udashboard.js} +0 -0
- /toolkit/workspace/precompiled/{uwidgets.js → web/uwidgets.js} +0 -0
- /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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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"\
|
|
137
|
-
|
|
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'] =
|
|
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"\
|
|
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
|
|
197
|
+
def _lm_execute(cmd_args):
|
|
161
198
|
nonlocal verdict, m_id
|
|
162
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
235
|
-
|
|
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
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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 =
|
|
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
|
|
347
|
+
if Telegram.INSTANCE is None:
|
|
267
348
|
return "Network unavailable."
|
|
268
|
-
verdict =
|
|
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
|
|
359
|
+
if Telegram.INSTANCE is None:
|
|
290
360
|
return "Network unavailable."
|
|
291
|
-
verdict =
|
|
361
|
+
verdict = Telegram.get_msg()
|
|
292
362
|
return "Missing telegram bot token" if verdict is None else verdict
|
|
293
363
|
|
|
294
364
|
|
|
295
|
-
|
|
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
|
|
367
|
+
Telegram BOT (repl) - ReadEvalPrintLoop for Load Modules
|
|
320
368
|
- Only executes module (function) if the module is already loaded
|
|
321
|
-
|
|
369
|
+
:param period: polling period in sec, default: 3
|
|
322
370
|
"""
|
|
323
|
-
if
|
|
324
|
-
return "Network unavailable
|
|
325
|
-
|
|
326
|
-
return
|
|
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
|
-
'
|
|
340
|
-
'
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
|
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(
|
|
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')
|
micrOS/source/urequests.py
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
217
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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();
|