From 5c86bfe1fda879dc9abf48bf8dbe303b4a7d4562 Mon Sep 17 00:00:00 2001 From: Rahat Ahmed Date: Wed, 1 Jul 2026 16:53:55 -0500 Subject: [PATCH] feat(network): add device serial number to web UI (#2506) --- src/network/CrossPointWebServer.cpp | 27 ++++++++++++++++++++++++--- src/network/html/HomePage.html | 5 +++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index dc54dd84..0c6164b2 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -6,9 +6,12 @@ #include #include #include +#include +#include #include #include +#include #include "CrossPointSettings.h" #include "FontInstaller.h" @@ -368,9 +371,27 @@ void CrossPointWebServer::handleStatus() const { doc["uptime"] = millis() / 1000; doc["device"] = gpio.deviceIsX3() ? "X3" : "X4"; - String json; - serializeJson(doc, json); - server->send(200, "application/json", json); + char snBuf[33] = {0}; + bool valid = false; + if (esp_efuse_read_field_blob(ESP_EFUSE_USER_DATA, snBuf, 256) == ESP_OK) { + valid = snBuf[0] != '\0' && snBuf[0] != (char)0xFF; + for (int i = 0; i < 32 && snBuf[i] != '\0'; i++) { + if (!std::isprint(static_cast(snBuf[i]))) { + valid = false; + break; + } + } + } + + if (valid) { + doc["serial"] = snBuf; + } else { + doc["serial"] = "Not found"; + } + + String response; + serializeJson(doc, response); + server->send(200, "application/json", response); } void CrossPointWebServer::scanFiles(const char* path, const std::function& callback) const { diff --git a/src/network/html/HomePage.html b/src/network/html/HomePage.html index a67ddbd1..1ea694aa 100644 --- a/src/network/html/HomePage.html +++ b/src/network/html/HomePage.html @@ -109,6 +109,10 @@

Device Status

+
+ Serial # + +
Version @@ -141,6 +145,7 @@ } const data = await response.json(); document.getElementById('version').textContent = data.version || 'N/A'; + document.getElementById('serial').textContent = data.serial; document.getElementById('ip-address').textContent = data.ip || 'N/A'; document.getElementById('free-heap').textContent = data.freeHeap ? data.freeHeap.toLocaleString() + ' bytes'