69 lines
3.3 KiB
Python
69 lines
3.3 KiB
Python
from typing import Any
|
||
from datetime import datetime
|
||
|
||
from typing import Literal
|
||
|
||
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_location import (
|
||
run_burst_location_by_network,
|
||
)
|
||
|
||
router = APIRouter()
|
||
|
||
|
||
class BurstLocationRequest(BaseModel):
|
||
"""爆管定位请求模型"""
|
||
network: str = Field(..., description="管网名称(或数据库名称)")
|
||
data_source: Literal["monitoring", "simulation"] = Field("monitoring", description="数据来源:monitoring(监测)或simulation(模拟)")
|
||
pressure_scada_ids: list[str] | None = Field(None, description="压力SCADA传感器ID列表")
|
||
burst_pressure: dict[str, float] | list[dict[str, Any]] | None = Field(None, description="爆管时的压力数据")
|
||
normal_pressure: dict[str, float] | list[dict[str, Any]] | None = Field(None, description="正常时的压力数据")
|
||
burst_leakage: float = Field(..., description="爆管时的漏水量")
|
||
flow_scada_ids: list[str] | None = Field(None, description="流量SCADA传感器ID列表")
|
||
burst_flow: dict[str, float] | list[dict[str, Any]] | None = Field(None, description="爆管时的流量数据")
|
||
normal_flow: dict[str, float] | list[dict[str, Any]] | None = Field(None, description="正常时的流量数据")
|
||
min_dpressure: float = Field(2.0, description="最小压力差(bar)")
|
||
basic_pressure: float = Field(10.0, description="基准压力(bar)")
|
||
scada_burst_start: datetime | None = Field(None, description="爆管/模拟方案开始时间")
|
||
scada_burst_end: datetime | None = Field(None, description="爆管/模拟方案结束时间")
|
||
scada_normal_start: datetime | None = Field(None, description="监测数据正常工况开始时间")
|
||
scada_normal_end: datetime | None = Field(None, description="监测数据正常工况结束时间")
|
||
use_scada_flow: bool = Field(False, description="是否使用SCADA流量数据")
|
||
scheme_name: str | None = Field(None, description="方案名称")
|
||
simulation_scheme_name: str | None = Field(None, description="模拟方案名称")
|
||
simulation_scheme_type: str | None = Field(None, description="模拟方案类型")
|
||
|
||
|
||
@router.post(
|
||
"/burst-locations",
|
||
summary="执行爆管定位",
|
||
description="基于压力和流量数据定位管网中的爆管位置"
|
||
)
|
||
async def locate_burst(
|
||
data: BurstLocationRequest = Body(..., description="爆管定位请求数据"),
|
||
username: str = Depends(get_current_keycloak_username),
|
||
) -> dict[str, Any]:
|
||
"""
|
||
执行爆管定位分析。
|
||
|
||
使用压力和流量SCADA数据,通过对比爆管和正常状态下的数据差异,
|
||
定位管网中的爆管位置。
|
||
|
||
Args:
|
||
data: 包含管网名称(或数据库名称)、压力、流量数据及相关参数的请求体
|
||
username: 当前认证用户名
|
||
|
||
Returns:
|
||
包含定位结果的字典
|
||
|
||
Raises:
|
||
HTTPException: 当数据类型或值不正确时
|
||
"""
|
||
try:
|
||
return run_burst_location_by_network(**data.model_dump(), username=username)
|
||
except (TypeError, ValueError) as exc:
|
||
raise HTTPException(status_code=400, detail=str(exc))
|