feat: Add local system override and manual entry controls with offline systems caching
This commit is contained in:
@@ -142,6 +142,8 @@ class MQTTManager:
|
||||
|
||||
async def _publish_checkin(self):
|
||||
from app.internal.discord_radio import radio_bot
|
||||
from app.internal.config_manager import load_node_config
|
||||
config = load_node_config()
|
||||
payload = {
|
||||
"node_id": settings.node_id,
|
||||
"name": settings.node_name,
|
||||
@@ -149,6 +151,10 @@ class MQTTManager:
|
||||
"lon": settings.node_lon,
|
||||
"discord_connected": radio_bot.is_connected,
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"node_type": config.node_type,
|
||||
"is_overridden": config.override_system_id is not None and config.node_type != "portable",
|
||||
"override_system_id": config.override_system_id,
|
||||
"enforce_override_timeout": config.enforce_override_timeout,
|
||||
}
|
||||
self._publish(self._t_checkin, payload, qos=1)
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Any, Optional
|
||||
import httpx
|
||||
from app.config import settings
|
||||
from app.internal.logger import logger
|
||||
from app.internal import credentials
|
||||
|
||||
_CACHE_FILE = Path(settings.config_path) / "systems_cache.json"
|
||||
|
||||
async def fetch_and_cache_systems() -> bool:
|
||||
"""Fetch all systems from the C2 server and cache them locally."""
|
||||
if not settings.c2_url:
|
||||
logger.warning("C2_URL not configured. Skipping system caching.")
|
||||
return False
|
||||
|
||||
url = f"{settings.c2_url}/systems"
|
||||
api_key = credentials.get_api_key()
|
||||
headers = {"Authorization": f"Bearer {api_key}"} if api_key else {}
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
r = await client.get(url, headers=headers)
|
||||
r.raise_for_status()
|
||||
systems = r.json()
|
||||
|
||||
_CACHE_FILE.parent.mkdir(parents=True, exist_ok=True)
|
||||
_CACHE_FILE.write_text(json.dumps(systems, indent=2))
|
||||
logger.info(f"Cached {len(systems)} systems from C2.")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to fetch systems from C2: {e}. Offline cache will be used.")
|
||||
return False
|
||||
|
||||
def load_cached_systems() -> List[Dict[str, Any]]:
|
||||
"""Load cached systems from disk."""
|
||||
if _CACHE_FILE.exists():
|
||||
try:
|
||||
return json.loads(_CACHE_FILE.read_text())
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to read systems cache: {e}")
|
||||
return []
|
||||
|
||||
def get_cached_system(system_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""Retrieve a single system config from the cache."""
|
||||
systems = load_cached_systems()
|
||||
for sys in systems:
|
||||
if sys.get("system_id") == system_id:
|
||||
return sys
|
||||
return None
|
||||
Reference in New Issue
Block a user