Système de gestion de clés de salles de classe en temps réel utilisant RFID/NFC, ZigBee, MQTT et architecture Edge Computing.
- Arduino Uno R4 WiFi avec lecteur RC522 RFID
- XBee S2C ZigBee (module émetteur en mode API)
- Boîtier à clés avec tags RFID/NFC uniques
- MQTT Broker (Mosquitto ou similaire) - Point central de communication
- Gateway XBee - Service Python qui écoute les données XBee et les publie sur MQTT
- Backend Python (Flask + SocketIO) - Traite les messages MQTT et met à jour le Dashboard
- Dashboard HTML - Interface temps réel WebSocket
- Stockage local des événements (pas de cloud)
/keybox-iot
│
├── arduino_TX.cpp # Code Arduino pour les salles (lecteur RFID + XBee)
│
├── /backend
│ ├── app.py # Serveur Flask + WebSocket (écoute MQTT)
│ ├── corresponding_table.json # Mapping clés ↔ salles
│ └── requirements.txt # Dépendances Python
│
├── /gateway
│ ├── gateway.py # Service XBee → MQTT
│ └── xbee_handler.py # Gestion communication XBee
│
└── /frontend
└── templates
└── index.html # Dashboard temps réel
- Python 3.8+
- MQTT Broker installé et en cours d'exécution (Mosquitto)
- XBee Coordinator configuré en mode API
- Drivers USB pour XBee installés
# Sur macOS avec Homebrew
brew services start mosquitto
# Sur Linux
sudo service mosquitto start
# Ou avec Docker
docker run -d -p 1883:1883 eclipse-mosquittoVérifier que le Broker est actif sur localhost:1883
cd backend
pip install -r requirements.txt-
Brancher l'XBee Coordinator en USB sur le PC
-
Identifier le port COM :
- macOS :
ls /dev/tty.usbserial* - Linux :
ls /dev/ttyUSB* - Windows : Gestionnaire de périphériques → Ports (COM et LPT)
- macOS :
-
Modifier gateway/gateway.py ligne 8 :
XBEE_PORT = "/dev/tty.usbserial-0001" # Remplacer par votre port
Terminal 1 - Gateway (XBee → MQTT) :
cd gateway
python gateway.pyTerminal 2 - Backend (MQTT → WebSocket) :
cd backend
python app.pyLe serveur démarre sur http://0.0.0.0:5000
Si jamais le port 5000 est occupé (notamment sur MacOS avec AirPlay), modifier la ligne 141 de app.py :
socketio.run(app, host='0.0.0.0', port=5001, debug=False, use_reloader=False)Ouvrir le navigateur :
- Local :
http://localhost:5000 - Réseau local :
http://<IP_DU_PC>:5000(depuis un autre appareil sur le même WiFi)
L'Arduino envoie un payload JSON via XBee :
{
"room": "206",
"key": "A3F2118C",
"state": "IN"
}room: Identifiant de la salle (ex: "106", "107", "206")key: UID du tag RFID lu par le RC522state:"IN"→ Clé déposée (salle ouverte)"OUT"→ Clé retirée (salle fermée)
Topic MQTT : ecole/salles/{room}/status
{
"room": "206",
"key": "A3F2118C",
"state": "IN",
"timestamp": "2026-02-01T10:30:45"
}Le backend s'abonne à : ecole/salles/+/status (wildcard pour toutes les salles)
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
SoftwareSerial xbeeSerial(2, 3); // RX, TX
void sendKeyEvent(String room, String keyUID, String state) {
StaticJsonDocument<128> doc;
doc["room"] = room;
doc["key"] = keyUID;
doc["state"] = state;
serializeJson(doc, xbeeSerial);
xbeeSerial.println(); // Fin de trame
}
void loop() {
// Après lecture RFID...
if (cardDetected) {
sendKeyEvent("206", "A3:F2:11:8C", "IN");
}
}- Carte verte (bordure gauche) → Clé présente (salle ouverte)
- Carte rouge (bordure gauche) → Clé absente (salle fermée)
- Horodatage de la dernière mise à jour
- Création dynamique des salles (pas besoin de pré-configuration)
Le dashboard utilise WebSocket (SocketIO) pour recevoir les mises à jour instantanément sans rafraîchir la page.
Utiliser un client MQTT pour publier des messages de test :
# Publier une clé déposée en salle 206
mosquitto_pub -h localhost -t "ecole/salles/206/status" -m '{"room":"206","key":"TEST_UID","state":"IN"}'
# Publier une clé retirée
mosquitto_pub -h localhost -t "ecole/salles/206/status" -m '{"room":"206","key":"TEST_UID","state":"OUT"}'Le Backend et Dashboard se mettront à jour en temps réel.
- Mode : Router/End Device
- API Mode : API Mode 1 (ATAP=1)
- PAN ID : Identique pour tout le réseau (ex: 1234)
- Baud Rate : 9600
- EE: 1 pour activer le chiffrement AES
- KY: par exemple
1A2B3C4D5E6Fpour la clé de chiffrement (doit être identique sur tous les XBee)
- Mode : Coordinator
- API Mode : API Mode 1 (ATAP=1)
- PAN ID : Identique au réseau
- Baud Rate : 9600
- EE: 1 pour activer le chiffrement AES
- KY: par exemple
1A2B3C4D5E6Fpour la clé de chiffrement (doit être identique sur tous les XBee)
Configuration via XCTU (logiciel Digi).
- Vérifier que Mosquitto est installé :
mosquitto -v - Si port 1883 déjà utilisé :
lsof -i :1883 - Redémarrer le service :
brew services restart mosquitto
- Vérifier que le port COM est correct dans gateway/gateway.py
- Vérifier que les drivers USB XBee sont installés
- Tester :
ls /dev/tty.usbserial*(macOS) - Vérifier les logs de la Gateway pour les erreurs
- Vérifier que le Broker MQTT est actif :
mosquitto_sub -h localhost -t "ecole/salles/+/status" - Vérifier les logs de la Gateway :
[GATEWAY] Publié sur MQTT... - Vérifier que
MQTT_BROKER = "localhost"dans gateway.py
- Ouvrir la console navigateur (F12) → Vérifier les messages WebSocket
- Vérifier que le Backend s'est bien abonné :
[BACKEND] Connecté à MQTTdans les logs - Regarder les logs du Backend Python (terminal)
- Vérifier le
MQTT_TOPICdans backend/app.py
- Vérifier que le WebSocket est actif (F12 → Network → WS)
- Vérifier les logs du Backend pour les messages reçus
- Vérifier le payload JSON du message MQTT
sudo chmod 666 /dev/tty.usbserial-0001- ✅ Démontrer la communication ZigBee mesh (40 salles)
- ✅ Interface temps réel sans latence perceptible
- ✅ Architecture Edge (pas de cloud, pas de dépendance Internet)
- ✅ Détection de clés RFID et mise à jour instantanée
- ✅ Évolutivité (ajout automatique de nouvelles salles)
Projet académique CESI - Gestion IoT de clés de salles de classe
Projet éducatif - Usage académique uniquement
