wola j'avais oublié ces codes
This commit is contained in:
246
composants/byPanda/alarme.py
Normal file
246
composants/byPanda/alarme.py
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
import time
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
|
GPIO.setmode(GPIO.BOARD)
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
|
||||||
|
|
||||||
|
class SystemeAlarme:
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Initialise les composants liés à l'alarme.
|
||||||
|
|
||||||
|
Cette classe gère uniquement la logique locale de sécurité :
|
||||||
|
- le capteur PIR
|
||||||
|
- le buzzer
|
||||||
|
- la LED RGB de statut
|
||||||
|
- le clavier 4x4
|
||||||
|
|
||||||
|
Elle ne dépend d'aucune autre partie du projet.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Définition des pins physiques
|
||||||
|
# -----------------------------
|
||||||
|
self.pinPir = 22
|
||||||
|
self.pinBuzzer = 12
|
||||||
|
|
||||||
|
self.pinLedRouge = 11
|
||||||
|
self.pinLedVerte = 13
|
||||||
|
self.pinLedBleue = 15
|
||||||
|
|
||||||
|
# Clavier 4x4
|
||||||
|
# 4 lignes + 4 colonnes
|
||||||
|
self.lignes = [29, 31, 33, 35]
|
||||||
|
self.colonnes = [37, 32, 36, 38]
|
||||||
|
|
||||||
|
# Disposition classique d'un clavier 4x4
|
||||||
|
self.touches = [
|
||||||
|
["1", "2", "3", "A"],
|
||||||
|
["4", "5", "6", "B"],
|
||||||
|
["7", "8", "9", "C"],
|
||||||
|
["*", "0", "#", "D"]
|
||||||
|
]
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Variables de fonctionnement
|
||||||
|
# -----------------------------
|
||||||
|
self.codeSecret = "1234"
|
||||||
|
self.codeSaisi = ""
|
||||||
|
|
||||||
|
# Etats possibles :
|
||||||
|
# - desarme
|
||||||
|
# - arme
|
||||||
|
# - alarme
|
||||||
|
self.etat = "desarme"
|
||||||
|
|
||||||
|
# Anti-rebond clavier
|
||||||
|
self.derniereLecture = 0
|
||||||
|
self.delaiLecture = 0.25
|
||||||
|
|
||||||
|
self.initialiserGPIO()
|
||||||
|
self.mettreAJourEtat()
|
||||||
|
|
||||||
|
def initialiserGPIO(self):
|
||||||
|
"""Configure les broches du Raspberry Pi pour l'alarme."""
|
||||||
|
GPIO.setup(self.pinPir, GPIO.IN)
|
||||||
|
GPIO.setup(self.pinBuzzer, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
|
||||||
|
GPIO.setup(self.pinLedRouge, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
GPIO.setup(self.pinLedVerte, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
GPIO.setup(self.pinLedBleue, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
|
||||||
|
for pin in self.lignes:
|
||||||
|
GPIO.setup(pin, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
|
||||||
|
for pin in self.colonnes:
|
||||||
|
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||||
|
|
||||||
|
def definirCouleur(self, rouge, vert, bleu):
|
||||||
|
"""
|
||||||
|
Allume la LED RGB selon la couleur voulue.
|
||||||
|
|
||||||
|
Paramètres :
|
||||||
|
- rouge : True / False
|
||||||
|
- vert : True / False
|
||||||
|
- bleu : True / False
|
||||||
|
"""
|
||||||
|
GPIO.output(self.pinLedRouge, GPIO.HIGH if rouge else GPIO.LOW)
|
||||||
|
GPIO.output(self.pinLedVerte, GPIO.HIGH if vert else GPIO.LOW)
|
||||||
|
GPIO.output(self.pinLedBleue, GPIO.HIGH if bleu else GPIO.LOW)
|
||||||
|
|
||||||
|
def mettreAJourEtat(self):
|
||||||
|
"""
|
||||||
|
Met à jour les sorties selon l'état actuel du système.
|
||||||
|
|
||||||
|
- desarme : LED verte, buzzer éteint
|
||||||
|
- arme : LED bleue, buzzer éteint
|
||||||
|
- alarme : LED rouge, buzzer allumé
|
||||||
|
"""
|
||||||
|
if self.etat == "desarme":
|
||||||
|
self.definirCouleur(False, True, False)
|
||||||
|
GPIO.output(self.pinBuzzer, GPIO.LOW)
|
||||||
|
|
||||||
|
elif self.etat == "arme":
|
||||||
|
self.definirCouleur(False, False, True)
|
||||||
|
GPIO.output(self.pinBuzzer, GPIO.LOW)
|
||||||
|
|
||||||
|
elif self.etat == "alarme":
|
||||||
|
self.definirCouleur(True, False, False)
|
||||||
|
GPIO.output(self.pinBuzzer, GPIO.HIGH)
|
||||||
|
|
||||||
|
def armer(self):
|
||||||
|
"""Passe le système en mode armé."""
|
||||||
|
self.etat = "arme"
|
||||||
|
self.codeSaisi = ""
|
||||||
|
self.mettreAJourEtat()
|
||||||
|
print("Alarme activée.")
|
||||||
|
|
||||||
|
def desarmer(self):
|
||||||
|
"""Passe le système en mode désarmé."""
|
||||||
|
self.etat = "desarme"
|
||||||
|
self.codeSaisi = ""
|
||||||
|
self.mettreAJourEtat()
|
||||||
|
print("Alarme désactivée.")
|
||||||
|
|
||||||
|
def declencherAlarme(self):
|
||||||
|
"""
|
||||||
|
Déclenche l'alarme si un mouvement est détecté alors
|
||||||
|
que le système est armé.
|
||||||
|
"""
|
||||||
|
if self.etat != "alarme":
|
||||||
|
self.etat = "alarme"
|
||||||
|
self.codeSaisi = ""
|
||||||
|
self.mettreAJourEtat()
|
||||||
|
print("Intrusion détectée : alarme déclenchée.")
|
||||||
|
|
||||||
|
def lireClavier(self):
|
||||||
|
"""
|
||||||
|
Scanne le clavier 4x4.
|
||||||
|
|
||||||
|
Retour :
|
||||||
|
- la touche détectée
|
||||||
|
- None si aucune touche n'est pressée
|
||||||
|
"""
|
||||||
|
maintenant = time.time()
|
||||||
|
|
||||||
|
if maintenant - self.derniereLecture < self.delaiLecture:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for indexLigne, ligne in enumerate(self.lignes):
|
||||||
|
GPIO.output(ligne, GPIO.HIGH)
|
||||||
|
|
||||||
|
for indexColonne, colonne in enumerate(self.colonnes):
|
||||||
|
if GPIO.input(colonne) == GPIO.HIGH:
|
||||||
|
GPIO.output(ligne, GPIO.LOW)
|
||||||
|
self.derniereLecture = maintenant
|
||||||
|
|
||||||
|
# Petite attente pour éviter la lecture multiple
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
return self.touches[indexLigne][indexColonne]
|
||||||
|
|
||||||
|
GPIO.output(ligne, GPIO.LOW)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def validerCode(self):
|
||||||
|
"""
|
||||||
|
Vérifie le code saisi.
|
||||||
|
|
||||||
|
Si le code est correct :
|
||||||
|
- alarme désarmée -> armée
|
||||||
|
- alarme armée -> désarmée
|
||||||
|
- alarme déclenchée -> désarmée
|
||||||
|
|
||||||
|
Si le code est faux :
|
||||||
|
- on efface la saisie
|
||||||
|
"""
|
||||||
|
if self.codeSaisi == self.codeSecret:
|
||||||
|
if self.etat == "desarme":
|
||||||
|
self.armer()
|
||||||
|
else:
|
||||||
|
self.desarmer()
|
||||||
|
else:
|
||||||
|
print("Code incorrect.")
|
||||||
|
self.codeSaisi = ""
|
||||||
|
|
||||||
|
def traiterClavier(self, touche):
|
||||||
|
"""
|
||||||
|
Gère la logique du clavier :
|
||||||
|
- chiffres : ajout au code saisi
|
||||||
|
- * : efface la saisie
|
||||||
|
- # : valide le code
|
||||||
|
"""
|
||||||
|
if touche is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
print("Touche appuyée :", touche)
|
||||||
|
|
||||||
|
if touche == "*":
|
||||||
|
self.codeSaisi = ""
|
||||||
|
print("Saisie effacée.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if touche == "#":
|
||||||
|
self.validerCode()
|
||||||
|
return
|
||||||
|
|
||||||
|
if touche.isdigit():
|
||||||
|
if len(self.codeSaisi) < 8:
|
||||||
|
self.codeSaisi += touche
|
||||||
|
print("Code en cours :", "*" * len(self.codeSaisi))
|
||||||
|
|
||||||
|
def surveillerPIR(self):
|
||||||
|
"""
|
||||||
|
Vérifie le capteur de mouvement.
|
||||||
|
|
||||||
|
Si un mouvement est détecté alors que l'alarme est armée,
|
||||||
|
on passe en état d'alarme.
|
||||||
|
"""
|
||||||
|
mouvement = GPIO.input(self.pinPir) == GPIO.HIGH
|
||||||
|
|
||||||
|
if self.etat == "arme" and mouvement:
|
||||||
|
self.declencherAlarme()
|
||||||
|
|
||||||
|
def mettreAJour(self):
|
||||||
|
"""
|
||||||
|
Fonction appelée en boucle dans le programme principal.
|
||||||
|
|
||||||
|
Elle :
|
||||||
|
- lit le clavier
|
||||||
|
- traite la touche appuyée
|
||||||
|
- surveille le PIR
|
||||||
|
- synchronise LED et buzzer avec l'état courant
|
||||||
|
"""
|
||||||
|
touche = self.lireClavier()
|
||||||
|
self.traiterClavier(touche)
|
||||||
|
self.surveillerPIR()
|
||||||
|
self.mettreAJourEtat()
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
"""
|
||||||
|
Remet les sorties dans un état propre à la fermeture.
|
||||||
|
"""
|
||||||
|
GPIO.output(self.pinBuzzer, GPIO.LOW)
|
||||||
|
self.definirCouleur(False, False, False)
|
||||||
31
composants/byPanda/board1main.py
Normal file
31
composants/byPanda/board1main.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import time
|
||||||
|
from alarme import SystemeAlarme
|
||||||
|
from porterfid import SystemePorteRFID
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# board1main.py
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# Ce fichier lance uniquement la logique locale de la board 1.
|
||||||
|
# Il ne dépend pas du site web, de la base de données ni de Flask.
|
||||||
|
# Son rôle est simplement de faire tourner :
|
||||||
|
# - le système d'alarme
|
||||||
|
# - le système de porte RFID
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
alarme = SystemeAlarme()
|
||||||
|
porte = SystemePorteRFID()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
# Mise à jour des deux modules locaux
|
||||||
|
alarme.mettreAJour()
|
||||||
|
porte.mettreAJour()
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nArrêt manuel du programme.")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# On remet les sorties dans un état propre avant de quitter
|
||||||
|
alarme.cleanup()
|
||||||
|
porte.cleanup()
|
||||||
110
composants/byPanda/porterfid.py
Normal file
110
composants/byPanda/porterfid.py
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
from mfrc522 import SimpleMFRC522
|
||||||
|
|
||||||
|
GPIO.setmode(GPIO.BOARD)
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
|
||||||
|
|
||||||
|
class SystemePorteRFID:
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Initialise le système local d'accès par RFID.
|
||||||
|
|
||||||
|
Cette classe gère uniquement :
|
||||||
|
- le lecteur RFID
|
||||||
|
- la LED qui symbolise l'ouverture de porte
|
||||||
|
|
||||||
|
Elle ne pilote pas l'alarme et ne dépend pas du site web.
|
||||||
|
"""
|
||||||
|
self.pinLed = 40
|
||||||
|
GPIO.setup(self.pinLed, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
|
||||||
|
self.lecteur = SimpleMFRC522()
|
||||||
|
|
||||||
|
# Remplacer ces identifiants par les vrais UID autorisés
|
||||||
|
self.badgesAutorises = {
|
||||||
|
123456789012: "Admin",
|
||||||
|
987654321098: "Utilisateur"
|
||||||
|
}
|
||||||
|
|
||||||
|
self.badgeDetecte = None
|
||||||
|
self.derniereOuverture = 0
|
||||||
|
self.delaiEntreScans = 2
|
||||||
|
|
||||||
|
# Ce thread sert à ne pas bloquer la boucle principale
|
||||||
|
# pendant l'attente d'un badge RFID.
|
||||||
|
self.threadLecture = threading.Thread(target=self.boucleLectureRFID, daemon=True)
|
||||||
|
self.threadLecture.start()
|
||||||
|
|
||||||
|
def boucleLectureRFID(self):
|
||||||
|
"""
|
||||||
|
Boucle secondaire qui attend les badges RFID.
|
||||||
|
|
||||||
|
La méthode read() est bloquante selon la bibliothèque utilisée,
|
||||||
|
donc on la place dans un thread séparé pour que le reste du
|
||||||
|
programme continue de tourner normalement.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
badgeId, _ = self.lecteur.read()
|
||||||
|
self.badgeDetecte = badgeId
|
||||||
|
except Exception as erreur:
|
||||||
|
print("Erreur RFID :", erreur)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def badgeAutorise(self, badgeId):
|
||||||
|
"""Retourne True si le badge est autorisé."""
|
||||||
|
return badgeId in self.badgesAutorises
|
||||||
|
|
||||||
|
def ouvrirPorte(self):
|
||||||
|
"""
|
||||||
|
Simule l'ouverture de la porte avec la LED.
|
||||||
|
|
||||||
|
Ici la LED reste allumée 2 secondes pour représenter
|
||||||
|
l'accès autorisé.
|
||||||
|
"""
|
||||||
|
print("Porte ouverte.")
|
||||||
|
GPIO.output(self.pinLed, GPIO.HIGH)
|
||||||
|
time.sleep(2)
|
||||||
|
GPIO.output(self.pinLed, GPIO.LOW)
|
||||||
|
|
||||||
|
def traiterBadge(self, badgeId):
|
||||||
|
"""
|
||||||
|
Vérifie si le badge présenté est autorisé.
|
||||||
|
Si oui, on ouvre la porte.
|
||||||
|
Sinon, on affiche un refus.
|
||||||
|
"""
|
||||||
|
print("Badge détecté :", badgeId)
|
||||||
|
|
||||||
|
if self.badgeAutorise(badgeId):
|
||||||
|
print("Accès autorisé pour", self.badgesAutorises[badgeId])
|
||||||
|
self.ouvrirPorte()
|
||||||
|
else:
|
||||||
|
print("Accès refusé.")
|
||||||
|
|
||||||
|
def mettreAJour(self):
|
||||||
|
"""
|
||||||
|
Fonction appelée en boucle dans le programme principal.
|
||||||
|
|
||||||
|
Elle récupère le dernier badge lu par le thread RFID
|
||||||
|
et le traite si nécessaire.
|
||||||
|
"""
|
||||||
|
if self.badgeDetecte is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if time.time() - self.derniereOuverture < self.delaiEntreScans:
|
||||||
|
return
|
||||||
|
|
||||||
|
badgeId = self.badgeDetecte
|
||||||
|
self.badgeDetecte = None
|
||||||
|
self.derniereOuverture = time.time()
|
||||||
|
|
||||||
|
self.traiterBadge(badgeId)
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
"""
|
||||||
|
Eteint la LED de porte lors de la fermeture du programme.
|
||||||
|
"""
|
||||||
|
GPIO.output(self.pinLed, GPIO.LOW)
|
||||||
Reference in New Issue
Block a user