Files
TJWaterServerBinary/app/api/v1/endpoints/simulation.py
2026-01-21 18:19:48 +08:00

141 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
)