Документация
Documentation
Quick start
Arduino IDE: Library Manager → RisalDash. PlatformIO:
; platformio.ini
lib_deps =
RisalDash
ESP Async WebServer
AsyncTCP ; ESP32 A minimal sketch — five widgets, an access point, live over WebSocket:
#include <RisalUI.h>
RisalUI dash("Greenhouse");
float temp, volts; bool pump = false;
void setup() {
dash.gauge ("Voltage", &volts, 0, 14, "V");
dash.chart ("Temp", &temp, "°C").history(30);
dash.toggle("Pump", &pump, [](bool on){ digitalWrite(PUMP_PIN, on); });
dash.beginAP("Greenhouse", "12345678"); // access point
}
void loop() {
temp = readTemp(); volts = readVolts();
dash.update(); // pushes changes over WebSocket
} Open http://192.168.4.1/ after joining the AP. No front-end code, no HTML files.
Core concepts
Zero-Waste UI
The linker (--gc-sections) strips the code of widgets you never instantiate. CSS/JS for a widget reaches flash only if its class is used. Empty core is < 8 KB flash / < 2 KB RAM; a new widget costs ~200–400 bytes.
Offline-first
Everything is served from the device — system fonts, zero external requests. The dashboard renders with no internet, which is the normal state on first boot.
WebSocket protocol
The device pushes only changed values as compact JSON ({ "Temp": 24.3 }); the client sends commands in the same shape. dash.update() diffs and pushes.
Widgets & sensors
30+ chainable widgets across display, control and layout — see the full catalog. A widget binds to a variable by pointer and configures via chaining:
dash.metric("CPU", &cpu, "%").zone(70, 90); Sensors are a composition of quantities — presets expand to the right widgets automatically:
// One line drops the right widgets, units, ranges and icon:
dash.sensor("bme280"); // temperature + humidity + pressure
dash.sensor("ina219"); // voltage + current + power First boot & Wi-Fi
On first power-up the client has no internet. beginAP() raises a SoftAP with a captive portal (catch-all DNS + OS probes) that auto-opens the dashboard. A provisioning page scans networks, takes credentials, stores them in NVS, then switches to station mode — falling back to AP if the connection fails.
Languages & RTL
EN / RU / AR ship in the library. Languages are picked at compile time, so unused ones cost nothing:
; choose languages at compile time (only these reach flash)
build_flags = -D RISAL_LANG_RU -D RISAL_LANG_AR Arabic gets full RTL via logical CSS properties; translations live in separate per-language files.
AI control (MCP)
Each widget automatically becomes an MCP tool, so Claude/Cursor can read sensors and flip relays by voice — same actions as the browser buttons, just driven by AI.
dash.enableMCP("risal_pat_xxx");
// metric/gauge -> get_* (read) ; toggle/slider -> set_* (write)