irrigation_trial / templates /predict.html
RushiMane2003's picture
Update templates/predict.html
e4d7927 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Prediction Results</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background-color: #f4f8f4; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
.header { background-color: #28a745; color: white; padding: 20px; text-align: center; font-weight: bold; }
.container { margin-top: 30px; padding: 20px; background-color: white; border-radius: 15px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
.result-label { font-weight: bold; color: #555; }
.form-control[readonly] { font-size: 1.2rem; text-align: center; font-weight: bold; color: #28a745; background-color: #e9f5e9; border: 2px solid #28a745; }
.gauge-container { margin-top: 20px; text-align: center; }
.info-card { background-color: #f8f9fa; border: 1px solid #dee2e6; border-radius: 10px; padding: 25px; margin-top: 40px; text-align: center; }
.camera-container { margin-top: 20px; display: none; flex-direction: column; align-items: center; gap: 20px; }
video { width: 100%; max-width: 720px; height: auto; border-radius: 10px; border: 2px solid #ddd; background-color: #000; }
.timer { font-size: 2rem; color: white; background-color: #28a745; font-weight: bold; padding: 10px 25px; border-radius: 10px; display: inline-block; min-width: 120px; text-align: center; }
.timer-finished { font-size: 1.5rem; padding: 15px 40px; background-color: #dc3545; }
.alert-message { font-size: 1.2rem; font-weight: bold; margin-top: 20px; text-align: center; }
.modal-header { background-color: #28a745; color: white; }
</style>
</head>
<body>
<div class="header">
<h1>Water Requirement Prediction Results</h1>
</div>
<div class="container">
<div class="row">
<div class="col-md-6 mb-4">
<label for="water_requirement" class="result-label">Predicted Water Requirement (m³/sq.m):</label>
<input type="text" class="form-control" id="water_requirement" value="{{ water_requirement }}" readonly>
<div class="gauge-container">
{% if water_img %}
<img src="{{ water_img }}" alt="Water gauge" class="img-fluid" style="max-height:360px;">
{% else %}
{{ water_gauge|safe }}
{% endif %}
</div>
</div>
<div class="col-md-6 mb-4">
<label for="estimated_time" class="result-label">Estimated Motor On-Time:</label>
<input type="text" class="form-control" id="estimated_time" value="{{ estimated_time_duration }} {{ time_unit }}" readonly>
<div class="gauge-container">
{% if time_img %}
<img src="{{ time_img }}" alt="Time gauge" class="img-fluid" style="max-height:360px;">
{% else %}
{{ time_gauge|safe }}
{% endif %}
</div>
</div>
</div>
<div class="info-card">
<h4>AI-Driven Irrigation Monitoring</h4>
<p class="mt-3">A message has been sent to your WhatsApp. Please reply <strong>1</strong> to start the motor and activate live monitoring here, or reply <strong>0</strong> to cancel the operation.</p>
</div>
<div class="camera-container" id="cameraContainer">
<h4 class="text-center mb-0">Live Irrigation Feed</h4>
<video id="videoElement" autoplay playsinline></video>
<div class="timer" id="timer"></div>
</div>
<div class="alert-message text-success" id="alertMessage">Waiting for WhatsApp confirmation...</div>
</div>
<script>
// --- GLOBAL VARIABLES ---
let pollingInterval = null;
let clientTimerInterval = null;
let cameraStream = null;
let isMonitoringActive = false;
// --- MAIN FUNCTION TO START POLLING ---
window.onload = function() {
// Start polling the server for status updates every 3 seconds
pollingInterval = setInterval(checkMonitorStatus, 3000);
checkMonitorStatus(); // Check immediately on load
};
// --- FUNCTION TO CHECK STATUS WITH THE SERVER ---
function checkMonitorStatus() {
fetch('/monitoring_status')
.then(resp => resp.json())
.then(data => {
if (data.monitoring && !isMonitoringActive) {
// --- START MONITORING ---
isMonitoringActive = true;
console.log("Server indicated to start monitoring.");
document.getElementById('alertMessage').textContent = "✅ Monitoring started via WhatsApp confirmation!";
startCameraAndTimer(data.time_remaining);
} else if (!data.monitoring && isMonitoringActive) {
// --- STOP MONITORING (e.g., if task is canceled or completed on server) ---
isMonitoringActive = false;
console.log("Server indicated to stop monitoring.");
document.getElementById('alertMessage').textContent = "Monitoring has been stopped or completed.";
stopCameraAndTimer();
}
})
.catch(err => {
console.error('Error polling for status:', err);
// Stop polling if there is an error to avoid spamming the console
clearInterval(pollingInterval);
});
}
// --- FUNCTION TO ACTIVATE CAMERA AND VISUAL TIMER ---
function startCameraAndTimer(timeRemainingSeconds) {
// Show camera container
document.getElementById('cameraContainer').style.display = 'flex';
// Start Camera
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' }, audio: false })
.then(function(stream) {
cameraStream = stream;
document.getElementById('videoElement').srcObject = stream;
})
.catch(function(err) {
console.error("Camera Error: ", err);
alert("Could not access the camera. Please ensure you have given permission.");
});
} else {
alert("Camera API not supported in this browser.");
}
// Start client-side visual countdown timer
let timeRemaining = Math.floor(timeRemainingSeconds);
let timerElem = document.getElementById('timer');
timerElem.classList.remove('timer-finished');
clearInterval(clientTimerInterval); // Clear any existing timer
clientTimerInterval = setInterval(function() {
if (timeRemaining <= 0) {
clearInterval(clientTimerInterval);
timerElem.textContent = "Finished";
timerElem.classList.add('timer-finished');
document.getElementById('alertMessage').textContent = "Irrigation time is over. The motor has stopped automatically.";
stopCameraAndTimer(); // Also stop camera stream
} else {
timerElem.textContent = timeRemaining + "s";
}
timeRemaining--;
}, 1000);
}
// --- FUNCTION TO STOP CAMERA AND TIMER ---
function stopCameraAndTimer() {
clearInterval(clientTimerInterval);
clearInterval(pollingInterval); // Stop polling once task is over
if (cameraStream) {
cameraStream.getTracks().forEach(track => track.stop());
cameraStream = null;
}
// We can hide the camera container or leave it visible with a "Finished" message
// document.getElementById('cameraContainer').style.display = 'none';
}
</script>
</body>
</html>