Update to v0.4.1 #3
@@ -24,13 +24,47 @@ def format_age(last_seen):
|
|||||||
return f"{int(hours)}h {int(mins)}m"
|
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():
|
def emit_status_snapshot():
|
||||||
"""
|
"""
|
||||||
Merge roster (what we *intend*) with emitter data (what is *actually happening*).
|
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()
|
db = get_db_session()
|
||||||
try:
|
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()}
|
roster = {r.id: r for r in db.query(RosterUnit).all()}
|
||||||
emitters = {e.id: e for e in db.query(Emitter).all()}
|
emitters = {e.id: e for e in db.query(Emitter).all()}
|
||||||
ignored = {i.id for i in db.query(IgnoredUnit).all()}
|
ignored = {i.id for i in db.query(IgnoredUnit).all()}
|
||||||
@@ -48,8 +82,9 @@ def emit_status_snapshot():
|
|||||||
fname = ""
|
fname = ""
|
||||||
else:
|
else:
|
||||||
if e:
|
if e:
|
||||||
status = e.status
|
|
||||||
last_seen = ensure_utc(e.last_seen)
|
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)
|
age = format_age(last_seen)
|
||||||
fname = e.last_file
|
fname = e.last_file
|
||||||
else:
|
else:
|
||||||
@@ -86,9 +121,11 @@ def emit_status_snapshot():
|
|||||||
for unit_id, e in emitters.items():
|
for unit_id, e in emitters.items():
|
||||||
if unit_id not in roster:
|
if unit_id not in roster:
|
||||||
last_seen = ensure_utc(e.last_seen)
|
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] = {
|
units[unit_id] = {
|
||||||
"id": unit_id,
|
"id": unit_id,
|
||||||
"status": e.status,
|
"status": status,
|
||||||
"age": format_age(last_seen),
|
"age": format_age(last_seen),
|
||||||
"last": last_seen.isoformat(),
|
"last": last_seen.isoformat(),
|
||||||
"fname": e.last_file,
|
"fname": e.last_file,
|
||||||
|
|||||||
Reference in New Issue
Block a user