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
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"""
|
|
2
|
+
micrOS Fileserver addon for WebEngine
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from json import dumps
|
|
6
|
+
from re import compile as recompile
|
|
7
|
+
from uos import stat, rename, mkdir, statvfs
|
|
8
|
+
|
|
9
|
+
from Common import web_endpoint, web_mounts, web_dir, syslog
|
|
10
|
+
from Files import path_join, is_dir, remove_dir, remove_file, OSPath, abs_path, ilist_fs
|
|
11
|
+
from Web import url_path_resolve
|
|
12
|
+
from Auth import sudo
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Shared:
|
|
16
|
+
ROOT_DIR = web_dir("user_data") # Default Public WEB dir
|
|
17
|
+
TMP_DIR = path_join(ROOT_DIR, "tmp") # Temporary directory for partial uploads
|
|
18
|
+
UPLOAD_COUNTER = 0 # Counter for handling partial uploads
|
|
19
|
+
MOUNTS_WRITE_ACCESS = {"$modules": False, "$data": False, "$logs": False}
|
|
20
|
+
# mpy: code bytestream
|
|
21
|
+
HIDE_FEXT = ("mpy",) # Hide / Protect (delete/upload) files with the listed extensions
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def check_write_access(path):
|
|
25
|
+
"""
|
|
26
|
+
Raw input path mount write access checker
|
|
27
|
+
"""
|
|
28
|
+
if "$" in path:
|
|
29
|
+
# Mount alias in path
|
|
30
|
+
for access in Shared.MOUNTS_WRITE_ACCESS:
|
|
31
|
+
if access in path:
|
|
32
|
+
if Shared.MOUNTS_WRITE_ACCESS[access]:
|
|
33
|
+
return # Writeable
|
|
34
|
+
raise ValueError(f'ReadOnly path: {path}')
|
|
35
|
+
else:
|
|
36
|
+
# No mount alias in path
|
|
37
|
+
return # Writeable
|
|
38
|
+
raise ValueError(f'ReadOnly path: {path}')
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
#############################################
|
|
42
|
+
# Web Endpoint Callbacks #
|
|
43
|
+
#############################################
|
|
44
|
+
|
|
45
|
+
def _list_file_paths_clb(root_dir=None):
|
|
46
|
+
"""
|
|
47
|
+
List files shared path
|
|
48
|
+
"""
|
|
49
|
+
if isinstance(root_dir, bytes)and len(root_dir.strip()) > 0:
|
|
50
|
+
# Decode input path from request body
|
|
51
|
+
root_dir = root_dir.decode("ascii")
|
|
52
|
+
else:
|
|
53
|
+
root_dir = Shared.ROOT_DIR
|
|
54
|
+
|
|
55
|
+
# Resolve and Validate path (mount aliases)
|
|
56
|
+
try:
|
|
57
|
+
root_dir = resolve_path(root_dir.replace(web_dir(), ""))
|
|
58
|
+
except Exception as e:
|
|
59
|
+
return "text/plain", str(e)
|
|
60
|
+
|
|
61
|
+
user_data = []
|
|
62
|
+
# Show file content on selected root_dir
|
|
63
|
+
# Hide: .mpy files (non-readable/non-editable)
|
|
64
|
+
for name in (f for f in ilist_fs(path=root_dir, type_filter='f') if f.split(".")[-1] not in Shared.HIDE_FEXT):
|
|
65
|
+
file_path = path_join(root_dir, name)
|
|
66
|
+
user_data.append(file_path)
|
|
67
|
+
|
|
68
|
+
response = [
|
|
69
|
+
{
|
|
70
|
+
'path': file_path.replace(web_dir(),""),
|
|
71
|
+
'size': stat(file_path)[6],
|
|
72
|
+
'created': stat(file_path)[9]
|
|
73
|
+
}
|
|
74
|
+
for file_path in user_data
|
|
75
|
+
]
|
|
76
|
+
return 'application/json', dumps(response)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _delete_file_clb(file_to_delete: bytes):
|
|
80
|
+
file_to_delete = file_to_delete.decode('ascii')
|
|
81
|
+
Shared.check_write_access(file_to_delete)
|
|
82
|
+
filepath = resolve_path(file_to_delete)
|
|
83
|
+
if is_dir(filepath):
|
|
84
|
+
raise ValueError(f'File does not exist: {filepath}')
|
|
85
|
+
# File name extension based delete protection
|
|
86
|
+
if filepath.split(".")[-1] in Shared.HIDE_FEXT:
|
|
87
|
+
raise ValueError(f'Delete access denied: {filepath}')
|
|
88
|
+
verdict = remove_file(filepath)
|
|
89
|
+
return 'text/plain', verdict
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _upload_file_clb(part_headers: dict, part_body: bytes, first=False, last=False):
|
|
93
|
+
"""
|
|
94
|
+
Callback function for handling file uploads (Content-Type: multipart/form-data)
|
|
95
|
+
This callback is invoked on every part.
|
|
96
|
+
"""
|
|
97
|
+
cd = part_headers.get('content-disposition', '')
|
|
98
|
+
target_filepath = None
|
|
99
|
+
filename = ""
|
|
100
|
+
cd_pattern = recompile(r'filename\*?=(?:"([^"]+)"|([^;]+))')
|
|
101
|
+
|
|
102
|
+
if match := cd_pattern.search(cd):
|
|
103
|
+
filepath = match.group(1) or match.group(2)
|
|
104
|
+
filepath = filepath.strip()
|
|
105
|
+
# Reject UTF-8 and percent-encoded UTF-8 filenames (RFC 8187)
|
|
106
|
+
if filepath.lower().startswith("utf-8'"):
|
|
107
|
+
raise ValueError("Percent encoded filenames are not supported")
|
|
108
|
+
Shared.check_write_access(filepath)
|
|
109
|
+
target_filepath = resolve_path(filepath)
|
|
110
|
+
filename = target_filepath.split("/")[-1]
|
|
111
|
+
|
|
112
|
+
# File name extension based upload protection
|
|
113
|
+
if not filename or filename.split(".")[-1] in Shared.HIDE_FEXT:
|
|
114
|
+
raise ValueError(f"Invalid filename in part headers: {filename}")
|
|
115
|
+
target_parts = target_filepath.strip("/").split("/")
|
|
116
|
+
if len(target_parts) == 2 and target_parts[-2] == "web":
|
|
117
|
+
# Write protected /web root -> redirect to user shared dir
|
|
118
|
+
target_filepath = path_join(Shared.ROOT_DIR, filename)
|
|
119
|
+
|
|
120
|
+
if first:
|
|
121
|
+
Shared.UPLOAD_COUNTER += 1
|
|
122
|
+
|
|
123
|
+
if first and last:
|
|
124
|
+
with open(target_filepath, 'wb') as f:
|
|
125
|
+
f.write(part_body)
|
|
126
|
+
elif first and not last:
|
|
127
|
+
tmp_file_path = path_join(Shared.TMP_DIR, f"{filename}.{Shared.UPLOAD_COUNTER}")
|
|
128
|
+
with open(tmp_file_path, 'wb') as f:
|
|
129
|
+
f.write(part_body)
|
|
130
|
+
else:
|
|
131
|
+
tmp_file_path = path_join(Shared.TMP_DIR, f"{filename}.{Shared.UPLOAD_COUNTER}")
|
|
132
|
+
with open(tmp_file_path, 'ab') as f:
|
|
133
|
+
f.write(part_body)
|
|
134
|
+
if last:
|
|
135
|
+
rename(tmp_file_path, target_filepath)
|
|
136
|
+
|
|
137
|
+
return 'text/plain', 'ok'
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _disk_usage_clb():
|
|
141
|
+
"""
|
|
142
|
+
Calculate disk usage
|
|
143
|
+
return {'used': <bytes used>, 'free': <bytes free>}
|
|
144
|
+
"""
|
|
145
|
+
# Check root dir usage
|
|
146
|
+
fs_stat = statvfs(OSPath._ROOT)
|
|
147
|
+
fs_free = fs_stat[0] * fs_stat[3]
|
|
148
|
+
fs_size = fs_stat[0] * fs_stat[2]
|
|
149
|
+
used = fs_size - fs_free
|
|
150
|
+
return 'application/json', dumps({'used': used, 'free': fs_free})
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
#############################################
|
|
154
|
+
# Public functions #
|
|
155
|
+
#############################################
|
|
156
|
+
|
|
157
|
+
def load(web_data_dir:str=None):
|
|
158
|
+
"""
|
|
159
|
+
Initialize fileserver.
|
|
160
|
+
:param web_data_dir: web data public directory (default: /web/<user_data>)
|
|
161
|
+
"""
|
|
162
|
+
if isinstance(web_data_dir, str):
|
|
163
|
+
# Customize public web dir name
|
|
164
|
+
Shared.ROOT_DIR = web_dir(web_data_dir)
|
|
165
|
+
Shared.TMP_DIR = path_join(Shared.ROOT_DIR, 'tmp')
|
|
166
|
+
if is_dir(Shared.TMP_DIR):
|
|
167
|
+
remove_dir(Shared.TMP_DIR, force=True) # Clean existing partial uploads, is force needed?
|
|
168
|
+
if not is_dir(Shared.ROOT_DIR):
|
|
169
|
+
root_dir = web_dir()
|
|
170
|
+
base_dir = root_dir
|
|
171
|
+
for subdir in Shared.TMP_DIR.replace(root_dir, "").split('/'):
|
|
172
|
+
current_dir = path_join(base_dir, subdir)
|
|
173
|
+
if not is_dir(current_dir):
|
|
174
|
+
mkdir(current_dir)
|
|
175
|
+
base_dir = current_dir
|
|
176
|
+
|
|
177
|
+
# Register endpoints
|
|
178
|
+
# [GET] List shared directories
|
|
179
|
+
web_endpoint('fs/dirs', lambda: ('application/json', dumps(get_shared_dirs())))
|
|
180
|
+
# [GET] List help message
|
|
181
|
+
web_endpoint('fs/list', lambda: ('text/plain', 'USE THIS AS POST Endpoint, select dir in http body'))
|
|
182
|
+
# [POST] List selected directory content
|
|
183
|
+
web_endpoint('fs/list', _list_file_paths_clb, 'POST')
|
|
184
|
+
# [GET] Files - list user files
|
|
185
|
+
web_endpoint('fs/files', _list_file_paths_clb)
|
|
186
|
+
# [DELETE] Files - delete selected file
|
|
187
|
+
web_endpoint('fs/files', _delete_file_clb, 'DELETE')
|
|
188
|
+
# [POST] Upload file to the selected path (in filename)
|
|
189
|
+
web_endpoint('fs/files', _upload_file_clb, 'POST')
|
|
190
|
+
# [GET] Show internal flash storage usage
|
|
191
|
+
web_endpoint('fs/usage', _disk_usage_clb)
|
|
192
|
+
# [GET] Fileserver homepage UI
|
|
193
|
+
web_endpoint('fs', 'filesui.html')
|
|
194
|
+
|
|
195
|
+
return "Fileserver was initialized, endpoints: /fs, /fs/files, /fs/dirs, /fs/usage"
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def resolve_path(path):
|
|
199
|
+
"""
|
|
200
|
+
Resolve and Validate input path
|
|
201
|
+
:param path: URL resource path or mount path string
|
|
202
|
+
"""
|
|
203
|
+
# Path resolve and validation
|
|
204
|
+
path = abs_path(path)
|
|
205
|
+
err, path = url_path_resolve(path)
|
|
206
|
+
if err:
|
|
207
|
+
raise ValueError(f"Invalid path: {path}")
|
|
208
|
+
filename = path.split("/")[-1]
|
|
209
|
+
# Filename validation
|
|
210
|
+
filename_pattern = recompile(r"^[a-zA-Z0-9._-]+$")
|
|
211
|
+
if not filename_pattern.match(filename):
|
|
212
|
+
raise ValueError(f"Filename contains invalid characters: {path}")
|
|
213
|
+
return path
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_shared_dirs() -> list:
|
|
217
|
+
"""
|
|
218
|
+
Getter for web shared dirs
|
|
219
|
+
- default: /web/Shared.ROOT_DIR
|
|
220
|
+
- extended: web_mounts()
|
|
221
|
+
"""
|
|
222
|
+
web_dirs = list([a for a, p in web_mounts().items() if p is not None])
|
|
223
|
+
web_dirs.insert(0, Shared.ROOT_DIR.replace(web_dir(), ""))
|
|
224
|
+
return web_dirs
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def get_user_dir():
|
|
228
|
+
"""
|
|
229
|
+
Getter for user configured shared dir
|
|
230
|
+
- used by other load modules
|
|
231
|
+
"""
|
|
232
|
+
return Shared.ROOT_DIR
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def extend_mounts(modules:bool=None, data:bool=None, logs:bool=None):
|
|
236
|
+
"""
|
|
237
|
+
Extend web engine shared root path list
|
|
238
|
+
:param modules: add/remove /modules to web shared path
|
|
239
|
+
:param data: add/remove /data to web shared path
|
|
240
|
+
:param logs: add/remove /logs web shared path
|
|
241
|
+
"""
|
|
242
|
+
return web_mounts(modules, data, logs)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@sudo
|
|
246
|
+
def mounts_write_access(modules:bool=None, data:bool=None, logs:bool=None):
|
|
247
|
+
if modules is not None:
|
|
248
|
+
Shared.MOUNTS_WRITE_ACCESS["$modules"] = modules
|
|
249
|
+
if data is not None:
|
|
250
|
+
Shared.MOUNTS_WRITE_ACCESS["$data"] = data
|
|
251
|
+
if logs is not None:
|
|
252
|
+
Shared.MOUNTS_WRITE_ACCESS["$logs"] = logs
|
|
253
|
+
return Shared.MOUNTS_WRITE_ACCESS
|
|
254
|
+
|
|
255
|
+
#######################
|
|
256
|
+
# Helper LM functions #
|
|
257
|
+
#######################
|
|
258
|
+
|
|
259
|
+
def help(widgets=False):
|
|
260
|
+
return (f'load web_data_dir=<shared directory under {web_dir()}>',
|
|
261
|
+
'resolve_path "<str>"',
|
|
262
|
+
'get_shared_dirs',
|
|
263
|
+
'get_user_dir',
|
|
264
|
+
'extend_mounts modules:bool=None data:bool=None logs:bool=None',
|
|
265
|
+
'mounts_write_access modules:bool=None data:bool=None logs:bool=None')
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from machine import Pin, PWM
|
|
2
|
-
from microIO import
|
|
2
|
+
from microIO import bind_pin, PinMap
|
|
3
3
|
from Common import SmartADC
|
|
4
4
|
from random import randint
|
|
5
5
|
|
|
@@ -10,15 +10,25 @@ from random import randint
|
|
|
10
10
|
|
|
11
11
|
class IObjects:
|
|
12
12
|
PIN_OBJS = {}
|
|
13
|
+
DENY_TAG_INPUT = True
|
|
13
14
|
|
|
14
15
|
@staticmethod
|
|
15
|
-
def store_obj(pin, obj):
|
|
16
|
+
def store_obj(pin:int, obj:object) -> None:
|
|
16
17
|
IObjects.PIN_OBJS[pin] = obj
|
|
17
18
|
|
|
18
19
|
@staticmethod
|
|
19
|
-
def get_obj(pin):
|
|
20
|
+
def get_obj(pin:int) -> object:
|
|
20
21
|
return IObjects.PIN_OBJS[pin]
|
|
21
22
|
|
|
23
|
+
@staticmethod
|
|
24
|
+
def is_unassigned(pin_number):
|
|
25
|
+
return IObjects.PIN_OBJS.get(pin_number, None) is None
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def protect_builtins(pin_num, tag):
|
|
29
|
+
if pin_num is None and IObjects.DENY_TAG_INPUT:
|
|
30
|
+
raise Exception(f"pin must be integer not {type(tag)}: {tag}")
|
|
31
|
+
|
|
22
32
|
|
|
23
33
|
##################################
|
|
24
34
|
# INTERNAL INIT FUNCTIONS #
|
|
@@ -28,48 +38,39 @@ def __digital_out_init(pin):
|
|
|
28
38
|
"""
|
|
29
39
|
Init Digital output
|
|
30
40
|
"""
|
|
31
|
-
if
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
pin_obj = Pin(pin, Pin.OUT)
|
|
39
|
-
IObjects.store_obj(pin, pin_obj)
|
|
40
|
-
return IObjects.get_obj(pin)
|
|
41
|
+
pin_tag, pin = (pin, None) if isinstance(pin, str) else (f"OUT{pin}", pin)
|
|
42
|
+
IObjects.protect_builtins(pin, pin_tag)
|
|
43
|
+
pin_num = bind_pin(pin_tag, pin)
|
|
44
|
+
if IObjects.is_unassigned(pin_number=pin_num):
|
|
45
|
+
pin_obj = Pin(pin_num, Pin.OUT)
|
|
46
|
+
IObjects.store_obj(pin_num, pin_obj)
|
|
47
|
+
return IObjects.get_obj(pin_num)
|
|
41
48
|
|
|
42
49
|
|
|
43
50
|
def __digital_in_init(pin):
|
|
44
51
|
"""
|
|
45
52
|
Init Digital output
|
|
46
53
|
"""
|
|
47
|
-
if
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
pin_obj = Pin(pin, Pin.IN, Pin.PULL_UP)
|
|
55
|
-
IObjects.store_obj(pin, pin_obj)
|
|
56
|
-
return IObjects.get_obj(pin)
|
|
54
|
+
pin_tag, pin = (pin, None) if isinstance(pin, str) else (f"IN{pin}", pin)
|
|
55
|
+
IObjects.protect_builtins(pin, pin_tag)
|
|
56
|
+
pin_num = bind_pin(pin_tag, pin)
|
|
57
|
+
if IObjects.is_unassigned(pin_number=pin_num):
|
|
58
|
+
pin_obj = Pin(pin_num, Pin.IN, Pin.PULL_UP)
|
|
59
|
+
IObjects.store_obj(pin_num, pin_obj)
|
|
60
|
+
return IObjects.get_obj(pin_num)
|
|
57
61
|
|
|
58
62
|
|
|
59
63
|
def __pwm_init(pin, freq):
|
|
60
64
|
"""
|
|
61
65
|
Init PWM signal
|
|
62
66
|
"""
|
|
63
|
-
if
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
pin_obj = PWM(Pin(pin), freq=freq)
|
|
71
|
-
IObjects.store_obj(pin, pin_obj)
|
|
72
|
-
return IObjects.get_obj(pin)
|
|
67
|
+
pin_tag, pin = (pin, None) if isinstance(pin, str) else (f"PWM{pin}", pin)
|
|
68
|
+
IObjects.protect_builtins(pin, pin_tag)
|
|
69
|
+
pin_num = bind_pin(pin_tag, pin)
|
|
70
|
+
if IObjects.is_unassigned(pin_number=pin_num):
|
|
71
|
+
pin_obj = PWM(Pin(pin_num), freq=freq)
|
|
72
|
+
IObjects.store_obj(pin_num, pin_obj)
|
|
73
|
+
return IObjects.get_obj(pin_num)
|
|
73
74
|
|
|
74
75
|
|
|
75
76
|
##################################
|
|
@@ -121,9 +122,9 @@ def get_adc(pin, key=None):
|
|
|
121
122
|
:param key: select adc parameter by key
|
|
122
123
|
:return dict: adc volt, percent, raw
|
|
123
124
|
"""
|
|
124
|
-
if isinstance(pin,
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
pin_tag, pin = (pin, None) if isinstance(pin, str) else (f"ADC{pin}", pin)
|
|
126
|
+
IObjects.protect_builtins(pin, pin_tag)
|
|
127
|
+
pin = bind_pin(pin_tag, pin)
|
|
127
128
|
data = SmartADC.get_instance(pin).get()
|
|
128
129
|
data["pin"] = pin
|
|
129
130
|
if key is None:
|
|
@@ -140,6 +141,19 @@ def get_in(pin):
|
|
|
140
141
|
return {'pin': pin, 'state': __digital_in_init(pin).value()}
|
|
141
142
|
|
|
142
143
|
|
|
144
|
+
def load(allow_tags=False):
|
|
145
|
+
"""
|
|
146
|
+
Optional load function to set
|
|
147
|
+
tag input besides pin numbers.
|
|
148
|
+
[WARNING] allow_tag=True can be dangerous
|
|
149
|
+
- it can overwrite existing I/O based on
|
|
150
|
+
the provided tag
|
|
151
|
+
:param allow_tag: default False
|
|
152
|
+
"""
|
|
153
|
+
IObjects.DENY_TAG_INPUT = not allow_tags
|
|
154
|
+
return "[WARNING] allow_tag=True can be dangerous, use it consciously!!!" if allow_tags else "Loaded"
|
|
155
|
+
|
|
156
|
+
|
|
143
157
|
#######################
|
|
144
158
|
# LM helper functions #
|
|
145
159
|
#######################
|
|
@@ -155,4 +169,5 @@ def help(widgets=False):
|
|
|
155
169
|
'set_random_pwm pin min_duty max_duty freq=20480)',\
|
|
156
170
|
'set_out pin=<int> state=<None/True/False>',\
|
|
157
171
|
'get_adc pin key=None',\
|
|
158
|
-
'get_in pin'
|
|
172
|
+
'get_in pin',\
|
|
173
|
+
'load allow_tags=False'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from microIO import
|
|
1
|
+
from microIO import bind_pin, pinmap_search
|
|
2
2
|
from Types import resolve
|
|
3
3
|
from machine import Pin, PWM
|
|
4
4
|
from utime import sleep_ms
|
|
@@ -18,7 +18,7 @@ def load(intensity=None):
|
|
|
18
18
|
:param intensity: low / high / None haptic feedback intensity
|
|
19
19
|
"""
|
|
20
20
|
if Haptic.HAPTIC_OBJ is None:
|
|
21
|
-
dimmer_pin = Pin(
|
|
21
|
+
dimmer_pin = Pin(bind_pin('haptic'))
|
|
22
22
|
Haptic.HAPTIC_OBJ = PWM(dimmer_pin, freq=20480)
|
|
23
23
|
Haptic.HAPTIC_OBJ.duty(0)
|
|
24
24
|
if intensity in ("high", "low"):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from microIO import
|
|
1
|
+
from microIO import bind_pin, pinmap_search
|
|
2
2
|
|
|
3
3
|
__I2C = None
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ def __init():
|
|
|
7
7
|
global __I2C
|
|
8
8
|
if __I2C is None:
|
|
9
9
|
from machine import Pin, I2C
|
|
10
|
-
__I2C = I2C(-1, Pin(
|
|
10
|
+
__I2C = I2C(-1, Pin(bind_pin('i2c_scl')), Pin(bind_pin('i2c_sda')))
|
|
11
11
|
return __I2C
|
|
12
12
|
|
|
13
13
|
|
|
@@ -24,8 +24,9 @@ def discover():
|
|
|
24
24
|
"""
|
|
25
25
|
Discover devices
|
|
26
26
|
"""
|
|
27
|
-
known_addresses = {hex(0x0A): "
|
|
28
|
-
hex(0x76): "
|
|
27
|
+
known_addresses = {hex(0x0A): "TRACKBALL", hex(0x3c): "OLED",
|
|
28
|
+
hex(0x76): "BME280", hex(0x10): 'VEML7700',
|
|
29
|
+
hex(0x6b): "QMI8658", hex(0x29): 'TCS3472'}
|
|
29
30
|
devices = scan()
|
|
30
31
|
output = {"unknown": []}
|
|
31
32
|
for k in devices:
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
from ustruct import unpack
|
|
2
|
-
from microIO import
|
|
2
|
+
from microIO import bind_pin, pinmap_search
|
|
3
3
|
from Common import micro_task, web_endpoint, manage_task
|
|
4
4
|
from machine import I2S, Pin
|
|
5
5
|
import uasyncio as asyncio
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class Data:
|
|
9
|
-
SCK_PIN = Pin(
|
|
10
|
-
WS_PIN = Pin(
|
|
11
|
-
SD_PIN = Pin(
|
|
9
|
+
SCK_PIN = Pin(bind_pin('i2s_sck')) # Serial clock
|
|
10
|
+
WS_PIN = Pin(bind_pin('i2s_ws')) # Word select
|
|
11
|
+
SD_PIN = Pin(bind_pin('i2s_sd')) # Serial data
|
|
12
12
|
I2S_CHANNEL = 1
|
|
13
13
|
FORMAT = I2S.STEREO
|
|
14
14
|
SAMPLING_RATE = 8000
|
|
@@ -94,8 +94,7 @@ def background_capture():
|
|
|
94
94
|
if not Data.MIC_ENABLED:
|
|
95
95
|
return "Microphone is disabled"
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
return "Starting" if state else "Already running"
|
|
97
|
+
return micro_task(tag=Data.TASK_TAG, task=__task(ms_period=1))
|
|
99
98
|
|
|
100
99
|
|
|
101
100
|
def get_from_buffer(capture_duration=Data.CAPTURE_DURATION,
|
|
@@ -276,7 +275,7 @@ def load(buf_length=Data.BUF_LENGTH, sampling_rate=Data.SAMPLING_RATE,
|
|
|
276
275
|
|
|
277
276
|
if control_button:
|
|
278
277
|
micro_task(tag=Data.CONTROL_TASK_TAG, task=__control_task())
|
|
279
|
-
Data.CONTROL_BUTTON_PIN = Pin(
|
|
278
|
+
Data.CONTROL_BUTTON_PIN = Pin(bind_pin(control_button), Pin.IN)
|
|
280
279
|
|
|
281
280
|
Data.BUF_LENGTH = buf_length
|
|
282
281
|
Data.SAMPLING_RATE = sampling_rate
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
|
|
18
18
|
from machine import Pin, UART
|
|
19
19
|
import utime
|
|
20
|
-
from microIO import
|
|
20
|
+
from microIO import bind_pin, pinmap_search
|
|
21
21
|
|
|
22
|
-
ser = UART(1, baudrate = 256000, tx=Pin(
|
|
22
|
+
ser = UART(1, baudrate = 256000, tx=Pin(bind_pin('tx')), rx=Pin(bind_pin('rx')), timeout = 1)
|
|
23
23
|
HEADER = bytes([0xfd, 0xfc, 0xfb, 0xfa])
|
|
24
24
|
TERMINATOR = bytes([0x04, 0x03, 0x02, 0x01])
|
|
25
25
|
NULLDATA = bytes([])
|
|
@@ -5,13 +5,9 @@ ADC.ATTN_2_5DB — the full range voltage: 1.5V
|
|
|
5
5
|
ADC.ATTN_6DB — the full range voltage: 2.0V
|
|
6
6
|
ADC.ATTN_11DB — the full range voltage: 3.3V
|
|
7
7
|
"""
|
|
8
|
-
from Common import SmartADC, micro_task
|
|
8
|
+
from Common import SmartADC, micro_task, exec_cmd
|
|
9
9
|
from Types import resolve
|
|
10
|
-
|
|
11
|
-
import LM_intercon as InterCon
|
|
12
|
-
except:
|
|
13
|
-
InterCon = None
|
|
14
|
-
from microIO import resolve_pin, pinmap_search
|
|
10
|
+
from microIO import bind_pin, pinmap_search
|
|
15
11
|
|
|
16
12
|
|
|
17
13
|
ADC = None
|
|
@@ -23,7 +19,7 @@ def __init_tempt6000():
|
|
|
23
19
|
"""
|
|
24
20
|
global ADC
|
|
25
21
|
if ADC is None:
|
|
26
|
-
ADC = SmartADC(
|
|
22
|
+
ADC = SmartADC(bind_pin('temp6000'))
|
|
27
23
|
return ADC
|
|
28
24
|
|
|
29
25
|
|
|
@@ -76,19 +72,15 @@ async def _task(on, off, threshold, tolerance=2, check_ms=5000):
|
|
|
76
72
|
# TURN ON
|
|
77
73
|
if percent <= threshold:
|
|
78
74
|
if on != last_ev:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
InterCon.send_cmd(host, cmd)
|
|
83
|
-
my_task.out = f"{percent}% <= threshold: {threshold}% - ON"
|
|
75
|
+
host = on[0]
|
|
76
|
+
state, _ = exec_cmd(on[1:] + [f">>{host}"], jsonify=True)
|
|
77
|
+
my_task.out = f"{percent}% <= threshold: {threshold}% - ON [{'OK' if state else 'NOK'}]"
|
|
84
78
|
last_ev = on
|
|
85
79
|
elif percent > threshold+tolerance: # +tolerance to avoid "on/off/on/off" on threshold limit
|
|
86
80
|
if off != last_ev:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
InterCon.send_cmd(host, cmd)
|
|
91
|
-
my_task.out = f"{percent}% > threshold: {threshold+tolerance}% - OFF"
|
|
81
|
+
host = off[0]
|
|
82
|
+
state, _ = exec_cmd(off[1:] + [f">>{host}"], jsonify=True)
|
|
83
|
+
my_task.out = f"{percent}% > threshold: {threshold+tolerance}% - OFF [{'OK' if state else 'NOK'}]"
|
|
92
84
|
last_ev = off
|
|
93
85
|
await my_task.feed(sleep_ms=check_ms) # Sample every <check_ms> sec
|
|
94
86
|
|
|
@@ -104,11 +96,8 @@ def subscribe_intercon(on, off, threshold=4, tolerance=2, sample_sec=60):
|
|
|
104
96
|
"""
|
|
105
97
|
# Start play - servo XY in async task
|
|
106
98
|
# [!] ASYNC TASK CREATION [1*] with async task callback + taskID (TAG) handling
|
|
107
|
-
|
|
99
|
+
return micro_task(tag="light_sensor.intercon", task=_task(on, off, threshold, tolerance=tolerance,
|
|
108
100
|
check_ms=sample_sec*1000))
|
|
109
|
-
if state:
|
|
110
|
-
return 'Light sensor remote trigger starts'
|
|
111
|
-
return 'Light sensor remote trigger - already running'
|
|
112
101
|
|
|
113
102
|
|
|
114
103
|
#######################
|