155 lines
6.2 KiB
Python
155 lines
6.2 KiB
Python
# Surveillance continue avec envoi d'alertes par email + rappels + log CSV
|
|
import mysql.connector
|
|
from datetime import datetime, timedelta
|
|
import time
|
|
import smtplib
|
|
from email.mime.text import MIMEText
|
|
import pandas as pd
|
|
from dotenv import load_dotenv
|
|
import os
|
|
|
|
load_dotenv()
|
|
|
|
# --- Config MySQL ---
|
|
config = {
|
|
"host": os.getenv("DB_HOST"),
|
|
"user": os.getenv("DB_USER"),
|
|
"password": os.getenv("DB_PASSWORD"),
|
|
"database": os.getenv("DB_NAME")
|
|
}
|
|
|
|
# --- Destinataires email ---
|
|
destinataires = ['services@domo91.fr', 'michel-68000@hotmail.fr']
|
|
|
|
# --- Suivi des alertes actives pour rappels ---
|
|
alertes_actives = {}
|
|
|
|
# --- Fonction d'envoi de mail ---
|
|
def envoyer_mail(sujet, message, destinataires):
|
|
msg = MIMEText(message)
|
|
msg['Subject'] = sujet
|
|
msg['From'] = 'alertes_saclay@domo91.fr'
|
|
msg['To'] = ', '.join(destinataires)
|
|
try:
|
|
with smtplib.SMTP_SSL('smtp.mail.ovh.net', 465) as server:
|
|
server.login('alertes_saclay@domo91.fr', 'Kdpke674y23Feq^H')
|
|
server.sendmail(msg['From'], destinataires, msg.as_string())
|
|
print(f"📧 Mail envoyé à {destinataires}", flush=True)
|
|
except Exception as e:
|
|
print(f"Erreur envoi mail : {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 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 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,))
|
|
relevés = cursor.fetchall()
|
|
|
|
for r in relevés:
|
|
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(relevés) == 6:
|
|
toutes_hors_seuil = all(r['Temperature'] > seuil for r in relevés)
|
|
plus_ancien = relevés[-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')}"
|
|
)
|
|
envoyer_mail(sujet, message, destinataires)
|
|
|
|
# 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')}"
|
|
)
|
|
envoyer_mail(sujet, message, destinataires)
|
|
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:
|
|
df_logs = pd.DataFrame(log_entries)
|
|
df_logs.to_csv("/home/debian/travail/Logs/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
|
|
|