changes
This commit is contained in:
@@ -12,7 +12,6 @@ from app.internal.discord_radio import radio_bot
|
||||
from app.internal.config_manager import (
|
||||
load_node_config,
|
||||
save_node_config,
|
||||
apply_system_config,
|
||||
)
|
||||
from app.routers import api, ui
|
||||
|
||||
@@ -22,12 +21,14 @@ from app.routers import api, ui
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
async def on_call_start(data: dict):
|
||||
radio_bot.start_stream()
|
||||
await mqtt_manager.publish_status("recording")
|
||||
await mqtt_manager.publish_metadata("call_start", data)
|
||||
await call_recorder.start_recording(data["call_id"])
|
||||
|
||||
|
||||
async def on_call_end(data: dict):
|
||||
radio_bot.stop_stream()
|
||||
file_path = await call_recorder.stop_recording()
|
||||
if file_path:
|
||||
audio_url = await call_recorder.upload_recording(file_path, data["call_id"])
|
||||
@@ -50,6 +51,7 @@ async def on_command(payload: dict):
|
||||
guild_id=int(payload["guild_id"]),
|
||||
channel_id=int(payload["channel_id"]),
|
||||
token=token,
|
||||
call_active=metadata_watcher.is_active,
|
||||
)
|
||||
elif action == "discord_leave":
|
||||
await radio_bot.leave()
|
||||
@@ -69,8 +71,38 @@ async def on_api_key(payload: dict):
|
||||
logger.info("Node API key received and saved.")
|
||||
|
||||
|
||||
def _to_hz(freq) -> int:
|
||||
"""Convert a frequency to Hz. Accepts MHz floats (< 1e6) or Hz ints."""
|
||||
f = float(freq)
|
||||
return int(f * 1_000_000) if f < 1_000_000 else int(f)
|
||||
|
||||
|
||||
async def _generate_op25_config(config: SystemConfig) -> bool:
|
||||
"""Translate a SystemConfig (Firestore format) into OP25 active.cfg.json + op25.liq."""
|
||||
from app.internal.op25_client import op25_client
|
||||
raw = config.config
|
||||
payload = {
|
||||
"type": config.type,
|
||||
"systemName": config.name,
|
||||
"channels": [_to_hz(ch) for ch in raw.get("control_channels", [])],
|
||||
"tags": [
|
||||
{"talkgroup": str(tg.get("name", "")), "tagDec": int(tg["id"])}
|
||||
for tg in raw.get("talkgroups", [])
|
||||
if tg.get("id") is not None
|
||||
],
|
||||
"whitelist": [int(tg["id"]) for tg in raw.get("talkgroups", []) if tg.get("id") is not None],
|
||||
"icecastConfig": {
|
||||
"icecast_host": settings.icecast_host,
|
||||
"icecast_port": settings.icecast_port,
|
||||
"icecast_mountpoint": settings.icecast_mount,
|
||||
"icecast_password": settings.icecast_source_password,
|
||||
},
|
||||
}
|
||||
return await op25_client.generate_config(payload)
|
||||
|
||||
|
||||
async def on_config_push(payload: dict):
|
||||
"""C2 pushes a system config — apply it and restart OP25 with the new settings."""
|
||||
"""C2 pushes a system config — translate it to OP25 format and restart OP25."""
|
||||
try:
|
||||
config = SystemConfig(**payload)
|
||||
except Exception as e:
|
||||
@@ -82,14 +114,15 @@ async def on_config_push(payload: dict):
|
||||
node_cfg.system_config = config
|
||||
node_cfg.configured = True
|
||||
save_node_config(node_cfg)
|
||||
apply_system_config(config)
|
||||
|
||||
# Restart OP25 so it picks up the new config
|
||||
from app.internal.op25_client import op25_client
|
||||
if not await _generate_op25_config(config):
|
||||
logger.error(f"Failed to generate OP25 config for {config.name}")
|
||||
return
|
||||
|
||||
await op25_client.stop()
|
||||
await asyncio.sleep(2)
|
||||
await op25_client.start()
|
||||
|
||||
logger.info(f"Config push applied: {config.name}")
|
||||
|
||||
|
||||
@@ -120,10 +153,15 @@ async def lifespan(app: FastAPI):
|
||||
initial_status = "online" if node_cfg.configured else "unconfigured"
|
||||
await mqtt_manager.publish_status(initial_status)
|
||||
|
||||
if node_cfg.configured:
|
||||
if node_cfg.configured and node_cfg.system_config:
|
||||
from app.internal.op25_client import op25_client
|
||||
logger.info("Node is configured — starting OP25.")
|
||||
await op25_client.start()
|
||||
logger.info("Node is configured — waiting for OP25 API then generating config.")
|
||||
for attempt in range(10):
|
||||
if await _generate_op25_config(node_cfg.system_config):
|
||||
await op25_client.start()
|
||||
break
|
||||
logger.warning(f"OP25 not ready yet (attempt {attempt + 1}/10), retrying in 3s…")
|
||||
await asyncio.sleep(3)
|
||||
|
||||
heartbeat_task = asyncio.create_task(mqtt_manager.heartbeat_loop())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user