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>
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 onlybase/table/string/math(deliberately notluaL_openlibs(), which would also exposeio,os,package/require,debug-- see AGENTS.md's "Lua should never access ESP-IDF directly"), registers thekvidaAPI table, then loads the default script (src/default_script.h, a compiled-in string) which just defineson_tick().lua_runtime_tick()callson_tick()-- one "wake, execute Lua, publish changes, sleep" cycle. A Lua runtime error is logged, not fatal.- The
kvidatable exposed to scripts:kvida.chip_temperature()-- reads the ESP32-C6's internal die temperature viaprofiles::ChipTemperatureSensor(the sameSensorimplementationmain.cppused directly before this component existed).kvida.set_led(r, g, b)-- sets the onboard WS2812 viadrivers::rgb_led_set_color().kvida.publish(name, value)-- callstransport::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-sdkcan push a script (anddriversmounts thestorageLittleFS 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 otheresp_timercallbacks too). Not a concern for a compiled-in, developer-authored script; becomes one once arbitrary user scripts can be uploaded.