allarmi: il marcatore "gia' detto" si scrive DOPO l'invio, non prima
Debito §5.2 chiuso su decisione dell'operatore. `run_once` salvava lo stato coi marcatori `alerted` gia' a True e l'invio lo faceva il chiamante DOPO: col 6,9% di invii falliti misurato (2 su 29), un 🚨 perso restava perso per l'EPISODIO INTERO — l'ora dopo lo stato diceva "gia' detto" e usciva WATCH/MUTO. Gli episodi storici durano 200-2.324 ore, quindi il buco non era teorico. - `run_once(state_path, sender=None)`: il sender e' INIETTATO, non importato — e' cio' che tiene la funzione testabile senza rete d'uscita, che era la ragione del disegno precedente. Senza sender il comportamento resta quello di prima e il report lo DICE (`invio`), invece di lasciar credere che qualcosa sia partito. - Su invio fallito si disfano SOLO i marcatori "gia' detto", non le misure: · asset in ALERT -> alerted=False, l'ora dopo ri-allerta; · lock MAINT/ALERT -> alerted_soft/hard=False ma le ORE restano a correre, cosi' una manutenzione che sfora la grazia sale ad ALERT anche col trasporto giu' (disfare anche le ore congelerebbe l'escalation proprio mentre non si riesce a parlare); · lock RIENTRATO -> si ripristina l'intero LockState, perche' il rientro si annuncia una volta sola e senza le ore non ci sarebbe piu' niente da dire. - `notify(..., tentativi=)`: il retry esisteva in `send` e non arrivava qui. venue_watch ora manda con 3 tentativi. - L'esito dell'invio finisce nel log del cron invece di sparire. 5 test nuovi. Il primo e' quello che conta — dopo un invio fallito, l'ora dopo ri-allerta — col suo controllo positivo (un invio riuscito consuma l'allarme UNA volta sola), senza il quale "ri-allerta sempre" passerebbe. Suite: 782 passati, 2 falliti (i due del gate GTAA, non toccati qui). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -76,8 +76,12 @@ def send(text: str, tentativi: int = 1, pausa_s: float = 2.0) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def notify(title: str, data: dict | None = None) -> bool:
|
||||
"""Invia un alert formattato. Ritorna True se inviato (config presente + rete ok)."""
|
||||
def notify(title: str, data: dict | None = None, tentativi: int = 1) -> bool:
|
||||
"""Invia un alert formattato. Ritorna True se inviato (config presente + rete ok).
|
||||
|
||||
`tentativi` DEFAULT 1 = comportamento invariato per tutti i chiamanti esistenti; chi manda
|
||||
un allarme che non puo' permettersi di perdere lo alza (venue_watch: 3).
|
||||
"""
|
||||
try:
|
||||
from src.version import APP_VERSION
|
||||
ver = f" <code>v{APP_VERSION}</code>"
|
||||
@@ -86,7 +90,7 @@ def notify(title: str, data: dict | None = None) -> bool:
|
||||
lines = [f"<b>{title}</b>{ver}"]
|
||||
for k, v in (data or {}).items():
|
||||
lines.append(f" {k}: {v}")
|
||||
return send("\n".join(lines))
|
||||
return send("\n".join(lines), tentativi=tentativi)
|
||||
|
||||
|
||||
def is_configured() -> bool:
|
||||
|
||||
Reference in New Issue
Block a user