Fix dashboard: hapus auto-reload 30s, detection window 60s, update stat 24jam realtime
This commit is contained in:
parent
3b30ccf2be
commit
4e3d5a6902
|
|
@ -686,22 +686,8 @@ function toggleSidebar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto refresh halaman setiap 30 detik untuk update alert
|
|
||||||
setTimeout(function() {
|
|
||||||
window.location.reload();
|
|
||||||
}, 30000);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// =============================================
|
|
||||||
// BUZZER & LED REALTIME POLLING
|
|
||||||
// =============================================
|
|
||||||
|
|
||||||
let alertDismissed = false;
|
|
||||||
let pollingInterval = null;
|
|
||||||
|
|
||||||
// Threshold waktu deteksi dianggap "aktif" (dalam detik)
|
// Threshold waktu deteksi dianggap "aktif" (dalam detik)
|
||||||
const DETECTION_WINDOW = 30;
|
const DETECTION_WINDOW = 60;
|
||||||
|
|
||||||
async function fetchSensorStatus() {
|
async function fetchSensorStatus() {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-gray-500 text-xs md:text-sm">Gerakan (24 jam)</p>
|
<p class="text-gray-500 text-xs md:text-sm">Gerakan (24 jam)</p>
|
||||||
<p class="text-2xl md:text-3xl font-display font-bold text-indigo-600">{{ $pirCount24h }}</p>
|
<p id="stat-pir" class="text-2xl md:text-3xl font-display font-bold text-indigo-600">{{ $pirCount24h }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white rounded-2xl shadow p-4 md:p-6 border border-gray-100 flex items-center gap-3 md:gap-4">
|
<div class="bg-white rounded-2xl shadow p-4 md:p-6 border border-gray-100 flex items-center gap-3 md:gap-4">
|
||||||
|
|
@ -158,7 +158,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-gray-500 text-xs md:text-sm">Getaran (24 jam)</p>
|
<p class="text-gray-500 text-xs md:text-sm">Getaran (24 jam)</p>
|
||||||
<p class="text-2xl md:text-3xl font-display font-bold text-yellow-600">{{ $vibrationCount24h }}</p>
|
<p id="stat-vib" class="text-2xl md:text-3xl font-display font-bold text-yellow-600">{{ $vibrationCount24h }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white rounded-2xl shadow p-4 md:p-6 border border-gray-100 flex items-center gap-3 md:gap-4">
|
<div class="bg-white rounded-2xl shadow p-4 md:p-6 border border-gray-100 flex items-center gap-3 md:gap-4">
|
||||||
|
|
@ -167,7 +167,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-gray-500 text-xs md:text-sm">Rak Dibuka (24 jam)</p>
|
<p class="text-gray-500 text-xs md:text-sm">Rak Dibuka (24 jam)</p>
|
||||||
<p class="text-2xl md:text-3xl font-display font-bold text-purple-600">{{ $reedCount24h }}</p>
|
<p id="stat-reed" class="text-2xl md:text-3xl font-display font-bold text-purple-600">{{ $reedCount24h }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -578,20 +578,31 @@ function renderReedHistory(data) {
|
||||||
// =============================================
|
// =============================================
|
||||||
async function pollSensorData() {
|
async function pollSensorData() {
|
||||||
try {
|
try {
|
||||||
const [pirRes, vibRes, reedRes] = await Promise.all([
|
const [pirRes, vibRes, reedRes, pirStat24, vibStat24, reedStat24] = await Promise.all([
|
||||||
fetch('/api/pir/readings?limit=5').then(r => r.json()).catch(() => null),
|
fetch('/api/pir/readings?limit=5').then(r => r.json()).catch(() => null),
|
||||||
fetch('/api/vibration/readings?limit=5').then(r => r.json()).catch(() => null),
|
fetch('/api/vibration/readings?limit=5').then(r => r.json()).catch(() => null),
|
||||||
fetch('/api/door-access/readings?limit=5').then(r => r.json()).catch(() => null),
|
fetch('/api/door-access/readings?limit=5').then(r => r.json()).catch(() => null),
|
||||||
|
fetch('/api/pir/statistics?hours=24').then(r => r.json()).catch(() => null),
|
||||||
|
fetch('/api/vibration/statistics?hours=24').then(r => r.json()).catch(() => null),
|
||||||
|
fetch('/api/door-access/statistics?hours=24').then(r => r.json()).catch(() => null),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
|
// ---- Update statistik 24 jam ----
|
||||||
|
const pirStatEl = document.getElementById('stat-pir');
|
||||||
|
const vibStatEl = document.getElementById('stat-vib');
|
||||||
|
const reedStatEl = document.getElementById('stat-reed');
|
||||||
|
if (pirStatEl && pirStat24?.success) pirStatEl.textContent = pirStat24.data?.motion_detected_count ?? pirStatEl.textContent;
|
||||||
|
if (vibStatEl && vibStat24?.success) vibStatEl.textContent = vibStat24.data?.warning_count + (vibStat24.data?.critical_count ?? 0) ?? vibStatEl.textContent;
|
||||||
|
if (reedStatEl && reedStat24?.success) reedStatEl.textContent = reedStat24.data?.door_opened_count ?? reedStatEl.textContent;
|
||||||
|
|
||||||
// ---- PIR ----
|
// ---- PIR ----
|
||||||
if (pirRes?.success && pirRes.data?.length > 0) {
|
if (pirRes?.success && pirRes.data?.length > 0) {
|
||||||
const d = pirRes.data[0];
|
const d = pirRes.data[0];
|
||||||
const isNew = d.id > lastPirId;
|
const isNew = d.id > lastPirId;
|
||||||
const age = (now - new Date(d.recorded_at).getTime()) / 1000;
|
const age = (now - new Date(d.recorded_at).getTime()) / 1000;
|
||||||
const active = d.motion_detected && age <= 30;
|
const active = d.motion_detected && age <= 60;
|
||||||
|
|
||||||
document.getElementById('pir-status-text').textContent = active ? '⚠ Gerakan' : '✓ Aman';
|
document.getElementById('pir-status-text').textContent = active ? '⚠ Gerakan' : '✓ Aman';
|
||||||
document.getElementById('pir-status-text').className = 'text-xl md:text-3xl font-display font-bold mb-1 ' + (active ? 'text-red-600' : 'text-green-600');
|
document.getElementById('pir-status-text').className = 'text-xl md:text-3xl font-display font-bold mb-1 ' + (active ? 'text-red-600' : 'text-green-600');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue