Compare commits

...

4 Commits

9 changed files with 72 additions and 52 deletions

View File

@@ -1,6 +1,6 @@
# TJWater Server 环境变量配置模板
# 复制此文件为 .env 并填写实际值
NETWORK_NAME="szh"
# ============================================
# 安全配置 (必填)
# ============================================
@@ -16,20 +16,20 @@ ENCRYPTION_KEY=
# ============================================
# 数据库配置 (PostgreSQL)
# ============================================
DB_NAME=tjwater
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=password
DB_NAME="tjwater"
DB_HOST="localhost"
DB_PORT="5432"
DB_USER="postgres"
DB_PASSWORD="password"
# ============================================
# 数据库配置 (TimescaleDB)
# ============================================
TIMESCALEDB_DB_NAME=szh
TIMESCALEDB_DB_HOST=localhost
TIMESCALEDB_DB_PORT=5433
TIMESCALEDB_DB_USER=tjwater
TIMESCALEDB_DB_PASSWORD=Tjwater@123456
TIMESCALEDB_DB_NAME="szh"
TIMESCALEDB_DB_HOST="localhost"
TIMESCALEDB_DB_PORT="5433"
TIMESCALEDB_DB_USER="tjwater"
TIMESCALEDB_DB_PASSWORD="Tjwater@123456"
# ============================================
# InfluxDB 配置 (时序数据)

13
.env.local Normal file
View File

@@ -0,0 +1,13 @@
NETWORK_NAME="szh"
DB_NAME="szh"
DB_HOST="192.168.1.114"
DB_PORT="5432"
DB_USER="tjwater"
DB_PASSWORD="Tjwater@123456"
TIMESCALEDB_DB_NAME="szh"
TIMESCALEDB_DB_HOST="192.168.1.114"
TIMESCALEDB_DB_PORT="5433"
TIMESCALEDB_DB_USER="tjwater"
TIMESCALEDB_DB_PASSWORD="Tjwater@123456"

View File

@@ -103,6 +103,7 @@ def burst_analysis(
if isinstance(burst_ID, list):
if (burst_size is not None) and (type(burst_size) is not list):
return json.dumps("Type mismatch.")
# 转化为列表形式
elif isinstance(burst_ID, str):
burst_ID = [burst_ID]
if burst_size is not None:
@@ -344,18 +345,42 @@ def flushing_analysis(
# status['setting'] = 0.1036 * pow(valve_k, -3.105)
# cs.append(status)
# set_status(new_name,cs)
units = get_option(new_name)
options = get_option(new_name)
units = options["UNITS"]
# step 2. set the emitter coefficient of drainage node or add flush flow to the drainage node
# 新建 pattern
time_option = get_time(new_name)
hydraulic_step = time_option["HYDRAULIC TIMESTEP"]
secs = from_clock_to_seconds_2(hydraulic_step)
cs_pattern = ChangeSet()
pt = {}
factors = []
tmp_duration = modify_total_duration
while tmp_duration > 0:
factors.append(1.0)
tmp_duration = tmp_duration - secs
pt["id"] = "flushing_pt"
pt["factors"] = factors
cs_pattern.append(pt)
add_pattern(new_name, cs_pattern)
# 为 emitter_demand 添加新的 pattern
emitter_demand = get_demand(new_name, drainage_node_ID)
cs = ChangeSet()
if flushing_flow > 0:
for r in emitter_demand["demands"]:
if units == "LPS":
r["demand"] += flushing_flow / 3.6
elif units == "CMH":
r["demand"] += flushing_flow
cs.append(emitter_demand)
set_demand(new_name, cs)
if units == "LPS":
emitter_demand["demands"].append(
{
"demand": flushing_flow / 3.6,
"pattern": "flushing_pt",
"category": None,
}
)
elif units == "CMH":
emitter_demand["demands"].append(
{"demand": flushing_flow, "pattern": "flushing_pt", "category": None}
)
cs.append(emitter_demand)
set_demand(new_name, cs)
else:
pipes = get_node_links(new_name, drainage_node_ID)
flush_diameter = 50

View File

@@ -196,10 +196,8 @@ async def burst_analysis_endpoint(
async def fastapi_burst_analysis(
network: str = Query(...),
modify_pattern_start_time: str = Query(...),
burst_ID: list | str = Query(..., alias="burst_ID[]"), # 添加别名以匹配 URL
burst_size: list | float | int = Query(
..., alias="burst_size[]"
), # 添加别名以匹配 URL
burst_ID: list[str] = Query(...),
burst_size: list[float] = Query(...),
modify_total_duration: int = Query(...),
scheme_name: str = Query(...),
) -> str:

View File

@@ -1,22 +1,4 @@
import os
import yaml
# 获取当前项目根目录的路径
_current_file = os.path.abspath(__file__)
project_root = os.path.dirname(os.path.dirname(os.path.dirname(_current_file)))
# 尝试读取 .yml 或 .yaml 文件
config_file = os.path.join(project_root, "configs", "project_info.yml")
if not os.path.exists(config_file):
config_file = os.path.join(project_root, "configs", "project_info.yaml")
if not os.path.exists(config_file):
raise FileNotFoundError(f"未找到项目配置文件 (project_info.yaml 或 .yml): {os.path.dirname(config_file)}")
with open(config_file, 'r', encoding='utf-8') as f:
_config = yaml.safe_load(f)
if not _config or 'name' not in _config:
raise KeyError(f"项目配置文件中缺少 'name' 配置: {config_file}")
name = _config['name']
# 从环境变量 NETWORK_NAME 读取
name = os.getenv("NETWORK_NAME")

View File

@@ -1190,12 +1190,12 @@ def run_simulation(
if modify_valve_opening[valve_name] == 0:
valve_status["status"] = "CLOSED"
valve_status["setting"] = 0
if modify_valve_opening[valve_name] < 1:
elif modify_valve_opening[valve_name] < 1:
valve_status["status"] = "OPEN"
valve_status["setting"] = 0.1036 * pow(
modify_valve_opening[valve_name], -3.105
)
if modify_valve_opening[valve_name] == 1:
elif modify_valve_opening[valve_name] == 1:
valve_status["status"] = "OPEN"
valve_status["setting"] = 0
cs = ChangeSet()

View File

@@ -1 +0,0 @@
name: szh

View File

@@ -1,13 +1,19 @@
FROM python:3.12-slim
FROM continuumio/miniconda3:latest
WORKDIR /app
# 安装 Python 3.12 和 pymetis (通过 conda-forge 避免编译问题)
RUN conda install -y -c conda-forge python=3.12 pymetis && \
conda clean -afy
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app
COPY resources ./resources
COPY .env .
ENV PYTHONPATH=/app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

View File

@@ -95,7 +95,6 @@ prometheus_client==0.24.1
psycopg==3.2.5
psycopg-binary==3.2.5
psycopg-pool==3.3.0
psycopg2==2.9.10
PuLP==3.1.1
py-key-value-aio==0.3.0
py-key-value-shared==0.3.0
@@ -157,8 +156,6 @@ starlette==0.50.0
threadpoolctl==3.6.0
tqdm==4.67.1
typer==0.21.1
typing-inspection==0.4.0
typing_extensions==4.12.2
tzdata==2025.2
urllib3==2.2.3
uvicorn==0.34.0