Sandboxed Lua state (espressif/lua v5.5.0, base/table/string/math only, no io/os/package/debug) exposes a kvida API table (chip_temperature, set_led, publish) to a compiled-in default script that reads chip temperature, maps it to an LED color, and publishes the reading to Home Assistant. Generalizes transport's publish_chip_temperature() into publish_value(name, value), the first real use of AGENTS.md's semantic publish API. Requires -DLUA_32BITS globally since this toolchain's long long support isn't visible to Lua's default build. Verified on real ESP32-C6 hardware: no crashes/errors across multiple serial monitor windows, LED changes color, chip_temperature sensor appears in Home Assistant via MQTT Discovery. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
26 lines
3.0 KiB
Markdown
26 lines
3.0 KiB
Markdown
# lua_runtime
|
|
|
|
Executes the sandboxed Lua program (compiled from Blockly) that defines device behaviour. Exposes the Kvida API (e.g. `publish("temperature", 21.3)`) to Lua scripts; Lua never touches ESP-IDF or `transport` directly. `REQUIRES drivers profiles transport`.
|
|
|
|
Built on `espressif/lua` (v5.5.0, pinned in `idf_component.yml`) -- Espressif's own official IDF Component Registry package, MIT licensed, built specifically for embedding Lua in ESP-IDF apps. No JS/exotic bindings: standard `lua_State`/`luaL_newstate`/`lua_pushcfunction` C API. The project's fourth external managed component (after `mdns`, `mqtt`, `led_strip`).
|
|
|
|
## What's here
|
|
|
|
- `lua_runtime_init()` creates the Lua state, opens only `base`/`table`/`string`/`math` (deliberately *not* `luaL_openlibs()`, which would also expose `io`, `os`, `package`/`require`, `debug` -- see AGENTS.md's "Lua should never access ESP-IDF directly"), registers the `kvida` API table, then loads the default script (`src/default_script.h`, a compiled-in string) which just *defines* `on_tick()`.
|
|
- `lua_runtime_tick()` calls `on_tick()` -- one "wake, execute Lua, publish changes, sleep" cycle. A Lua runtime error is logged, not fatal.
|
|
- The `kvida` table exposed to scripts:
|
|
- `kvida.chip_temperature()` -- reads the ESP32-C6's internal die temperature via `profiles::ChipTemperatureSensor` (the same `Sensor` implementation `main.cpp` used directly before this component existed).
|
|
- `kvida.set_led(r, g, b)` -- sets the onboard WS2812 via `drivers::rgb_led_set_color()`.
|
|
- `kvida.publish(name, value)` -- calls `transport::publish_value()`, AGENTS.md's semantic publish API, built for the first time here.
|
|
- The default script reads chip temperature, maps it to a blue(cool)-to-red(hot) LED color (linear interpolation, 20-60C, clamped), and publishes the reading to Home Assistant. Verified end-to-end on real hardware.
|
|
|
|
## Known limitation, accepted for now
|
|
|
|
The onboard LED is also controllable manually from Home Assistant (an MQTT light entity, see `components/transport/src/mqtt.cpp`). The two aren't reconciled: `on_tick()` overwrites a manually-chosen HA color every 30s. Accepted as a conflict between two "quick proof" demos rather than solved now -- a real answer (e.g. a Lua-settable "mode" toggle, or the MQTT light entity deferring to Lua) needs product input, not a guess.
|
|
|
|
## Not yet done
|
|
|
|
- The script is compiled in, not loaded from storage -- there's no upload mechanism yet. Once `kvida-sdk` can push a script (and `drivers` mounts the `storage` LittleFS partition -- both still TODO), scripts should be loaded from there instead.
|
|
- No Blockly-to-Lua compiler exists yet (that's `kvida-sdk`'s job per AGENTS.md's "Level 2").
|
|
- No memory/CPU/runtime limits on the Lua state beyond the restricted library set -- a script with an infinite loop would hang `lua_runtime_tick()` (and, since it currently runs on the same timer callback, block other `esp_timer` callbacks too). Not a concern for a compiled-in, developer-authored script; becomes one once arbitrary user scripts can be uploaded.
|