109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from datetime import datetime
|
|
from psycopg import AsyncConnection
|
|
|
|
from app.services.timeseries_analysis import TimeseriesAnalysisService
|
|
from app.domain.schemas.timeseries_history import (
|
|
ElementHistoryQuery,
|
|
ElementHistoryResponse,
|
|
)
|
|
from app.services.timeseries_history import TimeseriesHistoryService
|
|
from .dependencies import get_timescale_connection, get_postgres_connection
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post(
|
|
"/timeseries/views/element-history/query",
|
|
summary="批量查询管网元素历史数据",
|
|
response_model=ElementHistoryResponse,
|
|
)
|
|
async def query_element_history(
|
|
payload: ElementHistoryQuery,
|
|
timescale_conn: AsyncConnection = Depends(get_timescale_connection),
|
|
postgres_conn: AsyncConnection = Depends(get_postgres_connection),
|
|
) -> ElementHistoryResponse:
|
|
try:
|
|
return await TimeseriesHistoryService.query(
|
|
timescale_conn, postgres_conn, payload
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
|
|
|
|
|
@router.post("/timeseries/scada-cleaning-runs", summary="清洗SCADA监测数据")
|
|
async def clean_scada_data(
|
|
device_ids: str = Query(..., description="设备ID列表或 'all' 表示清洗所有设备"),
|
|
start_time: datetime = Query(..., description="清洗数据的开始时间"),
|
|
end_time: datetime = Query(..., description="清洗数据的结束时间"),
|
|
timescale_conn: AsyncConnection = Depends(get_timescale_connection),
|
|
postgres_conn: AsyncConnection = Depends(get_postgres_connection),
|
|
):
|
|
"""
|
|
清洗SCADA监测数据
|
|
|
|
根据device_ids查询monitored_value,清洗后更新cleaned_value。
|
|
支持清洗指定设备或所有设备的数据。
|
|
|
|
Args:
|
|
device_ids: 设备ID列表,用逗号分隔,或 'all' 表示清洗所有设备
|
|
start_time: 清洗数据的开始时间
|
|
end_time: 清洗数据的结束时间
|
|
timescale_conn: TimescaleDB连接
|
|
postgres_conn: PostgreSQL连接
|
|
|
|
Returns:
|
|
清洗结果信息
|
|
|
|
Raises:
|
|
HTTPException: 当清洗过程出现错误时返回400错误
|
|
"""
|
|
try:
|
|
if device_ids == "all":
|
|
device_ids_list = []
|
|
else:
|
|
device_ids_list = (
|
|
[id.strip() for id in device_ids.split(",") if id.strip()]
|
|
if device_ids
|
|
else []
|
|
)
|
|
return await TimeseriesAnalysisService.clean_scada_data(
|
|
timescale_conn, postgres_conn, device_ids_list, start_time, end_time
|
|
)
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
@router.get("/pipeline-health-predictions", summary="预测管道健康状况")
|
|
async def predict_pipeline_health(
|
|
query_time: datetime = Query(..., description="查询时间"),
|
|
timescale_conn: AsyncConnection = Depends(get_timescale_connection),
|
|
postgres_conn: AsyncConnection = Depends(get_postgres_connection),
|
|
):
|
|
"""
|
|
预测管道健康状况
|
|
|
|
根据管网名称和当前时间,查询管道信息和实时数据,
|
|
使用随机生存森林模型预测管道的生存概率。
|
|
|
|
Args:
|
|
query_time: 查询时间
|
|
timescale_conn: TimescaleDB连接
|
|
|
|
Returns:
|
|
预测结果列表,每个元素包含 link_id 和对应的生存函数
|
|
|
|
Raises:
|
|
HTTPException: 当模型文件不存在返回404错误,其他错误返回400或500错误
|
|
"""
|
|
try:
|
|
return await TimeseriesAnalysisService.predict_pipeline_health(
|
|
timescale_conn, postgres_conn, query_time
|
|
)
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
except FileNotFoundError as e:
|
|
raise HTTPException(status_code=404, detail=str(e))
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"内部服务器错误: {str(e)}")
|