document.addEventListener('DOMContentLoaded', () => { // A map to keep track of Chart instances to prevent memory leaks const chartInstances = {}; const createGauge = (canvasId, label, value, max, unit, thresholds) => { const ctx = document.getElementById(canvasId); if (!ctx) return; const parentCard = ctx.closest('.gauge-card'); if (!parentCard) return; const valueEl = parentCard.querySelector('.gauge-value'); const labelEl = parentCard.querySelector('.card-footer'); const normalColor = '#34A853'; // Green const warningColor = '#F9AB00'; // Orange const alertColor = '#EA4335'; // Red const bgColor = '#e9ecef'; let activeColor = normalColor; if (value >= thresholds.warning && value < thresholds.critical) { activeColor = warningColor; } else if (value >= thresholds.critical) { activeColor = alertColor; } // Update text content if(labelEl) labelEl.textContent = label; if(valueEl) { valueEl.textContent = `${value}${unit}`; valueEl.style.color = activeColor; } const percentage = Math.min(Math.max((value / max) * 100, 0), 100); // If a chart already exists for this canvas, destroy it before creating a new one. if (chartInstances[canvasId]) { chartInstances[canvasId].destroy(); } chartInstances[canvasId] = new Chart(ctx, { type: 'doughnut', data: { datasets: [{ data: [percentage, 100 - percentage], backgroundColor: [activeColor, bgColor], borderColor: [activeColor, bgColor], borderWidth: 1, circumference: 270, rotation: 225, }] }, options: { responsive: true, maintainAspectRatio: false, cutout: '80%', plugins: { legend: { display: false }, tooltip: { enabled: false } }, events: [] } }); }; const fetchSensorData = async () => { try { // Append a cache-busting query parameter const response = await fetch('api/sensor-data.php?v=' + new Date().getTime()); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const { data, thresholds } = await response.json(); // Update gauges with the new data createGauge('gauge1', 'Temperature', data.temperature, thresholds.temperature.max, '°C', thresholds.temperature); createGauge('gauge2', 'Humidity', data.humidity, thresholds.humidity.max, '%', thresholds.humidity); createGauge('gauge3', 'CO2 Level', data.co2, thresholds.co2.max, 'ppm', thresholds.co2); createGauge('gauge4', 'Gas Detection', data.gas_level, thresholds.gas_level.max, 'ppm', thresholds.gas_level); createGauge('gauge5', 'Pressure', data.pressure, thresholds.pressure.max, 'hPa', thresholds.pressure); createGauge('gauge6', 'Light Intensity', data.light_level, thresholds.light_level.max, 'lux', thresholds.light_level); } catch (error) { console.error("Could not fetch sensor data:", error); // Find the main row and display an error const mainRow = document.querySelector('.row'); if (mainRow) { mainRow.innerHTML = `
`; } } }; // Initial data load fetchSensorData(); // Refresh data every 15 seconds setInterval(fetchSensorData, 15000); });