webui: highlight temperature cards on alerts
This commit is contained in:
@@ -391,6 +391,17 @@ button[onclick^="scan"]{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.temp-alert {
|
||||||
|
border-color: #f97066 !important;
|
||||||
|
background: linear-gradient(180deg, rgba(122,39,26,0.95), rgba(67,24,24,0.95)) !important;
|
||||||
|
box-shadow: 0 0 0 1px rgba(249,112,102,0.35), 0 0 18px rgba(249,112,102,0.25) !important;
|
||||||
|
}
|
||||||
|
.temp-alert .muted,
|
||||||
|
.temp-alert .inputHelp {
|
||||||
|
color: #ffd7d3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -1015,6 +1026,7 @@ function render(data){
|
|||||||
$("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||"");
|
$("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||"");
|
||||||
$("uptime").textContent=formatUptime(s.uptime_seconds||0);
|
$("uptime").textContent=formatUptime(s.uptime_seconds||0);
|
||||||
renderConfigControls(data);
|
renderConfigControls(data);
|
||||||
|
applyTempAlertStyles(data);
|
||||||
populateSetupFields(data);
|
populateSetupFields(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,6 +1155,65 @@ async function factoryReset(){
|
|||||||
alert("Factory reset requested. Reconnect to the controller AP if needed.");
|
alert("Factory reset requested. Reconnect to the controller AP if needed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function tempHighAlertActive(t){
|
||||||
|
const temp = Number(t.temperature_f);
|
||||||
|
const threshold = Number(t.high_alert_f);
|
||||||
|
return !!(
|
||||||
|
t.high_alert ||
|
||||||
|
(
|
||||||
|
t.high_alert_enabled &&
|
||||||
|
Number.isFinite(temp) &&
|
||||||
|
Number.isFinite(threshold) &&
|
||||||
|
temp > threshold
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tempDisplayGroup(t){
|
||||||
|
const group = String(t.group || "").trim().toLowerCase();
|
||||||
|
if (t.weather || group === "outside" || group === "weather") return "outside";
|
||||||
|
if (group) return group;
|
||||||
|
return String(t.name || "").trim().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyTempAlertStyles(data){
|
||||||
|
const temps = data && Array.isArray(data.temps) ? data.temps : [];
|
||||||
|
const active = temps.filter(tempHighAlertActive);
|
||||||
|
|
||||||
|
document.querySelectorAll(".temp-alert").forEach(el => el.classList.remove("temp-alert"));
|
||||||
|
if (!active.length) return;
|
||||||
|
|
||||||
|
const alertKeys = new Set();
|
||||||
|
active.forEach(t => {
|
||||||
|
const name = String(t.name || "").trim().toLowerCase();
|
||||||
|
const group = tempDisplayGroup(t);
|
||||||
|
if (name) alertKeys.add(name);
|
||||||
|
if (group) alertKeys.add(group);
|
||||||
|
if (group === "fridge") alertKeys.add("fridge");
|
||||||
|
if (group === "cabin") alertKeys.add("cabin");
|
||||||
|
if (group === "outside") alertKeys.add("outside");
|
||||||
|
});
|
||||||
|
|
||||||
|
const candidates = document.querySelectorAll(
|
||||||
|
".card, .tile, .tempCard, .tempTile, .tempConfigCard, .reading, .sensor, .stat"
|
||||||
|
);
|
||||||
|
|
||||||
|
candidates.forEach(el => {
|
||||||
|
const text = (el.textContent || "").toLowerCase();
|
||||||
|
if (!text.includes("°") && !text.includes("temp") && !text.includes("fridge") && !text.includes("cabin")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const key of alertKeys) {
|
||||||
|
if (key && text.includes(key)) {
|
||||||
|
el.classList.add("temp-alert");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function renderConfigControls(data){
|
function renderConfigControls(data){
|
||||||
const cfg=data.config||{};
|
const cfg=data.config||{};
|
||||||
const relays=cfg.relays||[];
|
const relays=cfg.relays||[];
|
||||||
|
|||||||
Reference in New Issue
Block a user