<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Air Quality Monitor</title> <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400&display=swap" rel="stylesheet"> <style> /* General Styles */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Roboto', sans-serif; } body { display: flex; flex-direction: column; align-items: center; justify-content: center; background: #f5f5f5; color: #333; height: 100vh; } h1 { font-size: 2em; color: #444; margin-bottom: 20px; } /* Container for Sensors */ .sensor-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; width: 100%; max-width: 800px; padding: 10px; } /* Sensor Box */ .sensor { background: #fff; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border-radius: 10px; width: 180px; padding: 20px; text-align: center; transition: transform 0.2s ease, box-shadow 0.2s ease; } .sensor:hover { transform: scale(1.05); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15); } /* Sensor Titles */ .sensor-title { font-weight: 400; color: #555; font-size: 1.2em; margin-bottom: 10px; display: flex; align-items: center; justify-content: center; } /* Sensor Value */ .sensor-value { font-size: 2.5em; font-weight: 300; color: #333; margin-bottom: 5px; animation: fadeIn 0.5s ease; } .unit { font-size: 0.8em; color: #777; } /* Icon Styles */ .sensor-icon { width: 30px; height: 30px; margin-right: 8px; filter: grayscale(50%); } /* Keyframes for Smooth Animations */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } </style> </head> <body> <h1>Room Air Quality Monitor</h1> <div class="sensor-container"> <div id="temperature" class="sensor"> <div class="sensor-title"> <img src="./images/thermometer-outline.svg" class="sensor-icon" alt="Temperature Icon"> Temperature </div> <div class="sensor-value" id="temp-value">--</div> <div class="unit">℃</div> </div> <div id="humidity" class="sensor"> <div class="sensor-title"> <img src="./images/water-outline.svg" class="sensor-icon" alt="Humidity Icon"> Humidity </div> <div class="sensor-value" id="humidity-value">--</div> <div class="unit">%</div> </div> <div id="co2" class="sensor"> <div class="sensor-title"> <img src="./images/cloud-outline.svg" class="sensor-icon" alt="CO2 Icon"> CO₂ </div> <div class="sensor-value" id="co2-value">--</div> <div class="unit">ppm</div> </div> <div id="pressure" class="sensor"> <div class="sensor-title"> <img src="./images/sunny-outline.svg" class="sensor-icon" alt="Pressure Icon"> Pressure </div> <div class="sensor-value" id="pressure-value">--</div> <div class="unit">hPa</div> </div> </div> <script> async function fetchData() { try { const res = await Promise.all([ //fetch("./data/BH1750.json"), //fetch("./data/BMP180.json"), fetch("./data/HTU21D.json"), //fetch("./data/MH_Z19.json") ]); const data = (await Promise.all(res.map(r => r.json()))).reduce((acc, item) => ({ ...acc, ...item }), {}); return data; } catch (error) { console.error("Failed to fetch sensor data:", error); return {}; } } function updateUI(data) { document.getElementById("temp-value").textContent = data.temperature ? data.temperature.toFixed(1) : "--"; document.getElementById("humidity-value").textContent = data.humidity ? data.humidity.toFixed(1) : "--"; document.getElementById("co2-value").textContent = data.co2 ? data.co2 : "--"; document.getElementById("pressure-value").textContent = data.pressure ? data.pressure.toFixed(1) : "--"; } async function refreshData() { const data = await fetchData(); updateUI(data); } setInterval(refreshData, 6000); // Refresh every 60 seconds refreshData(); // Initial fetch </script> </body> </html>