# Application Streamlit avec coloration rouge des températures dépassant les seuils dans logs import streamlit as st import mysql.connector import pandas as pd from datetime import date import matplotlib.pyplot as plt import matplotlib.dates as mdates st.set_page_config(page_title="Domo91 - Surveillance", layout="wide") st.title("📡 Supervision Températures") # --- Configuration base de données --- db_config = { "host": "54.36.188.119", "user": "michel", "password": "#SO2&1nf%mZ@jfh", "database": "Sondes" } if "authenticated" not in st.session_state: st.session_state["authenticated"] = False st.session_state["role"] = None st.session_state["lieu_autorise"] = None # --- Accès aux logs dès connexion superviseur --- if st.session_state.get("authenticated") and st.session_state["role"] == "superviseur": st.markdown("### 🔍 Accès à l’analyse des relevés") if st.button("🧾 Analyse des logs Monitor.py"): st.session_state["page"] = "analyse_logs" st.rerun() # --- Analyse logs si page active --- if st.session_state.get("page") == "analyse_logs": st.title("🧾 Analyse des notifications de relevés") try: df_logs = pd.read_csv("/home/debian/travail/logs_monitor.csv", sep=";", parse_dates=["Date"]) df_logs["Date_str"] = df_logs["Date"].dt.date dates_dispo = sorted(df_logs["Date_str"].unique(), reverse=True) date_selection = st.selectbox("📅 Sélectionnez une date :", dates_dispo) lieux = sorted(df_logs["Lieu"].unique()) lieu_selection = st.selectbox("📍 Site :", lieux) df_filtré = df_logs[(df_logs["Date_str"] == date_selection) & (df_logs["Lieu"] == lieu_selection)] sondes = sorted(df_filtré["Sonde"].unique()) sonde_selection = st.selectbox("🧪 Sonde :", sondes) df_sonde = df_filtré[df_filtré["Sonde"] == sonde_selection].copy() st.subheader(f"📈 Évolution de la température - {sonde_selection}") fig, ax = plt.subplots(figsize=(10, 4)) ax.plot(df_sonde["Date"], df_sonde["Température"], marker='o') ax.set_title(f"{sonde_selection} - {date_selection}") ax.set_xlabel("Heure") ax.set_ylabel("Température (°C)") ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) st.pyplot(fig) st.subheader("📋 Détail des relevés") # Coloration conditionnelle des températures > seuil df_sonde["Depassement"] = df_sonde["Température"] > df_sonde["Seuil"] st.dataframe(df_sonde.style.apply( lambda row: [ 'background-color: red; color: white' if row["Depassement"] and col == "Température" else '' for col in df_sonde.columns ], axis=1 ), use_container_width=True) st.markdown("---") if st.button("⬅️ Retour à l'accueil"): st.session_state["page"] = None st.rerun() except Exception as e: st.error(f"Erreur lecture logs : {e}") st.stop() with st.sidebar: st.header("🔐 Connexion") if not st.session_state["authenticated"]: login = st.text_input("Nom d'utilisateur") password = st.text_input("Mot de passe", type="password") if st.button("Se connecter"): try: conn = mysql.connector.connect(**db_config) cursor = conn.cursor(dictionary=True) cursor.execute("SELECT * FROM MotsDePasse WHERE utilisateur = %s", (login,)) result = cursor.fetchone() if result and result["mot_de_passe"] == password: st.session_state["authenticated"] = True st.session_state["role"] = result["role"] st.session_state["lieu_autorise"] = result["Lieu"] st.success(f"Connecté comme {result['role']} ({result['Lieu']})") else: st.error("Identifiants invalides") cursor.close() conn.close() except Exception as e: st.error(f"Erreur lors de la connexion à la base : {e}") else: st.success(f"Connecté ({st.session_state['role']})") if st.button("🔓 Déconnexion"): st.session_state["authenticated"] = False st.session_state["role"] = None st.session_state["lieu_autorise"] = None st.rerun() # --- Interface principale if st.session_state["authenticated"]: try: conn = mysql.connector.connect(**db_config) cursor = conn.cursor(dictionary=True) sites_possibles = ["Saclay", "Meudon", "Roissy"] if st.session_state["role"] == "superviseur": site_selectionne = st.selectbox("📍 Choisissez un site :", sites_possibles) else: site_selectionne = st.session_state["lieu_autorise"] st.info(f"Site imposé : {site_selectionne}") selected_date = st.date_input("📅 Date du relevé", value=date.today()) cursor.execute( f"SELECT * FROM `{site_selectionne}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", (selected_date.strftime("%Y-%m-%d"),) ) rows = cursor.fetchall() if rows: df = pd.DataFrame(rows) df["Date"] = pd.to_datetime(df["Date"]) sondes = sorted(df["Sonde"].unique()) sonde_choisie = st.selectbox("🧪 Choisissez une sonde :", sondes) df_sonde = df[df["Sonde"] == sonde_choisie] cursor.execute("SELECT Temp_Max FROM Chambres_froides WHERE Lieu = %s AND Sonde = %s", (site_selectionne, sonde_choisie)) seuil = cursor.fetchone() seuil_temp = seuil["Temp_Max"] if seuil else 10 st.dataframe(df_sonde, use_container_width=True) st.subheader("📈 Évolution de la température") fig, ax = plt.subplots(figsize=(10, 4)) ax.plot(df_sonde["Date"], df_sonde["Temperature"], marker='o', label="Température") ax.axhline(seuil_temp, color='red', linestyle='--', label=f"Seuil {seuil_temp}°C") ax.set_xlabel("Heure") ax.set_ylabel("Température (°C)") ax.set_title(f"{sonde_choisie} - {selected_date.strftime('%d/%m/%Y')}") ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) ax.legend() st.pyplot(fig) else: st.warning("Aucune donnée trouvée pour cette date.") # --- Alertes et bouton vers analyse logs --- st.markdown("---") st.subheader("🚨 Alertes de température") if st.session_state["role"] == "superviseur": if st.button("🧾 Voir les notifications relevées dans Monitor"): st.session_state["page"] = "analyse_logs" st.rerun() table_alertes = f"Alertes_{site_selectionne}" voir_toutes = False if st.session_state["role"] == "superviseur": voir_toutes = st.toggle("Afficher toutes les alertes (y compris acquittées)", value=False) if voir_toutes: cursor.execute(f"SELECT * FROM {table_alertes} ORDER BY Debut_defaut DESC") else: cursor.execute(f"SELECT * FROM {table_alertes} WHERE Status = 'En cours' ORDER BY Debut_defaut DESC") alertes = cursor.fetchall() if alertes: for alerte in alertes: cols = st.columns([3, 3, 2, 2, 2]) cols[0].markdown(f"**Sonde :** {alerte['Sonde']}") cols[1].markdown(f"**Début :** {alerte['Debut_defaut'].strftime('%Y-%m-%d %H:%M')}") cols[2].markdown(f"**Statut :** {alerte['Status']}") if st.session_state["role"] == "superviseur" and alerte['Status'] == 'En cours': key_btn = f"acq_{alerte['Id']}" if cols[4].button("✅ Acquitter", key=key_btn): cursor.execute(f"UPDATE {table_alertes} SET Status = 'Acquitté' WHERE Id = %s", (alerte['Id'],)) conn.commit() st.success(f"Alerte acquittée pour {alerte['Sonde']}") st.rerun() else: st.info("✅ Aucune alerte en cours.") # --- Interface admin seuils / ON-OFF --- if st.session_state["role"] == "superviseur": st.markdown("---") st.subheader("🛠️ Paramètres des sondes") cursor.execute("SELECT * FROM Chambres_froides WHERE Lieu = %s", (site_selectionne,)) sondes_info = cursor.fetchall() if sondes_info: for sonde in sondes_info: cols = st.columns([3, 2, 3]) cols[0].markdown(f"**{sonde['Sonde']}**") etat_key = f"etat_{sonde['Id']}" seuil_key = f"seuil_{sonde['Id']}" etat_actuel = sonde["Etat"] == "ON" new_etat = cols[1].checkbox("Actif", value=etat_actuel, key=etat_key) new_seuil = cols[2].number_input("Seuil Max", min_value=-30.0, max_value=30.0, value=float(sonde["Temp_Max"]), step=0.5, key=seuil_key) sonde["_new_etat"] = "ON" if new_etat else "OFF" sonde["_new_seuil"] = new_seuil if st.button("💾 Enregistrer les modifications"): try: for sonde in sondes_info: cursor.execute("UPDATE Chambres_froides SET Etat = %s, Temp_Max = %s WHERE Id = %s", (sonde["_new_etat"], sonde["_new_seuil"], sonde["Id"])) conn.commit() st.success("✅ Modifications enregistrées.") st.rerun() except Exception as e: st.error(f"Erreur lors de la mise à jour : {e}") cursor.close() conn.close() except Exception as e: st.error(f"Erreur MySQL : {e}")