You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			148 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			HTML
		
	
			
		
		
	
	
			148 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			HTML
		
	
<!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>
 |