Version fonctionnelle

This commit is contained in:
2025-08-20 15:23:01 +02:00
parent 7429fd466c
commit 4e5cd2ec74
5 changed files with 275 additions and 856 deletions

174
app/alerte_sms.py Normal file
View File

@@ -0,0 +1,174 @@
import mysql.connector
from datetime import datetime, timedelta
import time
from dotenv import load_dotenv
import os
from pathlib import Path
if os.name != 'nt':
log_dir = Path('/home/debian/Gestion_sondes/Logs')
else:
log_dir = Path.cwd() / 'Logs'
log_dir.mkdir(parents=True, exist_ok=True)
load_dotenv()
ENVOI_SMS = os.getenv("ENVOI_SMS") == "1"
# --- Config MySQL ---
config = {
"host": os.getenv("DB_HOST"),
"user": os.getenv("DB_USER"),
"password": os.getenv("DB_PASSWORD"),
"database": os.getenv("DB_NAME")
}
# --- Suivi des alertes actives pour rappels ---
alertes_actives = {}
# --- Fonction d'envoi de mail ---
def envoyer_sms_ovh(message, lieu):
try:
import requests
sms_data = {
"account": os.getenv("OVH_SMS_ACCOUNT"),
"login": os.getenv("OVH_SERVICE_NAME"),
"password": os.getenv("OVH_PASSWORD"),
"message": f"{lieu}: {message}",
"receivers": os.getenv("SMS_RECEIVER", "").split(","),
"sender": os.getenv("OVH_SMS_SENDER")
}
# Exemple d'envoi avec l'API OVH (à adapter selon ton endpoint exact)
response = requests.post("https://www.ovh.com/cgi-bin/sms/http2sms.cgi", data=sms_data)
print(f"📱 SMS envoyé : {response.text}", flush=True)
except Exception as e:
print(f"Erreur envoi SMS : {e}", flush=True)
# --- Fonction de surveillance ---
def surveiller():
global alertes_actives
log_entries = []
try:
conn = mysql.connector.connect(**config)
cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT DISTINCT Lieu FROM Sondes.Chambres_froides")
lieux = [row['Lieu'] for row in cursor.fetchall()]
for lieu in lieux:
table_temp = lieu
table_alertes = f"Alertes_{lieu}"
cursor.execute("SELECT Sonde, Temp_Max FROM Sondes.Chambres_froides WHERE Lieu=%s AND Etat='ON'", (lieu,))
sondes = cursor.fetchall()
for sonde in sondes:
nom_sonde = sonde['Sonde']
seuil = sonde['Temp_Max']
cursor.execute(f"""
SELECT Date, Temperature FROM {table_temp}
WHERE Sonde = %s
ORDER BY Date DESC LIMIT 6
""", (nom_sonde,))
releves = cursor.fetchall()
for r in releves:
log_entries.append({
"Date": r['Date'],
"Lieu": lieu,
"Sonde": nom_sonde,
"Température": r['Temperature'],
"Seuil": seuil,
"État": "Dépassement" if r['Temperature'] > seuil else "Normal"
})
if len(releves) == 6:
toutes_hors_seuil = all(r['Temperature'] > seuil for r in releves)
plus_ancien = releves[-1]['Date']
maintenant = datetime.now()
if toutes_hors_seuil and (maintenant - plus_ancien >= timedelta(minutes=30)):
cursor.execute(f"""
SELECT COUNT(*) as total FROM {table_alertes}
WHERE Sonde=%s AND Status='En cours'
""", (nom_sonde,))
en_cours = cursor.fetchone()
if en_cours['total'] == 0:
cursor.execute(
f"INSERT INTO {table_alertes} (Sonde, Debut_defaut, Status) VALUES (%s, NOW(), 'En cours')",
(nom_sonde,)
)
print(f"🚨 Alerte déclenchée pour {nom_sonde} ({lieu})", flush=True)
sujet = f"🚨 ALERTE TEMPÉRATURE - {nom_sonde} ({lieu})"
message = (
f"La sonde '{nom_sonde}' du site '{lieu}' a dépassé le seuil de {seuil}°C "
f"depuis plus de 30 minutes.\nHeure : {maintenant.strftime('%Y-%m-%d %H:%M:%S')}"
)
if ENVOI_SMS:
envoyer_sms_ovh(message, lieu)
# Suivi pour rappels
alertes_actives[nom_sonde] = maintenant
else:
# Alerte déjà en cours : vérifier s'il faut faire un rappel
dernier_envoi = alertes_actives.get(nom_sonde)
if dernier_envoi and (maintenant - dernier_envoi >= timedelta(hours=1)):
sujet = f"🔔 RAPPEL ALERTE TEMPÉRATURE - {nom_sonde} ({lieu})"
message = (
f"La sonde '{nom_sonde}' du site '{lieu}' est TOUJOURS en dépassement de seuil (>{seuil}°C).\n"
f"Heure : {maintenant.strftime('%Y-%m-%d %H:%M:%S')}"
)
if ENVOI_SMS:
envoyer_sms_ovh(message, lieu)
alertes_actives[nom_sonde] = maintenant
# Vérifier retour à la normale (Acquittement)
cursor.execute(f"""
SELECT Temperature FROM {table_temp}
WHERE Sonde = %s
ORDER BY Date DESC LIMIT 1
""", (nom_sonde,))
derniere = cursor.fetchone()
if derniere and derniere['Temperature'] <= seuil:
cursor.execute(f"""
UPDATE {table_alertes}
SET Status = 'Acquitté'
WHERE Sonde = %s AND Status IN ('En cours', 'Test')
""", (nom_sonde,))
# Nettoyage du suivi si normalisé
if nom_sonde in alertes_actives:
del alertes_actives[nom_sonde]
conn.commit()
cursor.close()
conn.close()
if log_entries:
import pandas as pd
df_logs = pd.DataFrame(log_entries)
# Sauvegarde principale
df_logs.to_csv(log_dir / "monitor.csv", sep=";", index=False)
# Sauvegarde secondaire (Linux uniquement)
if os.name != 'nt':
df_logs.to_csv("/var/log/monitor.csv", sep=";", index=False)
except Exception as e:
print(f"Erreur : {e}", flush=True)
# --- Boucle principale ---
while True:
print(f"📡 Vérification à {datetime.now()}", flush=True)
surveiller()
time.sleep(300) # 5 minutes