diff --git a/app/routers/yudao_aiot_alarm.py b/app/routers/yudao_aiot_alarm.py index e73ed55..eb1d60b 100644 --- a/app/routers/yudao_aiot_alarm.py +++ b/app/routers/yudao_aiot_alarm.py @@ -15,12 +15,15 @@ API 路径规范: from fastapi import APIRouter, Query, Depends, HTTPException from typing import Optional from datetime import datetime +import httpx +import asyncio from app.yudao_compat import YudaoResponse, get_current_user from app.services.alarm_event_service import get_alarm_event_service, AlarmEventService from app.services.notification_service import get_notification_service from app.services.oss_storage import get_oss_storage from app.schemas import EdgeAlarmReport +from app.utils.logger import logger router = APIRouter(prefix="/admin-api/aiot/alarm", tags=["AIoT-告警"]) @@ -285,6 +288,16 @@ async def edge_alarm_report( except Exception: pass # WebSocket 通知失败不影响主流程 + # 异步上报运维平台(提前提取字段,避免 ORM session 关闭后无法访问) + ops_data = { + "alarm_id": alarm.alarm_id, + "alarm_type": alarm.alarm_type, + "device_id": alarm.device_id, + "event_time": alarm.event_time.strftime("%Y-%m-%dT%H:%M:%S") if isinstance(alarm.event_time, datetime) else str(alarm.event_time or ""), + "alarm_level": alarm.alarm_level or 2, + } + asyncio.create_task(_notify_ops_platform(ops_data)) + return YudaoResponse.success({ "alarmId": alarm.alarm_id, "created": True, @@ -293,6 +306,31 @@ async def edge_alarm_report( # ==================== 辅助函数 ==================== +OPS_ALARM_URL = "http://192.168.0.104:48080/admin-api/ops/alarm/receive" + + +async def _notify_ops_platform(data: dict): + """异步上报告警到运维平台(失败不影响主流程)""" + payload = { + "alarmId": data["alarm_id"], + "alarmType": data["alarm_type"], + "deviceId": data["device_id"], + "eventTime": data["event_time"], + "alarmLevel": data["alarm_level"], + "notifyUserIds": [1], + "tenantId": 1, + } + try: + async with httpx.AsyncClient(timeout=10) as client: + resp = await client.post(OPS_ALARM_URL, json=payload) + if resp.status_code == 200: + logger.info(f"运维平台上报成功: {data['alarm_id']}, resp={resp.text[:200]}") + else: + logger.warning(f"运维平台上报失败: status={resp.status_code}, body={resp.text[:200]}") + except Exception as e: + logger.warning(f"运维平台上报异常: {e}") + + def _get_alarm_type_name(alarm_type: Optional[str]) -> str: """获取告警类型名称""" type_names = {