Mise à jour
This commit is contained in:
@@ -1,10 +1,3 @@
|
||||
/**
|
||||
* ============================================
|
||||
* SERVER.JS - Serveur principal Smart Parking
|
||||
* VERSION 2.0 - MQTT Arduino + Expiration réservations
|
||||
* ============================================
|
||||
*/
|
||||
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const bodyParser = require('body-parser');
|
||||
@@ -27,27 +20,10 @@ app.use('/api', apiRoutes);
|
||||
app.get('/', (_req, res) => res.sendFile(path.join(__dirname, '..', 'index.html')));
|
||||
app.get('/dashboard', (_req, res) => res.sendFile(path.join(__dirname, '..', 'pages', 'dashboard.html')));
|
||||
|
||||
// ============================================
|
||||
// CONNEXION MQTT (Mosquitto sur le Raspberry Pi)
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Topics attendus depuis l'Arduino :
|
||||
*
|
||||
* smartparking/sensor/1 → "1" = voiture détectée (occupée)
|
||||
* smartparking/sensor/1 → "0" = place libre
|
||||
*
|
||||
* L'Arduino publie sur ce topic via le shield Ethernet/WiFi.
|
||||
* Le numéro à la fin correspond au numéro de place (1 à N).
|
||||
*
|
||||
* Pour tester sans Arduino (ligne de commande sur le Pi) :
|
||||
* mosquitto_pub -h localhost -t "smartparking/sensor/1" -m "1"
|
||||
* mosquitto_pub -h localhost -t "smartparking/sensor/1" -m "0"
|
||||
*/
|
||||
|
||||
const MQTT_HOST = process.env.MQTT_HOST || 'localhost';
|
||||
const MQTT_PORT = process.env.MQTT_PORT || 1883;
|
||||
const MQTT_TOPIC = 'smartparking/sensor/#'; // # = wildcard, reçoit tous les capteurs
|
||||
const MQTT_TOPIC = 'smartparking/sensor/#';
|
||||
|
||||
let mqttClient = null;
|
||||
|
||||
@@ -58,7 +34,7 @@ function connectMQTT() {
|
||||
mqttClient = mqtt.connect(brokerUrl, {
|
||||
clientId: 'smartparking-server-' + Math.random().toString(16).slice(3),
|
||||
keepalive: 60,
|
||||
reconnectPeriod: 5000, // Reconnexion automatique toutes les 5s si coupure
|
||||
reconnectPeriod: 5000,
|
||||
connectTimeout: 10000
|
||||
});
|
||||
|
||||
@@ -73,11 +49,11 @@ function connectMQTT() {
|
||||
});
|
||||
});
|
||||
|
||||
// Message reçu depuis un capteur Arduino
|
||||
|
||||
mqttClient.on('message', async (topic, messageBuffer) => {
|
||||
const message = messageBuffer.toString().trim();
|
||||
const topicParts = topic.split('/'); // ['smartparking', 'sensor', '1']
|
||||
const spotNumber = parseInt(topicParts[2]); // numéro de place
|
||||
const topicParts = topic.split('/');
|
||||
const spotNumber = parseInt(topicParts[2]);
|
||||
|
||||
if (isNaN(spotNumber)) {
|
||||
console.warn(`⚠️ Topic MQTT invalide : ${topic}`);
|
||||
@@ -86,11 +62,11 @@ function connectMQTT() {
|
||||
|
||||
console.log(`📩 MQTT reçu → topic: ${topic} | valeur: ${message}`);
|
||||
|
||||
// "1" = voiture présente → occupée | "0" = libre
|
||||
|
||||
const newStatus = message === '1' ? 'occupied' : 'free';
|
||||
|
||||
try {
|
||||
// Récupérer la place par son numéro
|
||||
|
||||
const spots = await db.getAllSpots();
|
||||
const spot = spots.find(s => s.number === spotNumber);
|
||||
|
||||
@@ -99,15 +75,14 @@ function connectMQTT() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ne pas écraser une place RÉSERVÉE avec un simple signal capteur
|
||||
// (la réservation prime sur le capteur physique)
|
||||
|
||||
if (spot.status === 'reserved' && newStatus === 'occupied') {
|
||||
console.log(`ℹ️ Place ${spotNumber} déjà réservée — capteur ignoré`);
|
||||
await db.recordMqttEvent(topic, message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mettre à jour en base
|
||||
|
||||
await db.updateSpotStatus(spot.id, newStatus);
|
||||
await db.recordMqttEvent(topic, message);
|
||||
|
||||
@@ -130,9 +105,7 @@ function connectMQTT() {
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// DÉMARRAGE DU SERVEUR
|
||||
// ============================================
|
||||
|
||||
|
||||
async function startServer() {
|
||||
try {
|
||||
@@ -153,10 +126,10 @@ async function startServer() {
|
||||
`);
|
||||
});
|
||||
|
||||
// 3. Connecter le client MQTT (broker Mosquitto)
|
||||
|
||||
connectMQTT();
|
||||
|
||||
// 4. Enregistrer les statistiques toutes les 5 minutes
|
||||
|
||||
setInterval(async () => {
|
||||
try {
|
||||
const spots = await db.getAllSpots();
|
||||
@@ -170,8 +143,7 @@ async function startServer() {
|
||||
}
|
||||
}, 5 * 60 * 1000);
|
||||
|
||||
// 5. ⭐ EXPIRATION AUTOMATIQUE DES RÉSERVATIONS toutes les minutes
|
||||
// Libère les places dont l'heure de fin est dépassée
|
||||
|
||||
setInterval(async () => {
|
||||
try {
|
||||
const count = await db.expireReservations();
|
||||
@@ -181,7 +153,7 @@ async function startServer() {
|
||||
} catch (err) {
|
||||
console.error('❌ Erreur expiration réservations :', err.message);
|
||||
}
|
||||
}, 60 * 1000); // toutes les 60 secondes
|
||||
}, 60 * 1000);
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Erreur au démarrage :', err);
|
||||
@@ -189,7 +161,7 @@ async function startServer() {
|
||||
}
|
||||
}
|
||||
|
||||
// Arrêt propre
|
||||
|
||||
process.on('SIGINT', async () => {
|
||||
console.log('\n🛑 Arrêt du serveur...');
|
||||
if (mqttClient) mqttClient.end();
|
||||
|
||||
Reference in New Issue
Block a user