feat(aiot): 告警生成时异步上报运维平台
- 边缘告警入库后异步 POST 到运维平台 /admin-api/ops/alarm/receive - 提前提取 ORM 字段避免异步执行时 session 关闭导致属性为空 - event_time 转为 ISO 字符串格式,修复时间显示为 1970 的问题 - 请求参数含 alarmId、alarmType、deviceId、eventTime、alarmLevel、notifyUserIds、tenantId Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user