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