Ajout date mise en service Tracker

This commit is contained in:
2025-08-26 11:05:06 +02:00
parent 6592e98bee
commit cd6bb7b5cf
3 changed files with 55 additions and 54 deletions

View File

@@ -1,34 +0,0 @@
🔁 Mise à jour de la branche product depuis develop : workflow recommandé
⚙️ Étapes standards :
Travaille uniquement sur develop
Quand tu es prêt à mettre en production :
git checkout product
git merge develop
git push origin product
Cela fusionne proprement toutes les modifications testées de develop vers product.
🖥️ Et sur le VPS ?
Si ton VPS suit la branche product, alors une fois que tu as fait :
git push origin product (sur pycharm)
Tu peux te connecter à ton VPS et faire :
cd /home/debian/Gestion_sondes git pull origin product
🔵 Mettre à jour supervisor
cd /etc/supervisor/conf.d
supervisorctl restart all
Et pour vérifier le bon état des services
supervisorctl status
exit
exit
🔵 4. Vérification
pour vérifier que les scripts tournent bien.
#tail -f /home/debian/Gestion_sondes/Logs/monitor.csv

BIN
README.md

Binary file not shown.

View File

@@ -2,7 +2,7 @@
# -------------------------------------------------------------
# Streamlit — Gestion de la table MySQL Sondes.tracker
# -------------------------------------------------------------
# Schéma attendu : id (PK), address, lieu, repere (optionnel), res_bits, date (timestamp)
# Schéma attendu : id (PK), address, lieu, repere, mise_en_service (DATE), res_bits, date (timestamp)
# -------------------------------------------------------------
import os
@@ -13,6 +13,7 @@ import streamlit as st
import mysql.connector as mysql
from contextlib import contextmanager
from dotenv import load_dotenv
from datetime import date
# ==========================
# Configuration / Constantes
@@ -22,7 +23,8 @@ TABLE_NAME = "tracker"
COL_ID = "id"
COL_ADDRESS = "address"
COL_LIEU = "lieu"
COL_REPERE = "repere" # 🆕 Nouveau champ
COL_REPERE = "repere"
COL_MES = "mise_en_service" # 🆕 DATE
COL_RESBITS = "res_bits"
COL_DATE = "date"
@@ -64,7 +66,7 @@ def get_conn():
def fetch_trackers(where_lieu: str | None = None) -> pd.DataFrame:
query = (
f"SELECT {COL_ID}, {COL_ADDRESS}, {COL_LIEU}, {COL_REPERE}, {COL_RESBITS}, {COL_DATE} "
f"SELECT {COL_ID}, {COL_ADDRESS}, {COL_LIEU}, {COL_REPERE}, {COL_MES}, {COL_RESBITS}, {COL_DATE} "
f"FROM {TABLE_NAME}"
)
params = []
@@ -77,27 +79,40 @@ def fetch_trackers(where_lieu: str | None = None) -> pd.DataFrame:
return df
def insert_tracker(address: str, lieu: str, res_bits: int, repere: str | None = None) -> int:
def insert_tracker(address: str, lieu: str, res_bits: int, repere: str | None = None, mise_en_service: date | None = None) -> int:
sql = f"""
INSERT INTO {TABLE_NAME} ({COL_ADDRESS}, {COL_LIEU}, {COL_REPERE}, {COL_RESBITS})
VALUES (%s, %s, %s, %s)
INSERT INTO {TABLE_NAME} ({COL_ADDRESS}, {COL_LIEU}, {COL_REPERE}, {COL_MES}, {COL_RESBITS})
VALUES (%s, %s, %s, %s, %s)
"""
with get_conn() as conn:
cur = conn.cursor()
cur.execute(sql, (address, lieu, (repere.strip() if repere and repere.strip() else None), res_bits))
cur.execute(sql, (
address,
lieu,
(repere.strip() if repere and str(repere).strip() else None),
mise_en_service, # mysql-connector accepte datetime.date
res_bits,
))
conn.commit()
return cur.lastrowid
def update_tracker(row_id: int, address: str, lieu: str, res_bits: int, repere: str | None) -> None:
def update_tracker(row_id: int, address: str, lieu: str, res_bits: int, repere: str | None, mise_en_service: date | None) -> None:
sql = f"""
UPDATE {TABLE_NAME}
SET {COL_ADDRESS}=%s, {COL_LIEU}=%s, {COL_REPERE}=%s, {COL_RESBITS}=%s
SET {COL_ADDRESS}=%s, {COL_LIEU}=%s, {COL_REPERE}=%s, {COL_MES}=%s, {COL_RESBITS}=%s
WHERE {COL_ID}=%s
"""
with get_conn() as conn:
cur = conn.cursor()
cur.execute(sql, (address, lieu, (repere.strip() if repere and repere.strip() else None), res_bits, row_id))
cur.execute(sql, (
address,
lieu,
(repere.strip() if repere and str(repere).strip() else None),
mise_en_service,
res_bits,
row_id,
))
conn.commit()
@@ -164,7 +179,8 @@ st.sidebar.subheader("Ajouter une sonde")
with st.sidebar.form("add_form", clear_on_submit=True):
new_address = st.text_input("Adresse ROM", placeholder="{0x28,0xFF,...}", help=rom_help())
new_lieu = st.text_input("Lieu d'installation", placeholder="Ex: Chaufferie / Saclay")
new_repere = st.text_input("Repère (optionnel)", placeholder="Ex: R1, Panneau N°, Local 3…") # 🆕
new_repere = st.text_input("Repère (optionnel)", placeholder="Ex: R1, Panneau N°, Local 3…")
new_mes = st.date_input("Mise en service (optionnel)", value=None, format="YYYY-MM-DD")
new_res = st.selectbox("Résolution (bits)", options=[9,10,11,12])
submitted = st.form_submit_button("Ajouter")
if submitted:
@@ -173,7 +189,13 @@ with st.sidebar.form("add_form", clear_on_submit=True):
elif not new_lieu.strip():
st.warning("Lieu requis.")
else:
rid = insert_tracker(new_address.strip(), new_lieu.strip(), int(new_res), new_repere)
rid = insert_tracker(
new_address.strip(),
new_lieu.strip(),
int(new_res),
new_repere,
new_mes if isinstance(new_mes, date) else None,
)
st.success(f"Sonde ajoutée (id={rid}).")
time.sleep(0.6)
st.rerun()
@@ -204,16 +226,17 @@ else:
df["resolution"] = df[COL_RESBITS].apply(res_label)
st.subheader("Enregistrements")
st.caption("Double-cliquez pour éditer les cellules. Les colonnes *resolution* et *date* sont non éditables.")
st.caption("Double-cliquez pour éditer les cellules. *resolution* et *date* sont non éditables.")
edited = st.data_editor(
df[[COL_ID, COL_ADDRESS, COL_LIEU, COL_REPERE, COL_RESBITS, "resolution", COL_DATE]],
df[[COL_ID, COL_ADDRESS, COL_LIEU, COL_REPERE, COL_MES, COL_RESBITS, "resolution", COL_DATE]],
hide_index=True,
column_config={
COL_ID: st.column_config.NumberColumn("ID", disabled=True),
COL_ADDRESS: st.column_config.TextColumn("Adresse (ROM)", help=rom_help()),
COL_LIEU: st.column_config.TextColumn("Lieu"),
COL_REPERE: st.column_config.TextColumn("Repère"), # 🆕 éditable
COL_REPERE: st.column_config.TextColumn("Repère"),
COL_MES: st.column_config.DateColumn("Mise en service", format="YYYY-MM-DD"),
COL_RESBITS: st.column_config.NumberColumn("Résolution (bits)", min_value=9, max_value=12, step=1),
"resolution": st.column_config.TextColumn("Détails", disabled=True),
COL_DATE: st.column_config.DatetimeColumn("Date insertion", disabled=True, format="YYYY-MM-DD HH:mm:ss"),
@@ -222,9 +245,8 @@ else:
num_rows="dynamic",
)
# Détection des suppressions (si des lignes ont disparu)
# Détections
removed_ids = set(df[COL_ID]) - set(edited[COL_ID])
# Détection des modifications cellule par cellule
to_update = []
for _, row in edited.iterrows():
orig = df.loc[df[COL_ID] == row[COL_ID]].iloc[0]
@@ -232,9 +254,21 @@ else:
(row[COL_ADDRESS] != orig[COL_ADDRESS]) or
(row[COL_LIEU] != orig[COL_LIEU]) or
((str(row.get(COL_REPERE) or "").strip()) != (str(orig.get(COL_REPERE) or "").strip())) or
((str(row.get(COL_MES) or "")[:10]) != (str(orig.get(COL_MES) or "")[:10])) or
(int(row[COL_RESBITS]) != int(orig[COL_RESBITS]))
)
if changed:
# Mise en service : convertir en date ou None
mes_val = row.get(COL_MES)
if pd.isna(mes_val):
mes_val = None
elif isinstance(mes_val, pd.Timestamp):
mes_val = mes_val.date()
elif isinstance(mes_val, str) and mes_val:
try:
mes_val = pd.to_datetime(mes_val).date()
except Exception:
mes_val = None
to_update.append(
(
int(row[COL_ID]),
@@ -242,6 +276,7 @@ else:
str(row[COL_LIEU]),
int(row[COL_RESBITS]),
(str(row.get(COL_REPERE)).strip() if row.get(COL_REPERE) and str(row.get(COL_REPERE)).strip() else None),
mes_val,
)
)
@@ -253,8 +288,8 @@ else:
col1, col2, col3 = st.columns([1,1,2])
with col1:
if st.button("Enregistrer les modifications", disabled=(len(to_update)==0 and len(removed_ids)==0)):
for rid, addr, lieu, rbits, repere in to_update:
update_tracker(rid, addr, lieu, rbits, repere)
for rid, addr, lieu, rbits, repere, mes in to_update:
update_tracker(rid, addr, lieu, rbits, repere, mes)
for rid in removed_ids:
delete_tracker(int(rid))
st.success("Modifications enregistrées ✔️")
@@ -281,5 +316,5 @@ else:
st.divider()
st.caption(
"Astuce : vous pouvez coller directement une adresse ROM depuis vos logs au format {0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..}.\n"
"Si vos noms de colonnes diffèrent (ex. 'res.bits'), ajustez les constantes en tête de fichier."
"Si vos noms de colonnes diffèrent, ajustez les constantes en tête de fichier."
)