Add full-screen alarm acknowledgement overlay

This commit is contained in:
root
2026-06-03 00:06:01 -06:00
parent f0878babd2
commit 1cb26aff20
2 changed files with 128 additions and 0 deletions
+51
View File
@@ -155,3 +155,54 @@ nav button {
font-size: 0.9rem; font-size: 0.9rem;
border-radius: 10px; border-radius: 10px;
} }
.alarm-overlay {
position: fixed;
inset: 0;
background: #200;
color: white;
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
}
.alarm-overlay.hidden {
display: none;
}
.alarm-box {
width: min(720px, 100%);
background: #3a0000;
border: 4px solid #ffdddd;
border-radius: 24px;
padding: 36px;
text-align: center;
box-shadow: 0 0 40px rgba(0,0,0,0.7);
}
.alarm-icon {
font-size: 5rem;
margin-bottom: 12px;
}
.alarm-box h1 {
font-size: 2.4rem;
margin-bottom: 18px;
}
.alarm-box p {
font-size: 1.8rem;
margin-bottom: 28px;
}
.alarm-box button {
width: 100%;
font-size: 1.5rem;
padding: 24px;
background: white;
color: #300;
font-weight: bold;
}
+77
View File
@@ -5,6 +5,15 @@
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/static/style.css">
</head> </head>
<body> <body>
<div id="alarmOverlay" class="alarm-overlay hidden">
<div class="alarm-box">
<div class="alarm-icon"></div>
<h1 id="alarmTitle">ALARM</h1>
<p id="alarmMessage">--</p>
<button onclick="acknowledgeAlarm()">Acknowledge</button>
</div>
</div>
<main> <main>
<header> <header>
<h1>Xterra Dashboard</h1> <h1>Xterra Dashboard</h1>
@@ -80,6 +89,8 @@
<script> <script>
let relayState = {}; let relayState = {};
let activeAlarmKey = null;
let acknowledgedAlarms = new Set();
function showScreen(id) { function showScreen(id) {
document.querySelectorAll('.screen').forEach(screen => { document.querySelectorAll('.screen').forEach(screen => {
@@ -92,6 +103,70 @@ function onOff(value) {
return value ? 'ON' : 'OFF'; return value ? 'ON' : 'OFF';
} }
function checkAlarms(data) {
const alarms = [];
if (data.temps.rear_seat >= 95) {
alarms.push({
key: 'rear_seat_critical',
title: 'REAR SEAT TEMP CRITICAL',
message: `${data.temps.rear_seat}°F detected near car seat area`
});
} else if (data.temps.rear_seat >= 85) {
alarms.push({
key: 'rear_seat_warning',
title: 'REAR SEAT TEMP HIGH',
message: `${data.temps.rear_seat}°F detected near car seat area`
});
}
if (data.temps.fridge_zone_1 >= 45) {
alarms.push({
key: 'fridge_zone_1_warm',
title: 'FRIDGE ZONE 1 WARM',
message: `${data.temps.fridge_zone_1}°F`
});
}
if (data.temps.fridge_zone_2 >= 45) {
alarms.push({
key: 'fridge_zone_2_warm',
title: 'FRIDGE ZONE 2 WARM',
message: `${data.temps.fridge_zone_2}°F`
});
}
if (data.battery.soc <= 20) {
alarms.push({
key: 'battery_low',
title: 'BATTERY LOW',
message: `${data.battery.soc}% remaining`
});
}
const unacked = alarms.find(alarm => !acknowledgedAlarms.has(alarm.key));
if (unacked) {
showAlarm(unacked);
}
}
function showAlarm(alarm) {
activeAlarmKey = alarm.key;
document.getElementById('alarmTitle').textContent = alarm.title;
document.getElementById('alarmMessage').textContent = alarm.message;
document.getElementById('alarmOverlay').classList.remove('hidden');
}
function acknowledgeAlarm() {
if (activeAlarmKey) {
acknowledgedAlarms.add(activeAlarmKey);
}
activeAlarmKey = null;
document.getElementById('alarmOverlay').classList.add('hidden');
}
async function loadStatus() { async function loadStatus() {
const res = await fetch('/status'); const res = await fetch('/status');
const data = await res.json(); const data = await res.json();
@@ -128,6 +203,8 @@ async function loadStatus() {
document.getElementById('sysRs485').textContent = data.network.rs485_connected ? 'Connected' : 'Disconnected'; document.getElementById('sysRs485').textContent = data.network.rs485_connected ? 'Connected' : 'Disconnected';
document.getElementById('sysWifi').textContent = data.network.wifi_enabled ? 'Enabled' : 'Disabled'; document.getElementById('sysWifi').textContent = data.network.wifi_enabled ? 'Enabled' : 'Disabled';
document.getElementById('sysWifiOverride').textContent = data.network.wifi_override_active ? 'Active' : 'Inactive'; document.getElementById('sysWifiOverride').textContent = data.network.wifi_override_active ? 'Active' : 'Inactive';
checkAlarms(data);
} }
async function toggleRelay(name) { async function toggleRelay(name) {