# Application Gestion de sondes 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" } def afficher_tableau_filtré(df): st.markdown("### 🔧 Filtrage horaire") df = df.copy() df["Date"] = pd.to_datetime(df["Date"]) # Supprimer la colonne Id si elle existe if "Id" in df.columns: df.drop(columns="Id", inplace=True) # Sélection de la tranche horaire plage = st.selectbox( "Sélectionnez une plage horaire :", ["Toutes", "Matin (06h-12h)", "Après-midi (12h-18h)", "Soir (18h-00h)"] ) if plage == "Matin (06h-12h)": df = df[(df["Date"].dt.hour >= 6) & (df["Date"].dt.hour < 12)] elif plage == "Après-midi (12h-18h)": df = df[(df["Date"].dt.hour >= 12) & (df["Date"].dt.hour < 18)] elif plage == "Soir (18h-00h)": df = df[(df["Date"].dt.hour >= 18)] # Centrage de la colonne Température (et autres si souhaité) def style_center(s): return ['text-align: center'] * len(s) st.dataframe( df.style.apply(style_center, subset=["Temperature"]), use_container_width=True ) return df 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"] 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 df_filtré = afficher_tableau_filtré(df_sonde) st.subheader("📈 Évolution de la température") fig, ax = plt.subplots(figsize=(10, 4)) ax.plot(df_filtré["Date"], df_filtré["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}")