Building Embedded Web Device Dashboards

Overview

An embedded device dashboard serves as the user interface for managing and monitoring embedded systems. Whether it's for a smart home controller, an industrial automation unit, or an IoT-enabled sensor module, the embedded web dashboard provides a convenient way to interact with devices using a standard web browser. These dashboards are particularly valuable because they eliminate the need for additional software or proprietary interfaces, leveraging the universal access provided by web technologies.

Typical use cases include:

Overview of Implementation Techniques

Building a device web dashboard requires integrating an embedded web server within the embedded device firmware. There are several techniques to render dynamic content and handle user interaction:

1. CGI (Common Gateway Interface)

The CGI technique is employed by lightweight web servers like LWIP HTTPD, a minimal web server commonly used in memory-constrained environments.

With CGI, the server maps specific URL paths to handler functions in the firmware. For example, accessing http://device-ip/led.cgi might trigger a function in C that toggles an LED and returns HTML content as a response.

Advantages:

Disadvantages:

2. REST API (Representational State Transfer)

A RESTful interface allows a web dashboard to communicate with the device via HTTP requests. For example:

This approach separates data and presentation logic. The embedded web dashboard can be written using HTML/JS/CSS and fetch or update device states using AJAX calls to the embedded web server.

Advantages:

Disadvantages:

3. Server-Side Includes (SSI)

SSI allows embedding dynamic content into static HTML pages. In LWIP HTTPD, <!--#tag--> style directives in HTML get replaced at runtime by server-side code.

Advantages:

Disadvantages:

4. WebSocket Communication

WebSockets offer full-duplex communication channels, allowing the server to push updates to the browser. This is useful for real-time monitoring.

Advantages:

Disadvantages:

5. MQTT over WebSockets

For devices already using MQTT, exposing MQTT data to a web dashboard via a WebSocket-MQTT bridge provides seamless integration.

Advantages:

Disadvantages:

All techniques rely on a properly configured embedded web server to serve content and handle client requests.

Step-by-Step: Simple REST API Implementation (LED Toggle Example)

Let's walk through a minimal example of building an embedded web dashboard using a REST API served by an embedded web server.

Step 1: Create Web Dashboard UI

web_root/index.html:

<!DOCTYPE html>
<html>
<head>
  <link href="style.css" rel="stylesheet" />
</head>
<body>
  <div class="main">
    <h1>My Device</h1>
    <span>LED status:</span>
    <span id="status">0</span>
    <button id="btn">Toggle LED</button>
    <p><small>Note: this UI is intentionally minimal</small></p>
  </div>
  <script src="main.js"></script>
</body>
</html>

web_root/style.css:

.main  { margin: 1em; }
#status { display: inline-block; width: 2em; }

web_root/main.js:

var getStatus = ev => fetch('api/led/get')
  .then(r => r.json())
  .then(r => { document.getElementById('status').innerHTML = r; });

var toggle = ev => fetch('api/led/toggle')
  .then(r => getStatus());

document.getElementById('btn').onclick = toggle;
//window.addEventListener('load', getStatus);

Step 2: Set Up Embedded Web Server

Choose a lightweight server like Mongoose.

#include "mongoose.h"

static void event_handler(struct mg_connection *c, int ev, void *ev_data) {
  if (ev == MG_EV_HTTP_MSG) {
    struct mg_http_message *hm = (struct mg_http_message *) ev_data;
    if (mg_match(hm->uri, mg_str("/api/led/get"), NULL)) {
      mg_http_reply(c, 200, "", "%d\n", HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0));
    } else if (mg_match(hm->uri, mg_str("/api/led/toggle"), NULL)) {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // Can be different on your board
      mg_http_reply(c, 200, "", "true\n");
    } else {
      struct mg_http_serve_opts opts = {.root_dir = "/web_root", .fs = &mg_fs_packed};
      mg_http_serve_dir(c, hm, &opts);
    }
  }
}

int main() {
  struct mg_mgr mgr;  // Mongoose event manager. Holds all connections
  mg_mgr_init(&mgr);  // Initialise event manager
  mg_http_listen(&mgr, "http://0.0.0.0:80", event_handler, NULL);  // Setup listener
  for (;;) {
    mg_mgr_poll(&mgr, 1000);  // Infinite event loop
  }
  return 0;
}

If you point your browser against your running device, you should see this simple UI:

Simple Web UI LED control

And here is the step-by-step explanation on the flow of requests:

Simple Web UI LED control flow

This simple example demonstrates the key concepts: a REST endpoint on the embedded web server, and a frontend embedded device dashboard that sends POST requests to control hardware.

Conclusion

Implementing a device dashboard using an embedded web server offers a scalable, browser-based control panel for embedded systems. Techniques such as CGI, SSI, REST APIs, and WebSockets cater to different device capabilities and complexity requirements. For modern applications, REST APIs strike a balance between simplicity and power, making them ideal for implementing features like an embedded web dashboard.

By choosing the right implementation approach and leveraging a lightweight embedded web server, developers can craft efficient, interactive, and user-friendly dashboards to control and monitor embedded devices.