From 4991b6354ccdb78724c3958f026a20be1c938c2d Mon Sep 17 00:00:00 2001 From: Michel Date: Tue, 22 Apr 2025 09:55:05 +0200 Subject: [PATCH] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20domo91.py=20depuis?= =?UTF-8?q?=20develop=20r=C3=A9vision=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domo91.py | 255 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 168 insertions(+), 87 deletions(-) diff --git a/domo91.py b/domo91.py index e26270b..484cfe7 100644 --- a/domo91.py +++ b/domo91.py @@ -34,7 +34,8 @@ def generer_pdf(site, date_str): conn = mysql.connector.connect(**db_config) cursor = conn.cursor(dictionary=True) - cursor.execute(f"SELECT Sonde, Date, Temperature FROM `{site}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", (date_str,)) + cursor.execute(f"SELECT Sonde, Date, Temperature FROM `{site}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", + (date_str,)) rows = cursor.fetchall() df = pd.DataFrame(rows) df["Heure"] = pd.to_datetime(df["Date"]).dt.strftime("%H:%M") @@ -45,7 +46,8 @@ def generer_pdf(site, date_str): releves[sonde] = list(zip(df_sonde["Heure"], df_sonde["Temperature"])) table_alertes = f"Alertes_{site}" - cursor.execute(f"SELECT Sonde, Debut_defaut, Status FROM {table_alertes} WHERE DATE(Debut_defaut) = %s", (date_str,)) + cursor.execute(f"SELECT Sonde, Debut_defaut, Status FROM {table_alertes} WHERE DATE(Debut_defaut) = %s", + (date_str,)) alertes = cursor.fetchall() cursor.close() @@ -106,6 +108,7 @@ def generer_pdf(site, date_str): except Exception as e: st.error(f"Erreur lors de la génération du PDF : {e}") + # --- Initialisation des variables de session --- if "authenticated" not in st.session_state: st.session_state["authenticated"] = False @@ -130,6 +133,16 @@ if not st.session_state.get("authenticated"): st.session_state["role"] = result["role"] st.session_state["lieu_autorise"] = result["Lieu"] st.success(f"Connecté comme {result['role']} ({result['Lieu']})") + # Enregistrement de la connexion dans Connexion_Log + try: + now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + cursor.execute(""" + INSERT INTO Connexion_Log (Utilisateur, Lieu, Date_Connexion) + VALUES (%s, %s, %s) + """, (login, result["Lieu"], now)) + conn.commit() + except Exception as e: + st.warning(f"⚠️ Connexion enregistrée échouée : {e}") st.rerun() else: st.sidebar.error("Identifiants invalides") @@ -158,7 +171,6 @@ if site_pdf and date_pdf: if st.sidebar.button("📥 Télécharger l’état du jour (PDF)", key="pdf_btn"): generer_pdf(site_pdf, date_pdf.strftime("%Y-%m-%d")) - # 🔔 Forcer une alerte de test dynamique avec choix de la sonde (réservé aux superviseurs) if st.session_state.get("authenticated") and st.session_state.get("role") == "superviseur": site_actuel = ( @@ -218,108 +230,179 @@ if st.session_state.get("authenticated") and st.session_state.get("role") == "su # --- CONTENU PRINCIPAL SI AUTHENTIFIÉ --- if st.session_state["authenticated"]: - st.markdown("## Sélection du site et de la date") + # --- AFFICHAGE GLOBAL DES ALERTES NON ACQUITTÉES --- 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) - st.session_state["selected_site"] = site_selectionne - 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()) - st.session_state["selected_date"] = selected_date - - cursor.execute( - f"SELECT * FROM `{site_selectionne}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", - (selected_date.strftime("%Y-%m-%d"),) + site_selectionne = ( + st.session_state["lieu_autorise"] + if st.session_state["role"] != "superviseur" + else st.session_state.get("selected_site", "Saclay") ) - rows = cursor.fetchall() - if rows: + + table_alertes = f"Alertes_{site_selectionne}" + cursor.execute( + f"SELECT Sonde, Debut_defaut, Status FROM `{table_alertes}` WHERE Status != 'Acquitté' ORDER BY Debut_defaut DESC" + ) + alertes = cursor.fetchall() + + if alertes: + df_alertes = pd.DataFrame(alertes) + st.subheader("🚨 Alertes non acquittées") + st.dataframe(df_alertes, use_container_width=True) + else: + st.success("✅ Aucune alerte en cours.") + + cursor.close() + conn.close() + except Exception as e: + st.error(f"Erreur lors de la récupération des alertes : {e}") + + # --- NAVIGATION --- + if st.session_state["role"] == "superviseur": + onglet = st.sidebar.radio("📁 Navigation", ["Accueil", "Statistiques"]) + else: + onglet = "Accueil" + + if onglet == "Accueil": + st.markdown("## Sélection du site et de la date") + 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) + st.session_state["selected_site"] = site_selectionne + 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()) + st.session_state["selected_date"] = selected_date + + 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, key="selectbox_accueil") + df_sonde = df[df["Sonde"] == sonde_choisie] + + df_sonde.loc[:, "Heure"] = df_sonde["Date"].dt.hour + + tranche = st.radio("🕒 Tranche horaire :", + ["Toute la journée", "Matin (6h-12h)", "Après-midi (12h-18h)", "Nuit (18h-6h)"]) + + if tranche == "Matin (6h-12h)": + df_sonde = df_sonde[(df_sonde["Heure"] >= 6) & (df_sonde["Heure"] < 12)] + elif tranche == "Après-midi (12h-18h)": + df_sonde = df_sonde[(df_sonde["Heure"] >= 12) & (df_sonde["Heure"] < 18)] + elif tranche == "Nuit (18h-6h)": + df_sonde = df_sonde[(df_sonde["Heure"] >= 18) | (df_sonde["Heure"] < 6)] + df_sonde = df_sonde.copy() + + 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.subheader("📊 Tableau des relevés") + df_filtré = df_sonde.copy() + df_filtré = df_filtré.drop(columns="Id", errors="ignore") + + + def surlignage_temp(val): + try: + if float(val) > seuil_temp: + return "color: red; font-weight: bold" + except: + pass + return "" + + + styled_df = df_filtré.style.applymap(surlignage_temp, subset=["Temperature"]) + st.dataframe(styled_df, use_container_width=True) + + 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) + + cursor.close() + conn.close() + + except Exception as e: + st.error(f"Erreur MySQL : {e}") + + elif onglet == "Statistiques": + st.markdown("## 📈 Statistiques de température") + try: + conn = mysql.connector.connect(**db_config) + cursor = conn.cursor(dictionary=True) + + site = ( + st.session_state["lieu_autorise"] + if st.session_state["role"] != "superviseur" + else st.session_state.get("selected_site", "Saclay") + ) + + date_val = st.session_state.get("selected_date", date.today()) + + cursor.execute( + f"SELECT * FROM `{site}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", + (date_val.strftime("%Y-%m-%d"),) + ) + rows = cursor.fetchall() 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] -# Ajouter une colonne Heure pour faciliter les filtres - df_sonde.loc[:, "Heure"] = df_sonde["Date"].dt.hour + if df.empty: + st.info("Aucune donnée pour cette date.") + else: + df["Date"] = pd.to_datetime(df["Date"]) + sondes = sorted(df["Sonde"].unique()) + sonde = st.selectbox("Choisir une sonde :", sondes, key="selectbox_stats") + df_sonde = df[df["Sonde"] == sonde] -# Filtrage par tranche horaire - tranche = st.radio("🕒 Tranche horaire :", - ["Toute la journée", "Matin (6h-12h)", "Après-midi (12h-18h)", "Nuit (18h-6h)"]) + st.subheader("Évolution journalière") + fig, ax = plt.subplots(figsize=(10, 4)) + ax.plot(df_sonde["Date"], df_sonde["Temperature"], marker='o') + ax.set_title(f"{sonde} - {date_val.strftime('%d/%m/%Y')}") + ax.set_xlabel("Heure") + ax.set_ylabel("Température (°C)") + ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) + st.pyplot(fig) - if tranche == "Matin (6h-12h)": - df_sonde = df_sonde[(df_sonde["Heure"] >= 6) & (df_sonde["Heure"] < 12)] - elif tranche == "Après-midi (12h-18h)": - df_sonde = df_sonde[(df_sonde["Heure"] >= 12) & (df_sonde["Heure"] < 18)] - elif tranche == "Nuit (18h-6h)": - df_sonde = df_sonde[(df_sonde["Heure"] >= 18) | (df_sonde["Heure"] < 6)] - df_sonde = df_sonde.copy() + cursor.close() + conn.close() - 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 + except Exception as e: + st.error(f"Erreur chargement statistiques : {e}") - st.subheader("📊 Tableau des relevés") - df_filtré = df_sonde.copy() - df_filtré = df_filtré.drop(columns="Id", errors="ignore") - - - def surlignage_temp(val): - try: - if float(val) > seuil_temp: - return "color: red; font-weight: bold" - except: - pass - return "" - - -# Appliquer le style uniquement à la colonne "Temperature" - - styled_df = df_filtré.style.applymap(surlignage_temp, subset=["Temperature"]) - - st.dataframe(styled_df, use_container_width=True) - - 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) -# --- Affichage automatique des alertes non acquittées --- + # --- Affichage automatique des alertes non acquittées --- try: conn = mysql.connector.connect(**db_config) cursor = conn.cursor(dictionary=True) table_alertes = f"Alertes_{site_selectionne}" - cursor.execute( - f"SELECT Sonde, Debut_defaut, Status FROM `{table_alertes}` WHERE Status != 'Acquitté' ORDER BY Debut_defaut DESC" - ) - alertes = cursor.fetchall() - - if alertes: - df_alertes = pd.DataFrame(alertes) - st.subheader("🚨 Alertes non acquittées") - st.dataframe(df_alertes, use_container_width=True) - else: - st.success("✅ Aucune alerte en cours.") cursor.close() conn.close() except Exception as e: st.error(f"Erreur lors de la récupération des alertes : {e}") - except Exception as e: - st.error(f"Erreur MySQL : {e}") + except Exception as e: + st.error(f"Erreur MySQL : {e}") if st.session_state["role"] == "superviseur": with st.expander("+ Ajouter une nouvelle chambre froide", expanded=False): with st.form("ajout_sonde"): @@ -378,13 +461,13 @@ if st.session_state["role"] == "superviseur": temp_max = chambre["Temp_Max"] moins, val, plus = st.columns([1, 2, 1]) with moins: - if st.button("-", key=f"moins_{chambre['Id']}"): + if st.button("▼", key=f"moins_{chambre['Id']}"): temp_max -= 1 with val: st.markdown(f"
{temp_max}°C
", unsafe_allow_html=True) with plus: - if st.button("+", key=f"plus_{chambre['Id']}"): + if st.button("▲", key=f"plus_{chambre['Id']}"): temp_max += 1 if new_etat != chambre["Etat"] or temp_max != chambre["Temp_Max"]: @@ -400,5 +483,3 @@ if st.session_state["role"] == "superviseur": except Exception as e: st.error(f"Erreur SQL (admin) : {e}") - -