fix(simulation): export ACTIVE valves correctly for EPANET 2
Generic Container CI/CD / test-build-publish (push) Successful in 2m12s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 2m12s

The legacy online simulation path still exported internal ACTIVE states as STATUS keywords, which EPANET 2 rejects. Preserve numeric settings and EPANET 3 output while passing the format through both exporters. Surface the original engine error inside the model transaction so failed runs roll back before result storage.

Regression guard: six failures reproduced on the deployed baseline, including native input validation. All 34 focused export, service and endpoint checks pass after the fix; the real project also returns native node and link results.
This commit is contained in:
2026-11-03 13:48:50 +08:00
parent 38a51ed65c
commit 9ab7b10e3c
5 changed files with 141 additions and 7 deletions
+17 -3
View File
@@ -490,6 +490,23 @@ def run_simulation(
set_status(name_c, cs)
# 运行并返回结果
result_data = json.loads(run_project(name_c))
if result_data.get("simulation_result") == "failed":
report = result_data.get("report") or ""
logging.error("EPANET failed for project %s:\n%s", name_c, report)
lines = report.splitlines()
error_index = next(
(i for i, line in enumerate(lines) if line.strip().startswith("Error ")),
None,
)
detail = (
" ".join(line.strip() for line in lines[error_index:error_index + 2])[:600]
if error_index is not None
else "引擎未返回错误详情,请查看服务日志"
)
raise RuntimeError(f"EPANET 计算失败:{detail}")
output_data = result_data.get("output")
if not isinstance(output_data, dict):
raise RuntimeError("run_project did not return JSON output content")
refresh_materialized_views_after_commit(name_c)
time_cost_end = time.perf_counter()
print(
@@ -498,9 +515,6 @@ def run_simulation(
time_cost_end - time_cost_start,
)
)
output_data = result_data.get("output")
if not isinstance(output_data, dict):
raise RuntimeError("run_project did not return JSON output content")
node_result = output_data.get("node_results")
link_result = output_data.get("link_results")
if node_result is None or link_result is None: