DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
dashboard.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file dashboard.h
6 * @brief Real-time SVG telemetry dashboard (DETWS_ENABLE_DASHBOARD).
7 *
8 * Widgets are declared once in a fixed compile-time DetwsWidget table - no heap,
9 * fixed at link. detws_dashboard_begin() serves three things at @p path:
10 * - GET path the self-contained SVG dashboard page (from web_assets);
11 * - GET path/layout the widget table serialized as a JSON array;
12 * - SSE path/stream a live stream of the current values.
13 * The page fetches the layout, renders one SVG widget per entry, and updates them
14 * from the SSE value stream. The application feeds readings with
15 * detws_dashboard_set(key, value) and pushes them with detws_dashboard_publish().
16 *
17 * The widget-table -> JSON serializers (layout + values) are pure and have no
18 * server dependency, so they unit-test on the host. Requires DETWS_ENABLE_SSE.
19 *
20 * @author Douglas Quigg (dstroy0)
21 * @date 2026
22 */
23
24#ifndef DETERMINISTICESPASYNCWEBSERVER_DASHBOARD_H
25#define DETERMINISTICESPASYNCWEBSERVER_DASHBOARD_H
26
27#include "ServerConfig.h"
28#include <stddef.h>
29#include <stdint.h>
30
31#if DETWS_ENABLE_DASHBOARD
32
33class DetWebServer;
34
35/** @brief Widget rendering / interaction style. */
36enum class DetwsWidgetType : uint8_t
37{
38 // Display widgets - updated from the SSE value stream.
39 DETWS_WIDGET_VALUE = 0, ///< plain numeric readout
40 DETWS_WIDGET_GAUGE, ///< radial arc gauge over [min, max]
41 DETWS_WIDGET_BAR, ///< horizontal bar over [min, max]
42 DETWS_WIDGET_SPARKLINE, ///< recent-history SVG line over [min, max]
43 DETWS_WIDGET_CHART, ///< dense Canvas line chart over [min, max]
44 // Control widgets - send values back to the device over WebSocket.
45 DETWS_WIDGET_BUTTON, ///< momentary button -> control value 1
46 DETWS_WIDGET_TOGGLE, ///< on/off toggle -> control value 0/1 (reflects SSE state)
47 DETWS_WIDGET_SLIDER ///< range slider over [min, max] -> control value
48};
49
50/** @brief Control callback: invoked when a control widget sends a value over WebSocket. */
51typedef void (*DetwsControlCb)(const char *key, float value);
52
53/** @brief One dashboard widget, declared in a fixed compile-time table. */
54struct DetwsWidget
55{
56 DetwsWidgetType type; ///< rendering style.
57 const char *label; ///< display label.
58 const char *key; ///< telemetry source key (matches detws_dashboard_set()).
59 float min; ///< scale minimum (gauge / bar / sparkline).
60 float max; ///< scale maximum.
61 const char *unit; ///< unit suffix shown by the widget (may be "").
62};
63
64// ---------------------------------------------------------------------------
65// Host-testable core (no server dependency)
66// ---------------------------------------------------------------------------
67
68/** @brief Bind the widget table and reset every value to 0. */
69void detws_dashboard_configure(const DetwsWidget *widgets, uint8_t count);
70
71/** @brief Set a widget's current value by key. @return false if the key is unknown. */
72bool detws_dashboard_set(const char *key, float value);
73
74/**
75 * @brief Serialize the widget layout as a JSON array into @p out.
76 * @return number of characters written, or 0 if @p cap is too small.
77 */
78int detws_dashboard_layout_json(char *out, size_t cap);
79
80/**
81 * @brief Serialize the current values as a JSON object {key:value,...} into @p out.
82 * @return number of characters written, or 0 if @p cap is too small.
83 */
84int detws_dashboard_values_json(char *out, size_t cap);
85
86/** @brief Register the callback invoked when a control widget sends a value. */
87void detws_dashboard_on_control(DetwsControlCb cb);
88
89/**
90 * @brief Parse a control message `{"k":"<key>","v":<number>}` from the page.
91 * @return true if well-formed; writes the key (bounded by @p key_cap) and value.
92 */
93bool detws_dashboard_parse_control(const char *msg, char *key_out, size_t key_cap, float *value_out);
94
95/**
96 * @brief Parse a control message and invoke the registered control callback.
97 * @return true if the message parsed and a callback was set.
98 */
99bool detws_dashboard_dispatch_control(const char *msg);
100
101// ---------------------------------------------------------------------------
102// Server integration
103// ---------------------------------------------------------------------------
104
105/**
106 * @brief Serve the dashboard at @p path (page, layout JSON, and SSE value stream).
107 *
108 * Calls detws_dashboard_configure(@p widgets, @p count). Default path "/dashboard".
109 */
110void detws_dashboard_begin(DetWebServer &server, const char *path, const DetwsWidget *widgets, uint8_t count);
111
112/** @brief Broadcast the current values to all SSE subscribers (after detws_dashboard_set()). */
113void detws_dashboard_publish();
114
115#endif // DETWS_ENABLE_DASHBOARD
116#endif // DETERMINISTICESPASYNCWEBSERVER_DASHBOARD_H
User-facing configuration for DeterministicESPAsyncWebServer.
Single-port HTTP server with deterministic, zero-allocation execution.
Definition dwserver.h:348