141 lines
4.9 KiB
Python
141 lines
4.9 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
|
||
)
|