// ========================================================= // Tank Monitor - app.js // ========================================================= const TANK_FULL_PASSWORD = "1234"; // 🔐 CHANGE THIS // =============================== // Fetch sensor data and update UI // =============================== async function fetchSensorData() { try { const response = await fetch("/sensor"); const data = await response.json(); // Level const level_mm = data.pressure / 9.810; document.getElementById("level").innerText = level_mm.toFixed(3) + " m"; // Pressure document.getElementById("pressure").innerText = data.pressure.toFixed(3) + " Kpa"; // Tank % + Liters (robust) const pct = data.tank_percent; const capacity = Number(TANK_CAPACITY_L); const percentEl = document.getElementById("percent"); if (!isNaN(capacity) && capacity > 0) { const liters = (pct / 100) * capacity; percentEl.innerText = `${pct.toFixed(1)} % [${liters.toFixed(0)} L]`; } else { percentEl.innerText = `${pct.toFixed(1)} %`; } // CPU temp document.getElementById("cpu").innerText = data.cpu_temp.toFixed(1) + " °C"; // RSSI: dBm → % let rssiPercent = (data.rssi + 100) * 2; rssiPercent = Math.max(0, Math.min(100, rssiPercent)); document.getElementById("rssi").innerText = rssiPercent.toFixed(0) + " %"; // Free memory → KB document.getElementById("mem").innerText = (data.mem / 1024).toFixed(1) + " KB"; // Uptime document.getElementById("uptime").innerText = data.uptime; updateTankBar(pct); // Change footer on html page // data.footer = "Powered by Raspberry Pi Pico W & HX710B - Test" document.getElementById("footer-text").innerText = data.footer; } catch (err) { console.log("Sensor fetch error:", err); } } // =============================== // Tank animation + color scaling // =============================== function updateTankBar(percent) { const fill = document.getElementById("tank-fill"); percent = Math.max(0, Math.min(100, percent)); fill.style.height = percent + "%"; fill.style.backgroundColor = tankColor(percent); } function tankColor(p) { let r, g, b; if (p <= 50) { const t = p / 50; r = 211 + (251 - 211) * t; g = 50 + (192 - 50) * t; b = 47 + (45 - 47) * t; } else { const t = (p - 50) / 50; r = 251 + (76 - 251) * t; g = 192 + (175 - 192) * t; b = 45 + (80 - 45) * t; } return `rgb(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)})`; } // =============================== // Date & Time // =============================== function updateClock() { const now = new Date(); document.getElementById("date").innerText = `${now.getFullYear()}-${String(now.getMonth()+1).padStart(2,"0")}-${String(now.getDate()).padStart(2,"0")}`; document.getElementById("time").innerText = `${String(now.getHours()).padStart(2,"0")}:${String(now.getMinutes()).padStart(2,"0")}:${String(now.getSeconds()).padStart(2,"0")}`; } // =============================== // Theme toggle // =============================== const modeSwitch = document.getElementById("modeSwitch"); if (localStorage.getItem("theme") === "dark") { document.body.classList.add("dark"); if (modeSwitch) modeSwitch.checked = true; } if (modeSwitch) { modeSwitch.addEventListener("change", () => { document.body.classList.toggle("dark", modeSwitch.checked); localStorage.setItem("theme", modeSwitch.checked ? "dark" : "light"); }); } // =============================== // Password-protected Tank Full // =============================== function tankFullProtected() { const entered = prompt("Enter password to set Tank FULL:"); if (entered !== TANK_FULL_PASSWORD) { alert("❌ Incorrect password"); return; } if (!confirm("Confirm: Set tank to FULL?")) return; fetch("/tare"); } window.tankFullProtected = tankFullProtected; // =============================== // Start // =============================== setInterval(fetchSensorData, 1000); setInterval(updateClock, 1000); fetchSensorData(); updateClock();