micrOSDevToolKit 2.13.0__py3-none-any.whl → 2.17.0__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.
Potentially problematic release.
This version of micrOSDevToolKit might be problematic. Click here for more details.
- micrOS/release_info/micrOS_ReleaseInfo/system_analysis_sum.json +125 -121
- micrOS/source/Common.py +48 -26
- micrOS/source/Config.py +13 -5
- micrOS/source/Espnow.py +100 -58
- micrOS/source/Files.py +77 -41
- micrOS/source/Hooks.py +18 -34
- micrOS/source/Logger.py +2 -7
- micrOS/source/Network.py +36 -16
- micrOS/source/Server.py +22 -8
- micrOS/source/Shell.py +9 -6
- micrOS/source/Tasks.py +34 -13
- micrOS/source/Web.py +69 -31
- micrOS/source/__pycache__/Common.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__/Server.cpython-312.pyc +0 -0
- micrOS/source/config/_git.keep +0 -0
- micrOS/source/micrOS.py +7 -0
- micrOS/source/micrOSloader.py +2 -10
- micrOS/source/microIO.py +2 -2
- micrOS/source/modules/IO_esp32c6.py +38 -0
- micrOS/source/modules/LM_L298N.py +161 -0
- micrOS/source/modules/LM_cluster.py +250 -0
- {toolkit/workspace/precompiled → micrOS/source/modules}/LM_esp32.py +5 -0
- micrOS/source/modules/LM_espnow.py +36 -0
- micrOS/source/{LM_i2c.py → modules/LM_i2c.py} +1 -1
- micrOS/source/{LM_light_sensor.py → modules/LM_light_sensor.py} +2 -2
- micrOS/source/modules/LM_mqtt_client.py +246 -0
- micrOS/source/{LM_neoeffects.py → modules/LM_neoeffects.py} +14 -4
- micrOS/source/{LM_neomatrix.py → modules/LM_neomatrix.py} +140 -38
- micrOS/source/{LM_oled_ui.py → modules/LM_oled_ui.py} +2 -2
- micrOS/source/{LM_oledui.py → modules/LM_oledui.py} +2 -2
- micrOS/source/{LM_pacman.py → modules/LM_pacman.py} +74 -29
- micrOS/source/{LM_presence.py → modules/LM_presence.py} +2 -2
- micrOS/source/{LM_robustness.py → modules/LM_robustness.py} +49 -2
- micrOS/source/{LM_tcs3472.py → modules/LM_tcs3472.py} +4 -6
- micrOS/source/web/dashboard.html +2 -0
- micrOS/source/web/matrix_draw.html +390 -0
- micrOS/source/web/uapi.js +9 -6
- {microsdevtoolkit-2.13.0.dist-info → microsdevtoolkit-2.17.0.dist-info}/METADATA +30 -37
- {microsdevtoolkit-2.13.0.dist-info → microsdevtoolkit-2.17.0.dist-info}/RECORD +201 -191
- toolkit/DevEnvCompile.py +21 -12
- toolkit/DevEnvOTA.py +27 -16
- toolkit/DevEnvUSB.py +35 -21
- toolkit/LM_to_compile.dat +3 -1
- toolkit/MicrOSDevEnv.py +37 -21
- toolkit/dashboard_apps/QMI8685_GYRO.py +1 -1
- toolkit/dashboard_apps/SystemTest.py +8 -5
- toolkit/{MicrosFiles.py → lib/MicrosFiles.py} +24 -4
- toolkit/lib/pip_package_installer.py +5 -2
- toolkit/micrOSdashboard.py +2 -2
- toolkit/micrOSlint.py +17 -7
- toolkit/simulator_lib/__pycache__/simulator.cpython-312.pyc +0 -0
- toolkit/simulator_lib/__pycache__/uos.cpython-312.pyc +0 -0
- toolkit/simulator_lib/mqtt_as/Note.md +15 -0
- toolkit/simulator_lib/mqtt_as/__init__.py +950 -0
- toolkit/simulator_lib/mqtt_as/__pycache__/__init__.cpython-312.pyc +0 -0
- toolkit/simulator_lib/mqtt_as/clean.py +69 -0
- toolkit/simulator_lib/mqtt_as/mqtt_v5_properties.py +239 -0
- toolkit/simulator_lib/mqtt_as/range.py +90 -0
- toolkit/simulator_lib/mqtt_as/range_ex.py +119 -0
- toolkit/simulator_lib/simulator.py +14 -1
- toolkit/simulator_lib/uos.py +2 -0
- toolkit/workspace/precompiled/Common.mpy +0 -0
- toolkit/workspace/precompiled/Config.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/Logger.mpy +0 -0
- toolkit/workspace/precompiled/Network.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/Web.mpy +0 -0
- toolkit/workspace/precompiled/config/_git.keep +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/{IO_esp32s3.mpy → modules/IO_esp32s3.mpy} +0 -0
- toolkit/workspace/precompiled/{IO_m5stamp.mpy → modules/IO_m5stamp.mpy} +0 -0
- toolkit/workspace/precompiled/{IO_qtpy.mpy → modules/IO_qtpy.mpy} +0 -0
- toolkit/workspace/precompiled/modules/IO_rp2.mpy +0 -0
- toolkit/workspace/precompiled/modules/IO_s3matrix.mpy +0 -0
- toolkit/workspace/precompiled/{IO_tinypico.mpy → modules/IO_tinypico.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_L298N.mpy +0 -0
- toolkit/workspace/precompiled/{LM_OV2640.mpy → modules/LM_OV2640.mpy} +0 -0
- 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/{LM_cct.mpy → 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/{LM_dimmer.mpy → modules/LM_dimmer.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_distance.mpy → modules/LM_distance.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_ds18.mpy → modules/LM_ds18.mpy} +0 -0
- {micrOS/source → toolkit/workspace/precompiled/modules}/LM_esp32.py +5 -0
- toolkit/workspace/precompiled/modules/LM_espnow.py +36 -0
- toolkit/workspace/precompiled/{LM_gameOfLife.mpy → modules/LM_gameOfLife.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_genIO.mpy → modules/LM_genIO.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_haptic.mpy → modules/LM_haptic.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_i2c.py → modules/LM_i2c.py} +1 -1
- toolkit/workspace/precompiled/{LM_i2s_mic.mpy → modules/LM_i2s_mic.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_keychain.mpy → modules/LM_keychain.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_mqtt_client.mpy +0 -0
- toolkit/workspace/precompiled/{LM_neoeffects.mpy → modules/LM_neoeffects.mpy} +0 -0
- toolkit/workspace/precompiled/modules/LM_neomatrix.mpy +0 -0
- toolkit/workspace/precompiled/{LM_neopixel.mpy → 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_oledui.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_pacman.mpy +0 -0
- toolkit/workspace/precompiled/modules/LM_presence.mpy +0 -0
- toolkit/workspace/precompiled/{LM_rest.mpy → modules/LM_rest.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_rgb.mpy → modules/LM_rgb.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_rgbcct.mpy → modules/LM_rgbcct.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_roboarm.mpy → modules/LM_roboarm.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_robustness.py → modules/LM_robustness.py} +49 -2
- 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/{LM_switch.mpy → modules/LM_switch.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_system.mpy → modules/LM_system.mpy} +0 -0
- toolkit/workspace/precompiled/{LM_tcs3472.py → modules/LM_tcs3472.py} +4 -6
- toolkit/workspace/precompiled/{LM_telegram.mpy → 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/web/dashboard.html +2 -0
- toolkit/workspace/precompiled/web/matrix_draw.html +390 -0
- toolkit/workspace/precompiled/web/uapi.js +9 -6
- micrOS/source/IO_esp32c6.py +0 -16
- micrOS/source/LM_L298N_DCmotor.py +0 -86
- micrOS/source/LM_espnow.py +0 -57
- micrOS/source/LM_mqtt_pro.py +0 -211
- toolkit/lib/file_extensions.py +0 -22
- toolkit/workspace/precompiled/Common.cpython-312.pyc +0 -0
- toolkit/workspace/precompiled/IO_esp32c6.mpy +0 -0
- toolkit/workspace/precompiled/IO_rp2.mpy +0 -0
- toolkit/workspace/precompiled/IO_s3matrix.mpy +0 -0
- toolkit/workspace/precompiled/LM_L298N_DCmotor.mpy +0 -0
- toolkit/workspace/precompiled/LM_espnow.py +0 -57
- toolkit/workspace/precompiled/LM_light_sensor.mpy +0 -0
- toolkit/workspace/precompiled/LM_mqtt_pro.py +0 -211
- toolkit/workspace/precompiled/LM_neomatrix.mpy +0 -0
- toolkit/workspace/precompiled/LM_oled_ui.mpy +0 -0
- toolkit/workspace/precompiled/LM_oledui.mpy +0 -0
- toolkit/workspace/precompiled/LM_pacman.mpy +0 -0
- toolkit/workspace/precompiled/LM_presence.mpy +0 -0
- toolkit/workspace/precompiled/Logger.cpython-312.pyc +0 -0
- toolkit/workspace/precompiled/Server.cpython-312.pyc +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_esp32s3.py → modules/IO_esp32s3.py} +0 -0
- /micrOS/source/{IO_m5stamp.py → modules/IO_m5stamp.py} +0 -0
- /micrOS/source/{IO_qtpy.py → modules/IO_qtpy.py} +0 -0
- /micrOS/source/{IO_rp2.py → modules/IO_rp2.py} +0 -0
- /micrOS/source/{IO_s3matrix.py → modules/IO_s3matrix.py} +0 -0
- /micrOS/source/{IO_tinypico.py → modules/IO_tinypico.py} +0 -0
- /micrOS/source/{LM_L9110_DCmotor.py → modules/LM_L9110_DCmotor.py} +0 -0
- /micrOS/source/{LM_OV2640.py → modules/LM_OV2640.py} +0 -0
- /micrOS/source/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +0 -0
- /micrOS/source/{LM_aht10.py → modules/LM_aht10.py} +0 -0
- /micrOS/source/{LM_bme280.py → modules/LM_bme280.py} +0 -0
- /micrOS/source/{LM_buzzer.py → modules/LM_buzzer.py} +0 -0
- /micrOS/source/{LM_cct.py → modules/LM_cct.py} +0 -0
- /micrOS/source/{LM_co2.py → modules/LM_co2.py} +0 -0
- /micrOS/source/{LM_dashboard_be.py → modules/LM_dashboard_be.py} +0 -0
- /micrOS/source/{LM_dht11.py → modules/LM_dht11.py} +0 -0
- /micrOS/source/{LM_dht22.py → modules/LM_dht22.py} +0 -0
- /micrOS/source/{LM_dimmer.py → modules/LM_dimmer.py} +0 -0
- /micrOS/source/{LM_distance.py → modules/LM_distance.py} +0 -0
- /micrOS/source/{LM_ds18.py → modules/LM_ds18.py} +0 -0
- /micrOS/source/{LM_gameOfLife.py → modules/LM_gameOfLife.py} +0 -0
- /micrOS/source/{LM_genIO.py → modules/LM_genIO.py} +0 -0
- /micrOS/source/{LM_haptic.py → modules/LM_haptic.py} +0 -0
- /micrOS/source/{LM_i2s_mic.py → modules/LM_i2s_mic.py} +0 -0
- /micrOS/source/{LM_keychain.py → modules/LM_keychain.py} +0 -0
- /micrOS/source/{LM_ld2410.py → modules/LM_ld2410.py} +0 -0
- /micrOS/source/{LM_neopixel.py → modules/LM_neopixel.py} +0 -0
- /micrOS/source/{LM_oled.py → modules/LM_oled.py} +0 -0
- /micrOS/source/{LM_oled_sh1106.py → modules/LM_oled_sh1106.py} +0 -0
- /micrOS/source/{LM_pet_feeder.py → modules/LM_pet_feeder.py} +0 -0
- /micrOS/source/{LM_qmi8658.py → modules/LM_qmi8658.py} +0 -0
- /micrOS/source/{LM_rencoder.py → modules/LM_rencoder.py} +0 -0
- /micrOS/source/{LM_rest.py → modules/LM_rest.py} +0 -0
- /micrOS/source/{LM_rgb.py → modules/LM_rgb.py} +0 -0
- /micrOS/source/{LM_rgbcct.py → modules/LM_rgbcct.py} +0 -0
- /micrOS/source/{LM_roboarm.py → modules/LM_roboarm.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_servo.py → modules/LM_servo.py} +0 -0
- /micrOS/source/{LM_sound_event.py → modules/LM_sound_event.py} +0 -0
- /micrOS/source/{LM_stepper.py → modules/LM_stepper.py} +0 -0
- /micrOS/source/{LM_switch.py → modules/LM_switch.py} +0 -0
- /micrOS/source/{LM_system.py → modules/LM_system.py} +0 -0
- /micrOS/source/{LM_telegram.py → modules/LM_telegram.py} +0 -0
- /micrOS/source/{LM_tinyrgb.py → modules/LM_tinyrgb.py} +0 -0
- /micrOS/source/{LM_trackball.py → modules/LM_trackball.py} +0 -0
- /micrOS/source/{LM_veml7700.py → modules/LM_veml7700.py} +0 -0
- {microsdevtoolkit-2.13.0.data → microsdevtoolkit-2.17.0.data}/scripts/devToolKit.py +0 -0
- {microsdevtoolkit-2.13.0.dist-info → microsdevtoolkit-2.17.0.dist-info}/WHEEL +0 -0
- {microsdevtoolkit-2.13.0.dist-info → microsdevtoolkit-2.17.0.dist-info}/licenses/LICENSE +0 -0
- {microsdevtoolkit-2.13.0.dist-info → microsdevtoolkit-2.17.0.dist-info}/top_level.txt +0 -0
- /toolkit/workspace/precompiled/{LM_L9110_DCmotor.py → modules/LM_L9110_DCmotor.py} +0 -0
- /toolkit/workspace/precompiled/{LM_VL53L0X.py → modules/LM_VL53L0X.py} +0 -0
- /toolkit/workspace/precompiled/{LM_dashboard_be.py → modules/LM_dashboard_be.py} +0 -0
- /toolkit/workspace/precompiled/{LM_pet_feeder.py → modules/LM_pet_feeder.py} +0 -0
- /toolkit/workspace/precompiled/{LM_qmi8658.py → modules/LM_qmi8658.py} +0 -0
- /toolkit/workspace/precompiled/{LM_rencoder.py → modules/LM_rencoder.py} +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
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from Espnow import ESPNowSS
|
|
2
|
+
ESPNOW = ESPNowSS()
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def send(peer:bytes|str, cmd:str='modules'):
|
|
6
|
+
"""
|
|
7
|
+
Send message to peer (by mac address)
|
|
8
|
+
:param peer: mac address of espnow device
|
|
9
|
+
:param cmd: message string/load module call
|
|
10
|
+
"""
|
|
11
|
+
return ESPNOW.send(peer, cmd)
|
|
12
|
+
|
|
13
|
+
def stats():
|
|
14
|
+
"""
|
|
15
|
+
Get ESPNOW stats
|
|
16
|
+
"""
|
|
17
|
+
return ESPNOW.stats()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def handshake(peer:bytes|str):
|
|
21
|
+
"""
|
|
22
|
+
Handshake with ESPNow Peer
|
|
23
|
+
:param peer: mac address of espnow device
|
|
24
|
+
- device name detection
|
|
25
|
+
- address:name caching
|
|
26
|
+
"""
|
|
27
|
+
return ESPNOW.handshake(peer)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def help():
|
|
31
|
+
"""
|
|
32
|
+
ESPNOW sender/receiver with LM execution
|
|
33
|
+
"""
|
|
34
|
+
return ('handshake peer=<mac-address>',
|
|
35
|
+
'send peer=<peer-name> cmd="hello"',
|
|
36
|
+
'stats')
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -26,7 +26,7 @@ def discover():
|
|
|
26
26
|
"""
|
|
27
27
|
known_addresses = {hex(0x0A): "TRACKBALL", hex(0x3c): "OLED",
|
|
28
28
|
hex(0x76): "BME280", hex(0x10): 'VEML7700',
|
|
29
|
-
hex(0x6b): "QMI8658"}
|
|
29
|
+
hex(0x6b): "QMI8658", hex(0x29): 'TCS3472'}
|
|
30
30
|
devices = scan()
|
|
31
31
|
output = {"unknown": []}
|
|
32
32
|
for k in devices:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from LM_system import memory_usage
|
|
2
|
-
from Common import socket_stream, syslog
|
|
2
|
+
from Common import socket_stream, syslog, micro_task
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
@socket_stream
|
|
@@ -61,6 +61,52 @@ def _recursion(cnt, msgobj=None):
|
|
|
61
61
|
remain = 0
|
|
62
62
|
return remain
|
|
63
63
|
|
|
64
|
+
################## TEST micro_task UCs ##########################
|
|
65
|
+
|
|
66
|
+
async def __task(tag, period_ms):
|
|
67
|
+
counter = 0
|
|
68
|
+
with micro_task(tag=tag) as my_task:
|
|
69
|
+
while True:
|
|
70
|
+
# DO something here in the async loop...
|
|
71
|
+
counter += 1
|
|
72
|
+
|
|
73
|
+
# Store data in task cache (task show mytask)
|
|
74
|
+
my_task.out = f'MyTask Counter: {counter}'
|
|
75
|
+
|
|
76
|
+
# Async sleep - feed event loop
|
|
77
|
+
await my_task.feed(sleep_ms=period_ms)
|
|
78
|
+
# [i] feed same as "await asyncio.sleep_ms(period_ms)" with micrOS features (WDT)
|
|
79
|
+
|
|
80
|
+
def create_task():
|
|
81
|
+
"""
|
|
82
|
+
Legacy way of task creation (with exact task tagging)
|
|
83
|
+
"""
|
|
84
|
+
# [!] ASYNC TASK CREATION [1*] with async task callback + taskID (TAG) handling
|
|
85
|
+
task_tag = "microtask.run"
|
|
86
|
+
state = micro_task(tag=task_tag, task=__task(tag=task_tag, period_ms=5))
|
|
87
|
+
return "Starting" if state else "Already running"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@micro_task("microtask", _wrap=True)
|
|
91
|
+
async def mytask(tag, period_ms=30):
|
|
92
|
+
"""
|
|
93
|
+
New shorter way of task creation
|
|
94
|
+
with decorator function
|
|
95
|
+
"""
|
|
96
|
+
counter = 0
|
|
97
|
+
with micro_task(tag=tag) as my_task:
|
|
98
|
+
while True:
|
|
99
|
+
# DO something here in the async loop...
|
|
100
|
+
counter += 1
|
|
101
|
+
|
|
102
|
+
# Store data in task cache (task show mytask)
|
|
103
|
+
my_task.out = f'MyTask Counter: {counter}'
|
|
104
|
+
|
|
105
|
+
# Async sleep - feed event loop
|
|
106
|
+
await my_task.feed(sleep_ms=period_ms)
|
|
107
|
+
# [i] feed same as "await asyncio.sleep_ms(period_ms)" with micrOS features (WDT)
|
|
108
|
+
|
|
109
|
+
##############################################################################
|
|
64
110
|
|
|
65
111
|
def help(widgets=False):
|
|
66
112
|
"""
|
|
@@ -70,5 +116,6 @@ def help(widgets=False):
|
|
|
70
116
|
(widgets=True) list of widget json for UI generation
|
|
71
117
|
"""
|
|
72
118
|
return 'NOTE: This is a test module to validate system robustness', \
|
|
73
|
-
'raise_error', 'memory_leak cnt=160', 'recursion_limit cnt=14'
|
|
119
|
+
'raise_error', 'memory_leak cnt=160', 'recursion_limit cnt=14', \
|
|
120
|
+
'create_task', 'mytask'
|
|
74
121
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -17,20 +17,15 @@ class TCS3472:
|
|
|
17
17
|
def __init__(self, bus, address=0x29):
|
|
18
18
|
self._bus = bus
|
|
19
19
|
self._i2c_address = address
|
|
20
|
-
|
|
21
|
-
self._bus.start()
|
|
22
|
-
|
|
23
20
|
self._bus.writeto(self._i2c_address, b'\x80\x03')
|
|
24
21
|
self._bus.writeto(self._i2c_address, b'\x81\x2b')
|
|
25
|
-
|
|
26
22
|
TCS3472.INSTANCE = self
|
|
27
23
|
|
|
28
24
|
def scaled(self):
|
|
29
25
|
crgb = self.raw()
|
|
30
26
|
if crgb[0] > 0:
|
|
31
27
|
return tuple(float(x) / crgb[0] for x in crgb[1:])
|
|
32
|
-
|
|
33
|
-
return (0, 0, 0)
|
|
28
|
+
return 0, 0, 0
|
|
34
29
|
|
|
35
30
|
def rgb(self):
|
|
36
31
|
return tuple(int(x * 255) for x in self.scaled())
|
|
@@ -72,4 +67,7 @@ def measure():
|
|
|
72
67
|
|
|
73
68
|
|
|
74
69
|
def help(widgest=False):
|
|
70
|
+
"""
|
|
71
|
+
TCS3472 Color sensor
|
|
72
|
+
"""
|
|
75
73
|
return 'load', 'measure'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
</head>
|
|
39
39
|
<body>
|
|
40
40
|
<h1> micrOS dashboard </h1>
|
|
41
|
+
<p id="restInfo"></p>
|
|
41
42
|
<!-- Container for the dynamically generated list -->
|
|
42
43
|
<section id="widgets-section"></section>
|
|
43
44
|
<br><br><br>
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
<script>
|
|
55
56
|
document.addEventListener("DOMContentLoaded", function() {
|
|
56
57
|
// Init basic info from board after DOM is fully loaded
|
|
58
|
+
restInfo(showPages=false);
|
|
57
59
|
|
|
58
60
|
// INIT DASHBOARD (load active modules -> build page)
|
|
59
61
|
DynamicWidgetLoad();
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
6
|
+
<meta name="theme-color" content="black" media="(prefers-color-scheme: dark)" />
|
|
7
|
+
<title>micrOS Matrix Drawer</title>
|
|
8
|
+
<link rel="stylesheet" href="ustyle.css" />
|
|
9
|
+
<script src="uapi.js" defer></script>
|
|
10
|
+
<style>
|
|
11
|
+
body { font-family: sans-serif; margin: 20px; }
|
|
12
|
+
.layout {
|
|
13
|
+
display: flex; justify-content: center; align-items: flex-start;
|
|
14
|
+
gap: 20px; margin: 20px auto; flex-wrap: wrap;
|
|
15
|
+
}
|
|
16
|
+
.matrix { display: grid; gap: 2px; touch-action: none; }
|
|
17
|
+
.pixel {
|
|
18
|
+
width: 30px; height: 30px; background: #000; border: 1px solid #333;
|
|
19
|
+
cursor: pointer; user-select: none; touch-action: none;
|
|
20
|
+
}
|
|
21
|
+
input[type="number"], input[type="color"] { margin: 10px; padding: 4px; }
|
|
22
|
+
button { margin: 6px; padding: 6px 12px; }
|
|
23
|
+
pre {
|
|
24
|
+
text-align: left; max-width: 800px; margin: auto; background: #111;
|
|
25
|
+
color: #0f0; padding: 10px; overflow-x: auto;
|
|
26
|
+
}
|
|
27
|
+
textarea {
|
|
28
|
+
width: 100%; max-width: 400px; display: block; margin: 10px auto;
|
|
29
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
|
30
|
+
background:#111; color:#0f0; border:1px solid #333; padding:8px;
|
|
31
|
+
resize:vertical; white-space:pre; overflow:auto;
|
|
32
|
+
}
|
|
33
|
+
.side-panel { flex: 0 0 420px; }
|
|
34
|
+
h1, .controls, h3 { text-align: center; }
|
|
35
|
+
</style>
|
|
36
|
+
</head>
|
|
37
|
+
<body>
|
|
38
|
+
<h1>microWeb Matrix LED Drawer</h1>
|
|
39
|
+
<p id="restInfo" class="controls"></p>
|
|
40
|
+
|
|
41
|
+
<!-- Controls -->
|
|
42
|
+
<div class="controls">
|
|
43
|
+
<input type="color" id="colorPicker" value="#00ff00" title="Pick LED color" class="custom-color-picker" />
|
|
44
|
+
<input type="number" id="matrixSize" value="8" min="1" max="64" title="Matrix size (NxN)" />
|
|
45
|
+
<button onclick="applySize()">Resize</button>
|
|
46
|
+
<button onclick="clearMatrix()">🧹 Clear Screen</button>
|
|
47
|
+
<button onclick="restAPI('neomatrix/stop', true)">⏹️ Stop Animation</button>
|
|
48
|
+
<button onclick="restAPI('neomatrix/snake', true)">▶️ Start Animation</button>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<!-- Matrix left, tools right -->
|
|
52
|
+
<div class="layout">
|
|
53
|
+
<!-- Matrix grid -->
|
|
54
|
+
<div id="matrix" class="matrix"></div>
|
|
55
|
+
|
|
56
|
+
<!-- Side panel -->
|
|
57
|
+
<div class="side-panel">
|
|
58
|
+
<!-- Read device state -->
|
|
59
|
+
<button id="readStateBtn" onclick="getMatrixState()">📥 Read Matrix State</button>
|
|
60
|
+
<textarea id="matrixStateOut" rows="4"
|
|
61
|
+
placeholder="Matrix state (original format) will appear here on ONE line…"></textarea>
|
|
62
|
+
|
|
63
|
+
<!-- Send Matrix Data -->
|
|
64
|
+
<h3>📤 Send Matrix Data</h3>
|
|
65
|
+
<textarea id="matrixInput" rows="6"
|
|
66
|
+
placeholder="Paste like: [(0,0,(131,17,0)), (1,0,(...)), ...]"></textarea>
|
|
67
|
+
<div style="display:flex;gap:10px;flex-wrap:wrap;justify-content:center">
|
|
68
|
+
<button id="sendMatrixBtn" onclick="sendMatrixFromInput()">🚀 Send (batched 15)</button>
|
|
69
|
+
<button onclick="applyMatrixInputLocally()">🖌️ Apply Locally</button>
|
|
70
|
+
</div>
|
|
71
|
+
<p id="matrixInputStatus" style="margin:6px auto;color:#9cf;text-align:center"></p>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<!-- REST Debug Console -->
|
|
76
|
+
<hr>
|
|
77
|
+
<h3>🛠 REST Debug Console</h3>
|
|
78
|
+
<p id="restConsoleUrl"></p>
|
|
79
|
+
<pre id="restConsoleResponse"></pre>
|
|
80
|
+
<p id="restConsoleTime"></p>
|
|
81
|
+
|
|
82
|
+
<!-- === ORIGINAL SCRIPT (unchanged except pointerleave/mouseleave for robustness) === -->
|
|
83
|
+
<script>
|
|
84
|
+
const matrixContainer = document.getElementById('matrix');
|
|
85
|
+
const colorPicker = document.getElementById('colorPicker');
|
|
86
|
+
const sizeInput = document.getElementById('matrixSize');
|
|
87
|
+
let pixels = [];
|
|
88
|
+
let drawing = false;
|
|
89
|
+
let activePointerId = null;
|
|
90
|
+
const supportsPointer = window.PointerEvent;
|
|
91
|
+
|
|
92
|
+
// Track last painted pixel
|
|
93
|
+
let lastX = null;
|
|
94
|
+
let lastY = null;
|
|
95
|
+
|
|
96
|
+
// --- Queue system (no overlapping REST calls) ---
|
|
97
|
+
let updateQueue = [];
|
|
98
|
+
let updating = false;
|
|
99
|
+
|
|
100
|
+
async function processQueue() {
|
|
101
|
+
if (updating || updateQueue.length === 0) return;
|
|
102
|
+
updating = true;
|
|
103
|
+
const { cmd } = updateQueue.shift();
|
|
104
|
+
try {
|
|
105
|
+
await restAPI(cmd, true);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
console.warn("REST call failed:", err);
|
|
108
|
+
}
|
|
109
|
+
updating = false;
|
|
110
|
+
if (updateQueue.length > 0) processQueue();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function queueUpdate(cmd) {
|
|
114
|
+
updateQueue.push({ cmd });
|
|
115
|
+
processQueue();
|
|
116
|
+
}
|
|
117
|
+
// -------------------------------------------------
|
|
118
|
+
|
|
119
|
+
function startDrawing(e) {
|
|
120
|
+
drawing = true;
|
|
121
|
+
if (supportsPointer) {
|
|
122
|
+
activePointerId = e.pointerId;
|
|
123
|
+
matrixContainer.setPointerCapture(activePointerId);
|
|
124
|
+
}
|
|
125
|
+
paintPixel(e.target);
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function moveDrawing(e) {
|
|
130
|
+
if (!drawing) return;
|
|
131
|
+
let target;
|
|
132
|
+
if (supportsPointer) {
|
|
133
|
+
target = document.elementFromPoint(e.clientX, e.clientY);
|
|
134
|
+
} else if (e.touches && e.touches.length) {
|
|
135
|
+
const t = e.touches[0];
|
|
136
|
+
target = document.elementFromPoint(t.clientX, t.clientY);
|
|
137
|
+
e.preventDefault();
|
|
138
|
+
} else {
|
|
139
|
+
target = document.elementFromPoint(e.clientX, e.clientY);
|
|
140
|
+
}
|
|
141
|
+
if (target && target.classList.contains('pixel')) {
|
|
142
|
+
paintPixel(target);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function stopDrawing() {
|
|
147
|
+
drawing = false;
|
|
148
|
+
lastX = null;
|
|
149
|
+
lastY = null;
|
|
150
|
+
if (supportsPointer && activePointerId !== null) {
|
|
151
|
+
matrixContainer.releasePointerCapture(activePointerId);
|
|
152
|
+
activePointerId = null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (supportsPointer) {
|
|
157
|
+
matrixContainer.addEventListener('pointermove', moveDrawing);
|
|
158
|
+
window.addEventListener('pointerup', stopDrawing);
|
|
159
|
+
window.addEventListener('pointercancel', stopDrawing);
|
|
160
|
+
matrixContainer.addEventListener('pointerleave', stopDrawing); // added
|
|
161
|
+
} else {
|
|
162
|
+
matrixContainer.addEventListener('mousemove', moveDrawing);
|
|
163
|
+
matrixContainer.addEventListener('touchmove', moveDrawing, { passive: false });
|
|
164
|
+
window.addEventListener('mouseup', stopDrawing);
|
|
165
|
+
window.addEventListener('touchend', stopDrawing);
|
|
166
|
+
window.addEventListener('touchcancel', stopDrawing);
|
|
167
|
+
matrixContainer.addEventListener('mouseleave', stopDrawing); // added
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function hexToRgb(hex) {
|
|
171
|
+
const val = parseInt(hex.slice(1), 16);
|
|
172
|
+
return [(val >> 16) & 255, (val >> 8) & 255, val & 255];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function buildMatrix(size) {
|
|
176
|
+
matrixContainer.innerHTML = "";
|
|
177
|
+
pixels = [];
|
|
178
|
+
matrixContainer.style.gridTemplateColumns = `repeat(${size}, 30px)`;
|
|
179
|
+
matrixContainer.style.gridTemplateRows = `repeat(${size}, 30px)`;
|
|
180
|
+
|
|
181
|
+
for (let y = 0; y < size; y++) {
|
|
182
|
+
for (let x = 0; x < size; x++) {
|
|
183
|
+
const cell = document.createElement('div');
|
|
184
|
+
cell.className = "pixel";
|
|
185
|
+
cell.dataset.x = x;
|
|
186
|
+
cell.dataset.y = y;
|
|
187
|
+
cell.dataset.color = "#000000";
|
|
188
|
+
cell.style.backgroundColor = "#000000";
|
|
189
|
+
if (supportsPointer) {
|
|
190
|
+
cell.addEventListener('pointerdown', startDrawing);
|
|
191
|
+
} else {
|
|
192
|
+
cell.addEventListener('mousedown', startDrawing);
|
|
193
|
+
cell.addEventListener('touchstart', startDrawing, { passive: false });
|
|
194
|
+
}
|
|
195
|
+
matrixContainer.appendChild(cell);
|
|
196
|
+
pixels.push(cell);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
sendClearCommand();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function paintPixel(pixelDiv) {
|
|
203
|
+
const color = colorPicker.value;
|
|
204
|
+
const x = parseInt(pixelDiv.dataset.x);
|
|
205
|
+
const y = parseInt(pixelDiv.dataset.y);
|
|
206
|
+
|
|
207
|
+
// Only update if new pixel
|
|
208
|
+
if (x === lastX && y === lastY) return;
|
|
209
|
+
lastX = x;
|
|
210
|
+
lastY = y;
|
|
211
|
+
|
|
212
|
+
pixelDiv.dataset.color = color;
|
|
213
|
+
pixelDiv.style.backgroundColor = color;
|
|
214
|
+
|
|
215
|
+
const [r, g, b] = hexToRgb(color);
|
|
216
|
+
const cmd = `neomatrix/draw_colormap/[(${x},${y},(${r},${g},${b}))]`;
|
|
217
|
+
queueUpdate(cmd);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function clearMatrix() {
|
|
221
|
+
pixels.forEach(p => {
|
|
222
|
+
p.dataset.color = "#000000";
|
|
223
|
+
p.style.backgroundColor = "#000000";
|
|
224
|
+
});
|
|
225
|
+
sendClearCommand();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function sendClearCommand() {
|
|
229
|
+
queueUpdate("neomatrix/draw_colormap/[]");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function applySize() {
|
|
233
|
+
buildMatrix(parseInt(sizeInput.value, 10));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Initialize matrix
|
|
237
|
+
buildMatrix(parseInt(sizeInput.value, 10));
|
|
238
|
+
|
|
239
|
+
document.addEventListener("DOMContentLoaded", function() {
|
|
240
|
+
// Add device info
|
|
241
|
+
restInfo(showPages=false);
|
|
242
|
+
});
|
|
243
|
+
</script>
|
|
244
|
+
<!-- === END original script === -->
|
|
245
|
+
|
|
246
|
+
<!-- === getMatrixState (robust parsing + auto-resize) === -->
|
|
247
|
+
<script>
|
|
248
|
+
// tolerant tuple parser used here and by sender
|
|
249
|
+
function parseTuplesRegex(str) {
|
|
250
|
+
if (!str || typeof str !== 'string') return null;
|
|
251
|
+
const out = [];
|
|
252
|
+
const re = /\(\s*(\d+)\s*,\s*(\d+)\s*,\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*\)/g;
|
|
253
|
+
let m;
|
|
254
|
+
while ((m = re.exec(str)) !== null) {
|
|
255
|
+
out.push({ x:+m[1], y:+m[2], r:+m[3], g:+m[4], b:+m[5] });
|
|
256
|
+
}
|
|
257
|
+
return out.length ? out : null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function rgbToHex(r, g, b) {
|
|
261
|
+
const toHex = (n) => Math.max(0, Math.min(255, n|0)).toString(16).padStart(2, '0');
|
|
262
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
263
|
+
}
|
|
264
|
+
function blackoutMatrixUI() {
|
|
265
|
+
const cells = document.querySelectorAll('.pixel');
|
|
266
|
+
cells.forEach(p => { p.dataset.color = "#000000"; p.style.backgroundColor = "#000000"; });
|
|
267
|
+
}
|
|
268
|
+
function ensureGridFits(cells) {
|
|
269
|
+
if (!Array.isArray(cells) || !cells.length) return;
|
|
270
|
+
const maxX = Math.max(...cells.map(c => c.x));
|
|
271
|
+
const maxY = Math.max(...cells.map(c => c.y));
|
|
272
|
+
const need = Math.max(maxX, maxY) + 1;
|
|
273
|
+
const current = parseInt(document.getElementById('matrixSize').value, 10) || 8;
|
|
274
|
+
if (need > current) {
|
|
275
|
+
document.getElementById('matrixSize').value = need;
|
|
276
|
+
applySize();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async function getMatrixState() {
|
|
281
|
+
const btn = document.getElementById('readStateBtn');
|
|
282
|
+
const out = document.getElementById('matrixStateOut');
|
|
283
|
+
if (btn) btn.disabled = true;
|
|
284
|
+
if (out) out.value = "Reading…";
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const resp = await restAPI('neomatrix/get_colormap', true);
|
|
288
|
+
|
|
289
|
+
// Extract original tuple-like data as a string
|
|
290
|
+
let raw = '';
|
|
291
|
+
if (resp && typeof resp === 'object' && 'result' in resp) raw = String(resp.result);
|
|
292
|
+
else if (typeof resp === 'string') raw = resp;
|
|
293
|
+
else if (resp && typeof resp.text === 'string') raw = resp.text;
|
|
294
|
+
else if (resp && typeof resp.body === 'string') raw = resp.body;
|
|
295
|
+
else raw = JSON.stringify(resp);
|
|
296
|
+
|
|
297
|
+
// Single-line for easy copy
|
|
298
|
+
const oneLine = String(raw).replace(/[\r\n]+/g, ' ').trim();
|
|
299
|
+
if (out) out.value = oneLine;
|
|
300
|
+
|
|
301
|
+
const parsed = parseTuplesRegex(oneLine);
|
|
302
|
+
blackoutMatrixUI();
|
|
303
|
+
if (!parsed) return;
|
|
304
|
+
|
|
305
|
+
ensureGridFits(parsed);
|
|
306
|
+
|
|
307
|
+
for (const {x,y,r,g,b} of parsed) {
|
|
308
|
+
const cell = document.querySelector(`.pixel[data-x="${x}"][data-y="${y}"]`);
|
|
309
|
+
if (!cell) continue;
|
|
310
|
+
const hex = rgbToHex(r,g,b);
|
|
311
|
+
cell.dataset.color = hex;
|
|
312
|
+
cell.style.backgroundColor = hex;
|
|
313
|
+
}
|
|
314
|
+
} catch (e) {
|
|
315
|
+
if (out) out.value = "Error: could not read matrix state.";
|
|
316
|
+
blackoutMatrixUI();
|
|
317
|
+
} finally {
|
|
318
|
+
if (btn) btn.disabled = false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// expose globally (matches your original pattern)
|
|
322
|
+
window.getMatrixState = getMatrixState;
|
|
323
|
+
</script>
|
|
324
|
+
<!-- === END getMatrixState === -->
|
|
325
|
+
|
|
326
|
+
<!-- === SENDER: GLOBAL FUNCTIONS (fixes ReferenceError) === -->
|
|
327
|
+
<script>
|
|
328
|
+
function setSenderStatus(msg, isError=false){
|
|
329
|
+
const el = document.getElementById('matrixInputStatus');
|
|
330
|
+
if (!el) return;
|
|
331
|
+
el.textContent = msg;
|
|
332
|
+
el.style.color = isError ? '#f99' : '#9cf';
|
|
333
|
+
}
|
|
334
|
+
function applyCellsToUI(cells){
|
|
335
|
+
for (const {x,y,r,g,b} of cells) {
|
|
336
|
+
const cell = document.querySelector(`.pixel[data-x="${x}"][data-y="${y}"]`);
|
|
337
|
+
if (!cell) continue;
|
|
338
|
+
const toHex = n => Math.max(0,Math.min(255,n|0)).toString(16).padStart(2,'0');
|
|
339
|
+
const hex = `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
340
|
+
cell.dataset.color = hex;
|
|
341
|
+
cell.style.backgroundColor = hex;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function buildPayload(cells){
|
|
345
|
+
const parts = cells.map(({x,y,r,g,b}) => `(${x},${y},(${r},${g},${b}))`);
|
|
346
|
+
return `[${parts.join(',')}]`.replace(/\//g, '');
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Make these GLOBAL so inline onclick finds them:
|
|
350
|
+
function applyMatrixInputLocally(){
|
|
351
|
+
const raw = (document.getElementById('matrixInput')?.value || '').trim();
|
|
352
|
+
const parsed = parseTuplesRegex(raw);
|
|
353
|
+
if (!parsed) { setSenderStatus('Could not parse input. Use [(x,y,(r,g,b)), ...]', true); return; }
|
|
354
|
+
applyCellsToUI(parsed);
|
|
355
|
+
setSenderStatus(`Applied ${parsed.length} cells locally.`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function sendMatrixFromInput(){
|
|
359
|
+
const btn = document.getElementById('sendMatrixBtn');
|
|
360
|
+
const raw = (document.getElementById('matrixInput')?.value || '').trim();
|
|
361
|
+
const parsed = parseTuplesRegex(raw);
|
|
362
|
+
if (!parsed) { setSenderStatus('Could not parse input. Use [(x,y,(r,g,b)), ...]', true); return; }
|
|
363
|
+
|
|
364
|
+
if (btn) btn.disabled = true;
|
|
365
|
+
setSenderStatus(`Sending ${parsed.length} cells in batches of 15…`);
|
|
366
|
+
|
|
367
|
+
// Update UI immediately for responsiveness
|
|
368
|
+
applyCellsToUI(parsed);
|
|
369
|
+
|
|
370
|
+
const CHUNK = 10;
|
|
371
|
+
let sent = 0;
|
|
372
|
+
for (let i = 0; i < parsed.length; i += CHUNK) {
|
|
373
|
+
const chunk = parsed.slice(i, i + CHUNK);
|
|
374
|
+
const payload = buildPayload(chunk);
|
|
375
|
+
const cmd = `neomatrix/draw_colormap/${payload}`;
|
|
376
|
+
queueUpdate(cmd);
|
|
377
|
+
sent += chunk.length;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
setSenderStatus(`Queued ${sent} cells in ${Math.ceil(parsed.length / CHUNK)} batch(es).`);
|
|
381
|
+
if (btn) btn.disabled = false;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Expose on window explicitly (paranoia, but harmless)
|
|
385
|
+
window.applyMatrixInputLocally = applyMatrixInputLocally;
|
|
386
|
+
window.sendMatrixFromInput = sendMatrixFromInput;
|
|
387
|
+
</script>
|
|
388
|
+
<!-- === END sender === -->
|
|
389
|
+
</body>
|
|
390
|
+
</html>
|
|
@@ -41,18 +41,21 @@ function restConsole(apiUrl, data, delta) {
|
|
|
41
41
|
document.getElementById('restConsoleTime').innerHTML = `⏱ Response time: ${delta} ms`;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function restInfo() {
|
|
44
|
+
function restInfo(showPages=true) {
|
|
45
45
|
// UPDATES: 'restInfo' and restConsole(...)
|
|
46
|
-
restAPICore(cmd='').then(({ response, delta, query }) => {
|
|
46
|
+
restAPICore(cmd = '').then(({ response, delta, query }) => {
|
|
47
47
|
// Update API Console
|
|
48
48
|
restConsole(query, response, delta)
|
|
49
|
-
// Update '
|
|
49
|
+
// Update 'restInfo' tag
|
|
50
50
|
const result = response['result'];
|
|
51
51
|
const auth = result.auth ? "🔑" : "";
|
|
52
52
|
let infoHeader = `micrOS: ${result.micrOS} ❖ node: ${result.node}${auth}`;
|
|
53
|
-
let infoSubpages =
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
let infoSubpages = "";
|
|
54
|
+
if (showPages && result['usr_endpoints']) {
|
|
55
|
+
infoSubpages = "<br><br>📎 " + Object.entries(result['usr_endpoints'])
|
|
56
|
+
.map(([key, value]) => `<a href="${value}" target="_blank" style="color: white;">${value} </a>`)
|
|
57
|
+
.join(' | ');
|
|
58
|
+
}
|
|
56
59
|
document.getElementById('restInfo').innerHTML = infoHeader + infoSubpages;
|
|
57
60
|
}).catch(error => {
|
|
58
61
|
console.error('Error in restAPI:', error);
|
micrOS/source/IO_esp32c6.py
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
from micropython import const
|
|
2
|
-
|
|
3
|
-
# BUILTIN LED
|
|
4
|
-
builtin = const(-15) # BUILT IN LED - progress_led
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# I2C BUS
|
|
8
|
-
i2c_sda = const(4) # D21 - oled - data
|
|
9
|
-
i2c_scl = const(5) # D22 - oled - clock
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# EXTERNAL EVENT IRQ
|
|
13
|
-
irq1 = const(3) # D4 - event irq pin
|
|
14
|
-
irq2 = const(2) # D18 - event irq pin
|
|
15
|
-
irq3 = const(1) # D19 - event irq pin
|
|
16
|
-
irq4 = const(0) # D13 - event irq pin
|