bugfix: unit status updating based on last heard, not just using cached status

This commit is contained in:
serversdwn
2026-01-05 18:56:20 +00:00
parent e16f61aca7
commit 85b211e532

View File

@@ -24,13 +24,47 @@ def format_age(last_seen):
return f"{int(hours)}h {int(mins)}m"
def calculate_status(last_seen, status_ok_threshold=12, status_pending_threshold=24):
"""
Calculate status based on how long ago the unit was last seen.
Args:
last_seen: datetime of last seen (UTC)
status_ok_threshold: hours before status becomes Pending (default 12)
status_pending_threshold: hours before status becomes Missing (default 24)
Returns:
"OK", "Pending", or "Missing"
"""
if not last_seen:
return "Missing"
last_seen = ensure_utc(last_seen)
now = datetime.now(timezone.utc)
hours_ago = (now - last_seen).total_seconds() / 3600
if hours_ago > status_pending_threshold:
return "Missing"
elif hours_ago > status_ok_threshold:
return "Pending"
else:
return "OK"
def emit_status_snapshot():
"""
Merge roster (what we *intend*) with emitter data (what is *actually happening*).
Status is recalculated based on current time to ensure accuracy.
"""
db = get_db_session()
try:
# Get user preferences for status thresholds
from backend.models import UserPreferences
prefs = db.query(UserPreferences).filter_by(id=1).first()
status_ok_threshold = prefs.status_ok_threshold_hours if prefs else 12
status_pending_threshold = prefs.status_pending_threshold_hours if prefs else 24
roster = {r.id: r for r in db.query(RosterUnit).all()}
emitters = {e.id: e for e in db.query(Emitter).all()}
ignored = {i.id for i in db.query(IgnoredUnit).all()}
@@ -48,8 +82,9 @@ def emit_status_snapshot():
fname = ""
else:
if e:
status = e.status
last_seen = ensure_utc(e.last_seen)
# RECALCULATE status based on current time, not stored value
status = calculate_status(last_seen, status_ok_threshold, status_pending_threshold)
age = format_age(last_seen)
fname = e.last_file
else:
@@ -86,9 +121,11 @@ def emit_status_snapshot():
for unit_id, e in emitters.items():
if unit_id not in roster:
last_seen = ensure_utc(e.last_seen)
# RECALCULATE status for unknown units too
status = calculate_status(last_seen, status_ok_threshold, status_pending_threshold)
units[unit_id] = {
"id": unit_id,
"status": e.status,
"status": status,
"age": format_age(last_seen),
"last": last_seen.isoformat(),
"fname": e.last_file,