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