115 lines
3.8 KiB
HTML
115 lines
3.8 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Xterra Dashboard Simulator</title>
|
|
<link rel="stylesheet" href="/static/style.css">
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<h1>Xterra Dashboard</h1>
|
|
|
|
<section class="grid">
|
|
<div class="card">
|
|
<h2>Battery</h2>
|
|
<p><span id="soc">--</span>%</p>
|
|
<small><span id="voltage">--</span>V / <span id="current">--</span>A</small>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Runtime</h2>
|
|
<p><span id="runtime">--</span> hr</p>
|
|
<small><span id="remaining">--</span> Ah remaining</small>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Fridge Zone 1</h2>
|
|
<p><span id="fridge1">--</span>°F</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Fridge Zone 2</h2>
|
|
<p><span id="fridge2">--</span>°F</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Rear Seat</h2>
|
|
<p><span id="rear">--</span>°F</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Outside</h2>
|
|
<p><span id="outside">--</span>°F</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="controls">
|
|
<button onclick="toggleRelay('starlink')" id="starlinkBtn">Starlink</button>
|
|
<button onclick="toggleRelay('fridge')" id="fridgeBtn">Fridge</button>
|
|
<button onclick="enableWifi()">Enable WiFi 10 min</button>
|
|
</section>
|
|
|
|
<section class="status">
|
|
<p>RS-485: <span id="rs485">--</span></p>
|
|
<p>WiFi: <span id="wifi">--</span></p>
|
|
</section>
|
|
</main>
|
|
|
|
<script>
|
|
let relayState = {};
|
|
|
|
async function loadStatus() {
|
|
const res = await fetch('/status');
|
|
const data = await res.json();
|
|
|
|
document.getElementById('soc').textContent = data.battery.soc;
|
|
document.getElementById('voltage').textContent = data.battery.voltage;
|
|
document.getElementById('current').textContent = data.battery.current;
|
|
document.getElementById('runtime').textContent = data.battery.runtime_hours;
|
|
document.getElementById('remaining').textContent = data.battery.remaining_ah;
|
|
|
|
document.getElementById('fridge1').textContent = data.temps.fridge_zone_1;
|
|
document.getElementById('fridge2').textContent = data.temps.fridge_zone_2;
|
|
document.getElementById('rear').textContent = data.temps.rear_seat;
|
|
document.getElementById('outside').textContent = data.temps.outside;
|
|
|
|
relayState = data.relays;
|
|
|
|
document.getElementById('starlinkBtn').textContent =
|
|
relayState.starlink ? 'Starlink: ON' : 'Starlink: OFF';
|
|
|
|
document.getElementById('fridgeBtn').textContent =
|
|
relayState.fridge ? 'Fridge: ON' : 'Fridge: OFF';
|
|
|
|
document.getElementById('rs485').textContent =
|
|
data.network.rs485_connected ? 'Connected' : 'Disconnected';
|
|
|
|
document.getElementById('wifi').textContent =
|
|
data.network.wifi_enabled ? 'Enabled' : 'Disabled';
|
|
}
|
|
|
|
async function toggleRelay(name) {
|
|
await fetch(`/relay/${name}`, {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({state: !relayState[name]})
|
|
});
|
|
|
|
loadStatus();
|
|
}
|
|
|
|
async function enableWifi() {
|
|
await fetch('/network/wifi', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({minutes: 10})
|
|
});
|
|
|
|
loadStatus();
|
|
}
|
|
|
|
loadStatus();
|
|
setInterval(loadStatus, 2000);
|
|
</script>
|
|
</body>
|
|
</html>
|