diff --git a/app/api/v1/endpoints/timeseries/realtime.py b/app/api/v1/endpoints/timeseries/realtime.py index d6fabf3..5725eb6 100644 --- a/app/api/v1/endpoints/timeseries/realtime.py +++ b/app/api/v1/endpoints/timeseries/realtime.py @@ -9,8 +9,7 @@ from .dependencies import get_timescale_connection router = APIRouter() -@router.post("/realtime/links/batch", status_code=201, summary="批量插入实时管道数据", - tags=["时间序列-实时数据"]) +@router.post("/realtime/links/batch", status_code=201, summary="批量插入实时管道数据") async def insert_realtime_links( data: List[dict] = Body(..., description="管道数据列表,每项包含管道ID、时间戳等信息"), conn: AsyncConnection = Depends(get_timescale_connection) @@ -30,7 +29,7 @@ async def insert_realtime_links( return {"message": f"Inserted {len(data)} records"} -@router.get("/realtime/links", summary="查询实时管道数据", tags=["时间序列-实时数据"]) +@router.get("/realtime/links", summary="查询实时管道数据") async def get_realtime_links( start_time: datetime = Query(..., description="查询开始时间"), end_time: datetime = Query(..., description="查询结束时间"), @@ -51,7 +50,7 @@ async def get_realtime_links( return await RealtimeRepository.get_links_by_time_range(conn, start_time, end_time) -@router.delete("/realtime/links", summary="删除实时管道数据", tags=["时间序列-实时数据"]) +@router.delete("/realtime/links", summary="删除实时管道数据") async def delete_realtime_links( start_time: datetime = Query(..., description="删除开始时间"), end_time: datetime = Query(..., description="删除结束时间"), @@ -73,8 +72,7 @@ async def delete_realtime_links( return {"message": "Deleted successfully"} -@router.patch("/realtime/links/{link_id}/field", summary="更新实时管道字段", - tags=["时间序列-实时数据"]) +@router.patch("/realtime/links/{link_id}/field", summary="更新实时管道字段") async def update_realtime_link_field( link_id: str = Path(..., description="管道ID"), time: datetime = Query(..., description="更新数据的时间戳"), @@ -106,8 +104,7 @@ async def update_realtime_link_field( raise HTTPException(status_code=400, detail=str(e)) -@router.post("/realtime/nodes/batch", status_code=201, summary="批量插入实时节点数据", - tags=["时间序列-实时数据"]) +@router.post("/realtime/nodes/batch", status_code=201, summary="批量插入实时节点数据") async def insert_realtime_nodes( data: List[dict] = Body(..., description="节点数据列表,每项包含节点ID、时间戳等信息"), conn: AsyncConnection = Depends(get_timescale_connection) @@ -127,7 +124,7 @@ async def insert_realtime_nodes( return {"message": f"Inserted {len(data)} records"} -@router.get("/realtime/nodes", summary="查询实时节点数据", tags=["时间序列-实时数据"]) +@router.get("/realtime/nodes", summary="查询实时节点数据") async def get_realtime_nodes( start_time: datetime = Query(..., description="查询开始时间"), end_time: datetime = Query(..., description="查询结束时间"), @@ -148,7 +145,7 @@ async def get_realtime_nodes( return await RealtimeRepository.get_nodes_by_time_range(conn, start_time, end_time) -@router.delete("/realtime/nodes", summary="删除实时节点数据", tags=["时间序列-实时数据"]) +@router.delete("/realtime/nodes", summary="删除实时节点数据") async def delete_realtime_nodes( start_time: datetime = Query(..., description="删除开始时间"), end_time: datetime = Query(..., description="删除结束时间"), @@ -172,8 +169,7 @@ async def delete_realtime_nodes( -@router.post("/realtime/simulation/store", status_code=201, summary="存储实时模拟结果", - tags=["时间序列-实时数据"]) +@router.post("/realtime/simulation/store", status_code=201, summary="存储实时模拟结果") async def store_realtime_simulation_result( node_result_list: List[dict] = Body(..., description="节点模拟结果列表"), link_result_list: List[dict] = Body(..., description="管道模拟结果列表"), @@ -199,8 +195,7 @@ async def store_realtime_simulation_result( return {"message": "Simulation results stored successfully"} -@router.get("/realtime/query/by-time-property", summary="按时间和属性查询实时数据", - tags=["时间序列-实时数据"]) +@router.get("/realtime/query/by-time-property", summary="按时间和属性查询实时数据") async def query_realtime_records_by_time_property( query_time: str = Query(..., description="查询时间"), type: str = Query(..., description="数据类型,pipe(管道)或 junction(节点)"), @@ -232,8 +227,7 @@ async def query_realtime_records_by_time_property( raise HTTPException(status_code=400, detail=str(e)) -@router.get("/realtime/query/by-id-time", summary="按ID和时间查询实时模拟数据", - tags=["时间序列-实时数据"]) +@router.get("/realtime/query/by-id-time", summary="按ID和时间查询实时模拟数据") async def query_realtime_simulation_by_id_time( id: str = Query(..., description="元素ID(管道ID或节点ID)"), type: str = Query(..., description="元素类型,pipe(管道)或 junction(节点)"), diff --git a/app/api/v1/endpoints/timeseries/scada.py b/app/api/v1/endpoints/timeseries/scada.py index a42f87c..3ed1bab 100644 --- a/app/api/v1/endpoints/timeseries/scada.py +++ b/app/api/v1/endpoints/timeseries/scada.py @@ -9,20 +9,19 @@ from .dependencies import get_timescale_connection router = APIRouter() -@router.post("/scada/batch", status_code=201, summary="批量插入SCADA监测数据", - tags=["时间序列-监测数据"]) +@router.post("/scada/batch", status_code=201, summary="批量插入SCADA监测数据") async def insert_scada_data( data: List[dict] = Body(..., description="SCADA设备监测数据列表"), - conn: AsyncConnection = Depends(get_timescale_connection) + conn: AsyncConnection = Depends(get_timescale_connection), ): """ 批量插入SCADA监测数据 - + 将多个设备的实时监测数据批量插入时间序列数据库。 - + Args: data: SCADA设备监测数据列表,每项包含device_id、时间戳和监测值等信息 - + Returns: 插入成功的记录数 """ @@ -30,24 +29,25 @@ async def insert_scada_data( return {"message": f"Inserted {len(data)} records"} -@router.get("/scada/by-ids-time-range", summary="按设备ID和时间范围查询SCADA数据", - tags=["时间序列-监测数据"]) +@router.get("/scada/by-ids-time-range", summary="按设备ID和时间范围查询SCADA数据") async def get_scada_by_ids_time_range( start_time: datetime = Query(..., description="查询开始时间"), end_time: datetime = Query(..., description="查询结束时间"), - device_ids: str = Query(..., description="设备ID列���,逗号分隔,如 'device1,device2,device3'"), + device_ids: str = Query( + ..., description="设备ID列表,逗号分隔,如 'device1,device2,device3'" + ), conn: AsyncConnection = Depends(get_timescale_connection), ): """ 按设备ID和时间范围查询SCADA监测数据 - + 查询多个设备在指定时间范围内的所有监测数据。 - + Args: start_time: 查询开始时间 end_time: 查询结束时间 device_ids: 设备ID列表,用逗号分隔 - + Returns: SCADA监测数据列表 """ @@ -59,29 +59,32 @@ async def get_scada_by_ids_time_range( ) -@router.get("/scada/by-ids-field-time-range", summary="按设备ID、字段和时间范围查询SCADA数据", - tags=["时间序列-监测数据"]) +@router.get( + "/scada/by-ids-field-time-range", summary="按设备ID、字段和时间范围查询SCADA数据" +) async def get_scada_field_by_ids_time_range( start_time: datetime = Query(..., description="查询开始时间"), end_time: datetime = Query(..., description="查询结束时间"), field: str = Query(..., description="要查询的字段名称"), - device_ids: str = Query(..., description="设备ID列表,逗号分隔,如 'device1,device2,device3'"), + device_ids: str = Query( + ..., description="设备ID列表,逗号分隔,如 'device1,device2,device3'" + ), conn: AsyncConnection = Depends(get_timescale_connection), ): """ 按设备ID、字段和时间范围查询特定SCADA数据 - + 查询多个设备在指定时间范围内的特定字段监测数据。 - + Args: start_time: 查询开始时间 end_time: 查询结束时间 field: 字段名称 device_ids: 设备ID列表,用逗号分隔 - + Returns: SCADA字段数据列表 - + Raises: HTTPException: 当字段不存在或查询参数无效时返回400错误 """ @@ -98,8 +101,7 @@ async def get_scada_field_by_ids_time_range( raise HTTPException(status_code=400, detail=str(e)) -@router.patch("/scada/{device_id}/field", summary="更新SCADA设备字段", - tags=["时间序列-监测数据"]) +@router.patch("/scada/{device_id}/field", summary="更新SCADA设备字段") async def update_scada_field( device_id: str = Path(..., description="设备ID"), time: datetime = Query(..., description="更新数据的时间戳"), @@ -109,18 +111,18 @@ async def update_scada_field( ): """ 更新指定设备的字段值 - + 更新SCADA设备在特定时间的某个字段监测数据。 - + Args: device_id: 设备ID time: 数据时间戳 field: 字段名称 value: 字段新值 - + Returns: 更新结果信息 - + Raises: HTTPException: 当字段不存在或更新失败时返回400错误 """ @@ -131,8 +133,7 @@ async def update_scada_field( raise HTTPException(status_code=400, detail=str(e)) -@router.delete("/scada/by-id-time-range", summary="按设备ID和时间范围删除SCADA数据", - tags=["时间序列-监测数据"]) +@router.delete("/scada/by-id-time-range", summary="按设备ID和时间范围删除SCADA数据") async def delete_scada_data( device_id: str = Query(..., description="设备ID"), start_time: datetime = Query(..., description="删除开始时间"), @@ -141,14 +142,14 @@ async def delete_scada_data( ): """ 删除指定设备和时间范围内的SCADA数据 - + 删除在指定时间范围内的特定设备监测数据。 - + Args: device_id: 设备ID start_time: 删除开始时间 end_time: 删除结束时间 - + Returns: 删除结果信息 """ diff --git a/app/api/v1/endpoints/timeseries/scheme.py b/app/api/v1/endpoints/timeseries/scheme.py index 7e342c0..76f71e6 100644 --- a/app/api/v1/endpoints/timeseries/scheme.py +++ b/app/api/v1/endpoints/timeseries/scheme.py @@ -9,20 +9,19 @@ from .dependencies import get_timescale_connection router = APIRouter() -@router.post("/scheme/links/batch", status_code=201, summary="批量插入方案管道数据", - tags=["时间序列-方案数据"]) +@router.post("/scheme/links/batch", status_code=201, summary="批量插入方案管道数据") async def insert_scheme_links( data: List[dict] = Body(..., description="方案管道数据列表"), - conn: AsyncConnection = Depends(get_timescale_connection) + conn: AsyncConnection = Depends(get_timescale_connection), ): """ 批量插入方案管道数据 - + 将特定方案的管道模拟数据批量插入时间序列数据库。 - + Args: data: 方案管道数据列表 - + Returns: 插入成功的记录数 """ @@ -30,7 +29,7 @@ async def insert_scheme_links( return {"message": f"Inserted {len(data)} records"} -@router.get("/scheme/links", summary="查询方案管道数据", tags=["时间序列-方案数据"]) +@router.get("/scheme/links", summary="查询方案管道数据") async def get_scheme_links( scheme_type: str = Query(..., description="方案类型"), scheme_name: str = Query(..., description="方案名称"), @@ -40,15 +39,15 @@ async def get_scheme_links( ): """ 查询指定方案和时间范围内的管道数据 - + 根据方案和时间范围查询管道的模拟值。 - + Args: scheme_type: 方案类型 scheme_name: 方案名称 start_time: 查询开始时间 end_time: 查询结束时间 - + Returns: 方案管道数据列表 """ @@ -57,8 +56,7 @@ async def get_scheme_links( ) -@router.get("/scheme/links/{link_id}/field", summary="查询方案管道字段数据", - tags=["时间序列-方案数据"]) +@router.get("/scheme/links/{link_id}/field", summary="查询方案管道字段数据") async def get_scheme_link_field( link_id: str = Path(..., description="管道ID"), scheme_type: str = Query(..., description="方案类型"), @@ -70,9 +68,9 @@ async def get_scheme_link_field( ): """ 查询指定方案管道的特定字段数据 - + 查询特定方案中指定管道在时间范围内的特定字段值。 - + Args: link_id: 管道ID scheme_type: 方案类型 @@ -80,10 +78,10 @@ async def get_scheme_link_field( start_time: 查询开始时间 end_time: 查询结束时间 field: 字段名称 - + Returns: 字段数据列表 - + Raises: HTTPException: 当查询参数无效时返回400错误 """ @@ -95,8 +93,7 @@ async def get_scheme_link_field( raise HTTPException(status_code=400, detail=str(e)) -@router.patch("/scheme/links/{link_id}/field", summary="更新方案管道字段", - tags=["时间序列-方案数据"]) +@router.patch("/scheme/links/{link_id}/field", summary="更新方案管道字段") async def update_scheme_link_field( link_id: str = Path(..., description="管道ID"), scheme_type: str = Query(..., description="方案类型"), @@ -108,9 +105,9 @@ async def update_scheme_link_field( ): """ 更新指定方案管道的字段值 - + 更新特定方案中指定管道在某个时间的字段数据。 - + Args: link_id: 管道ID scheme_type: 方案类型 @@ -118,10 +115,10 @@ async def update_scheme_link_field( time: 数据时间戳 field: 字段名称 value: 字段新值 - + Returns: 更新结果信息 - + Raises: HTTPException: 当字段不存在或更新失败时返回400错误 """ @@ -134,7 +131,7 @@ async def update_scheme_link_field( raise HTTPException(status_code=400, detail=str(e)) -@router.delete("/scheme/links", summary="删除方案管道数据", tags=["时间序列-方案数据"]) +@router.delete("/scheme/links", summary="删除方案管道数据") async def delete_scheme_links( scheme_type: str = Query(..., description="方案类型"), scheme_name: str = Query(..., description="方案名称"), @@ -144,15 +141,15 @@ async def delete_scheme_links( ): """ 删除指定方案和时间范围内的管道数据 - + 删除在指定方案和时间范围内的所有管道模拟数据。 - + Args: scheme_type: 方案类型 scheme_name: 方案名称 start_time: 删除开始时间 end_time: 删除结束时间 - + Returns: 删除结果信息 """ @@ -162,20 +159,19 @@ async def delete_scheme_links( return {"message": "Deleted successfully"} -@router.post("/scheme/nodes/batch", status_code=201, summary="批量插入方案节点数据", - tags=["时间序列-方案数据"]) +@router.post("/scheme/nodes/batch", status_code=201, summary="批量插入方案节点数据") async def insert_scheme_nodes( data: List[dict] = Body(..., description="方案节点数据列表"), - conn: AsyncConnection = Depends(get_timescale_connection) + conn: AsyncConnection = Depends(get_timescale_connection), ): """ 批量插入方案节点数据 - + 将特定方案的节点模拟数据批量插入时间序列数据库。 - + Args: data: 方案节点数据列表 - + Returns: 插入成功的记录数 """ @@ -183,8 +179,7 @@ async def insert_scheme_nodes( return {"message": f"Inserted {len(data)} records"} -@router.get("/scheme/nodes/{node_id}/field", summary="查询方案节点字段数据", - tags=["时间序列-方案数据"]) +@router.get("/scheme/nodes/{node_id}/field", summary="查询方案节点字段数据") async def get_scheme_node_field( node_id: str = Path(..., description="节点ID"), scheme_type: str = Query(..., description="方案类型"), @@ -196,9 +191,9 @@ async def get_scheme_node_field( ): """ 查询指定方案节点的特定字段数据 - + 查询特定方案中指定节点在时间范围内的特定字段值。 - + Args: node_id: 节点ID scheme_type: 方案类型 @@ -206,10 +201,10 @@ async def get_scheme_node_field( start_time: 查询开始时间 end_time: 查询结束时间 field: 字段名称 - + Returns: 字段数据列表 - + Raises: HTTPException: 当查询参数无效时返回400错误 """ @@ -221,8 +216,7 @@ async def get_scheme_node_field( raise HTTPException(status_code=400, detail=str(e)) -@router.patch("/scheme/nodes/{node_id}/field", summary="更新方案节点字段", - tags=["时间序列-方案数据"]) +@router.patch("/scheme/nodes/{node_id}/field", summary="更新方案节点字段") async def update_scheme_node_field( node_id: str = Path(..., description="节点ID"), scheme_type: str = Query(..., description="方案类型"), @@ -234,9 +228,9 @@ async def update_scheme_node_field( ): """ 更新指定方案节点的字段值 - + 更新特定方案中指定节点在某个时间的字段数据。 - + Args: node_id: 节点ID scheme_type: 方案类型 @@ -244,10 +238,10 @@ async def update_scheme_node_field( time: 数据时间戳 field: 字段名称 value: 字段新值 - + Returns: 更新结果信息 - + Raises: HTTPException: 当字段不存在或更新失败时返回400错误 """ @@ -260,7 +254,7 @@ async def update_scheme_node_field( raise HTTPException(status_code=400, detail=str(e)) -@router.delete("/scheme/nodes", summary="删除方案节点数据", tags=["时间序列-方案数据"]) +@router.delete("/scheme/nodes", summary="删除方案节点数据") async def delete_scheme_nodes( scheme_type: str = Query(..., description="方案类型"), scheme_name: str = Query(..., description="方案名称"), @@ -270,15 +264,15 @@ async def delete_scheme_nodes( ): """ 删除指定方案和时间范围内的节点数据 - + 删除在指定方案和时间范围内的所有节点模拟数据。 - + Args: scheme_type: 方案类型 scheme_name: 方案名称 start_time: 删除开始时间 end_time: 删除结束时间 - + Returns: 删除结果信息 """ @@ -288,8 +282,7 @@ async def delete_scheme_nodes( return {"message": "Deleted successfully"} -@router.post("/scheme/simulation/store", status_code=201, summary="存储方案模拟结果", - tags=["时间序列-方案数据"]) +@router.post("/scheme/simulation/store", status_code=201, summary="存储方案模拟结果") async def store_scheme_simulation_result( scheme_type: str = Query(..., description="方案类型"), scheme_name: str = Query(..., description="方案名称"), @@ -300,16 +293,16 @@ async def store_scheme_simulation_result( ): """ 存储方案模拟结果到时间序列数据库 - + 将特定方案的节点和管道模拟计算结果批量存储到TimescaleDB数据库。 - + Args: scheme_type: 方案类型 scheme_name: 方案名称 node_result_list: 节点模拟结果列表 link_result_list: 管道模拟结果列表 result_start_time: 模拟结果对应的起始时间 - + Returns: 存储结果信息 """ @@ -324,8 +317,9 @@ async def store_scheme_simulation_result( return {"message": "Scheme simulation results stored successfully"} -@router.get("/scheme/query/by-scheme-time-property", summary="按方案、时间和属性查询数据", - tags=["时间序列-方案数据"]) +@router.get( + "/scheme/query/by-scheme-time-property", summary="按方案、时间和属性查询数据" +) async def query_scheme_records_by_scheme_time_property( scheme_type: str = Query(..., description="方案类型"), scheme_name: str = Query(..., description="方案名称"), @@ -336,19 +330,19 @@ async def query_scheme_records_by_scheme_time_property( ): """ 按指定方案、时间和属性查询所有方案数据 - + 查询在特定方案和时间点,所有指定类型元素的特定属性值。 - + Args: scheme_type: 方案类型 scheme_name: 方案名称 query_time: 查询时间 type: 元素类型(pipe或junction) property: 属性名称 - + Returns: 查询结果列表 - + Raises: HTTPException: 当查询参数无效时返回400错误 """ @@ -361,8 +355,7 @@ async def query_scheme_records_by_scheme_time_property( raise HTTPException(status_code=400, detail=str(e)) -@router.get("/scheme/query/by-id-time", summary="按ID和时间查询方案模拟数据", - tags=["时间序列-方案数据"]) +@router.get("/scheme/query/by-id-time", summary="按ID和时间查询方案模拟数据") async def query_scheme_simulation_by_id_time( scheme_type: str = Query(..., description="方案类型"), scheme_name: str = Query(..., description="方案名称"), @@ -373,19 +366,19 @@ async def query_scheme_simulation_by_id_time( ): """ 按指定ID和时间查询方案模拟结果 - + 查询特定方案中的元素在某一时间点的模拟数据。 - + Args: scheme_type: 方案类型 scheme_name: 方案名称 id: 元素ID type: 元素类型(pipe或junction) query_time: 查询时间 - + Returns: 模拟结果数据 - + Raises: HTTPException: 当查询参数无效时返回400错误 """ diff --git a/copilot-sidecar/server.py b/copilot-sidecar/server.py index 1930c69..a00fdf8 100644 --- a/copilot-sidecar/server.py +++ b/copilot-sidecar/server.py @@ -29,7 +29,7 @@ app = FastAPI(title="TJWater Copilot Sidecar") client: Optional[CopilotClient] = None sessions: dict[str, SessionHolder] = {} session_ttl_seconds = int(os.getenv("COPILOT_SESSION_TTL_SECONDS", "1800")) -model = os.getenv("COPILOT_MODEL", "gpt-4.1") +model = os.getenv("COPILOT_MODEL", "gpt-5.4") logger = logging.getLogger("copilot_sidecar")