Files
Gestion_sondes/domo91.py
2025-04-13 09:40:47 +02:00

249 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 à lanalyse 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}")