From 5e2f2080cb7484bd630cf24f2b5da36dea2d6f5f Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 11 Jun 2026 00:28:31 -0600 Subject: [PATCH] dashboard: add temperature group priority --- docs/API.md | 11 +++++ docs/dashboard-esp32s3.md | 11 +++++ docs/project-state.md | 11 +++++ .../esp32-s3-dashboard/dashboard_config.h | 2 +- .../esp32-s3-dashboard/esp32-s3-dashboard.ino | 44 ++++++++++++++++--- .../esp32/overland-controller/app_config.cpp | 12 ++++- .../esp32/overland-controller/app_config.h | 1 + .../overland-controller.ino | 21 ++++++++- 8 files changed, 101 insertions(+), 12 deletions(-) diff --git a/docs/API.md b/docs/API.md index c9ecc0f..db2250b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -944,3 +944,14 @@ Supported group values: - `other` The dashboard overview combines multiple online sensors in the same group into one tile. For example, two fridge sensors may display as `34°/45°` under a single `Fridge` tile. Sensors marked `weather: true` continue to be treated as the outside/weather sensor for dashboard display. + +### Temperature Sensor Priority + +Temperature sensors support a numeric `priority` field. Lower numbers are displayed first within a grouped dashboard tile. + +Example: + +- Fridge Zone 1: `group=fridge`, `priority=1` +- Fridge Zone 2: `group=fridge`, `priority=2` + +The dashboard displays the grouped fridge tile in priority order, for example `34°/45°`. diff --git a/docs/dashboard-esp32s3.md b/docs/dashboard-esp32s3.md index b0a364e..be24ac2 100644 --- a/docs/dashboard-esp32s3.md +++ b/docs/dashboard-esp32s3.md @@ -262,3 +262,14 @@ Supported group values: - `other` The dashboard overview combines multiple online sensors in the same group into one tile. For example, two fridge sensors may display as `34°/45°` under a single `Fridge` tile. Sensors marked `weather: true` continue to be treated as the outside/weather sensor for dashboard display. + +### Temperature Sensor Priority + +Temperature sensors support a numeric `priority` field. Lower numbers are displayed first within a grouped dashboard tile. + +Example: + +- Fridge Zone 1: `group=fridge`, `priority=1` +- Fridge Zone 2: `group=fridge`, `priority=2` + +The dashboard displays the grouped fridge tile in priority order, for example `34°/45°`. diff --git a/docs/project-state.md b/docs/project-state.md index 717e54e..5730dab 100644 --- a/docs/project-state.md +++ b/docs/project-state.md @@ -329,3 +329,14 @@ Supported group values: - `other` The dashboard overview combines multiple online sensors in the same group into one tile. For example, two fridge sensors may display as `34°/45°` under a single `Fridge` tile. Sensors marked `weather: true` continue to be treated as the outside/weather sensor for dashboard display. + +### Temperature Sensor Priority + +Temperature sensors support a numeric `priority` field. Lower numbers are displayed first within a grouped dashboard tile. + +Example: + +- Fridge Zone 1: `group=fridge`, `priority=1` +- Fridge Zone 2: `group=fridge`, `priority=2` + +The dashboard displays the grouped fridge tile in priority order, for example `34°/45°`. diff --git a/firmware/esp32-s3-dashboard/dashboard_config.h b/firmware/esp32-s3-dashboard/dashboard_config.h index f2e59a2..08230f0 100644 --- a/firmware/esp32-s3-dashboard/dashboard_config.h +++ b/firmware/esp32-s3-dashboard/dashboard_config.h @@ -1,6 +1,6 @@ #pragma once -static const char *DASHBOARD_VERSION = "0.1.38-outside-status-temp"; +static const char *DASHBOARD_VERSION = "0.1.39-temp-priority"; // Update these if your Cargo ESP AP credentials are different. static const char *CARGO_WIFI_SSID = "OverlandController"; diff --git a/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino b/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino index d910094..463d746 100644 --- a/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino +++ b/firmware/esp32-s3-dashboard/esp32-s3-dashboard.ino @@ -667,6 +667,16 @@ static void parse_status_json(const String &body) bool tile_has_value[4] = {false, false, false, false}; String outside_status = "OUT --"; + struct TempDisplayItem { + int tile_index; + int priority; + int rounded_f; + String name; + }; + + TempDisplayItem items[8]; + int item_count = 0; + for (JsonObject temp : doc["temps"].as()) { bool enabled = temp["enabled"] | false; bool online = temp["online"] | false; @@ -691,9 +701,6 @@ static void parse_status_json(const String &body) String name = raw_name && raw_name[0] ? String(raw_name) : String("Cabin"); String group = normalize_temp_group(String(raw_group), name, false); - // Weather-tagged sensors are excluded above. A manually configured outside - // group can still be shown later on a dedicated Temps page, but the main - // overview reserves the top status strip for outside/weather temp. if (group == "outside") { outside_status = "OUT "; outside_status += String((int)round(temp_f)); @@ -702,12 +709,34 @@ static void parse_status_json(const String &body) } int index = temp_group_index(group); - if (index == 2) { - index = 3; // Keep main temp card from using an Outside tile. + if (index < 0 || index > 3) { + index = 3; } - int rounded = (int)round(temp_f); - String value = String(rounded); + int priority = temp["priority"] | 99; + + if (item_count < 8) { + items[item_count] = {index, priority, (int)round(temp_f), name}; + item_count++; + } + } + + for (int a = 0; a < item_count - 1; a++) { + for (int b = a + 1; b < item_count; b++) { + if ( + items[b].tile_index < items[a].tile_index || + (items[b].tile_index == items[a].tile_index && items[b].priority < items[a].priority) + ) { + TempDisplayItem tmp = items[a]; + items[a] = items[b]; + items[b] = tmp; + } + } + } + + for (int i = 0; i < item_count; i++) { + int index = items[i].tile_index; + String value = String(items[i].rounded_f); value += "°"; if (tile_has_value[index]) { @@ -718,6 +747,7 @@ static void parse_status_json(const String &body) tile_has_value[index] = true; if (index == 0) { + String name = items[i].name; name.replace(" Area", ""); name.replace(" Zone", ""); tile_names[index] = name.length() ? name : "Cabin"; diff --git a/firmware/esp32/overland-controller/app_config.cpp b/firmware/esp32/overland-controller/app_config.cpp index 264bd21..39431ed 100644 --- a/firmware/esp32/overland-controller/app_config.cpp +++ b/firmware/esp32/overland-controller/app_config.cpp @@ -39,7 +39,8 @@ void loadDefaultConfig() { "", i < appConfig.tempSensorCount, false, - "cabin" + "cabin", + i + 1 }; } @@ -106,6 +107,10 @@ void loadConfig() { (prefix + "group").c_str(), appConfig.tempSensors[i].group ); + appConfig.tempSensors[i].priority = preferences.getInt( + (prefix + "priority").c_str(), + appConfig.tempSensors[i].priority + ); } appConfig.bms.enabled = preferences.getBool("bms_enabled", appConfig.bms.enabled); @@ -142,6 +147,7 @@ void saveConfig() { preferences.putBool((prefix + "enabled").c_str(), appConfig.tempSensors[i].enabled); preferences.putBool((prefix + "weather").c_str(), appConfig.tempSensors[i].weather); preferences.putString((prefix + "group").c_str(), appConfig.tempSensors[i].group); + preferences.putInt((prefix + "priority").c_str(), appConfig.tempSensors[i].priority); } preferences.putBool("bms_enabled", appConfig.bms.enabled); @@ -195,7 +201,9 @@ void printConfig() { Serial.print(" / address "); Serial.print(appConfig.tempSensors[i].address); Serial.print(" / group "); - Serial.println(appConfig.tempSensors[i].group); + Serial.print(appConfig.tempSensors[i].group); + Serial.print(" / priority "); + Serial.println(appConfig.tempSensors[i].priority); } Serial.println(" BMS:"); diff --git a/firmware/esp32/overland-controller/app_config.h b/firmware/esp32/overland-controller/app_config.h index d838e18..9ffa42d 100644 --- a/firmware/esp32/overland-controller/app_config.h +++ b/firmware/esp32/overland-controller/app_config.h @@ -23,6 +23,7 @@ struct TempSensorConfig { bool enabled; bool weather; String group; + int priority; }; struct BmsConfig { diff --git a/firmware/esp32/overland-controller/overland-controller.ino b/firmware/esp32/overland-controller/overland-controller.ino index ca57411..37792bc 100644 --- a/firmware/esp32/overland-controller/overland-controller.ino +++ b/firmware/esp32/overland-controller/overland-controller.ino @@ -1192,6 +1192,9 @@ function renderConfigControls(data){ + + +