Add ability to pause radio connection (closes #51)

This commit is contained in:
Jack Kingsman
2026-03-11 17:17:03 -07:00
parent e993009782
commit 4e0b6a49b0
18 changed files with 371 additions and 34 deletions
+20
View File
@@ -15,6 +15,7 @@ class HealthResponse(BaseModel):
status: str
radio_connected: bool
radio_initializing: bool = False
radio_state: str = "disconnected"
connection_info: str | None
database_size_mb: float
oldest_undecrypted_timestamp: int | None
@@ -56,12 +57,31 @@ async def build_health_data(radio_connected: bool, connection_info: str | None)
if not radio_connected:
setup_complete = False
connection_desired = getattr(radio_manager, "connection_desired", True)
if not isinstance(connection_desired, bool):
connection_desired = True
is_reconnecting = getattr(radio_manager, "is_reconnecting", False)
if not isinstance(is_reconnecting, bool):
is_reconnecting = False
radio_initializing = bool(radio_connected and (setup_in_progress or not setup_complete))
if not connection_desired:
radio_state = "paused"
elif radio_initializing:
radio_state = "initializing"
elif radio_connected:
radio_state = "connected"
elif is_reconnecting:
radio_state = "connecting"
else:
radio_state = "disconnected"
return {
"status": "ok" if radio_connected and not radio_initializing else "degraded",
"radio_connected": radio_connected,
"radio_initializing": radio_initializing,
"radio_state": radio_state,
"connection_info": connection_info,
"database_size_mb": db_size_mb,
"oldest_undecrypted_timestamp": oldest_ts,
+23 -3
View File
@@ -14,13 +14,14 @@ from app.services.radio_commands import (
import_private_key_and_refresh_keystore,
)
from app.services.radio_runtime import radio_runtime as radio_manager
from app.websocket import broadcast_health
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/radio", tags=["radio"])
async def _prepare_connected(*, broadcast_on_success: bool) -> None:
await radio_manager.prepare_connected(broadcast_on_success=broadcast_on_success)
async def _prepare_connected(*, broadcast_on_success: bool) -> bool:
return await radio_manager.prepare_connected(broadcast_on_success=broadcast_on_success)
async def _reconnect_and_prepare(*, broadcast_on_success: bool) -> bool:
@@ -170,6 +171,8 @@ async def send_advertisement() -> dict:
async def _attempt_reconnect() -> dict:
"""Shared reconnection logic for reboot and reconnect endpoints."""
radio_manager.resume_connection()
if radio_manager.is_reconnecting:
return {
"status": "pending",
@@ -194,6 +197,20 @@ async def _attempt_reconnect() -> dict:
return {"status": "ok", "message": "Reconnected successfully", "connected": True}
@router.post("/disconnect")
async def disconnect_radio() -> dict:
"""Disconnect from the radio and pause automatic reconnect attempts."""
logger.info("Manual radio disconnect requested")
await radio_manager.pause_connection()
broadcast_health(False, radio_manager.connection_info)
return {
"status": "ok",
"message": "Disconnected. Automatic reconnect is paused.",
"connected": False,
"paused": True,
}
@router.post("/reboot")
async def reboot_radio() -> dict:
"""Reboot the radio, or reconnect if not currently connected.
@@ -228,8 +245,11 @@ async def reconnect_radio() -> dict:
logger.info("Radio connected but setup incomplete, retrying setup")
try:
await _prepare_connected(broadcast_on_success=True)
if not await _prepare_connected(broadcast_on_success=True):
raise HTTPException(status_code=503, detail="Radio connection is paused")
return {"status": "ok", "message": "Setup completed", "connected": True}
except HTTPException:
raise
except Exception as e:
logger.exception("Post-connect setup failed")
raise HTTPException(