Metric
A compact, info-dense card with one big number, an optional label and unit, and rich styling. Use it to surface a key metric at a glance.
[image] Metric widget on canvas, value 22.5, label « Temperature », unit « °C »
What it does
Metric displays a number your sketch pushes from setValue(). On top of the number, you can show a label, a unit, a prefix (e.g. $), a suffix (e.g. /s), and an optional secondary value with its own label below the main one. Five visual styles, five semantic value states (Normal / Success / Warning / Error / Info) that map to color accents.
When to use it
- Live counter — Decimals 0, prefix
#. Update from your sketch. - Sensor reading with peak — Set the live value with
setValue(), push the rolling peak into the secondary line viasetSecondaryValue().
Properties
The Inspector opens as a bottom sheet with a Widget ID field at the top, then these sections in order.
Widget ID
| Property | Type | What it controls |
|---|---|---|
| Widget ID | text | Identifier used by your sketch (IMetric("…")). |
1. Essential
| Property | Type | Default | What it controls |
|---|---|---|---|
| Enabled | toggle | on | Whether the widget displays content. |
| Label | text | empty (placeholder Enter label…) | Caption shown next to the value. |
| Unit | text | empty (placeholder e.g. °C, %, rpm) | Unit appended to the value. |
| Current value | number | 0 | Initial value (your sketch updates it later). |
2. Header
| Property | Type | Default | What it controls |
|---|---|---|---|
| Show header | toggle | off | Display a header above the card. |
| Header text | text | empty (placeholder Widget title…) | Header text. Only when Show header is on. |
| Alignment | Left / Center / Right | Center | Header text position. Only when Show header is on. |
3. Format
| Property | Type | Default | What it controls |
|---|---|---|---|
| Decimals | 0–6 | 1 | Decimal places shown. |
| Thousands separator | text | empty (placeholder e.g. space or comma) | Character between thousand groups. |
| Prefix | text | empty (placeholder e.g. $, €) | Text prepended to the value. |
| Suffix | text | empty (placeholder e.g. /h, /s) | Text appended after the unit. |
4. Secondary value
| Property | Type | Default | What it controls |
|---|---|---|---|
| Show secondary | toggle | off | Display a secondary line under the main value. |
| Secondary value | text | empty (placeholder e.g. +5%, Min: 10) | Secondary value text. Only when Show secondary is on. |
| Secondary label | text | empty (placeholder e.g. Change, Previous) | Secondary label text. Only when Show secondary is on. |
5. Appearance
| Property | Type | Default | What it controls |
|---|---|---|---|
| Visual style | segmented | — | Container appearance. |
| Value state | Normal / Success / Warning / Error / Info | Normal | Semantic accent color. |
| Text size mode | Auto / Fixed | Auto | Whether text size auto-fits or stays fixed. |
| Value size | S / M / L / XL | M | Fixed value size. Only when Text size mode is Fixed. |
| Corner radius | 0–32 | 8 | Container corner roundness. |
| Border width | 0–8 | 2 | Container border stroke. |
6. Visibility
| Property | Type | Default | What it controls |
|---|---|---|---|
| Show label | toggle | on | Display the label next to the value. |
| Show unit | toggle | on | Display the unit. |
| Show accent bar | toggle | on | Colored bar at the bottom. |
7. Effects
| Property | Type | Default | What it controls |
|---|---|---|---|
| Animate value changes | toggle | on | Smooth count-up / count-down. |
| Pulse on change | toggle | off | Brief flash when the value updates. |
8. Colors
| Property | Type | What it controls |
|---|---|---|
| Value | color | Main number. |
| Label | color | Caption next to the value. |
| Unit | color | Unit text. |
| Background | color | Card background. |
| Border | color | Card border. |
| Accent bar | color | Bar at the bottom of the card. |
States and behavior
[image] Same metric in five Value States — Normal, Success, Warning, Error, Info
Visual states are picked from two axes:
- Visual style — the container’s shape and fill.
- Value state — semantic color: Normal (theme), Success (green), Warning (orange), Error (red), Info (blue).
The number itself animates between updates if Animate value changes is on. Pulse on change adds a brief flash to grab attention.
In code
The widget mirrors what your sketch sends. To update its value:
instant.metric("cpu_load").setValue(42.5);
That single line is what shows up on the dashboard. Don’t put it directly in loop() — Arduino’s loop() runs thousands of times per second, which would flood the link. Use a timer to push at a sensible rate (200–1000 ms is plenty).
Two methods: .setValue(float) and .setSecondaryValue(const char* value, const char* label). See InstantIoT Library / Send Data to App.
Working Arduino code example
A complete sketch you can flash. The Widget ID cpu_load matches the one you set on your Metric in the app.
[gif] Metric widget on the dashboard updating every 500 ms as the ESP32 pushes new values
Direct Mode
Your phone connects directly to the ESP32’s SoftAP — no router, no server. Best for prototyping and standalone setups.
#include <InstantIoTWiFiAP.hpp>
#include <utils/InstantIoTTimer.hpp>
const char* AP_SSID = "InstantIoT-Greenhouse";
const char* AP_PASS = "12345678";
InstantIoTWiFiAP instant(AP_SSID, AP_PASS);
InstantTimer timers;
float readCpuLoad() {
// Replace with your real sensor read
return random(0, 100);
}
void pushCpu() {
if (!instant.connected()) return;
float load = readCpuLoad();
instant.metric("cpu_load").setValue(load);
static float peak = 0;
if (load > peak) peak = load;
instant.metric("cpu_load").setSecondaryValue(String(peak, 1).c_str(), "peak");
}
void setup() {
instant.begin();
timers.every(500, pushCpu);
}
void loop() {
instant.loop();
timers.run();
}
Server Mode
The ESP32 connects to your self-hosted InstantIoT Server over WiFi. Multiple devices, persistent state, history.
#include <InstantIoTWiFiServer.hpp>
#include <utils/InstantIoTTimer.hpp>
const char* WIFI_SSID = "YOUR_WIFI_SSID";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* SERVER_IP = "192.168.1.42";
const uint16_t SERVER_PORT = 9001;
const char* DEVICE_TOKEN = "YOUR_DEVICE_TOKEN";
InstantIoTWiFiServer instant(SERVER_IP, SERVER_PORT, DEVICE_TOKEN);
InstantTimer timers;
float readCpuLoad() {
// Replace with your real sensor read
return random(0, 100);
}
void pushCpu() {
if (!instant.connected()) return;
float load = readCpuLoad();
instant.metric("cpu_load").setValue(load);
static float peak = 0;
if (load > peak) peak = load;
instant.metric("cpu_load").setSecondaryValue(String(peak, 1).c_str(), "peak");
}
void setup() {
instant.begin(WIFI_SSID, WIFI_PASS);
timers.every(500, pushCpu);
}
void loop() {
instant.loop();
timers.run();
}
The widget code is identical — only the include and constructor change.
Notes
- This is a Display — no Target Devices dropdown.
- The Value state picks an accent color automatically — handy to surface alarms (Warning / Error) without writing color logic in your sketch.
Next
→ Gauge — When the value lives in a known range and benefits from an arc.
→ Text — When the value is a string, not a number.
→ Advanced Chart — When you want history, not just the latest value.