Files
TJWaterServerBinary/app/api/v1/endpoints/burst_detection.py
T

79 lines
3.0 KiB
Python

from datetime import datetime
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, Body
from pydantic import BaseModel, Field
from app.auth.keycloak_dependencies import get_current_keycloak_username
from app.services.burst_detection import (
run_burst_detection,
)
router = APIRouter()
class BurstDetectionRequest(BaseModel):
"""爆管检测请求模型"""
network: str = Field(..., description="管网名称(或数据库名称)")
observed_pressure_data: (
dict[str, list[Any]] | list[dict[str, Any]] | list[list[Any]] | None
) = Field(
default=None,
description=(
"压力观测数据。支持列式字典 {sensor_id: [values,...]}、"
"逐时刻对象数组 [{sensor_id: value,...}, ...]、"
"或二维数组 [[t1_s1, t1_s2], [t2_s1, t2_s2], ...]。"
),
)
points_per_day: int = Field(1440, description="每天的数据点数")
mu: int = Field(100, description="异常值检测的参数")
iforest_params: dict[str, Any] | None = Field(None, description="隔离森林算法参数")
target_time: datetime | None = Field(
None,
description="目标侦测时刻;为空时自动使用最近一个完整的监测时刻",
)
sampling_interval_minutes: int | None = Field(
None,
ge=1,
le=1440,
description="采样间隔(分钟);为空时根据压力 SCADA 传输频率自动推断",
)
scada_start: datetime | None = Field(None, description="SCADA数据起始时间")
scada_end: datetime | None = Field(None, description="SCADA数据结束时间")
sensor_nodes: list[str] | None = Field(None, description="传感器节点列表")
scheme_name: str | None = Field(None, description="方案名称")
data_source: str = Field("monitoring", description="数据来源:monitoring(监测)或simulation(模拟)")
simulation_scheme_name: str | None = Field(None, description="模拟方案名称")
simulation_scheme_type: str | None = Field(None, description="模拟方案类型")
@router.post(
"/burst-detections",
summary="执行爆管检测",
description="基于压力观测数据和其他参数执行爆管检测分析"
)
async def detect_burst(
data: BurstDetectionRequest = Body(..., description="爆管检测请求数据"),
username: str = Depends(get_current_keycloak_username),
) -> dict[str, Any]:
"""
执行爆管检测分析。
使用异常检测算法(隔离森林)识别压力时间序列中的异常,
将其作为潜在的爆管事件。
Args:
data: 包含管网名称(或数据库名称)、压力数据及相关参数的请求体
username: 当前认证用户名
Returns:
包含检测结果的字典
Raises:
HTTPException: 当处理过程中发生错误时
"""
try:
return run_burst_detection(**data.model_dump(), username=username)
except Exception as exc:
raise HTTPException(status_code=400, detail=str(exc))