"Ajout de bouton pour PDF"

This commit is contained in:
2025-04-17 09:40:00 +02:00
parent b2b8da528a
commit f5dcb764fa

236
domo91.py
View File

@@ -5,7 +5,7 @@ import pandas as pd
from datetime import date from datetime import date
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import matplotlib.dates as mdates import matplotlib.dates as mdates
import random from fpdf import FPDF
st.set_page_config(page_title="Domo91 - Surveillance", layout="wide") st.set_page_config(page_title="Domo91 - Surveillance", layout="wide")
st.title("📡 Supervision Températures") st.title("📡 Supervision Températures")
@@ -18,101 +18,16 @@ db_config = {
"database": "Sondes" "database": "Sondes"
} }
def afficher_tableau_filtré(df): # --- Initialisation session ---
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: if "authenticated" not in st.session_state:
st.session_state["authenticated"] = False st.session_state["authenticated"] = False
st.session_state["role"] = None st.session_state["role"] = None
st.session_state["lieu_autorise"] = None st.session_state["lieu_autorise"] = None
# --- Accès aux logs dès connexion superviseur --- # --- Sidebar (connexion + bouton PDF) ---
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: with st.sidebar:
st.header("🔐 Connexion") st.header("🔐 Connexion")
if not st.session_state["authenticated"]: if not st.session_state.get("authenticated"):
login = st.text_input("Nom d'utilisateur") login = st.text_input("Nom d'utilisateur")
password = st.text_input("Mot de passe", type="password") password = st.text_input("Mot de passe", type="password")
if st.button("Se connecter"): if st.button("Se connecter"):
@@ -140,8 +55,78 @@ with st.sidebar:
st.session_state["lieu_autorise"] = None st.session_state["lieu_autorise"] = None
st.rerun() st.rerun()
# --- Interface principale st.markdown("---")
st.subheader("📄 Rapport PDF")
if "selected_date" in st.session_state:
if st.button("📥 Télécharger létat du jour (PDF)"):
site = st.session_state["lieu_autorise"]
date_val = st.session_state["selected_date"].strftime("%Y-%m-%d")
def generer_pdf(site, date_str):
releves = {
"Chambre 1": [("06:00", 3.5), ("07:00", 3.2), ("08:00", 3.1)],
"Congélateur": [("06:00", -18.1), ("07:00", -17.8), ("08:00", -17.5)]
}
alertes = [
{"Sonde": "Chambre 2", "Debut": f"{date_str} 08:45", "Statut": "En cours"},
{"Sonde": "Congélateur", "Debut": f"{date_str} 12:30", "Statut": "Acquittée"}
]
class RapportPDF(FPDF):
def header(self):
self.set_font("Arial", "B", 14)
self.cell(0, 10, "Rapport de surveillance des sondes", ln=1, align="C")
self.set_font("Arial", "", 12)
self.cell(0, 10, f"Date : {date_str}", ln=1, align="C")
self.ln(5)
def site_info(self, site_name):
self.set_font("Arial", "B", 12)
self.cell(0, 10, f"Site : {site_name}", ln=1)
self.ln(2)
def releves_section(self, data):
self.set_font("Arial", "B", 12)
self.cell(0, 10, "Relevés de température", ln=1)
for sonde, mesures in data.items():
self.set_font("Arial", "B", 11)
self.cell(0, 8, f"Sonde : {sonde}", ln=1)
self.set_font("Arial", "", 10)
for heure, temp in mesures:
self.cell(0, 6, f"{heure} - {temp} °C", ln=1)
self.ln(2)
def alertes_section(self, data):
self.set_font("Arial", "B", 12)
self.cell(0, 10, "Alertes enregistrées", ln=1)
self.set_font("Arial", "", 10)
for a in data:
self.cell(0, 6, f"{a['Sonde']} - {a['Debut']} - {a['Statut']}", ln=1)
pdf = RapportPDF()
pdf.add_page()
pdf.site_info(site)
pdf.releves_section(releves)
pdf.alertes_section(alertes)
file_name = f"rapport_{site}_{date_str}.pdf"
output_path =file_name
pdf.output(output_path)
with open(output_path, "rb") as f:
st.download_button(
label="📥 Télécharger le rapport PDF",
data=f,
file_name=file_name,
mime="application/pdf"
)
generer_pdf(site, date_val)
else:
st.info("Sélectionnez une date pour activer la génération PDF.")
# --- CONTENU PRINCIPAL SI AUTHENTIFIÉ ---
if st.session_state["authenticated"]: if st.session_state["authenticated"]:
st.markdown("## Sélection du site et de la date")
try: try:
conn = mysql.connector.connect(**db_config) conn = mysql.connector.connect(**db_config)
cursor = conn.cursor(dictionary=True) cursor = conn.cursor(dictionary=True)
@@ -151,7 +136,10 @@ if st.session_state["authenticated"]:
else: else:
site_selectionne = st.session_state["lieu_autorise"] site_selectionne = st.session_state["lieu_autorise"]
st.info(f"Site imposé : {site_selectionne}") st.info(f"Site imposé : {site_selectionne}")
selected_date = st.date_input("📅 Date du relevé", value=date.today()) selected_date = st.date_input("📅 Date du relevé", value=date.today())
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",
(selected_date.strftime("%Y-%m-%d"),) (selected_date.strftime("%Y-%m-%d"),)
@@ -163,12 +151,15 @@ if st.session_state["authenticated"]:
sondes = sorted(df["Sonde"].unique()) sondes = sorted(df["Sonde"].unique())
sonde_choisie = st.selectbox("🧪 Choisissez une sonde :", sondes) sonde_choisie = st.selectbox("🧪 Choisissez une sonde :", sondes)
df_sonde = df[df["Sonde"] == sonde_choisie] 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)) cursor.execute("SELECT Temp_Max FROM Chambres_froides WHERE Lieu = %s AND Sonde = %s", (site_selectionne, sonde_choisie))
seuil = cursor.fetchone() seuil = cursor.fetchone()
seuil_temp = seuil["Temp_Max"] if seuil else 10 seuil_temp = seuil["Temp_Max"] if seuil else 10
df_filtré = afficher_tableau_filtré(df_sonde) st.subheader("📊 Tableau des relevés")
df_filtré = df_sonde.copy()
df_filtré = df_filtré.drop(columns="Id", errors="ignore")
st.dataframe(df_filtré, use_container_width=True)
st.subheader("📈 Évolution de la température") st.subheader("📈 Évolution de la température")
fig, ax = plt.subplots(figsize=(10, 4)) fig, ax = plt.subplots(figsize=(10, 4))
@@ -180,69 +171,10 @@ if st.session_state["authenticated"]:
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
ax.legend() ax.legend()
st.pyplot(fig) st.pyplot(fig)
else: else:
st.warning("Aucune donnée trouvée pour cette date.") 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([5, 2, 5])
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() cursor.close()
conn.close() conn.close()