| | <!DOCTYPE html> |
| | <html> |
| | <head> |
| | <title>Gas Danger Monitoring</title> |
| | <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
| | <style> |
| | body { font-family: Arial, sans-serif; margin: 20px; } |
| | .dashboard { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; } |
| | .card { background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 15px; } |
| | .danger { background: #ffcccc; border-left: 5px solid red; } |
| | .safe { background: #ccffcc; border-left: 5px solid green; } |
| | .gauge { height: 20px; background: #ddd; border-radius: 10px; margin: 5px 0; } |
| | .gauge-fill { height: 100%; border-radius: 10px; } |
| | </style> |
| | </head> |
| | <body> |
| | <h1>Factory Gas Monitoring</h1> |
| | <div class="dashboard"> |
| | <div> |
| | <div class="card" id="status-card"> |
| | <h2>System Status: <span id="overall-status">Loading...</span></h2> |
| | <p>Danger Probability: <span id="danger-prob">-</span></p> |
| | <div class="gauge"> |
| | <div class="gauge-fill" id="danger-gauge"></div> |
| | </div> |
| | </div> |
| | |
| | <div class="card"> |
| | <h2>Gas Levels vs Safety Thresholds</h2> |
| | <canvas id="gasChart" height="300"></canvas> |
| | </div> |
| | </div> |
| | |
| | <div> |
| | <div class="card"> |
| | <h2>Alerts</h2> |
| | <div id="alerts-container"></div> |
| | </div> |
| | |
| | <div class="card"> |
| | <h2>Key Metrics</h2> |
| | <div id="metrics"> |
| | <p>Last Updated: <span id="timestamp">-</span></p> |
| | <p>Top Risk Factor: <span id="top-risk">CO_rolling_12h</span></p> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | <script> |
| | let gasChart; |
| | |
| | |
| | function updateData() { |
| | fetch('/api/predict') |
| | .then(response => response.json()) |
| | .then(data => { |
| | |
| | document.getElementById('overall-status').textContent = |
| | data.overall_status.toUpperCase(); |
| | document.getElementById('overall-status').className = data.overall_status; |
| | |
| | |
| | const dangerPercent = (data.prediction * 100).toFixed(1); |
| | document.getElementById('danger-prob').textContent = ${dangerPercent}%; |
| | document.getElementById('danger-gauge').style.width = ${dangerPercent}%; |
| | document.getElementById('danger-gauge').style.backgroundColor = |
| | data.prediction > 0.4 ? 'red' : 'green'; |
| | |
| | |
| | document.getElementById('timestamp').textContent = |
| | new Date(data.timestamp).toLocaleString(); |
| | |
| | |
| | const alertsContainer = document.getElementById('alerts-container'); |
| | alertsContainer.innerHTML = ''; |
| | for (const [gas, info] of Object.entries(data.alerts)) { |
| | const alertDiv = document.createElement('div'); |
| | alertDiv.className = card ${info.status}; |
| | alertDiv.innerHTML = ` |
| | <h3>${gas}</h3> |
| | <p>${info.value.toFixed(2)} ppm (Threshold: ${info.threshold} ppm)</p> |
| | <p>Status: <strong>${info.status.toUpperCase()}</strong></p> |
| | `; |
| | alertsContainer.appendChild(alertDiv); |
| | } |
| | |
| | |
| | updateChart(data.alerts); |
| | }); |
| | } |
| | |
| | function updateChart(alerts) { |
| | const gases = Object.keys(alerts); |
| | const values = gases.map(gas => alerts[gas].value); |
| | const thresholds = gases.map(gas => alerts[gas].threshold); |
| | |
| | if (gasChart) { |
| | gasChart.data.datasets[0].data = values; |
| | gasChart.data.datasets[1].data = thresholds; |
| | gasChart.update(); |
| | } else { |
| | const ctx = document.getElementById('gasChart').getContext('2d'); |
| | gasChart = new Chart(ctx, { |
| | type: 'bar', |
| | data: { |
| | labels: gases, |
| | datasets: [ |
| | { |
| | label: 'Current Level (ppm)', |
| | data: values, |
| | backgroundColor: values.map((v, i) => |
| | v > thresholds[i] ? 'rgba(255, 99, 132, 0.7)' : 'rgba(54, 162, 235, 0.7)' |
| | ) |
| | }, |
| | { |
| | label: 'Safety Threshold', |
| | data: thresholds, |
| | type: 'line', |
| | borderColor: 'rgba(255, 159, 64, 1)', |
| | borderWidth: 2, |
| | fill: false |
| | } |
| | ] |
| | }, |
| | options: { |
| | scales: { |
| | y: { beginAtZero: true, title: { display: true, text: 'Concentration (ppm)' } } |
| | } |
| | } |
| | }); |
| | } |
| | } |
| | |
| | |
| | updateData(); |
| | setInterval(updateData, 5000); |
| | </script> |
| | </body> |
| | </html> |
| |
|