165 lines
5.0 KiB
Python
165 lines
5.0 KiB
Python
from typing import Any
|
|
from fastapi import APIRouter, HTTPException
|
|
from fastapi.responses import PlainTextResponse
|
|
from app.infra.cache.redis_client import redis_client
|
|
from app.services.tjnetwork import (
|
|
run_project,
|
|
run_project_return_dict,
|
|
run_inp,
|
|
dump_output,
|
|
)
|
|
from app.algorithms.online_Analysis import (
|
|
burst_analysis,
|
|
valve_close_analysis,
|
|
flushing_analysis,
|
|
contaminant_simulation,
|
|
age_analysis,
|
|
# scheduling_analysis,
|
|
pressure_regulation,
|
|
project_management,
|
|
# daily_scheduling_analysis,
|
|
network_update,
|
|
# pump_failure,
|
|
pressure_sensor_placement_sensitivity,
|
|
pressure_sensor_placement_kmeans,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# 必须用这个PlainTextResponse,不然每个key都有引号
|
|
@router.get("/runproject/", response_class=PlainTextResponse)
|
|
async def run_project_endpoint(network: str) -> str:
|
|
lock_key = "exclusive_api_lock"
|
|
timeout = 120 # 锁自动过期时间(秒)
|
|
|
|
# 尝试获取锁(NX=True: 不存在时设置,EX=timeout: 过期时间)
|
|
acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout)
|
|
|
|
if not acquired:
|
|
raise HTTPException(status_code=409, detail="is in simulation")
|
|
else:
|
|
try:
|
|
return run_project(network)
|
|
finally:
|
|
# 手动释放锁(可选,依赖过期时间自动释放更安全)
|
|
redis_client.delete(lock_key)
|
|
|
|
|
|
# DingZQ, 2025-02-04, 返回dict[str, Any]
|
|
# output 和 report
|
|
# output 是 json
|
|
# report 是 text
|
|
@router.get("/runprojectreturndict/")
|
|
async def run_project_return_dict_endpoint(network: str) -> dict[str, Any]:
|
|
lock_key = "exclusive_api_lock"
|
|
timeout = 120 # 锁自动过期时间(秒)
|
|
|
|
# 尝试获取锁(NX=True: 不存在时设置,EX=timeout: 过期时间)
|
|
acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout)
|
|
|
|
if not acquired:
|
|
raise HTTPException(status_code=409, detail="is in simulation")
|
|
else:
|
|
try:
|
|
return run_project_return_dict(network)
|
|
finally:
|
|
# 手动释放锁(可选,依赖过期时间自动释放更安全)
|
|
redis_client.delete(lock_key)
|
|
|
|
|
|
# put in inp folder, name without extension
|
|
@router.get("/runinp/")
|
|
async def run_inp_endpoint(network: str) -> str:
|
|
return run_inp(network)
|
|
|
|
|
|
# path is absolute path
|
|
@router.get("/dumpoutput/")
|
|
async def dump_output_endpoint(output: str) -> str:
|
|
return dump_output(output)
|
|
|
|
|
|
# Analysis Endpoints
|
|
@router.get("/burstanalysis/")
|
|
async def burst_analysis_endpoint(
|
|
network: str, pipe_id: str, start_time: str, end_time: str, burst_flow: float
|
|
):
|
|
return burst_analysis(network, pipe_id, start_time, end_time, burst_flow)
|
|
|
|
|
|
@router.get("/valvecloseanalysis/")
|
|
async def valve_close_analysis_endpoint(
|
|
network: str, valve_id: str, start_time: str, end_time: str
|
|
):
|
|
return valve_close_analysis(network, valve_id, start_time, end_time)
|
|
|
|
|
|
@router.get("/flushinganalysis/")
|
|
async def flushing_analysis_endpoint(
|
|
network: str, pipe_id: str, start_time: str, duration: float, flow: float
|
|
):
|
|
return flushing_analysis(network, pipe_id, start_time, duration, flow)
|
|
|
|
|
|
@router.get("/contaminantsimulation/")
|
|
async def contaminant_simulation_endpoint(
|
|
network: str, node_id: str, start_time: str, duration: float, concentration: float
|
|
):
|
|
return contaminant_simulation(network, node_id, start_time, duration, concentration)
|
|
|
|
|
|
@router.get("/ageanalysis/")
|
|
async def age_analysis_endpoint(network: str):
|
|
return age_analysis(network)
|
|
|
|
|
|
@router.get("/schedulinganalysis/")
|
|
async def scheduling_analysis_endpoint(network: str):
|
|
return scheduling_analysis(network)
|
|
|
|
|
|
@router.get("/pressureregulation/")
|
|
async def pressure_regulation_endpoint(
|
|
network: str, target_node: str, target_pressure: float
|
|
):
|
|
return pressure_regulation(network, target_node, target_pressure)
|
|
|
|
|
|
@router.get("/projectmanagement/")
|
|
async def project_management_endpoint(network: str):
|
|
return project_management(network)
|
|
|
|
|
|
@router.get("/dailyschedulinganalysis/")
|
|
async def daily_scheduling_analysis_endpoint(network: str):
|
|
return daily_scheduling_analysis(network)
|
|
|
|
|
|
@router.get("/networkupdate/")
|
|
async def network_update_endpoint(network: str):
|
|
return network_update(network)
|
|
|
|
|
|
@router.get("/pumpfailure/")
|
|
async def pump_failure_endpoint(network: str, pump_id: str, time: str):
|
|
return pump_failure(network, pump_id, time)
|
|
|
|
|
|
@router.get("/pressuresensorplacementsensitivity/")
|
|
async def pressure_sensor_placement_sensitivity_endpoint(
|
|
name: str, scheme_name: str, sensor_number: int, min_diameter: int, username: str
|
|
):
|
|
return pressure_sensor_placement_sensitivity(
|
|
name, scheme_name, sensor_number, min_diameter, username
|
|
)
|
|
|
|
|
|
@router.get("/pressuresensorplacementkmeans/")
|
|
async def pressure_sensor_placement_kmeans_endpoint(
|
|
name: str, scheme_name: str, sensor_number: int, min_diameter: int, username: str
|
|
):
|
|
return pressure_sensor_placement_kmeans(
|
|
name, scheme_name, sensor_number, min_diameter, username
|
|
)
|