File size: 6,986 Bytes
73f907e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pump Prediction</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<style>
body { background-color: #f4f8f4; }
.card { border-radius: 15px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }
.card-header { background-color: #28a745; color: white; font-weight: bold; text-align: center; font-size: 1.5rem; }
.status-card { text-align: center; }
.status-label { font-size: 1.2rem; color: #555; }
.status-text { font-size: 2rem; font-weight: bold; padding: 10px 20px; border-radius: 8px; display: inline-block; transition: all 0.3s ease; }
.status-text.on { color: #28a745; background-color: #e9f5e9; border: 2px solid #28a745; }
.status-text.off { color: #dc3545; background-color: #f8d7da; border: 2px solid #dc3545; }
.chart-container { width: 100%; height: 400px; }
</style>
</head>
<body>
<div class="container my-4">
<div class="card">
<div class="card-header">Live Irrigation Status</div>
<div class="card-body">
<div class="row text-center mb-4">
<div class="col-md-6">
<div class="status-label">Current Pump Status</div>
<div id="pumpStatus" class="status-text off">Loading...</div>
</div>
<div class="col-md-6 mt-3 mt-md-0">
<div class="status-label">Time Elapsed</div>
<div id="time-counter" class="status-text" style="color: #5a2d0c; background-color: #f0e6e0; border-color: #5a2d0c;">0 seconds</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-body">
<div id="gauge" class="chart-container"></div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-body">
<div id="graph1" class="chart-container"></div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-body">
<div id="graph2" class="chart-container"></div>
</div>
</div>
</div>
<div class="col-lg-6 mb-4">
<div class="card h-100">
<div class="card-body">
<div id="graph3" class="chart-container"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
let alertSound; // Will be initialized after user interaction
function initializeAudio() {
if (!alertSound) {
alertSound = new Audio('{{ url_for("static", filename="alarn_tune.mp3") }}');
console.log("Audio initialized.");
}
}
document.body.addEventListener('click', initializeAudio, { once: true });
function fetchPumpStatus() {
fetch('/update_pump_status')
.then(response => response.json())
.then(data => {
const statusElement = document.getElementById('pumpStatus');
const newStatus = data.pump_status;
const oldStatus = statusElement.innerText;
statusElement.innerText = newStatus;
statusElement.className = 'status-text ' + (newStatus === 'On' ? 'on' : 'off');
if (newStatus === 'Off' && oldStatus === 'On' && alertSound) {
alertSound.play().catch(e => console.error("Audio play failed:", e));
}
});
}
function fetchGraphData() {
fetch('/update_graph')
.then(response => response.json())
.then(data => {
if (data.length === 0) return;
const time = data.map((_, i) => i * 2); // Assuming 2 second intervals
const soilMoisture = data.map(entry => entry[0]);
const pumpStatus = data.map(entry => entry[1]);
const currentSoilMoisture = soilMoisture[soilMoisture.length - 1];
// Responsive layout for all plots
const responsiveLayout = { margin: { t: 40, b: 50, l: 50, r: 20 }, autosize: true };
Plotly.react('gauge', getGaugeData(currentSoilMoisture), { ...responsiveLayout, title: 'Soil Moisture' });
Plotly.react('graph1', getPumpStatusData(time, pumpStatus), { ...responsiveLayout, title: 'Pump Status vs. Time', yaxis: { tickvals: [-1, 1], ticktext: ['Off', 'On'], range: [-1.5, 1.5] }});
Plotly.react('graph2', getSoilMoistureData(time, soilMoisture), { ...responsiveLayout, title: 'Soil Moisture vs. Time' });
Plotly.react('graph3', getMoistureVsStatusData(soilMoisture, pumpStatus), { ...responsiveLayout, title: 'Pump Status vs. Soil Moisture', yaxis: { tickvals: [-1, 1], ticktext: ['Off', 'On'], range: [-1.5, 1.5] }});
});
}
// --- Chart Data Functions ---
const getGaugeData = value => [{ type: "indicator", mode: "gauge+number", value: value, gauge: { axis: { range: [0, 100] }, steps: [{ range: [0, 30], color: "#ea4335" },{ range: [30, 60], color: "#fbbc05" },{ range: [60, 100], color: "#34a853" }]}}];
const getPumpStatusData = (x, y) => [{ x, y, mode: 'lines+markers', type: 'scatter', line: { color: '#4285f4' } }];
const getSoilMoistureData = (x, y) => [{ x, y, mode: 'lines+markers', type: 'scatter', line: { color: '#34a853' } }];
const getMoistureVsStatusData = (x, y) => [{ x, y, mode: 'lines', type: 'scatter', line: { color: '#ea4335' } }];
let timeCounter = 0;
setInterval(() => { document.getElementById('time-counter').innerText = `${++timeCounter} seconds`; }, 1000);
setInterval(fetchPumpStatus, 2000);
setInterval(fetchGraphData, 2000);
</script>
</body>
</html> |