| <!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> |
|
|