"Ajout bt impression rapports et dossier PDF crée"

This commit is contained in:
2025-04-17 13:57:27 +02:00
parent ae94a88c8b
commit 187d4a1650

242
domo91.py
View File

@@ -5,6 +5,8 @@ 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
from fpdf import FPDF
import os
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")
@@ -17,101 +19,92 @@ db_config = {
"database": "Sondes" "database": "Sondes"
} }
def afficher_tableau_filtré(df): # --- Fonction de génération PDF ---
st.markdown("### 🔧 Filtrage horaire") def generer_pdf(site, date_str):
st.info(f"Génération du rapport PDF pour {site} à la date {date_str}")
try:
conn = mysql.connector.connect(**db_config)
cursor = conn.cursor(dictionary=True)
df = df.copy() cursor.execute(f"SELECT Sonde, Date, Temperature FROM `{site}` WHERE DATE(Date) = %s ORDER BY Sonde, Date", (date_str,))
df["Date"] = pd.to_datetime(df["Date"]) rows = cursor.fetchall()
df = pd.DataFrame(rows)
df["Heure"] = pd.to_datetime(df["Date"]).dt.strftime("%H:%M")
# Supprimer la colonne Id si elle existe releves = {}
if "Id" in df.columns: for sonde in df["Sonde"].unique():
df.drop(columns="Id", inplace=True) df_sonde = df[df["Sonde"] == sonde]
releves[sonde] = list(zip(df_sonde["Heure"], df_sonde["Temperature"]))
# Sélection de la tranche horaire table_alertes = f"Alertes_{site}"
plage = st.selectbox( cursor.execute(f"SELECT Sonde, Debut_defaut, Status FROM {table_alertes} WHERE DATE(Debut_defaut) = %s", (date_str,))
"Sélectionnez une plage horaire :", alertes = cursor.fetchall()
["Toutes", "Matin (06h-12h)", "Après-midi (12h-18h)", "Soir (18h-00h)"]
cursor.close()
conn.close()
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_defaut']} - {a['Status']}", 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 = os.path.join("PDF", 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"
) )
if plage == "Matin (06h-12h)": except Exception as e:
df = df[(df["Date"].dt.hour >= 6) & (df["Date"].dt.hour < 12)] st.error(f"Erreur lors de la génération du PDF : {e}")
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
# --- Initialisation session ---
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"):
@@ -139,8 +132,19 @@ 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")
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)
@@ -150,7 +154,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"),)
@@ -162,12 +169,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))
@@ -179,71 +189,13 @@ 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([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() cursor.close()
conn.close() conn.close()
except Exception as e: except Exception as e:
st.error(f"Erreur MySQL : {e}") st.error(f"Erreur MySQL : {e}")