add websocket counter plate

This commit is contained in:
2026-01-12 22:48:27 -03:00
parent a62acdc47d
commit 000009595d
3 changed files with 40 additions and 8 deletions

View File

@@ -57,10 +57,24 @@ def save_plate_capture(plate_number, full_frame):
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
# Solo guardar frame completo # Solo guardar frame completo
filename = f"{DATASET_DIR}/{plate_number}_{timestamp}.jpg" filename = f"{plate_number}_{timestamp}.jpg"
cv2.imwrite(filename, full_frame, [cv2.IMWRITE_JPEG_QUALITY, 95]) filepath = f"{DATASET_DIR}/{filename}"
cv2.imwrite(filepath, full_frame, [cv2.IMWRITE_JPEG_QUALITY, 95])
print(f"📸 Saved to dataset: {plate_number}") # Contar total de capturas
total_count = len([f for f in os.listdir(DATASET_DIR) if f.endswith('.jpg')])
# Notificar al backend para WebSocket
try:
requests.post(f"{BACKEND_URL}/api/dataset/capture", json={
'plate_number': plate_number,
'filename': filename,
'count': total_count
}, timeout=2)
except:
pass # No bloquear si falla la notificación
print(f"📸 Saved to dataset: {plate_number} (Total: {total_count})")
return True return True
except Exception as e: except Exception as e:
print(f"❌ Error saving capture: {e}") print(f"❌ Error saving capture: {e}")

View File

@@ -329,6 +329,22 @@ app.post('/api/detect', async (req, res) => {
} }
}); });
// Dataset Capture Notification (from ALPR Python)
app.post('/api/dataset/capture', (req, res) => {
const { plate_number, filename, count } = req.body;
console.log(`📸 Dataset capture: ${plate_number} (Total: ${count})`);
// Notify Frontend via WebSocket
io.emit('dataset_updated', {
plate: plate_number,
filename,
count,
timestamp: new Date()
});
res.json({ message: 'Notification sent' });
});
const bcrypt = require('bcryptjs'); const bcrypt = require('bcryptjs');
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;

View File

@@ -33,29 +33,31 @@ function AdminDashboard({ token }) {
fetchData(); fetchData();
fetchDatasetCount(); fetchDatasetCount();
// Actualizar contador de dataset cada 10 segundos
const datasetInterval = setInterval(fetchDatasetCount, 10000);
// Live detection listener // Live detection listener
socket.on('new_detection', (data) => { socket.on('new_detection', (data) => {
setDetections(prev => [data, ...prev].slice(0, 10)); setDetections(prev => [data, ...prev].slice(0, 10));
}); });
// Real-time dataset updates
socket.on('dataset_updated', (data) => {
setDatasetCount(data.count);
});
// Real-time updates for approvals // Real-time updates for approvals
socket.on('new_plate_registered', () => fetchData()); socket.on('new_plate_registered', () => fetchData());
socket.on('new_person_registered', () => fetchData()); socket.on('new_person_registered', () => fetchData());
socket.on('plate_status_updated', () => fetchData()); // Reused for consistency socket.on('plate_status_updated', () => fetchData());
socket.on('plate_deleted', () => fetchData()); socket.on('plate_deleted', () => fetchData());
socket.on('person_deleted', () => fetchData()); socket.on('person_deleted', () => fetchData());
return () => { return () => {
socket.off('new_detection'); socket.off('new_detection');
socket.off('dataset_updated');
socket.off('new_plate_registered'); socket.off('new_plate_registered');
socket.off('new_person_registered'); socket.off('new_person_registered');
socket.off('plate_status_updated'); socket.off('plate_status_updated');
socket.off('plate_deleted'); socket.off('plate_deleted');
socket.off('person_deleted'); socket.off('person_deleted');
clearInterval(datasetInterval);
}; };
}, [token]); }, [token]);