🧩 Merge auto develop → product

This commit is contained in:
root
2025-04-26 10:30:54 +02:00
3 changed files with 63 additions and 22 deletions

View File

@@ -1,4 +1,4 @@
# Surveillance continue avec envoi d'alertes par email + log CSV # Surveillance continue avec envoi d'alertes par email + rappels + log CSV
import mysql.connector import mysql.connector
from datetime import datetime, timedelta from datetime import datetime, timedelta
import time import time
@@ -19,7 +19,10 @@ config = {
} }
# --- Destinataires email --- # --- Destinataires email ---
destinataires = ['services@domo91.fr,cuisine@bw-paris-saclay.com>'] destinataires = ['services@domo91.fr', 'michel-68000@hotmail.fr']
# --- Suivi des alertes actives pour rappels ---
alertes_actives = {}
# --- Fonction d'envoi de mail --- # --- Fonction d'envoi de mail ---
def envoyer_mail(sujet, message, destinataires): def envoyer_mail(sujet, message, destinataires):
@@ -37,6 +40,7 @@ def envoyer_mail(sujet, message, destinataires):
# --- Fonction de surveillance --- # --- Fonction de surveillance ---
def surveiller(): def surveiller():
global alertes_actives
log_entries = [] log_entries = []
try: try:
conn = mysql.connector.connect(**config) conn = mysql.connector.connect(**config)
@@ -63,7 +67,6 @@ def surveiller():
""", (nom_sonde,)) """, (nom_sonde,))
relevés = cursor.fetchall() relevés = cursor.fetchall()
# Log CSV : tous les relevés analysés
for r in relevés: for r in relevés:
log_entries.append({ log_entries.append({
"Date": r['Date'], "Date": r['Date'],
@@ -91,14 +94,30 @@ def surveiller():
(nom_sonde,) (nom_sonde,)
) )
print(f"🚨 Alerte déclenchée pour {nom_sonde} ({lieu})", flush=True) print(f"🚨 Alerte déclenchée pour {nom_sonde} ({lieu})", flush=True)
sujet = f"🚨 ALERTE TEMPÉRATURE - {nom_sonde} ({lieu})" sujet = f"🚨 ALERTE TEMPÉRATURE - {nom_sonde} ({lieu})"
message = ( message = (
f"La sonde '{nom_sonde}' du site '{lieu}' a dépassé le seuil de {seuil}°C " f"La sonde '{nom_sonde}' du site '{lieu}' a dépassé le seuil de {seuil}°C "
f"depuis plus de 30 minutes.\nHeure : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" f"depuis plus de 30 minutes.\nHeure : {maintenant.strftime('%Y-%m-%d %H:%M:%S')}"
) )
envoyer_mail(sujet, message, destinataires) envoyer_mail(sujet, message, destinataires)
# Acquittement automatique # 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""" cursor.execute(f"""
SELECT Temperature FROM {table_temp} SELECT Temperature FROM {table_temp}
WHERE Sonde = %s WHERE Sonde = %s
@@ -112,11 +131,14 @@ def surveiller():
WHERE Sonde = %s AND Status IN ('En cours', 'Test') WHERE Sonde = %s AND Status IN ('En cours', 'Test')
""", (nom_sonde,)) """, (nom_sonde,))
# Nettoyage du suivi si normalisé
if nom_sonde in alertes_actives:
del alertes_actives[nom_sonde]
conn.commit() conn.commit()
cursor.close() cursor.close()
conn.close() conn.close()
# Enregistrer le log
if log_entries: if log_entries:
df_logs = pd.DataFrame(log_entries) df_logs = pd.DataFrame(log_entries)
df_logs.to_csv("/home/debian/travail/Logs/monitor.csv", sep=";", index=False) df_logs.to_csv("/home/debian/travail/Logs/monitor.csv", sep=";", index=False)
@@ -129,3 +151,4 @@ while True:
print(f"📡 Vérification à {datetime.now()}", flush=True) print(f"📡 Vérification à {datetime.now()}", flush=True)
surveiller() surveiller()
time.sleep(300) # 5 minutes time.sleep(300) # 5 minutes

View File

@@ -291,7 +291,7 @@ if st.session_state["authenticated"]:
st.session_state["selected_date"] = selected_date st.session_state["selected_date"] = selected_date
cursor.execute( cursor.execute(
f"SELECT * FROM `{site_selectionne}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", f"SELECT * FROM `{site_selectionne}` WHERE DATE(Date) = %s ORDER BY Sonde, Date DESC",
(selected_date.strftime("%Y-%m-%d"),) (selected_date.strftime("%Y-%m-%d"),)
) )
rows = cursor.fetchall() rows = cursor.fetchall()

View File

@@ -9,35 +9,53 @@ load_dotenv()
HOST = os.getenv("SSH_HOST") HOST = os.getenv("SSH_HOST")
USER = os.getenv("SSH_USER") USER = os.getenv("SSH_USER")
KEY = os.getenv("SSH_KEY") KEY = os.getenv("SSH_KEY")
PASSPHRASE = os.getenv("SSH_KEY_PASSPHRASE")
root = tk.Tk()
root.withdraw()
# 🛡 Vérifie que le fichier existe
if not os.path.exists(KEY):
messagebox.showerror("❌ Erreur", f"Clé SSH introuvable :\n{KEY}")
exit(1)
# 🛡 Vérifie que la clé est lisible par paramiko
try:
paramiko.RSAKey.from_private_key_file(KEY, password=PASSPHRASE)
except paramiko.PasswordRequiredException:
messagebox.showerror("❌ Clé protégée", "La clé est protégée par une passphrase, mais aucune n'a été fournie.")
exit(1)
except paramiko.SSHException:
messagebox.showerror("❌ Erreur de format", "Le fichier de clé nest pas au format OpenSSH.\n\nSolution : Exporter depuis PuTTYgen → Conversions > Export OpenSSH key")
exit(1)
except Exception as e:
messagebox.showerror("❌ Autre erreur", f"{e}")
exit(1)
# ✅ Si la clé est valide, on continue
client = paramiko.SSHClient() client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try: try:
client.connect(hostname=HOST, username=USER, key_filename=KEY) client.connect(
hostname=HOST,
username=USER,
key_filename=KEY,
passphrase=PASSPHRASE
)
stdin, stdout, stderr = client.exec_command("bash ~/travail/Gestion_sondes/scripts/deploy_all.sh") stdin, stdout, stderr = client.exec_command("bash ~/travail/Gestion_sondes/scripts/deploy_all.sh")
output = stdout.read().decode() output = stdout.read().decode()
errors = stderr.read().decode() errors = stderr.read().decode()
if "Déploiement complet terminé avec succès" in output: if "Déploiement complet terminé avec succès" in output:
success = True messagebox.showinfo("✅ Déploiement réussi", "Le déploiement s'est bien déroulé.")
else: else:
success = False messagebox.showwarning("⚠️ Déploiement incomplet", f"Vérifie les logs :\n\n{errors}")
# Affichage de la notification visuelle
root = tk.Tk()
root.withdraw() # cache la fenêtre principale
if success:
messagebox.showinfo("Déploiement terminé", "✅ Le déploiement s'est bien déroulé !")
else:
messagebox.showwarning("Déploiement partiel", f"⚠️ Déploiement incomplet. Vérifiez les logs.\n\n{errors}")
except Exception as e: except Exception as e:
root = tk.Tk() messagebox.showerror("❌ Erreur SSH", f"{e}")
root.withdraw()
messagebox.showerror("Erreur SSH", f"❌ Erreur : {e}")
finally: finally:
client.close() client.close()