Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Animal Health Monitor</title> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet"> | |
<style> | |
:root { | |
--primary-color: #3498db; | |
--secondary-color: #2ecc71; | |
--background-color: #ecf0f1; | |
--text-color: #34495e; | |
--card-background: #ffffff; | |
} | |
body { | |
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
background-color: var(--background-color); | |
color: var(--text-color); | |
margin: 0; | |
padding: 20px; | |
line-height: 1.6; | |
} | |
.container { | |
max-width: 1200px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
h1 { | |
color: var(--primary-color); | |
text-align: center; | |
margin-bottom: 30px; | |
font-size: 2.5em; | |
} | |
.dashboard { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
gap: 20px; | |
} | |
.card { | |
background: var(--card-background); | |
border-radius: 10px; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
padding: 20px; | |
text-align: center; | |
transition: transform 0.3s ease; | |
} | |
.card:hover { | |
transform: translateY(-5px); | |
} | |
.card-title { | |
font-size: 1.2em; | |
color: var(--primary-color); | |
margin-bottom: 10px; | |
} | |
.card-value { | |
font-size: 2em; | |
font-weight: bold; | |
margin: 10px 0; | |
} | |
.card i { | |
font-size: 2em; | |
margin-bottom: 10px; | |
color: var(--secondary-color); | |
} | |
#map { | |
height: 300px; | |
border-radius: 10px; | |
margin-top: 20px; | |
} | |
@media (max-width: 768px) { | |
.dashboard { | |
grid-template-columns: 1fr; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Animal Health Monitor</h1> | |
<div class="dashboard"> | |
<div class="card"> | |
<i class="fas fa-thermometer-half"></i> | |
<div class="card-title">Temperature</div> | |
<div class="card-value"><span id="tempCelsius">--</span>°C</div> | |
<div class="card-value"><span id="tempFahrenheit">--</span>°F</div> | |
</div> | |
<div class="card"> | |
<i class="fas fa-heartbeat"></i> | |
<div class="card-title">Heart Rate</div> | |
<div class="card-value"><span id="bpm">--</span> BPM</div> | |
</div> | |
<div class="card"> | |
<i class="fas fa-lungs"></i> | |
<div class="card-title">Blood Oxygen</div> | |
<div class="card-value"><span id="spo2">--</span>%</div> | |
</div> | |
<div class="card"> | |
<i class="fas fa-map-marker-alt"></i> | |
<div class="card-title">GPS Location</div> | |
<div class="card-value"> | |
<div>Lat: <span id="latitude">--</span></div> | |
<div>Long: <span id="longitude">--</span></div> | |
</div> | |
</div> | |
</div> | |
<div id="map"></div> | |
</div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/9.22.2/firebase-app-compat.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/9.22.2/firebase-database-compat.min.js"></script> | |
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAOVYRIgupAurZup5y1PRh8Ismb1A3lLao&callback=initMap" async defer></script> | |
<script> | |
// Initialize Google Map | |
let map; | |
let marker; | |
function initMap() { | |
try { | |
map = new google.maps.Map(document.getElementById('map'), { | |
center: {lat: 7.2297, lng: 3.4392}, // Center map at the original coordinates | |
zoom: 15 // Adjust zoom level to focus on the area | |
}); | |
marker = new google.maps.Marker({ | |
position: {lat: 7.2297, lng: 3.4392}, // Start marker at the original coordinates | |
map: map | |
}); | |
console.log("Map initialized successfully"); | |
} catch (error) { | |
console.error("Error initializing map:", error); | |
document.getElementById('map').innerHTML = '<p>Error loading map. Please check the console for details.</p>'; | |
} | |
} | |
// Function to fetch the latest data from the FastAPI endpoint | |
async function fetchLatestData() { | |
try { | |
const response = await fetch('http://localhost:8000/latest-data'); | |
const data = await response.json(); | |
return data; | |
} catch (error) { | |
console.error("Error fetching data:", error); | |
return null; | |
} | |
} | |
// Function to update the dashboard with real data | |
async function updateDashboard() { | |
const data = await fetchLatestData(); | |
if (data) { | |
document.getElementById('tempCelsius').textContent = data.temperature || '--'; | |
document.getElementById('tempFahrenheit').textContent = data.temperature_in_F || '--'; | |
document.getElementById('bpm').textContent = data.heart_rate || '--'; | |
document.getElementById('spo2').textContent = data.blood_oxygen || '--'; | |
document.getElementById('latitude').textContent = data.latitude || '--'; | |
document.getElementById('longitude').textContent = data.longitude || '--'; | |
if (map && marker && data.latitude && data.longitude) { | |
try { | |
const newPosition = new google.maps.LatLng(parseFloat(data.latitude), parseFloat(data.longitude)); | |
marker.setPosition(newPosition); | |
map.panTo(newPosition); | |
} catch (error) { | |
console.error("Error updating map:", error); | |
} | |
} else { | |
console.warn("Map or marker not initialized or invalid data"); | |
} | |
} else { | |
console.warn("No data fetched"); | |
} | |
} | |
// Initialize the dashboard on load | |
window.onload = function() { | |
initMap(); | |
updateDashboard(); | |
}; | |
// Update dashboard every 5 seconds | |
setInterval(updateDashboard, 5000); | |
</script> | |
</body> | |
</html> | |