diff --git a/main.py b/main.py index 946fd32..1eee207 100644 --- a/main.py +++ b/main.py @@ -6,7 +6,17 @@ from pydantic import BaseModel from starlette.responses import FileResponse, JSONResponse from starlette.middleware.base import BaseHTTPMiddleware from starlette.types import Receive -from fastapi import FastAPI, File, UploadFile, Response, status, Request, Body, HTTPException,Query +from fastapi import ( + FastAPI, + File, + UploadFile, + Response, + status, + Request, + Body, + HTTPException, + Query, +) from fastapi.responses import PlainTextResponse from fastapi.middleware.gzip import GZipMiddleware from tjnetwork import * @@ -16,7 +26,14 @@ import msgpack from run_simulation import run_simulation, run_simulation_ex from online_Analysis import * from fastapi.middleware.cors import CORSMiddleware -from influxdb_client import InfluxDBClient, BucketsApi, WriteApi, OrganizationsApi, Point, QueryApi +from influxdb_client import ( + InfluxDBClient, + BucketsApi, + WriteApi, + OrganizationsApi, + Point, + QueryApi, +) from typing import List, Dict from datetime import datetime, timedelta, timezone from dateutil import parser @@ -56,58 +73,65 @@ if not os.path.exists(inpDir): if not os.path.exists(tmpDir): os.mkdir(tmpDir) + # 全局依赖项 async def global_auth(request: Request): # 白名单跳过 # if request.url.path in WHITE_LIST: - # return + # return # 验证 token = request.headers.get("Authorization") if token != "Bearer 567e33c876a2" and token != "Bearer 38b3be72b8af": raise HTTPException(status_code=401, detail="Invalid token") + # 简易令牌验证(实际项目中应替换为 JWT/OAuth2 等) AUTH_TOKEN = "567e33c876a2" # 预设的有效令牌 + async def verify_token(authorization: Annotated[str, Header()] = None): # 检查请求头是否存在 if not authorization: raise HTTPException(status_code=401, detail="Authorization header missing") - + # 提取 Bearer 后的令牌 (格式: Bearer ) try: token_type, token = authorization.split(" ", 1) if token_type.lower() != "bearer": raise ValueError except ValueError: - raise HTTPException(status_code=401, detail="Invalid authorization format. Use: Bearer ") - + raise HTTPException( + status_code=401, detail="Invalid authorization format. Use: Bearer " + ) + # 验证令牌 if token != AUTH_TOKEN: raise HTTPException(status_code=403, detail="Invalid authentication token") - + return True + # 全局依赖项 # app = FastAPI(dependencies=[Depends(global_auth)]) app = FastAPI() access_tokens = [] + def generate_access_token(username: str, password: str) -> str: """ 根据用户名和密码生成JWT access token - + 参数: username: 用户名 password: 密码 - + 返回: JWT access token字符串 """ if username != "tjwater" or password != "tjwater@123": - raise ValueError("用户名或密码错误") + raise ValueError("用户名或密码错误") token = "567e33c876a2" return token @@ -119,21 +143,18 @@ def generate_access_token(username: str, password: str) -> str: def encode_datetime(obj): """将datetime转换为可序列化的字典结构""" if isinstance(obj, datetime): - return { - '__datetime__': True, - 'as_str': obj.strftime("%Y%m%dT%H:%M:%S.%f") - } + return {"__datetime__": True, "as_str": obj.strftime("%Y%m%dT%H:%M:%S.%f")} return obj + # 反序列化处理器 def decode_datetime(obj): """将字典还原为datetime对象""" - if '__datetime__' in obj: - return datetime.strptime( - obj['as_str'], "%Y%m%dT%H:%M:%S.%f" - ) + if "__datetime__" in obj: + return datetime.strptime(obj["as_str"], "%Y%m%dT%H:%M:%S.%f") return obj + # 初始化 Redis 连接 # 用redis 限制并发访u redis_client = redis.Redis(host="localhost", port=6379, db=0) @@ -155,23 +176,25 @@ app.add_middleware( ) # 定义一个共享变量 -lock_simulation = Value('i', 0) +lock_simulation = Value("i", 0) app.add_middleware(GZipMiddleware, minimum_size=1000) logger = logging.getLogger() logger.setLevel(logging.INFO) + @app.on_event("startup") async def startup_db(): - logger.info('**********************************************************') + logger.info("**********************************************************") logger.info(str(datetime.now())) logger.info("TJWater CloudService is starting...") - logger.info('**********************************************************') + logger.info("**********************************************************") # open 'szh' by default open_project("szh") - + + ############################################################ # auth ############################################################ @@ -183,19 +206,22 @@ async def fastapi_login(username: str, password: str) -> str: ############################################################ # extension_data ############################################################ -@app.get('/getallextensiondatakeys/') +@app.get("/getallextensiondatakeys/") async def fastapi_get_all_extension_data_keys(network: str) -> list[str]: return get_all_extension_data_keys(network) -@app.get('/getallextensiondata/') + +@app.get("/getallextensiondata/") async def fastapi_get_all_extension_data(network: str) -> dict[str, Any]: return get_all_extension_data(network) -@app.get('/getextensiondata/') + +@app.get("/getextensiondata/") async def fastapi_get_extension_data(network: str, key: str) -> str | None: return get_extension_data(network, key) -@app.post('/setextensiondata',response_model=None) + +@app.post("/setextensiondata", response_model=None) async def fastapi_set_extension_data(network: str, req: Request) -> ChangeSet: props = await req.json() print(props) @@ -203,94 +229,106 @@ async def fastapi_set_extension_data(network: str, req: Request) -> ChangeSet: print(cs.operations[0]) return cs + ############################################################ # project ############################################################ -@app.get('/listprojects/') + +@app.get("/listprojects/") async def fastapi_list_projects() -> list[str]: return list_project() + @app.get("/haveproject/") async def fastapi_have_project(network: str): return have_project(network) + @app.post("/createproject/") async def fastapi_create_project(network: str): create_project(network) return network + @app.post("/deleteproject/") async def fastapi_delete_project(network: str): delete_project(network) return True + @app.get("/isprojectopen/") async def fastapi_is_project_open(network: str): return is_project_open(network) + @app.post("/openproject/") async def fastapi_open_project(network: str): open_project(network) return network + @app.post("/closeproject/") async def fastapi_close_project(network: str): close_project(network) return True + @app.post("/copyproject/") async def fastapi_copy_project(source: str, target: str): copy_project(source, target) return True + @app.post("/importinp/") async def fastapi_import_inp(network: str, req: Request): jo_root = await req.json() - inp_text = jo_root['inp'] - ps = { - "inp" : inp_text - } + inp_text = jo_root["inp"] + ps = {"inp": inp_text} ret = import_inp(network, ChangeSet(ps)) print(ret) return ret -@app.get("/exportinp/",response_model=None) + +@app.get("/exportinp/", response_model=None) async def fastapi_export_inp(network: str, version: str) -> ChangeSet: cs = export_inp(network, version) op = cs.operations[0] open_project(network) - op['vertex'] = json.dumps(get_all_vertices(network)) - op['scada'] = json.dumps(get_all_scada_elements(network)) - op['dma'] = json.dumps(get_all_district_metering_areas(network)) - op['sa'] = json.dumps(get_all_service_areas(network)) - op['vd'] = json.dumps(get_all_virtual_districts(network)) - op['legend'] = get_extension_data(network, 'legend') + op["vertex"] = json.dumps(get_all_vertices(network)) + op["scada"] = json.dumps(get_all_scada_elements(network)) + op["dma"] = json.dumps(get_all_district_metering_areas(network)) + op["sa"] = json.dumps(get_all_service_areas(network)) + op["vd"] = json.dumps(get_all_virtual_districts(network)) + op["legend"] = get_extension_data(network, "legend") - db = get_extension_data(network, 'scada_db') + db = get_extension_data(network, "scada_db") print(db) - scada_db = '' + scada_db = "" if db: scada_db = db print(scada_db) - op['scada_db'] = scada_db - + op["scada_db"] = scada_db + close_project(network) return cs + @app.post("/readinp/") async def fastapi_read_inp(network: str, inp: str) -> bool: read_inp(network, inp) return True + @app.get("/dumpinp/") async def fastapi_dump_inp(network: str, inp: str) -> bool: dump_inp(network, inp) return True + # 必须用这个PlainTextResponse,不然每个key都有引号 -@app.get("/runproject/", response_class = PlainTextResponse) +@app.get("/runproject/", response_class=PlainTextResponse) async def fastapi_run_project(network: str) -> str: lock_key = "exclusive_api_lock" timeout = 120 # 锁自动过期时间(秒) @@ -299,16 +337,17 @@ async def fastapi_run_project(network: str) -> str: acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout) if not acquired: - raise HTTPException(status_code=409, detail="is in simulation") + 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 和 report # output 是 json # report 是 text @app.get("/runprojectreturndict/") @@ -320,33 +359,38 @@ async def fastapi_run_project_return_dict(network: str) -> dict[str, Any]: acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout) if not acquired: - raise HTTPException(status_code=409, detail="is in simulation") + raise HTTPException(status_code=409, detail="is in simulation") else: try: return run_project_return_dict(network) finally: # 手动释放锁(可选,依赖过期时间自动释放更安全) - redis_client.delete(lock_key) - + redis_client.delete(lock_key) + + # put in inp folder, name without extension @app.get("/runinp/") async def fastapi_run_inp(network: str) -> str: return run_inp(network) + # path is absolute path @app.get("/dumpoutput/") async def fastapi_dump_output(output: str) -> str: return dump_output(output) + @app.get("/isprojectlocked/") async def fastapi_is_locked(network: str, req: Request): return str in lockedPrjs.keys() + @app.get("/isprojectlockedbyme/") async def fastapi_is_locked_by_me(network: str, req: Request): client_host = req.client.host return lockedPrjs.get(network) == client_host + # 0 successfully locked # 1 already locked by you # 2 locked by others @@ -362,6 +406,7 @@ async def fastapi_lock_project(network: str, req: Request): else: return 2 + @app.post("/unlockproject/") def fastapi_unlock_project(network: str, req: Request): client_host = req.client.host @@ -369,307 +414,380 @@ def fastapi_unlock_project(network: str, req: Request): print("delete key") del lockedPrjs[network] return True - + return False + ### operations -@app.get('/getcurrentoperationid/') + +@app.get("/getcurrentoperationid/") async def fastapi_get_current_operaiton_id(network: str) -> int: return get_current_operation(network) -@app.post('/undo/') + +@app.post("/undo/") async def fastapi_undo(network: str): return execute_undo(network) -@app.post('/redo/') + +@app.post("/redo/") async def fastapi_redo(network: str): return execute_redo(network) -@app.get('/getsnapshots/') + +@app.get("/getsnapshots/") def fastapi_list_snapshot(network: str) -> list[tuple[int, str]]: return list_snapshot(network) -@app.get('/havesnapshot/') + +@app.get("/havesnapshot/") async def fastapi_have_snapshot(network: str, tag: str) -> bool: return have_snapshot(network, tag) - -@app.get('/havesnapshotforoperation/') + + +@app.get("/havesnapshotforoperation/") async def fastapi_have_snapshot_for_operation(network: str, operation: int) -> bool: return have_snapshot_for_operation(network, operation) -@app.get('/havesnapshotforcurrentoperation/') + +@app.get("/havesnapshotforcurrentoperation/") async def fastapi_have_snapshot_for_current_operation(network: str) -> bool: return have_snapshot_for_current_operation(network) -@app.post('/takesnapshotforoperation/') -async def fastapi_take_snapshot_for_operation(network: str, operation: int, tag: str) -> None: + +@app.post("/takesnapshotforoperation/") +async def fastapi_take_snapshot_for_operation( + network: str, operation: int, tag: str +) -> None: return take_snapshot_for_operation(network, operation, tag) -@app.post('takenapshotforcurrentoperation') + +@app.post("takenapshotforcurrentoperation") async def fastapi_take_snapshot_for_current_operation(network: str, tag: str) -> None: return take_snapshot_for_current_operation(network, tag) - -@app.post('/takesnapshot/') + + +@app.post("/takesnapshot/") def fastapi_take_snapshot(network: str, tag: str) -> None: return take_snapshot(network, tag) -@app.post('/picksnapshot/',response_model=None) + +@app.post("/picksnapshot/", response_model=None) def fastapi_pick_snapshot(network: str, tag: str, discard: bool = False) -> ChangeSet: return pick_snapshot(network, tag, discard) -@app.post('/pickoperation/',response_model=None) -async def fastapi_pick_operation(network: str, operation: int, discard: bool = False) -> ChangeSet: + +@app.post("/pickoperation/", response_model=None) +async def fastapi_pick_operation( + network: str, operation: int, discard: bool = False +) -> ChangeSet: return pick_operation(network, operation, discard) -@app.get("/syncwithserver/",response_model=None) + +@app.get("/syncwithserver/", response_model=None) async def fastapi_sync_with_server(network: str, operation: int) -> ChangeSet: return sync_with_server(network, operation) -@app.post("/batch/",response_model=None) -async def fastapi_execute_batch_commands(network: str, req: Request)-> ChangeSet: + +@app.post("/batch/", response_model=None) +async def fastapi_execute_batch_commands(network: str, req: Request) -> ChangeSet: jo_root = await req.json() cs: ChangeSet = ChangeSet() - cs.operations = jo_root['operations'] + cs.operations = jo_root["operations"] rcs = execute_batch_commands(network, cs) return rcs -@app.post("/compressedbatch/",response_model=None) -async def fastapi_execute_compressed_batch_commands(network: str, req: Request)-> ChangeSet: + +@app.post("/compressedbatch/", response_model=None) +async def fastapi_execute_compressed_batch_commands( + network: str, req: Request +) -> ChangeSet: jo_root = await req.json() cs: ChangeSet = ChangeSet() - cs.operations = jo_root['operations'] + cs.operations = jo_root["operations"] return execute_batch_command(network, cs) + @app.get("/getrestoreoperation/") -async def fastapi_get_restore_operation(network : str) -> int: +async def fastapi_get_restore_operation(network: str) -> int: return get_restore_operation(network) + @app.post("/setrestoreoperation/") async def fastapi_set_restore_operation(network: str, operation: int) -> None: return set_restore_operation(network, operation) - + + ############################################################ # type ############################################################ -@app.get('/isnode/') + +@app.get("/isnode/") async def fastapi_is_node(network: str, node: str) -> bool: return is_node(network, node) -@app.get('/isjunction/') + +@app.get("/isjunction/") async def fastapi_is_junction(network: str, node: str) -> bool: return is_junction(network, node) -@app.get('/isreservoir/') + +@app.get("/isreservoir/") async def fastapi_is_reservoir(network: str, node: str) -> bool: return is_reservoir(network, node) -@app.get('/istank/') + +@app.get("/istank/") async def fastapi_is_tank(network: str, node: str) -> bool: return is_tank(network, node) -@app.get('/islink/') + +@app.get("/islink/") async def fastapi_is_link(network: str, link: str) -> bool: return is_link(network, link) -@app.get('/ispipe/') + +@app.get("/ispipe/") async def fastapi_is_pipe(network: str, link: str) -> bool: return is_pipe(network, link) -@app.get('/ispump/') + +@app.get("/ispump/") async def fastapi_is_pump(network: str, link: str) -> bool: return is_pump(network, link) -@app.get('/isvalve/') + +@app.get("/isvalve/") async def fastapi_is_valve(network: str, link: str) -> bool: return is_valve(network, link) -# DingZQ, 2025-02-05 -@app.get('/getnodetype/') -async def fastapi_get_node_type(network: str, node: str) -> str: - return get_node_type(network, node) -@app.get('/getlinktype/') +# DingZQ, 2025-02-05 +@app.get("/getnodetype/") +async def fastapi_get_node_type(network: str, node: str) -> str: + return get_node_type(network, node) + + +@app.get("/getlinktype/") async def fastapi_get_link_type(network: str, link: str) -> str: return get_link_type(network, link) -@app.get('/getelementtype/') + +@app.get("/getelementtype/") async def fastapi_get_element_type(network: str, element: str) -> str: return get_element_type(network, element) -@app.get('/getelementtypevalue/') + +@app.get("/getelementtypevalue/") async def fastapi_get_element_type_value(network: str, element: str) -> int: return get_element_type_value(network, element) -@app.get('/iscurve/') + +@app.get("/iscurve/") async def fastapi_is_curve(network: str, curve: str) -> bool: return is_curve(network, curve) -@app.get('/ispattern/') + +@app.get("/ispattern/") async def fastapi_is_pattern(network: str, pattern: str) -> bool: return is_pattern(network, pattern) + @app.get("/getnodes/") async def fastapi_get_nodes(network: str) -> list[str]: return get_nodes(network) + @app.get("/getlinks/") async def fastapi_get_links(network: str) -> list[str]: return get_links(network) + @app.get("/getcurves/") async def fastapi_get_curves(network: str) -> list[str]: return get_curves(network) + @app.get("/getpatterns/") async def fastapi_get_patterns(network: str) -> list[str]: return get_patterns(network) + @app.get("/getnodelinks/") def get_node_links(network: str, node: str) -> list[str]: return get_node_links(network, node) + ############################################################ # DingZQ, 2025-02-05 # 用统一的接口来获取 Node & Link properties, Node和Link的Id可以一样,不能进一步统一成获取Element 的 properties # Node & Link properties ############################################################ -@app.get('/getnodeproperties/') +@app.get("/getnodeproperties/") async def fast_get_node_properties(network: str, node: str) -> dict[str, Any]: return get_node_properties(network, node) -@app.get('/getlinkproperties/') + +@app.get("/getlinkproperties/") async def fast_get_link_properties(network: str, link: str) -> dict[str, Any]: return get_link_properties(network, link) -@app.get('/getscadaproperties/') + +@app.get("/getscadaproperties/") async def fast_get_scada_properties(network: str, scada: str) -> dict[str, Any]: return get_scada_info(network, scada) -@app.get('/getallscadaproperties/') + +@app.get("/getallscadaproperties/") async def fast_get_all_scada_properties(network: str) -> list[dict[str, Any]]: return get_all_scada_info(network) + # elementtype can be 'node' or 'link' or 'scada' -@app.get('/getelementpropertieswithtype/') -async def fast_get_element_properties_with_type(network: str, elementtype: str, element: str) -> dict[str, Any]: +@app.get("/getelementpropertieswithtype/") +async def fast_get_element_properties_with_type( + network: str, elementtype: str, element: str +) -> dict[str, Any]: return get_element_properties_with_type(network, elementtype, element) + # type can be 'node' or 'link' or 'scada' -@app.get('/getelementproperties/') +@app.get("/getelementproperties/") async def fast_get_element_properties(network: str, element: str) -> dict[str, Any]: return get_element_properties(network, element) + ############################################################ # title 1.[TITLE] ############################################################ -@app.get('/gettitleschema/') +@app.get("/gettitleschema/") async def fast_get_title_schema(network: str) -> dict[str, dict[str, Any]]: return get_title_schema(network) -@app.get('/gettitle/') + +@app.get("/gettitle/") async def fast_get_title(network: str) -> dict[str, Any]: return get_title(network) -@app.get('/settitle/',response_model=None) + +@app.get("/settitle/", response_model=None) async def fastapi_set_title(network: str, req: Request) -> ChangeSet: props = await req.json() return set_title(network, ChangeSet(props)) + ############################################################ # junction 2.[JUNCTIONS] ############################################################ -@app.get('/getjunctionschema') +@app.get("/getjunctionschema") async def fast_get_junction_schema(network: str) -> dict[str, dict[str, Any]]: return get_junction_schema(network) -@app.post("/addjunction/",response_model=None) -async def fastapi_add_junction(network: str, junction: str, x: float, y: float, z: float) -> ChangeSet: - ps = { 'id' : junction, - 'x' : x, - 'y' : y, - 'elevation' : z } + +@app.post("/addjunction/", response_model=None) +async def fastapi_add_junction( + network: str, junction: str, x: float, y: float, z: float +) -> ChangeSet: + ps = {"id": junction, "x": x, "y": y, "elevation": z} return add_junction(network, ChangeSet(ps)) -@app.post("/deletejunction/",response_model=None) + +@app.post("/deletejunction/", response_model=None) async def fastapi_delete_junction(network: str, junction: str) -> ChangeSet: - ps = {'id' : junction} + ps = {"id": junction} return delete_junction(network, ChangeSet(ps)) + @app.get("/getjunctionelevation/") async def fastapi_get_junction_elevation(network: str, junction: str) -> float: ps = get_junction(network, junction) - return ps['elevation'] + return ps["elevation"] + @app.get("/getjunctionx/") async def fastapi_get_junction_x(network: str, junction: str) -> float: ps = get_junction(network, junction) - return ps['x'] + return ps["x"] + @app.get("/getjunctiony/") async def fastapi_get_junction_x(network: str, junction: str) -> float: ps = get_junction(network, junction) - return ps['y'] + return ps["y"] + @app.get("/getjunctioncoord/") async def fastapi_get_junction_coord(network: str, junction: str) -> dict[str, float]: ps = get_junction(network, junction) - coord = { 'x' : ps['x'], - 'y' : ps['y'] } + coord = {"x": ps["x"], "y": ps["y"]} return coord + @app.get("/getjunctiondemand/") async def fastapi_get_junction_demand(network: str, junction: str) -> float: ps = get_junction(network, junction) - return ps['demand'] + return ps["demand"] + @app.get("/getjunctionpattern/") async def fastapi_get_junction_pattern(network: str, junction: str) -> str: ps = get_junction(network, junction) - return ps['pattern'] + return ps["pattern"] -@app.post("/setjunctionelevation/",response_model=None) -async def fastapi_set_junction_elevation(network: str, junction: str, elevation: float) -> ChangeSet: - ps = { 'id' : junction, - 'elevation' : elevation } + +@app.post("/setjunctionelevation/", response_model=None) +async def fastapi_set_junction_elevation( + network: str, junction: str, elevation: float +) -> ChangeSet: + ps = {"id": junction, "elevation": elevation} return set_junction(network, ChangeSet(ps)) -@app.post("/setjunctionx/",response_model=None) + +@app.post("/setjunctionx/", response_model=None) async def fastapi_set_junction_x(network: str, junction: str, x: float) -> ChangeSet: - ps = { 'id' : junction, - 'x' : x } + ps = {"id": junction, "x": x} return set_junction(network, ChangeSet(ps)) - -@app.post("/setjunctiony/",response_model=None) + + +@app.post("/setjunctiony/", response_model=None) async def fastapi_set_junction_y(network: str, junction: str, y: float) -> ChangeSet: - ps = { 'id' : junction, - 'y' : y } + ps = {"id": junction, "y": y} return set_junction(network, ChangeSet(ps)) -@app.post("/setjunctioncoord/",response_model=None) -async def fastapi_set_junction_coord(network: str, junction: str, x: float, y: float) -> ChangeSet: - ps = { 'id' : junction, - 'x' : x, - 'y' : y } - return set_junction(network, ChangeSet(ps)) - -@app.post("/setjunctiondemand/",response_model=None) -async def fastapi_set_junction_demand(network: str, junction: str, demand: float) -> ChangeSet: - ps = { 'id' : junction, - 'demand' : demand } + +@app.post("/setjunctioncoord/", response_model=None) +async def fastapi_set_junction_coord( + network: str, junction: str, x: float, y: float +) -> ChangeSet: + ps = {"id": junction, "x": x, "y": y} return set_junction(network, ChangeSet(ps)) -@app.post("/setjunctionpattern/",response_model=None) -async def fastapi_set_junction_pattern(network: str, junction: str, pattern: str) -> ChangeSet: - ps = { 'id' : junction, - 'pattern' : pattern } + +@app.post("/setjunctiondemand/", response_model=None) +async def fastapi_set_junction_demand( + network: str, junction: str, demand: float +) -> ChangeSet: + ps = {"id": junction, "demand": demand} return set_junction(network, ChangeSet(ps)) + +@app.post("/setjunctionpattern/", response_model=None) +async def fastapi_set_junction_pattern( + network: str, junction: str, pattern: str +) -> ChangeSet: + ps = {"id": junction, "pattern": pattern} + return set_junction(network, ChangeSet(ps)) + + @app.get("/getjunctionproperties/") -async def fastapi_get_junction_properties(network: str, junction: str) -> dict[str, Any]: +async def fastapi_get_junction_properties( + network: str, junction: str +) -> dict[str, Any]: return get_junction(network, junction) + # DingZQ, 2025-03-29 @app.get("/getalljunctionproperties/") async def fastapi_get_all_junction_properties(network: str) -> list[dict[str, Any]]: @@ -688,95 +806,117 @@ async def fastapi_get_all_junction_properties(network: str) -> list[dict[str, An return results -@app.post("/setjunctionproperties/",response_model=None) -async def fastapi_set_junction_properties(network: str, junction: str, req: Request) -> ChangeSet: +@app.post("/setjunctionproperties/", response_model=None) +async def fastapi_set_junction_properties( + network: str, junction: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : junction } | props + ps = {"id": junction} | props return set_junction(network, ChangeSet(ps)) + ############################################################ # reservoir 3.[RESERVOIRS] ############################################################ -@app.get('/getreservoirschema') +@app.get("/getreservoirschema") async def fast_get_reservoir_schema(network: str) -> dict[str, dict[str, Any]]: return get_reservoir_schema(network) -@app.post("/addreservoir/",response_model=None) -async def fastapi_add_reservoir(network: str, reservoir: str, x: float, y: float, head: float) -> ChangeSet: - ps = { 'id' : reservoir, - 'x' : x, - 'y' : y, - 'head' : head } - return add_reservoir(network, ChangeSet(ps)) -@app.post("/deletereservoir/",response_model=None) +@app.post("/addreservoir/", response_model=None) +async def fastapi_add_reservoir( + network: str, reservoir: str, x: float, y: float, head: float +) -> ChangeSet: + ps = {"id": reservoir, "x": x, "y": y, "head": head} + return add_reservoir(network, ChangeSet(ps)) + + +@app.post("/deletereservoir/", response_model=None) async def fastapi_delete_reservoir(network: str, reservoir: str) -> ChangeSet: - ps = { 'id' : reservoir } + ps = {"id": reservoir} return delete_reservoir(network, ChangeSet(ps)) + @app.get("/getreservoirhead/") async def fastapi_get_reservoir_head(network: str, reservoir: str) -> float | None: ps = get_reservoir(network, reservoir) - return ps['head'] + return ps["head"] + @app.get("/getreservoirpattern/") async def fastapi_get_reservoir_pattern(network: str, reservoir: str) -> str | None: ps = get_reservoir(network, reservoir) - return ps['pattern'] + return ps["pattern"] + @app.get("/getreservoirx/") -async def fastapi_get_reservoir_x(network: str, reservoir: str) -> dict[str, float] | None: +async def fastapi_get_reservoir_x( + network: str, reservoir: str +) -> dict[str, float] | None: ps = get_reservoir(network, reservoir) - return ps['x'] + return ps["x"] + @app.get("/getreservoiry/") -async def fastapi_get_reservoir_y(network: str, reservoir: str) -> dict[str, float] | None: +async def fastapi_get_reservoir_y( + network: str, reservoir: str +) -> dict[str, float] | None: ps = get_reservoir(network, reservoir) - return ps['y'] + return ps["y"] + @app.get("/getreservoircoord/") -async def fastapi_get_reservoir_y(network: str, reservoir: str) -> dict[str, float] | None: +async def fastapi_get_reservoir_y( + network: str, reservoir: str +) -> dict[str, float] | None: ps = get_reservoir(network, reservoir) - coord = { 'id' : reservoir, - 'x' : ps['x'], - 'y' : ps['y'] } + coord = {"id": reservoir, "x": ps["x"], "y": ps["y"]} return coord -@app.post("/setreservoirhead/",response_model=None) -async def fastapi_set_reservoir_head(network: str, reservoir: str, head: float) -> ChangeSet: - ps = { 'id' : reservoir, - 'head' : head } + +@app.post("/setreservoirhead/", response_model=None) +async def fastapi_set_reservoir_head( + network: str, reservoir: str, head: float +) -> ChangeSet: + ps = {"id": reservoir, "head": head} return set_reservoir(network, ChangeSet(ps)) -@app.post("/setreservoirpattern/",response_model=None) -async def fastapi_set_reservoir_pattern(network: str, reservoir: str, pattern: str) -> ChangeSet: - ps = { 'id' : reservoir, - 'pattern' : pattern } + +@app.post("/setreservoirpattern/", response_model=None) +async def fastapi_set_reservoir_pattern( + network: str, reservoir: str, pattern: str +) -> ChangeSet: + ps = {"id": reservoir, "pattern": pattern} return set_reservoir(network, ChangeSet(ps)) -@app.post("/setreservoirx/",response_model=None) + +@app.post("/setreservoirx/", response_model=None) async def fastapi_set_reservoir_x(network: str, reservoir: str, x: float) -> ChangeSet: - ps = { 'id' : reservoir, - 'x' : x } + ps = {"id": reservoir, "x": x} return set_reservoir(network, ChangeSet(ps)) -@app.post("/setreservoirx/",response_model=None) + +@app.post("/setreservoirx/", response_model=None) async def fastapi_set_reservoir_y(network: str, reservoir: str, y: float) -> ChangeSet: - ps = { 'id' : reservoir, - 'y' : y } + ps = {"id": reservoir, "y": y} return set_reservoir(network, ChangeSet(ps)) -@app.post("/setreservoircoord/",response_model=None) -async def fastapi_set_reservoir_y(network: str, reservoir: str, x: float, y: float) -> ChangeSet: - ps = { 'id' : reservoir, - 'x' : x, - 'y' : y } + +@app.post("/setreservoircoord/", response_model=None) +async def fastapi_set_reservoir_y( + network: str, reservoir: str, x: float, y: float +) -> ChangeSet: + ps = {"id": reservoir, "x": x, "y": y} return set_reservoir(network, ChangeSet(ps)) + @app.get("/getreservoirproperties/") -async def fastapi_get_reservoir_properties(network: str, reservoir: str) -> dict[str, Any]: +async def fastapi_get_reservoir_properties( + network: str, reservoir: str +) -> dict[str, Any]: return get_reservoir(network, reservoir) + # DingZQ, 2025-03-29 @app.get("/getallreservoirproperties/") async def fastapi_get_all_reservoir_properties(network: str) -> list[dict[str, Any]]: @@ -795,168 +935,212 @@ async def fastapi_get_all_reservoir_properties(network: str) -> list[dict[str, A return results -@app.post("/setreservoirproperties/",response_model=None) -async def fastapi_set_reservoir_properties(network: str, reservoir: str - , req: Request) -> ChangeSet: +@app.post("/setreservoirproperties/", response_model=None) +async def fastapi_set_reservoir_properties( + network: str, reservoir: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : reservoir } | props + ps = {"id": reservoir} | props return set_reservoir(network, ChangeSet(ps)) ############################################################ # tank 4.[TANKS] ############################################################ -@app.get('/gettankschema') +@app.get("/gettankschema") async def fast_get_tank_schema(network: str) -> dict[str, dict[str, Any]]: return get_tank_schema(network) -@app.post("/addtank/",response_model=None) -async def fastapi_add_tank(network: str, tank: str, x: float, y: float, elevation: float, init_level: float = 0, min_level: float = 0, max_level: float = 0, diameter: float = 0, min_vol: float = 0) -> ChangeSet: - ps = { 'id' : tank, - 'x' : x, - 'y' : y, - 'elevation' : elevation, - 'init_level' : init_level, - 'min_level' : min_level, - 'max_level' : max_level, - 'diameter' : diameter, - 'min_vol' : min_vol - } - return add_tank(network, ChangeSet(ps)) -@app.post("/deletetank/",response_model=None) +@app.post("/addtank/", response_model=None) +async def fastapi_add_tank( + network: str, + tank: str, + x: float, + y: float, + elevation: float, + init_level: float = 0, + min_level: float = 0, + max_level: float = 0, + diameter: float = 0, + min_vol: float = 0, +) -> ChangeSet: + ps = { + "id": tank, + "x": x, + "y": y, + "elevation": elevation, + "init_level": init_level, + "min_level": min_level, + "max_level": max_level, + "diameter": diameter, + "min_vol": min_vol, + } + return add_tank(network, ChangeSet(ps)) + + +@app.post("/deletetank/", response_model=None) async def fastapi_delete_tank(network: str, tank: str) -> ChangeSet: - ps = { 'id' : tank } + ps = {"id": tank} return delete_tank(network, ChangeSet(ps)) + @app.get("/gettankelevation/") async def fastapi_get_tank_elevation(network: str, tank: str) -> float | None: ps = get_tank(network, tank) - return ps['elevation'] + return ps["elevation"] + @app.get("/gettankinitlevel/") async def fastapi_get_tank_init_level(network: str, tank: str) -> float | None: ps = get_tank(network, tank) - return ps['init_level'] + return ps["init_level"] + @app.get("/gettankminlevel/") async def fastapi_get_tank_min_level(network: str, tank: str) -> float | None: ps = get_tank(network, tank) - return ps['min_level'] + return ps["min_level"] + @app.get("/gettankmaxlevel/") async def fastapi_get_tank_max_level(network: str, tank: str) -> float | None: ps = get_tank(network, tank) - return ps['max_level'] + return ps["max_level"] + @app.get("/gettankdiameter/") async def fastapi_get_tank_diameter(network: str, tank: str) -> float | None: ps = get_tank(network, tank) - return ps['diameter'] + return ps["diameter"] + @app.get("/gettankminvol/") async def fastapi_get_tank_min_vol(network: str, tank: str) -> float | None: ps = get_tank(network, tank) - return ps['min_vol'] + return ps["min_vol"] + @app.get("/gettankvolcurve/") async def fastapi_get_tank_vol_curve(network: str, tank: str) -> str | None: ps = get_tank(network, tank) - return ps['vol_curve'] + return ps["vol_curve"] + @app.get("/gettankoverflow/") async def fastapi_get_tank_overflow(network: str, tank: str) -> str | None: ps = get_tank(network, tank) - return ps['overflow'] + return ps["overflow"] + @app.get("/gettankx/") async def fastapi_get_tank_x(network: str, tank: str) -> float: ps = get_tank(network, tank) - return ps['x'] + return ps["x"] + @app.get("/gettanky/") async def fastapi_get_tank_x(network: str, tank: str) -> float: ps = get_tank(network, tank) - return ps['y'] + return ps["y"] + @app.get("/gettankcoord/") async def fastapi_get_tank_coord(network: str, tank: str) -> dict[str, float]: ps = get_tank(network, tank) - coord = { 'x' : ps['x'], - 'y' : ps['y'] } + coord = {"x": ps["x"], "y": ps["y"]} return coord -@app.post("/settankelevation/",response_model=None) -async def fastapi_set_tank_elevation(network: str, tank: str, elevation: float) -> ChangeSet: - ps = { 'id' : tank, - 'elevation' : elevation } + +@app.post("/settankelevation/", response_model=None) +async def fastapi_set_tank_elevation( + network: str, tank: str, elevation: float +) -> ChangeSet: + ps = {"id": tank, "elevation": elevation} return set_tank(network, ChangeSet(ps)) -@app.post("/settankinitlevel/",response_model=None) -async def fastapi_set_tank_init_level(network: str, tank: str, init_level: float) -> ChangeSet: - ps = { 'id' : tank, - 'init_level' : init_level } + +@app.post("/settankinitlevel/", response_model=None) +async def fastapi_set_tank_init_level( + network: str, tank: str, init_level: float +) -> ChangeSet: + ps = {"id": tank, "init_level": init_level} return set_tank(network, ChangeSet(ps)) -@app.post("/settankminlevel/",response_model=None) -async def fastapi_set_tank_min_level(network: str, tank: str, min_level: float) -> ChangeSet: - ps = { 'id' : tank, - 'min_level' : min_level } + +@app.post("/settankminlevel/", response_model=None) +async def fastapi_set_tank_min_level( + network: str, tank: str, min_level: float +) -> ChangeSet: + ps = {"id": tank, "min_level": min_level} return set_tank(network, ChangeSet(ps)) -@app.post("/settankmaxlevel/",response_model=None) -async def fastapi_set_tank_max_level(network: str, tank: str, max_level: float) -> ChangeSet: - ps = { 'id' : tank, - 'max_level' : max_level } + +@app.post("/settankmaxlevel/", response_model=None) +async def fastapi_set_tank_max_level( + network: str, tank: str, max_level: float +) -> ChangeSet: + ps = {"id": tank, "max_level": max_level} return set_tank(network, ChangeSet(ps)) -@app.post("settankdiameter//",response_model=None) -async def fastapi_set_tank_diameter(network: str, tank: str, diameter: float) -> ChangeSet: - ps = { 'id' : tank, - 'diameter' : diameter } + +@app.post("settankdiameter//", response_model=None) +async def fastapi_set_tank_diameter( + network: str, tank: str, diameter: float +) -> ChangeSet: + ps = {"id": tank, "diameter": diameter} return set_tank(network, ChangeSet(ps)) -@app.post("/settankminvol/",response_model=None) -async def fastapi_set_tank_min_vol(network: str, tank: str, min_vol: float) -> ChangeSet: - ps = { 'id' : tank, - 'min_vol' : min_vol } + +@app.post("/settankminvol/", response_model=None) +async def fastapi_set_tank_min_vol( + network: str, tank: str, min_vol: float +) -> ChangeSet: + ps = {"id": tank, "min_vol": min_vol} return set_tank(network, ChangeSet(ps)) -@app.post("/settankvolcurve/",response_model=None) -async def fastapi_set_tank_vol_curve(network: str, tank: str, vol_curve: str) -> ChangeSet: - ps = { 'id' : tank, - 'vol_curve' : vol_curve} + +@app.post("/settankvolcurve/", response_model=None) +async def fastapi_set_tank_vol_curve( + network: str, tank: str, vol_curve: str +) -> ChangeSet: + ps = {"id": tank, "vol_curve": vol_curve} return set_tank(network, ChangeSet(ps)) -@app.post("/settankoverflow/",response_model=None) -async def fastapi_set_tank_overflow(network: str, tank: str, overflow: str) -> ChangeSet: - ps = { 'id' : tank, - 'overflow' : overflow } + +@app.post("/settankoverflow/", response_model=None) +async def fastapi_set_tank_overflow( + network: str, tank: str, overflow: str +) -> ChangeSet: + ps = {"id": tank, "overflow": overflow} return set_tank(network, ChangeSet(ps)) -@app.post("/settankx/",response_model=None) + +@app.post("/settankx/", response_model=None) async def fastapi_set_tank_x(network: str, tank: str, x: float) -> ChangeSet: - ps = { 'id' : tank, - 'x' : x } + ps = {"id": tank, "x": x} return set_tank(network, ChangeSet(ps)) -@app.post("/settanky/",response_model=None) + +@app.post("/settanky/", response_model=None) async def fastapi_set_tank_y(network: str, tank: str, y: float) -> ChangeSet: - ps = { 'id' : tank, - 'y' : y } + ps = {"id": tank, "y": y} return set_tank(network, ChangeSet(ps)) -@app.post("/settankcoord/",response_model=None) -async def fastapi_set_tank_coord(network: str, tank: str, x: float, y: float) -> ChangeSet: - ps = { 'id' : tank, - 'x' : x, - 'y' : y } + +@app.post("/settankcoord/", response_model=None) +async def fastapi_set_tank_coord( + network: str, tank: str, x: float, y: float +) -> ChangeSet: + ps = {"id": tank, "x": x, "y": y} return set_tank(network, ChangeSet(ps)) + @app.get("/gettankproperties/") async def fastapi_get_tank_properties(network: str, tank: str) -> dict[str, Any]: return get_tank(network, tank) + # DingZQ, 2025-03-29 @app.get("/getalltankproperties/") async def fastapi_get_all_tank_properties(network: str) -> list[dict[str, Any]]: @@ -974,112 +1158,142 @@ async def fastapi_get_all_tank_properties(network: str) -> list[dict[str, Any]]: return results -@app.post("/settankproperties/",response_model=None) -async def fastapi_set_tank_properties(network: str, tank: str, req: Request) -> ChangeSet: + +@app.post("/settankproperties/", response_model=None) +async def fastapi_set_tank_properties( + network: str, tank: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : tank } | props - return set_tank(network, ChangeSet(ps)) + ps = {"id": tank} | props + return set_tank(network, ChangeSet(ps)) + ############################################################ # pipe 4.[PIPES] ############################################################ -@app.get('/getpipeschema') +@app.get("/getpipeschema") async def fastapi_get_pipe_schema(network: str) -> dict[str, dict[str, Any]]: return get_pipe_schema(network) -@app.post("/addpipe/",response_model=None) -async def fastapi_add_pipe(network: str, pipe: str, node1: str, node2: str, length: float = 0, - diameter: float = 0, roughness: float = 0, minor_loss: float = 0, status: str = PIPE_STATUS_OPEN) -> ChangeSet: - ps = { 'id' : pipe, - 'node1' : node1, - 'node2' : node2, - 'length' : length, - 'diameter' : diameter, - 'roughness' : roughness, - 'minor_loss' : minor_loss, - 'status' : status } + +@app.post("/addpipe/", response_model=None) +async def fastapi_add_pipe( + network: str, + pipe: str, + node1: str, + node2: str, + length: float = 0, + diameter: float = 0, + roughness: float = 0, + minor_loss: float = 0, + status: str = PIPE_STATUS_OPEN, +) -> ChangeSet: + ps = { + "id": pipe, + "node1": node1, + "node2": node2, + "length": length, + "diameter": diameter, + "roughness": roughness, + "minor_loss": minor_loss, + "status": status, + } return add_pipe(network, ChangeSet(ps)) -@app.post("/deletepipe/",response_model=None) + +@app.post("/deletepipe/", response_model=None) async def fastapi_delete_pipe(network: str, pipe: str) -> ChangeSet: - ps = {'id' : pipe} + ps = {"id": pipe} return delete_pipe(network, ChangeSet(ps)) + @app.get("/getpipenode1/") async def fastapi_get_pipe_node1(network: str, pipe: str) -> str | None: ps = get_pipe(network, pipe) - return ps['node1'] + return ps["node1"] + @app.get("/getpipenode2/") async def fastapi_get_pipe_node2(network: str, pipe: str) -> str | None: ps = get_pipe(network, pipe) - return ps['node2'] + return ps["node2"] + @app.get("/getpipelength/") async def fastapi_get_pipe_length(network: str, pipe: str) -> float | None: ps = get_pipe(network, pipe) - return ps['length'] + return ps["length"] + @app.get("/getpipediameter/") async def fastapi_get_pipe_diameter(network: str, pipe: str) -> float | None: ps = get_pipe(network, pipe) - return ps['diameter'] + return ps["diameter"] + @app.get("/getpiperoughness/") async def fastapi_get_pipe_roughness(network: str, pipe: str) -> float | None: ps = get_pipe(network, pipe) - return ps['roughness'] + return ps["roughness"] + @app.get("/getpipeminorloss/") async def fastapi_get_pipe_minor_loss(network: str, pipe: str) -> float | None: ps = get_pipe(network, pipe) - return ps['minor_loss'] + return ps["minor_loss"] + @app.get("/getpipestatus/") async def fastapi_get_pipe_status(network: str, pipe: str) -> str | None: ps = get_pipe(network, pipe) - return ps['status'] + return ps["status"] -@app.post("/setpipenode1/",response_model=None) + +@app.post("/setpipenode1/", response_model=None) async def fastapi_set_pipe_node1(network: str, pipe: str, node1: str) -> ChangeSet: - ps = { 'id' : pipe, - 'node1' : node1 } + ps = {"id": pipe, "node1": node1} return set_pipe(network, ChangeSet(ps)) -@app.post("/setpipenode2/",response_model=None) + +@app.post("/setpipenode2/", response_model=None) async def fastapi_set_pipe_node2(network: str, pipe: str, node2: str) -> ChangeSet: - ps = { 'id' : pipe, - 'node2' : node2 } + ps = {"id": pipe, "node2": node2} return set_pipe(network, ChangeSet(ps)) -@app.post("/setpipelength/",response_model=None) + +@app.post("/setpipelength/", response_model=None) async def fastapi_set_pipe_length(network: str, pipe: str, length: float) -> ChangeSet: - ps = { 'id' : pipe, - 'length' : length } + ps = {"id": pipe, "length": length} return set_pipe(network, ChangeSet(ps)) -@app.post("/setpipediameter/",response_model=None) -async def fastapi_set_pipe_diameter(network: str, pipe: str, diameter: float) -> ChangeSet: - ps = { 'id' : pipe, - 'diameter' : diameter } + +@app.post("/setpipediameter/", response_model=None) +async def fastapi_set_pipe_diameter( + network: str, pipe: str, diameter: float +) -> ChangeSet: + ps = {"id": pipe, "diameter": diameter} return set_pipe(network, ChangeSet(ps)) -@app.post("/setpiperoughness/",response_model=None) -async def fastapi_set_pipe_roughness(network: str, pipe: str, roughness: float) -> ChangeSet: - ps = { 'id' : pipe, - 'roughness' : roughness } + +@app.post("/setpiperoughness/", response_model=None) +async def fastapi_set_pipe_roughness( + network: str, pipe: str, roughness: float +) -> ChangeSet: + ps = {"id": pipe, "roughness": roughness} return set_pipe(network, ChangeSet(ps)) -@app.post("/setpipeminorloss/",response_model=None) -async def fastapi_set_pipe_minor_loss(network: str, pipe: str, minor_loss: float) -> ChangeSet: - ps = { 'id' : pipe, - 'minor_loss' : minor_loss } + +@app.post("/setpipeminorloss/", response_model=None) +async def fastapi_set_pipe_minor_loss( + network: str, pipe: str, minor_loss: float +) -> ChangeSet: + ps = {"id": pipe, "minor_loss": minor_loss} return set_pipe(network, ChangeSet(ps)) -@app.post("/setpipestatus/",response_model=None) + +@app.post("/setpipestatus/", response_model=None) async def fastapi_set_pipe_status(network: str, pipe: str, status: str) -> ChangeSet: - ps = { 'id' : pipe, - 'status' : status } + ps = {"id": pipe, "status": status} print(status) print(ps) @@ -1088,12 +1302,14 @@ async def fastapi_set_pipe_status(network: str, pipe: str, status: str) -> Chang print(ret) return ret + @app.get("/getpipeproperties/") async def fastapi_get_pipe_properties(network: str, pipe: str) -> dict[str, Any]: return get_pipe(network, pipe) + # DingZQ, 2025-03-29 -@app.get('/getallpipeproperties/') +@app.get("/getallpipeproperties/") async def fastapi_get_all_pipe_properties(network: str) -> list[dict[str, Any]]: # 缓存查询结果提高性能 global redis_client @@ -1110,62 +1326,68 @@ async def fastapi_get_all_pipe_properties(network: str) -> list[dict[str, Any]]: return results -@app.post("/setpipeproperties/",response_model=None) -async def fastapi_set_pipe_properties(network: str, pipe: str, req: Request) -> ChangeSet: +@app.post("/setpipeproperties/", response_model=None) +async def fastapi_set_pipe_properties( + network: str, pipe: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : pipe } | props + ps = {"id": pipe} | props return set_pipe(network, ChangeSet(ps)) - + ############################################################ # pump 4.[PUMPS] ############################################################ -@app.get('/getpumpschema') +@app.get("/getpumpschema") async def fastapi_get_pump_schema(network: str) -> dict[str, dict[str, Any]]: return get_pump_schema(network) -@app.post("/addpump/",response_model=None) -async def fastapi_add_pump(network: str, pump: str, node1: str, node2: str, power: float = 0.0) -> ChangeSet: - ps = { 'id' : pump, - 'node1' : node1, - 'node2' : node2, - 'power' : power - } + +@app.post("/addpump/", response_model=None) +async def fastapi_add_pump( + network: str, pump: str, node1: str, node2: str, power: float = 0.0 +) -> ChangeSet: + ps = {"id": pump, "node1": node1, "node2": node2, "power": power} return add_pump(network, ChangeSet(ps)) -@app.post("/deletepump/",response_model=None) + +@app.post("/deletepump/", response_model=None) async def fastapi_delete_pump(network: str, pump: str) -> ChangeSet: - ps = { 'id' : pump } - return delete_pump(network, ChangeSet(ps)) + ps = {"id": pump} + return delete_pump(network, ChangeSet(ps)) + @app.get("/getpumpnode1/") async def fastapi_get_pump_node1(network: str, pump: str) -> str | None: ps = get_pump(network, pump) - return ps['node1'] + return ps["node1"] + @app.get("/getpumpnode2/") async def fastapi_get_pump_node2(network: str, pump: str) -> str | None: ps = get_pump(network, pump) - return ps['node2'] + return ps["node2"] -@app.post("/setpumpnode1/",response_model=None) + +@app.post("/setpumpnode1/", response_model=None) async def fastapi_set_pump_node1(network: str, pump: str, node1: str) -> ChangeSet: - ps = { 'id' : pump, - 'node1' : node1 } + ps = {"id": pump, "node1": node1} return set_pump(network, ChangeSet(ps)) -@app.post("/setpumpnode2/",response_model=None) + +@app.post("/setpumpnode2/", response_model=None) async def fastapi_set_pump_node2(network: str, pump: str, node2: str) -> ChangeSet: - ps = { 'id' : pump, - 'node2' : node2 } + ps = {"id": pump, "node2": node2} return set_pump(network, ChangeSet(ps)) + @app.get("/getpumpproperties/") async def fastapi_get_pump_properties(network: str, pump: str) -> dict[str, Any]: return get_pump(network, pump) + # DingZQ, 2025-03-29 -@app.get('/getallpumpproperties/') +@app.get("/getallpumpproperties/") async def fastapi_get_all_pump_properties(network: str) -> list[dict[str, Any]]: # 缓存查询结果提高性能 global redis_client @@ -1181,103 +1403,131 @@ async def fastapi_get_all_pump_properties(network: str) -> list[dict[str, Any]]: return results -@app.post("/setpumpproperties/",response_model=None) -async def fastapi_set_pump_properties(network: str, pump: str, req: Request) -> ChangeSet: + +@app.post("/setpumpproperties/", response_model=None) +async def fastapi_set_pump_properties( + network: str, pump: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : pump } | props - return set_pump(network, ChangeSet(ps)) + ps = {"id": pump} | props + return set_pump(network, ChangeSet(ps)) ############################################################ # valve 4.[VALVES] ############################################################ -@app.get('/getvalveschema') +@app.get("/getvalveschema") async def fastapi_get_valve_schema(network: str) -> dict[str, dict[str, Any]]: return get_valve_schema(network) -@app.post("/addvalve/",response_model=None) -async def fastapi_add_valve(network: str, valve: str, node1: str, node2: str, diameter: float = 0, v_type: str = VALVES_TYPE_PRV, setting: float = 0, minor_loss: float = 0) -> ChangeSet: - ps = { 'id' : valve, - 'node1' : node1, - 'node2' : node2, - 'diameter' : diameter, - 'v_type' : v_type, - 'setting' : setting, - 'minor_loss' : minor_loss } - - return add_valve(network, ChangeSet(ps)) -@app.post("/deletevalve/",response_model=None) +@app.post("/addvalve/", response_model=None) +async def fastapi_add_valve( + network: str, + valve: str, + node1: str, + node2: str, + diameter: float = 0, + v_type: str = VALVES_TYPE_PRV, + setting: float = 0, + minor_loss: float = 0, +) -> ChangeSet: + ps = { + "id": valve, + "node1": node1, + "node2": node2, + "diameter": diameter, + "v_type": v_type, + "setting": setting, + "minor_loss": minor_loss, + } + + return add_valve(network, ChangeSet(ps)) + + +@app.post("/deletevalve/", response_model=None) async def fastapi_delete_valve(network: str, valve: str) -> ChangeSet: - ps = { 'id' : valve } - return delete_valve(network, ChangeSet(ps)) + ps = {"id": valve} + return delete_valve(network, ChangeSet(ps)) + @app.get("/getvalvenode1/") async def fastapi_get_valve_node1(network: str, valve: str) -> str | None: ps = get_valve(network, valve) - return ps['node1'] + return ps["node1"] + @app.get("/getvalvenode2/") async def fastapi_get_valve_node2(network: str, valve: str) -> str | None: ps = get_valve(network, valve) - return ps['node2'] + return ps["node2"] + @app.get("/getvalvediameter/") async def fastapi_get_valve_diameter(network: str, valve: str) -> float | None: ps = get_valve(network, valve) - return ps['diameter'] + return ps["diameter"] + @app.get("/getvalvetype/") async def fastapi_get_valve_type(network: str, valve: str) -> str | None: ps = get_valve(network, valve) - return ps['type'] + return ps["type"] + @app.get("/getvalvesetting/") async def fastapi_get_valve_setting(network: str, valve: str) -> float | None: ps = get_valve(network, valve) - return ps['setting'] + return ps["setting"] + @app.get("/getvalveminorloss/") async def fastapi_get_valve_minor_loss(network: str, valve: str) -> float | None: ps = get_valve(network, valve) - return ps['minor_loss'] + return ps["minor_loss"] -@app.post("/setvalvenode1/",response_model=None) + +@app.post("/setvalvenode1/", response_model=None) async def fastapi_set_valve_node1(network: str, valve: str, node1: str) -> ChangeSet: - ps = { 'id' : valve, - 'node1' : node1 } + ps = {"id": valve, "node1": node1} return set_valve(network, ChangeSet(ps)) -@app.post("/setvalvenode2/",response_model=None) + +@app.post("/setvalvenode2/", response_model=None) async def fastapi_set_valve_node2(network: str, valve: str, node2: str) -> ChangeSet: - ps = { 'id' : valve, - 'node2' : node2 } + ps = {"id": valve, "node2": node2} return set_valve(network, ChangeSet(ps)) -@app.post("/setvalvenodediameter/",response_model=None) -async def fastapi_set_valve_diameter(network: str, valve: str, diameter: float) -> ChangeSet: - ps = { 'id' : valve, - 'diameter' : diameter } + +@app.post("/setvalvenodediameter/", response_model=None) +async def fastapi_set_valve_diameter( + network: str, valve: str, diameter: float +) -> ChangeSet: + ps = {"id": valve, "diameter": diameter} return set_valve(network, ChangeSet(ps)) -@app.post("/setvalvetype/",response_model=None) + +@app.post("/setvalvetype/", response_model=None) async def fastapi_set_valve_type(network: str, valve: str, type: str) -> ChangeSet: - ps = { 'id' : valve, - 'type' : type } + ps = {"id": valve, "type": type} return set_valve(network, ChangeSet(ps)) -@app.post("/setvalvesetting/",response_model=None) -async def fastapi_set_valve_setting(network: str, valve: str, setting: float) -> ChangeSet: - ps = { 'id' : valve, - 'setting' : setting } + +@app.post("/setvalvesetting/", response_model=None) +async def fastapi_set_valve_setting( + network: str, valve: str, setting: float +) -> ChangeSet: + ps = {"id": valve, "setting": setting} return set_valve(network, ChangeSet(ps)) + @app.get("/getvalveproperties/") async def fastapi_get_valve_properties(network: str, valve: str) -> dict[str, Any]: return get_valve(network, valve) + # DingZQ, 2025-03-29 -@app.get('/getallvalveproperties/') +@app.get("/getallvalveproperties/") async def fastapi_get_all_valve_properties(network: str) -> list[dict[str, Any]]: # 缓存查询结果提高性能 global redis_client @@ -1293,27 +1543,31 @@ async def fastapi_get_all_valve_properties(network: str) -> list[dict[str, Any]] return results -@app.post("/setvalveproperties/",response_model=None) -async def fastapi_set_valve_properties(network: str, valve: str, req: Request) -> ChangeSet: + +@app.post("/setvalveproperties/", response_model=None) +async def fastapi_set_valve_properties( + network: str, valve: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : valve } | props - return set_valve(network, ChangeSet(ps)) - - + ps = {"id": valve} | props + return set_valve(network, ChangeSet(ps)) + + # node & link -@app.post("/deletenode/",response_model=None) +@app.post("/deletenode/", response_model=None) async def fastapi_delete_node(network: str, node: str) -> ChangeSet: - ps = {'id' : node} + ps = {"id": node} if is_junction(network, node): return delete_junction(network, ChangeSet(ps)) elif is_reservoir(network, node): return delete_reservoir(network, ChangeSet(ps)) elif is_tank(network, node): return delete_tank(network, ChangeSet(ps)) - -@app.post("/deletelink/",response_model=None) + + +@app.post("/deletelink/", response_model=None) async def fastapi_delete_link(network: str, link: str) -> ChangeSet: - ps = {'id' : link} + ps = {"id": link} if is_pipe(network, link): return delete_pipe(network, ChangeSet(ps)) elif is_pump(network, link): @@ -1321,6 +1575,7 @@ async def fastapi_delete_link(network: str, link: str) -> ChangeSet: elif is_valve(network, link): return delete_valve(network, ChangeSet(ps)) + ############################################################ # tag 8.[TAGS] ############################################################ @@ -1329,150 +1584,181 @@ async def fastapi_delete_link(network: str, link: str) -> ChangeSet: # TAG_TYPE_LINK = api.TAG_TYPE_LINK # -@app.get('/gettagschema/') + +@app.get("/gettagschema/") async def fastapi_get_tag_schema(network: str) -> dict[str, dict[str, Any]]: return get_tag_schema(network) -@app.get('/gettag/') + +@app.get("/gettag/") async def fastapi_get_tag(network: str, t_type: str, id: str) -> dict[str, Any]: return get_tag(network, t_type, id) -@app.get('/gettags/') + +@app.get("/gettags/") async def fastapi_get_tags(network: str) -> list[dict[str, Any]]: tags = get_tags(network) print(tags) return tags + # example: # set_tag(p, ChangeSet({'t_type': TAG_TYPE_NODE, 'id': 'j1', 'tag': 'j1t' })) # set_tag(p, ChangeSet({'t_type': TAG_TYPE_LINK, 'id': 'p0', 'tag': 'p0t' })) -@app.post('/settag/',response_model=None) +@app.post("/settag/", response_model=None) async def fastapi_set_tag(network: str, req: Request) -> ChangeSet: props = await req.json() return set_tag(network, ChangeSet(props)) - + + ############################################################ # demand 9.[DEMANDS] ############################################################ -@app.get('/getdemandschema') +@app.get("/getdemandschema") async def fastapi_get_demand_schema(network: str) -> dict[str, dict[str, Any]]: return get_demand_schema(network) + @app.get("/getdemandproperties/") async def fastapi_get_demand_properties(network: str, junction: str) -> dict[str, Any]: return get_demand(network, junction) + # example: set_demand(p, ChangeSet({'junction': 'j1', 'demands': [{'demand': 10.0, 'pattern': None, 'category': 'x'}, {'demand': 20.0, 'pattern': None, 'category': None}]})) -@app.post("/setdemandproperties/",response_model=None) -async def fastapi_set_demand_properties(network: str, junction: str, req: Request) -> ChangeSet: +@app.post("/setdemandproperties/", response_model=None) +async def fastapi_set_demand_properties( + network: str, junction: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'junction' : junction } | props - return set_demand(network, ChangeSet(ps)) + ps = {"junction": junction} | props + return set_demand(network, ChangeSet(ps)) + ############################################################ # status 10.[STATUS] init_status ############################################################ -@app.get('/getstatusschema') +@app.get("/getstatusschema") async def fastapi_get_status_schema(network: str) -> dict[str, dict[str, Any]]: return get_status_schema(network) + @app.get("/getstatus/") async def fastapi_get_status(network: str, link: str) -> dict[str, Any]: return get_status(network, link) + # example: set_status(p, ChangeSet({'link': 'p0', 'status': LINK_STATUS_OPEN, 'setting': 10.0})) -@app.post("/setstatus/",response_model=None) -async def fastapi_set_status_properties(network: str, link: str, req: Request) -> ChangeSet: +@app.post("/setstatus/", response_model=None) +async def fastapi_set_status_properties( + network: str, link: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'link' : link } | props - return set_status(network, ChangeSet(ps)) + ps = {"link": link} | props + return set_status(network, ChangeSet(ps)) + ############################################################ # pattern 11.[PATTERNS] ############################################################ -@app.get('/getpatternschema') +@app.get("/getpatternschema") async def fastapi_get_pattern_schema(network: str) -> dict[str, dict[str, Any]]: return get_pattern_schema(network) -@app.post("/addpattern/",response_model=None) + +@app.post("/addpattern/", response_model=None) async def fastapi_add_pattern(network: str, pattern: str, req: Request) -> ChangeSet: props = await req.json() - ps = { - 'id' : pattern, - } | props + ps = { + "id": pattern, + } | props return add_pattern(network, ChangeSet(ps)) -@app.post("/deletepattern/",response_model=None) + +@app.post("/deletepattern/", response_model=None) async def fastapi_delete_pattern(network: str, pattern: str) -> ChangeSet: - ps = { 'id' : pattern } + ps = {"id": pattern} return delete_pattern(network, ChangeSet(ps)) + @app.get("/getpatternproperties/") async def fastapi_get_pattern_properties(network: str, pattern: str) -> dict[str, Any]: return get_pattern(network, pattern) + # example: set_pattern(p, ChangeSet({'id' : 'p0', 'factors': [1.0, 2.0, 3.0]})) -@app.post("/setpatternproperties/",response_model=None) -async def fastapi_set_pattern_properties(network: str, pattern: str, req: Request) -> ChangeSet: +@app.post("/setpatternproperties/", response_model=None) +async def fastapi_set_pattern_properties( + network: str, pattern: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : pattern } | props - return set_pattern(network, ChangeSet(ps)) + ps = {"id": pattern} | props + return set_pattern(network, ChangeSet(ps)) + ############################################################ # curve 12.[CURVES] ############################################################ -@app.get('/getcurveschema') +@app.get("/getcurveschema") async def fastapi_get_curve_schema(network: str) -> dict[str, dict[str, Any]]: return get_curve_schema(network) -@app.post("/addcurve/",response_model=None) + +@app.post("/addcurve/", response_model=None) async def fastapi_add_curve(network: str, curve: str, req: Request) -> ChangeSet: props = await req.json() print(props) - ps = { - 'id' : curve, - } | props - - print(ps) - - return add_curve(network, ChangeSet(ps)) + ps = { + "id": curve, + } | props -@app.post("/deletecurve/",response_model=None) + print(ps) + + return add_curve(network, ChangeSet(ps)) + + +@app.post("/deletecurve/", response_model=None) async def fastapi_delete_curve(network: str, curve: str) -> ChangeSet: - ps = { 'id' : curve } + ps = {"id": curve} return delete_curve(network, ChangeSet(ps)) + @app.get("/getcurveproperties/") async def fastapi_get_curve_properties(network: str, curve: str) -> dict[str, Any]: return get_curve(network, curve) + # example: set_curve(p, ChangeSet({'id' : 'c0', 'c_type' : CURVE_TYPE_PUMP, 'coords': [{'x': 1.0, 'y': 2.0}, {'x': 2.0, 'y': 1.0}]})) -@app.post("/setcurveproperties/",response_model=None) -async def fastapi_set_curve_properties(network: str, curve: str, req: Request) -> ChangeSet: +@app.post("/setcurveproperties/", response_model=None) +async def fastapi_set_curve_properties( + network: str, curve: str, req: Request +) -> ChangeSet: props = await req.json() # c_type放到request中 - ps = { 'id' : curve } | props - return set_curve(network, ChangeSet(ps)) + ps = {"id": curve} | props + return set_curve(network, ChangeSet(ps)) ############################################################ # control 13.[CONTROLS] ############################################################ -@app.get('/getcontrolschema/') +@app.get("/getcontrolschema/") async def fastapi_get_control_schema(network: str) -> dict[str, dict[str, Any]]: return get_control_schema(network) + @app.get("/getcontrolproperties/") async def fastapi_get_control_properties(network: str) -> dict[str, Any]: return get_control(network) + # example: set_control(p, ChangeSet({'control': 'x'})) -@app.post("/setcontrolproperties/",response_model=None) +@app.post("/setcontrolproperties/", response_model=None) async def fastapi_set_control_properties(network: str, req: Request) -> ChangeSet: props = await req.json() - return set_control(network, ChangeSet(props)) + return set_control(network, ChangeSet(props)) + ############################################################ # rule 14.[RULES] @@ -1481,12 +1767,14 @@ async def fastapi_set_control_properties(network: str, req: Request) -> ChangeSe async def fastapi_get_rule_schema(network: str) -> dict[str, dict[str, Any]]: return get_rule_schema(network) + @app.get("/getruleproperties/") async def fastapi_get_rule_properties(network: str) -> dict[str, Any]: return get_rule(network) + # example: set_rule(p, ChangeSet({'rule': 'x'})) -@app.post("/setruleproperties/",response_model=None) +@app.post("/setruleproperties/", response_model=None) async def fastapi_set_rule_properties(network: str, req: Request) -> ChangeSet: props = await req.json() return set_rule(network, ChangeSet(props)) @@ -1499,133 +1787,159 @@ async def fastapi_set_rule_properties(network: str, req: Request) -> ChangeSet: async def fastapi_get_energy_schema(network: str) -> dict[str, dict[str, Any]]: return get_energy_schema(network) + @app.get("/getenergyproperties/") async def fastapi_get_energy_properties(network: str) -> dict[str, Any]: return get_energy(network) -@app.post("/setenergyproperties/",response_model=None) + +@app.post("/setenergyproperties/", response_model=None) async def fastapi_set_energy_properties(network: str, req: Request) -> ChangeSet: props = await req.json() return set_energy(network, ChangeSet(props)) + @app.get("/getpumpenergyschema/") async def fastapi_get_pump_energy_schema(network: str) -> dict[str, dict[str, Any]]: return get_pump_energy_schema(network) + @app.get("/getpumpenergyproperties//") async def fastapi_get_pump_energy_proeprties(network: str, pump: str) -> dict[str, Any]: return get_pump_energy(network, pump) -@app.get("/setpumpenergyproperties//",response_model=None) -async def fastapi_set_pump_energy_properties(network: str, pump: str, req: Request) -> ChangeSet: + +@app.get("/setpumpenergyproperties//", response_model=None) +async def fastapi_set_pump_energy_properties( + network: str, pump: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'id' : pump } | props + ps = {"id": pump} | props return set_pump_energy(network, ChangeSet(ps)) + ############################################################ # emitter 16.[EMITTERS] ############################################################ -@app.get('/getemitterschema') +@app.get("/getemitterschema") async def fastapi_get_emitter_schema(network: str) -> dict[str, dict[str, Any]]: return get_emitter_schema(network) + @app.get("/getemitterproperties/") async def fastapi_get_emitter_properties(network: str, junction: str) -> dict[str, Any]: return get_emitter(network, junction) + # example: set_emitter(p, ChangeSet({'junction': 'j1', 'coefficient': 10.0})) -@app.post("/setemitterproperties/",response_model=None) -async def fastapi_set_emitter_properties(network: str, junction: str, req: Request) -> ChangeSet: +@app.post("/setemitterproperties/", response_model=None) +async def fastapi_set_emitter_properties( + network: str, junction: str, req: Request +) -> ChangeSet: props = await req.json() - ps = { 'junction' : junction } | props - return set_emitter(network, ChangeSet(ps)) + ps = {"junction": junction} | props + return set_emitter(network, ChangeSet(ps)) ############################################################ # quality 17.[QUALITY] ############################################################ -@app.get('/getqualityschema/') +@app.get("/getqualityschema/") async def fastapi_get_quality_schema(network: str) -> dict[str, dict[str, Any]]: return get_quality_schema(network) -@app.get('/getqualityproperties/') + +@app.get("/getqualityproperties/") async def fastapi_get_quality_properties(network: str, node: str) -> dict[str, Any]: return get_quality(network, node) + # example: set_quality(p, ChangeSet({'node': 'j1', 'quality': 10.0})) -@app.post("/setqualityproperties/",response_model=None) +@app.post("/setqualityproperties/", response_model=None) async def fastapi_set_quality_properties(network: str, req: Request) -> ChangeSet: props = await req.json() - return set_quality(network, ChangeSet(props)) - + return set_quality(network, ChangeSet(props)) + ############################################################ # source 18.[SOURCES] ############################################################ -@app.get('/getsourcechema/') +@app.get("/getsourcechema/") async def fastapi_get_source_schema(network: str) -> dict[str, dict[str, Any]]: return get_source_schema(network) -@app.get('/getsource/') + +@app.get("/getsource/") async def fastapi_get_source(network: str, node: str) -> dict[str, Any]: return get_source(network, node) -@app.post('/setsource/',response_model=None) + +@app.post("/setsource/", response_model=None) async def fastapi_set_source(network: str, req: Request) -> ChangeSet: props = await req.json() return set_source(network, ChangeSet(props)) + # example: add_source(p, ChangeSet({'node': 'j0', 's_type': SOURCE_TYPE_CONCEN, 'strength': 10.0, 'pattern': 'p0'})) -@app.post('/addsource/',response_model=None) +@app.post("/addsource/", response_model=None) async def fastapi_add_source(network: str, req: Request) -> ChangeSet: props = await req.json() return add_source(network, ChangeSet(props)) -@app.post('/deletesource/',response_model=None) + +@app.post("/deletesource/", response_model=None) async def fastapi_delete_source(network: str, node: str) -> ChangeSet: - props = { 'node': node } + props = {"node": node} return delete_source(network, ChangeSet(props)) ############################################################ # reaction 19.[REACTIONS] ############################################################ -@app.get('/getreactionschema/') +@app.get("/getreactionschema/") async def fastapi_get_reaction_schema(network: str) -> dict[str, dict[str, Any]]: return get_reaction_schema(network) -@app.get('/getreaction/') + +@app.get("/getreaction/") async def fastapi_get_reaction(network: str) -> dict[str, Any]: return get_reaction(network) -@app.post('/setreaction/',response_model=None) + +@app.post("/setreaction/", response_model=None) # set_reaction(p, ChangeSet({ 'ORDER BULK' : '10' })) async def fastapi_set_reaction(network: str, req: Request) -> ChangeSet: props = await req.json() return set_reaction(network, ChangeSet(props)) -@app.get('/getpipereactionschema/') + +@app.get("/getpipereactionschema/") async def fastapi_get_pipe_reaction_schema(network: str) -> dict[str, dict[str, Any]]: return get_pipe_reaction_schema(network) -@app.get('/getpipereaction/') + +@app.get("/getpipereaction/") async def fastapi_get_pipe_reaction(network: str, pipe: str) -> dict[str, Any]: return get_pipe_reaction(network, pipe) -@app.post('/setpipereaction/',response_model=None) + +@app.post("/setpipereaction/", response_model=None) async def fastapi_set_pipe_reaction(network: str, req: Request) -> ChangeSet: props = await req.json() return set_pipe_reaction(network, ChangeSet(props)) -@app.get('/gettankreactionschema/') + +@app.get("/gettankreactionschema/") async def fastapi_get_tank_reaction_schema(network: str) -> dict[str, dict[str, Any]]: return get_tank_reaction_schema(network) -@app.get('/gettankreaction/') + +@app.get("/gettankreaction/") async def fastapi_get_tank_reaction(network: str, tank: str) -> dict[str, Any]: return get_tank_reaction(network, tank) -@app.post('/settankreaction/',response_model=None) + +@app.post("/settankreaction/", response_model=None) async def fastapi_set_tank_reaction(network: str, req: Request) -> ChangeSet: props = await req.json() return set_tank_reaction(network, ChangeSet(props)) @@ -1634,26 +1948,30 @@ async def fastapi_set_tank_reaction(network: str, req: Request) -> ChangeSet: ############################################################ # mixing 20.[MIXING] ############################################################ -@app.get('/getmixingschema/') +@app.get("/getmixingschema/") async def fastapi_get_mixing_schema(network: str) -> dict[str, dict[str, Any]]: return get_mixing_schema(network) -@app.get('/getmixing/') + +@app.get("/getmixing/") async def fastapi_get_mixing(network: str, tank: str) -> dict[str, Any]: return get_mixing(network, tank) -@app.post('/setmixing/',response_model=None) + +@app.post("/setmixing/", response_model=None) async def fastapi_set_mixing(network: str, req: Request) -> ChangeSet: props = await req.json() return api.set_mixing(network, ChangeSet(props)) + # example: add_mixing(p, ChangeSet({'tank': 't0', 'model': MIXING_MODEL_MIXED, 'value': 10.0})) -@app.post('/addmixing/',response_model=None) +@app.post("/addmixing/", response_model=None) async def fastapi_add_mixing(network: str, req: Request) -> ChangeSet: props = await req.json() return add_mixing(network, ChangeSet(props)) -@app.post('/deletemixing/',response_model=None) + +@app.post("/deletemixing/", response_model=None) async def fastapi_delete_mixing(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_mixing(network, ChangeSet(props)) @@ -1662,34 +1980,40 @@ async def fastapi_delete_mixing(network: str, req: Request) -> ChangeSet: ############################################################ # time 21.[TIME] ############################################################ -@app.get('/gettimeschema') +@app.get("/gettimeschema") async def fastapi_get_time_schema(network: str) -> dict[str, dict[str, Any]]: return get_time_schema(network) + @app.get("/gettimeproperties/") async def fastapi_get_time_properties(network: str) -> dict[str, Any]: return get_time(network) -@app.post("/settimeproperties/",response_model=None) + +@app.post("/settimeproperties/", response_model=None) async def fastapi_set_time_properties(network: str, req: Request) -> ChangeSet: props = await req.json() - return set_time(network, ChangeSet(props)) + return set_time(network, ChangeSet(props)) + ############################################################ # option 23.[OPTIONS] ############################################################ -@app.get('/getoptionschema/') +@app.get("/getoptionschema/") async def fastapi_get_option_schema(network: str) -> dict[str, dict[str, Any]]: return get_option_v3_schema(network) + @app.get("/getoptionproperties/") async def fastapi_get_option_properties(network: str) -> dict[str, Any]: return get_option_v3(network) -@app.post("/setoptionproperties/",response_model=None) + +@app.post("/setoptionproperties/", response_model=None) async def fastapi_set_option_properties(network: str, req: Request) -> ChangeSet: props = await req.json() - return set_option_v3(network, ChangeSet(props)) + return set_option_v3(network, ChangeSet(props)) + ############################################################ # coord 24.[COORDINATES] @@ -1698,6 +2022,7 @@ async def fastapi_set_option_properties(network: str, req: Request) -> ChangeSet async def fastapi_get_node_coord(network: str, node: str) -> dict[str, float] | None: return get_node_coord(network, node) + # DingZQ, 2025-01-27, get all node coord/links # nodes: id:type:x:y # links: id:type:node1:node2 @@ -1720,27 +2045,28 @@ async def fastapi_get_network_geometries(network: str) -> dict[str, Any] | None: for node_id, coord in coords.items(): nodes.append(f"{node_id}:{coord['type']}:{coord['x']}:{coord['y']}") links = get_network_link_nodes(network) - + # return list of scadas. scada : id, x, y # scadas = get_all_scada_elements(network) # data from WMH's scada info scadas = get_all_scada_info(network) - results = { 'nodes': nodes, - 'links': links, - 'scadas': scadas } + results = {"nodes": nodes, "links": links, "scadas": scadas} # 缓存查询结果提高性能 redis_client.set(cache_key, msgpack.packb(results, default=encode_datetime)) - + return results + # DingZQ, 2024-12-31, get major node coord # id:type:x:y # type: junction, reservoir, tank @app.get("/getmajornodecoords/") -async def fastapi_get_major_node_coords(network: str, diameter: int) -> list[str] | None: +async def fastapi_get_major_node_coords( + network: str, diameter: int +) -> list[str] | None: start_time = time.time() coords = get_major_node_coords(network, diameter) end_time = time.time() @@ -1751,19 +2077,24 @@ async def fastapi_get_major_node_coords(network: str, diameter: int) -> list[str result.append(f"{node_id}:{coord['type']}:{coord['x']}:{coord['y']}") return result + # DingZQ, 2025-01-03, get network in extent @app.get("/getnetworkinextent/") -async def fastapi_get_network_in_extent(network: str, x1: float, y1: float, x2: float, y2: float) -> dict[str, Any] | None: +async def fastapi_get_network_in_extent( + network: str, x1: float, y1: float, x2: float, y2: float +) -> dict[str, Any] | None: nodes = api.get_nodes_in_extent(network, x1, y1, x2, y2) links = api.get_links_in_extent(network, x1, y1, x2, y2) - return { 'nodes': nodes, 'links': links } + return {"nodes": nodes, "links": links} -# DingZQ, 2024-12-08, get all links' start and end node + +# DingZQ, 2024-12-08, get all links' start and end node # link_id:link_type:node_id1:node_id2 @app.get("/getnetworklinknodes/") async def fastapi_get_network_link_nodes(network: str) -> list[str] | None: return get_network_link_nodes(network) + # DingZQ 2024-12-31 # 获取直径大于800的管道 @app.get("/getmajorpipenodes/") @@ -1774,63 +2105,77 @@ async def fastapi_get_major_pipe_nodes(network: str, diameter: int) -> list[str] logger.info("get_major_pipe_nodes: %s, time: %s", result, end_time - start_time) return result + ############################################################ # vertex 25.[VERTICES] ############################################################ -@app.get('/getvertexschema/') +@app.get("/getvertexschema/") async def fastapi_get_vertex_schema(network: str) -> dict[str, dict[str, Any]]: return get_vertex_schema(network) -@app.get('/getvertexproperties/') + +@app.get("/getvertexproperties/") async def fastapi_get_vertex_properties(network: str, link: str) -> dict[str, Any]: return get_vertex(network, link) + # set_vertex(p, ChangeSet({'link' : 'p0', 'coords': [{'x': 1.0, 'y': 2.0}, {'x': 2.0, 'y': 1.0}]})) -@app.post('/setvertexproperties/',response_model=None) +@app.post("/setvertexproperties/", response_model=None) async def fastapi_set_vertex_properties(network: str, req: Request) -> ChangeSet: props = await req.json() - return set_vertex(network, ChangeSet(props)) + return set_vertex(network, ChangeSet(props)) -@app.post('/addvertex/',response_model=None) + +@app.post("/addvertex/", response_model=None) async def fastapi_add_vertex(network: str, req: Request) -> ChangeSet: props = await req.json() - return add_vertex(network, ChangeSet(props)) + return add_vertex(network, ChangeSet(props)) -@app.post('/deletevertex/',response_model=None) + +@app.post("/deletevertex/", response_model=None) async def fastapi_delete_vertex(network: str, req: Request) -> ChangeSet: props = await req.json() return api.delete_vertex(network, ChangeSet(props)) -@app.get('/getallvertexlinks/', response_class = PlainTextResponse) + +@app.get("/getallvertexlinks/", response_class=PlainTextResponse) async def fastapi_get_all_vertex_links(network: str) -> list[str]: return json.dumps(get_all_vertex_links(network)) -@app.get('/getallvertices/', response_class = PlainTextResponse) + +@app.get("/getallvertices/", response_class=PlainTextResponse) async def fastapi_get_all_vertices(network: str) -> list[dict[str, Any]]: return json.dumps(get_all_vertices(network)) + ############################################################ # label 26.[LABELS] ############################################################ -@app.get('/getlabelschema/') +@app.get("/getlabelschema/") async def fastapi_get_label_schema(network: str) -> dict[str, dict[str, Any]]: return get_label_schema(network) -@app.get('/getlabelproperties/') -async def fastapi_get_label_properties(network: str, x: float, y: float) -> dict[str, Any]: + +@app.get("/getlabelproperties/") +async def fastapi_get_label_properties( + network: str, x: float, y: float +) -> dict[str, Any]: return get_label(network, x, y) -@app.post('/setlabelproperties/',response_model=None) + +@app.post("/setlabelproperties/", response_model=None) async def fastapi_set_label_properties(network: str, req: Request) -> ChangeSet: props = await req.json() return set_label(network, ChangeSet(props)) -@app.post('/addlabel/',response_model=None) + +@app.post("/addlabel/", response_model=None) async def fastapi_add_label(network: str, req: Request) -> ChangeSet: props = await req.json() return add_label(network, ChangeSet(props)) -@app.post('/deletelabel/',response_model=None) + +@app.post("/deletelabel/", response_model=None) async def fastapi_delete_label(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_label(network, ChangeSet(props)) @@ -1839,54 +2184,64 @@ async def fastapi_delete_label(network: str, req: Request) -> ChangeSet: ############################################################ # backdrop 27.[BACKDROP] ############################################################ -@app.get('/getbackdropschema/') +@app.get("/getbackdropschema/") async def fastapi_get_backdrop_schema(network: str) -> dict[str, dict[str, Any]]: return get_backdrop_schema(network) -@app.get('/getbackdropproperties/') + +@app.get("/getbackdropproperties/") async def fastapi_get_backdrop_properties(network: str) -> dict[str, Any]: return get_backdrop(network) -@app.post('/setbackdropproperties/',response_model=None) + +@app.post("/setbackdropproperties/", response_model=None) async def fastapi_set_backdrop_properties(network: str, req: Request) -> ChangeSet: props = await req.json() return set_backdrop(network, ChangeSet(props)) + ############################################################ # scada_device 29 ############################################################ -@app.get('/getscadadeviceschema/') +@app.get("/getscadadeviceschema/") async def fastapi_get_scada_device_schema(network: str) -> dict[str, dict[str, Any]]: return get_scada_device_schema(network) -@app.get('/getscadadevice/') + +@app.get("/getscadadevice/") async def fastapi_get_scada_device(network: str, id: str) -> dict[str, Any]: return get_scada_device(network, id) -@app.post('/setscadadevice/',response_model=None) + +@app.post("/setscadadevice/", response_model=None) async def fastapi_set_scada_device(network: str, req: Request) -> ChangeSet: props = await req.json() return set_scada_device(network, ChangeSet(props)) -@app.post('/addscadadevice/',response_model=None) + +@app.post("/addscadadevice/", response_model=None) async def fastapi_add_scada_device(network: str, req: Request) -> ChangeSet: props = await req.json() return add_scada_device(network, ChangeSet(props)) -@app.post('/deletescadadevice/',response_model=None) + +@app.post("/deletescadadevice/", response_model=None) async def fastapi_delete_scada_device(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_scada_device(network, ChangeSet(props)) -@app.post('/cleanscadadevice/',response_model=None) + +@app.post("/cleanscadadevice/", response_model=None) async def fastapi_clean_scada_device(network: str) -> ChangeSet: return clean_scada_device(network) -@app.get('/getallscadadeviceids/') + +@app.get("/getallscadadeviceids/") async def fastapi_get_all_scada_device_ids(network: str) -> list[str]: return get_all_scada_device_ids(network) -@app.get('/getallscadadevices/', response_class = PlainTextResponse) + +@app.get("/getallscadadevices/", response_class=PlainTextResponse) async def fastapi_get_all_scada_devices(network: str) -> list[dict[str, Any]]: return json.dumps(get_all_scada_devices(network)) @@ -1894,34 +2249,41 @@ async def fastapi_get_all_scada_devices(network: str) -> list[dict[str, Any]]: ############################################################ # scada_device_data 30 ############################################################ -@app.get('/getscadadevicedataschema/') -async def fastapi_get_scada_device_data_schema(network: str) -> dict[str, dict[str, Any]]: +@app.get("/getscadadevicedataschema/") +async def fastapi_get_scada_device_data_schema( + network: str, +) -> dict[str, dict[str, Any]]: return get_scada_device_data_schema(network) -@app.get('/getscadadevicedata/') + +@app.get("/getscadadevicedata/") async def fastapi_get_scada_device_data(network: str, id: str) -> dict[str, Any]: return get_scada_device_data(network, id) + # example: set_scada_device_data(p, ChangeSet({'device_id': 'sm_device', 'data': [{ 'time': '2023-02-10 00:02:22', 'value': 100.0 }, { 'time': '2023-02-10 00:03:22', 'value': 200.0 }]})) # time format must be 'YYYY-MM-DD HH:MM:SS' -@app.post('/setscadadevicedata/',response_model=None) +@app.post("/setscadadevicedata/", response_model=None) async def fastapi_set_scada_device_data(network: str, req: Request) -> ChangeSet: props = await req.json() return set_scada_device_data(network, ChangeSet(props)) + # example: add_scada_device_data(p, ChangeSet({'device_id': 'sm_device', 'time': '2023-02-10 00:02:22', 'value': 100.0})) -@app.post('/addscadadevicedata/',response_model=None) +@app.post("/addscadadevicedata/", response_model=None) async def fastapi_add_scada_device_data(network: str, req: Request) -> ChangeSet: props = await req.json() return add_scada_device_data(network, ChangeSet(props)) + # example: delete_scada_device_data(p, ChangeSet({'device_id': 'sm_device', 'time': '2023-02-12 00:02:22'})) -@app.post('/deletescadadevicedata/',response_model=None) +@app.post("/deletescadadevicedata/", response_model=None) async def fastapi_delete_scada_device_data(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_scada_device_data(network, ChangeSet(props)) -@app.post('/cleanscadadevicedata/',response_model=None) + +@app.post("/cleanscadadevicedata/", response_model=None) async def fastapi_clean_scada_device_data(network: str) -> ChangeSet: return clean_scada_device_data(network) @@ -1929,255 +2291,336 @@ async def fastapi_clean_scada_device_data(network: str) -> ChangeSet: ############################################################ # scada_element 31 ############################################################ -@app.get('/getscadaelementschema/') +@app.get("/getscadaelementschema/") async def fastapi_get_scada_element_schema(network: str) -> dict[str, dict[str, Any]]: return get_scada_element_schema(network) -@app.get('/getscadaelements/') + +@app.get("/getscadaelements/") async def fastapi_get_scada_elements(network: str) -> list[str]: return get_all_scada_elements(network) -@app.get('/getscadaelement/') + +@app.get("/getscadaelement/") async def fastapi_get_scada_element(network: str, id: str) -> dict[str, Any]: return get_scada_element(network, id) -@app.post('/setscadaelement/',response_model=None) + +@app.post("/setscadaelement/", response_model=None) async def fastapi_set_scada_element(network: str, req: Request) -> ChangeSet: props = await req.json() return set_scada_element(network, ChangeSet(props)) -@app.post('/addscadaelement/',response_model=None) + +@app.post("/addscadaelement/", response_model=None) async def fastapi_add_scada_element(network: str, req: Request) -> ChangeSet: props = await req.json() return add_scada_element(network, ChangeSet(props)) -@app.post('/deletescadaelement/',response_model=None) + +@app.post("/deletescadaelement/", response_model=None) async def fastapi_delete_scada_element(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_scada_element(network, ChangeSet(props)) -@app.post('/cleanscadaelement/',response_model=None) + +@app.post("/cleanscadaelement/", response_model=None) async def fastapi_clean_scada_element(network: str) -> ChangeSet: return clean_scada_element(network) + ############################################################ # general_region 32 ############################################################ -@app.get('/getregionschema/') +@app.get("/getregionschema/") async def fastapi_get_region_schema(network: str) -> dict[str, dict[str, Any]]: return get_region_schema(network) -@app.get('/getregion/') + +@app.get("/getregion/") async def fastapi_get_region(network: str, id: str) -> dict[str, Any]: return get_region(network, id) -@app.post('/setregion/',response_model=None) -async def fastapi_set_region(network : str, req: Request) -> ChangeSet: + +@app.post("/setregion/", response_model=None) +async def fastapi_set_region(network: str, req: Request) -> ChangeSet: props = await req.json() return set_region(network, ChangeSet(props)) + # example: add_region(p, ChangeSet({'id': 'r', 'boundary': [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]})) -@app.post('/addregion/',response_model=None) +@app.post("/addregion/", response_model=None) async def fastapi_add_region(network: str, req: Request) -> ChangeSet: props = await req.json() return add_region(network, ChangeSet(props)) -@app.post('/deleteregion/',response_model=None) + +@app.post("/deleteregion/", response_model=None) async def fastapi_delete_region(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_region(network, ChangeSet(props)) + ############################################################ # district_metering_area 33 ############################################################ -@app.get('/calculatedistrictmeteringareafornodes/') -async def fastapi_calculate_district_metering_area_for_nodes(network: str, req: Request) -> list[list[str]]: +@app.get("/calculatedistrictmeteringareafornodes/") +async def fastapi_calculate_district_metering_area_for_nodes( + network: str, req: Request +) -> list[list[str]]: props = await req.json() - nodes = props['nodes'] - part_count = props['part_count'] - part_type = props['part_type'] - return calculate_district_metering_area_for_nodes(network, nodes, part_count, part_type) + nodes = props["nodes"] + part_count = props["part_count"] + part_type = props["part_type"] + return calculate_district_metering_area_for_nodes( + network, nodes, part_count, part_type + ) -@app.get('/calculatedistrictmeteringareaforregion/') -async def fastapi_calculate_district_metering_area_for_region(network: str, req: Request) -> list[list[str]]: - props = await req.json() - region = props['region'] - part_count = props['part_count'] - part_type = props['part_type'] - return calculate_district_metering_area_for_region(network, region, part_count, part_type) -@app.get('/calculatedistrictmeteringareafornetwork/') -async def fastapi_calculate_district_metering_area_for_network(network: str, req: Request) -> list[list[str]]: +@app.get("/calculatedistrictmeteringareaforregion/") +async def fastapi_calculate_district_metering_area_for_region( + network: str, req: Request +) -> list[list[str]]: props = await req.json() - part_count = props['part_count'] - part_type = props['part_type'] + region = props["region"] + part_count = props["part_count"] + part_type = props["part_type"] + return calculate_district_metering_area_for_region( + network, region, part_count, part_type + ) + + +@app.get("/calculatedistrictmeteringareafornetwork/") +async def fastapi_calculate_district_metering_area_for_network( + network: str, req: Request +) -> list[list[str]]: + props = await req.json() + part_count = props["part_count"] + part_type = props["part_type"] return calculate_district_metering_area_for_network(network, part_count, part_type) -@app.get('/getdistrictmeteringareaschema/') -async def fastapi_get_district_metering_area_schema(network: str) -> dict[str, dict[str, Any]]: + +@app.get("/getdistrictmeteringareaschema/") +async def fastapi_get_district_metering_area_schema( + network: str, +) -> dict[str, dict[str, Any]]: return get_district_metering_area_schema(network) -@app.get('/getdistrictmeteringarea/') + +@app.get("/getdistrictmeteringarea/") async def fastapi_get_district_metering_area(network: str, id: str) -> dict[str, Any]: return get_district_metering_area(network, id) -@app.post('/setdistrictmeteringarea/',response_model=None) + +@app.post("/setdistrictmeteringarea/", response_model=None) async def fastapi_set_district_metering_area(network: str, req: Request) -> ChangeSet: props = await req.json() return set_district_metering_area(network, ChangeSet(props)) -@app.post('/adddistrictmeteringarea/',response_model=None) + +@app.post("/adddistrictmeteringarea/", response_model=None) async def fastapi_add_district_metering_area(network: str, req: Request) -> ChangeSet: props = await req.json() -# boundary should be [(x,y), (x,y)] - boundary = props['boundary'] + # boundary should be [(x,y), (x,y)] + boundary = props["boundary"] newBoundary = [] for pt in boundary: newBoundary.append((pt[0], pt[1])) - - props['boundary'] = newBoundary - + + props["boundary"] = newBoundary + return add_district_metering_area(network, ChangeSet(props)) -@app.post('/deletedistrictmeteringarea/',response_model=None) -async def fastapi_delete_district_metering_area(network: str, req: Request) -> ChangeSet: + +@app.post("/deletedistrictmeteringarea/", response_model=None) +async def fastapi_delete_district_metering_area( + network: str, req: Request +) -> ChangeSet: props = await req.json() return delete_district_metering_area(network, ChangeSet(props)) -@app.get('/getalldistrictmeteringareaids/') + +@app.get("/getalldistrictmeteringareaids/") async def fastapi_get_all_district_metering_area_ids(network: str) -> list[str]: return get_all_district_metering_area_ids(network) -@app.get('/getalldistrictmeteringareas/') + +@app.get("/getalldistrictmeteringareas/") async def getalldistrictmeteringareas(network: str) -> list[dict[str, Any]]: return get_all_district_metering_areas(network) -@app.post('/generatedistrictmeteringarea/',response_model=None) -async def fastapi_generate_district_metering_area(network: str, part_count: int, part_type: int, inflate_delta: float) -> ChangeSet: - return generate_district_metering_area(network, part_count, part_type, inflate_delta) -@app.post('/generatesubdistrictmeteringarea/',response_model=None) -async def fastapi_generate_sub_district_metering_area(network: str, dma: str, part_count: int, part_type: int, inflate_delta: float) -> ChangeSet: +@app.post("/generatedistrictmeteringarea/", response_model=None) +async def fastapi_generate_district_metering_area( + network: str, part_count: int, part_type: int, inflate_delta: float +) -> ChangeSet: + return generate_district_metering_area( + network, part_count, part_type, inflate_delta + ) + + +@app.post("/generatesubdistrictmeteringarea/", response_model=None) +async def fastapi_generate_sub_district_metering_area( + network: str, dma: str, part_count: int, part_type: int, inflate_delta: float +) -> ChangeSet: print(network) print(dma) print(part_count) print(part_type) print(inflate_delta) - return generate_sub_district_metering_area(network, dma, part_count, part_type, inflate_delta) + return generate_sub_district_metering_area( + network, dma, part_count, part_type, inflate_delta + ) + ############################################################ # service_area 34 ############################################################ -@app.get('/calculateservicearea/') -async def fastapi_calculate_service_area(network: str, time_index: int) -> dict[str, Any]: +@app.get("/calculateservicearea/") +async def fastapi_calculate_service_area( + network: str, time_index: int +) -> dict[str, Any]: return calculate_service_area(network, time_index) -@app.get('/getserviceareaschema/') + +@app.get("/getserviceareaschema/") async def fastapi_get_service_area_schema(network: str) -> dict[str, dict[str, Any]]: return get_service_area_schema(network) -@app.get('/getservicearea/') + +@app.get("/getservicearea/") async def fastapi_get_service_area(network: str, id: str) -> dict[str, Any]: return get_service_area(network, id) -@app.post('/setservicearea/',response_model=None) + +@app.post("/setservicearea/", response_model=None) async def fastapi_set_service_area(network: str, req: Request) -> ChangeSet: props = await req.json() return set_service_area(network, ChangeSet(props)) -@app.post('/addservicearea/',response_model=None) + +@app.post("/addservicearea/", response_model=None) async def fastapi_add_service_area(network: str, req: Request) -> ChangeSet: props = await req.json() return add_service_area(network, ChangeSet(props)) -@app.post('/deleteservicearea/',response_model=None) + +@app.post("/deleteservicearea/", response_model=None) async def fastapi_delete_service_area(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_service_area(network, ChangeSet(props)) -@app.get('/getallserviceareas/') + +@app.get("/getallserviceareas/") async def fastapi_get_all_service_areas(network: str) -> list[dict[str, Any]]: return get_all_service_areas(network) -@app.post('/generateservicearea/',response_model=None) -async def fastapi_generate_service_area(network: str, inflate_delta: float) -> ChangeSet: + +@app.post("/generateservicearea/", response_model=None) +async def fastapi_generate_service_area( + network: str, inflate_delta: float +) -> ChangeSet: return generate_service_area(network, inflate_delta) ############################################################ # virtual_district 35 ############################################################ -@app.get('/calculatevirtualdistrict/') -async def fastapi_calculate_virtual_district(network: str, centers: list[str]) -> dict[str, list[Any]]: +@app.get("/calculatevirtualdistrict/") +async def fastapi_calculate_virtual_district( + network: str, centers: list[str] +) -> dict[str, list[Any]]: return calculate_virtual_district(network, centers) -@app.get('/getvirtualdistrictschema/') -async def fastapi_get_virtual_district_schema(network: str) -> dict[str, dict[str, Any]]: + +@app.get("/getvirtualdistrictschema/") +async def fastapi_get_virtual_district_schema( + network: str, +) -> dict[str, dict[str, Any]]: return get_virtual_district_schema(network) -@app.get('/getvirtualdistrict/') + +@app.get("/getvirtualdistrict/") async def fastapi_get_virtual_district(network: str, id: str) -> dict[str, Any]: return get_virtual_district(network, id) -@app.post('/setvirtualdistrict/',response_model=None) + +@app.post("/setvirtualdistrict/", response_model=None) async def fastapi_set_virtual_district(network: str, req: Request) -> ChangeSet: props = await req.json() return set_virtual_district(network, ChangeSet(props)) -@app.post('/addvirtualdistrict/',response_model=None) + +@app.post("/addvirtualdistrict/", response_model=None) async def fastapi_add_virtual_district(network: str, req: Request) -> ChangeSet: props = await req.json() return add_virtual_district(network, ChangeSet(props)) -@app.post('/deletevirtualdistrict/',response_model=None) + +@app.post("/deletevirtualdistrict/", response_model=None) async def fastapi_delete_virtual_district(network: str, req: Request) -> ChangeSet: props = await req.json() return delete_virtual_district(network, ChangeSet(props)) -@app.get('/getallvirtualdistrict/') + +@app.get("/getallvirtualdistrict/") async def fastapi_get_all_virtual_district(network: str) -> list[dict[str, Any]]: return get_all_virtual_districts(network) -@app.post('/generatevirtualdistrict/',response_model=None) -async def fastapi_generate_virtual_district(network: str, inflate_delta: float, req: Request) -> ChangeSet: + +@app.post("/generatevirtualdistrict/", response_model=None) +async def fastapi_generate_virtual_district( + network: str, inflate_delta: float, req: Request +) -> ChangeSet: props = await req.json() - return generate_virtual_district(network, props['centers'], inflate_delta) + return generate_virtual_district(network, props["centers"], inflate_delta) + ############################################################ # water_distribution_area 36 ############################################################ -@app.get('/calculatedemandtonodes/') -async def fastapi_calculate_demand_to_nodes(network: str, req: Request) -> dict[str, float]: +@app.get("/calculatedemandtonodes/") +async def fastapi_calculate_demand_to_nodes( + network: str, req: Request +) -> dict[str, float]: props = await req.json() - demand = props['demand'] - nodes = props['nodes'] + demand = props["demand"] + nodes = props["nodes"] return calculate_demand_to_nodes(network, demand, nodes) -@app.get('/calculatedemandtoregion/') -async def fastapi_calculate_demand_to_region(network: str, req: Request) -> dict[str, float]: + +@app.get("/calculatedemandtoregion/") +async def fastapi_calculate_demand_to_region( + network: str, req: Request +) -> dict[str, float]: props = await req.json() - demand = props['demand'] - region = props['region'] + demand = props["demand"] + region = props["region"] return calculate_demand_to_region(network, demand, region) -@app.get('/calculatedemandtonetwork/') -async def fastapi_calculate_demand_to_network(network: str, demand: float) -> dict[str, float]: + +@app.get("/calculatedemandtonetwork/") +async def fastapi_calculate_demand_to_network( + network: str, demand: float +) -> dict[str, float]: return calculate_demand_to_network(network, demand) ########################################################### # scada_info 38 || written by WMH ############################################################ -@app.get('/getscadainfoschema/') +@app.get("/getscadainfoschema/") async def fastapi_get_scada_info_schema(network: str) -> dict[str, dict[str, Any]]: - return get_scada_info_schema(network) + return get_scada_info_schema(network) -@app.get('/getscadainfo/') + +@app.get("/getscadainfo/") async def fastapi_get_scada_info(network: str, id: str) -> dict[str, float]: return get_scada_info(network, id) -@app.get('/getallscadainfo/') + +@app.get("/getallscadainfo/") async def fastapi_get_all_scada_info(network: str) -> list[dict[str, float]]: return get_all_scada_info(network) @@ -2185,31 +2628,35 @@ async def fastapi_get_all_scada_info(network: str) -> list[dict[str, float]]: ########################################################### # user 39 ########################################################### -@app.get('/getuserschema/') +@app.get("/getuserschema/") async def fastapi_get_user_schema(network: str) -> dict[str, dict[Any, Any]]: - return get_user_schema(network) + return get_user_schema(network) -@app.get('/getuser/') + +@app.get("/getuser/") async def fastapi_get_user(network: str, user_name: str) -> dict[Any, Any]: return get_user(network, user_name) -@app.get('/getallusers/') + +@app.get("/getallusers/") async def fastapi_get_all_users(network: str) -> list[dict[Any, Any]]: return get_all_users(network) ############################################################ # scheme 40 -############################################################ -@app.get('/getschemeschema/') +############################################################ +@app.get("/getschemeschema/") async def fastapi_get_scheme_schema(network: str) -> dict[str, dict[Any, Any]]: - return get_scheme_schema(network) + return get_scheme_schema(network) -@app.get('/getscheme/') + +@app.get("/getscheme/") async def fastapi_get_scheme(network: str, schema_name: str) -> dict[Any, Any]: return get_scheme(network, schema_name) -@app.get('/getallschemes/') + +@app.get("/getallschemes/") async def fastapi_get_all_schemes(network: str) -> list[dict[Any, Any]]: return get_all_schemes(network) @@ -2217,23 +2664,35 @@ async def fastapi_get_all_schemes(network: str) -> list[dict[Any, Any]]: ############################################################ # pipe_risk_probability 41 ############################################################ -@app.get('/getpiperiskprobabilitynow/') -async def fastapi_get_pipe_risk_probability_now(network: str, pipe_id: str) -> dict[str, Any]: +@app.get("/getpiperiskprobabilitynow/") +async def fastapi_get_pipe_risk_probability_now( + network: str, pipe_id: str +) -> dict[str, Any]: return get_pipe_risk_probability_now(network, pipe_id) -@app.get('/getpiperiskprobability/') -async def fastapi_get_pipe_risk_probability(network: str, pipe_id: str) -> dict[str, Any]: + +@app.get("/getpiperiskprobability/") +async def fastapi_get_pipe_risk_probability( + network: str, pipe_id: str +) -> dict[str, Any]: return get_pipe_risk_probability(network, pipe_id) -@app.get('/getpipesriskprobability/') -async def fastapi_get_pipes_risk_probability(network: str, pipe_ids: str) -> list[dict[str, Any]]: - pipeids = pipe_ids.split(',') + +@app.get("/getpipesriskprobability/") +async def fastapi_get_pipes_risk_probability( + network: str, pipe_ids: str +) -> list[dict[str, Any]]: + pipeids = pipe_ids.split(",") return get_pipes_risk_probability(network, pipeids) -@app.get('/getnetworkpiperiskprobabilitynow/') -async def fastapi_get_network_pipe_risk_probability_now(network: str) -> list[dict[str, Any]]: + +@app.get("/getnetworkpiperiskprobabilitynow/") +async def fastapi_get_network_pipe_risk_probability_now( + network: str, +) -> list[dict[str, Any]]: return get_network_pipe_risk_probability_now(network) + # 返回一个字典,key 是管道的 id,value 是管道的几何信息 # 几何信息是一个字典,包含 start 和 end 两个 key,value 是管道的起点和终点的坐标 # 例如: @@ -2247,7 +2706,7 @@ async def fastapi_get_network_pipe_risk_probability_now(network: str) -> list[di # 29.814950582 # ] # }, -@app.get('/getpiperiskprobabilitygeometries/') +@app.get("/getpiperiskprobabilitygeometries/") async def fastapi_get_pipe_risk_probability_geometries(network: str) -> dict[str, Any]: return get_pipe_risk_probability_geometries(network) @@ -2255,7 +2714,7 @@ async def fastapi_get_pipe_risk_probability_geometries(network: str) -> dict[str ############################################################ # sensor_placement 42 ############################################################ -@app.get('/getallsensorplacements/') +@app.get("/getallsensorplacements/") async def fastapi_get_all_sensor_placements(network: str) -> list[dict[Any, Any]]: return get_all_sensor_placements(network) @@ -2263,83 +2722,72 @@ async def fastapi_get_all_sensor_placements(network: str) -> list[dict[Any, Any] ############################################################ # burst_locate_result 43 ############################################################ -@app.get('/getallburstlocateresults/') +@app.get("/getallburstlocateresults/") async def fastapi_get_all_burst_locate_results(network: str) -> list[dict[Any, Any]]: return get_all_burst_locate_results(network) - - - - - - - - - - - - - - - # inp file @app.post("/uploadinp/", status_code=status.HTTP_200_OK) -async def fastapi_upload_inp(afile: bytes, name: str ): +async def fastapi_upload_inp(afile: bytes, name: str): filePath = inpDir + str(name) - f = open(filePath, 'wb') + f = open(filePath, "wb") f.write(afile) f.close() return True + @app.get("/downloadinp/", status_code=status.HTTP_200_OK) async def fastapi_download_inp(name: str, response: Response): - filePath = inpDir + name + filePath = inpDir + name if os.path.exists(filePath): - return FileResponse(filePath, media_type='application/octet-stream', filename="inp.inp") + return FileResponse( + filePath, media_type="application/octet-stream", filename="inp.inp" + ) else: response.status_code = status.HTTP_400_BAD_REQUEST return True - - + + # DingZQ, 2024-12-28, convert v3 to v2 -@app.get("/convertv3tov2/",response_model=None) +@app.get("/convertv3tov2/", response_model=None) async def fastapi_convert_v3_to_v2(req: Request) -> ChangeSet: - network = 'v3Tov2' + network = "v3Tov2" jo_root = await req.json() - inp = jo_root['inp'] + inp = jo_root["inp"] cs = convert_inp_v3_to_v2(inp) op = cs.operations[0] open_project(network) - op['vertex'] = json.dumps(get_all_vertices(network)) - op['scada'] = json.dumps(get_all_scada_elements(network)) - op['dma'] = json.dumps(get_all_district_metering_areas(network)) - op['sa'] = json.dumps(get_all_service_areas(network)) - op['vd'] = json.dumps(get_all_virtual_districts(network)) - op['legend'] = get_extension_data(network, 'legend') + op["vertex"] = json.dumps(get_all_vertices(network)) + op["scada"] = json.dumps(get_all_scada_elements(network)) + op["dma"] = json.dumps(get_all_district_metering_areas(network)) + op["sa"] = json.dumps(get_all_service_areas(network)) + op["vd"] = json.dumps(get_all_virtual_districts(network)) + op["legend"] = get_extension_data(network, "legend") - db = get_extension_data(network, 'scada_db') + db = get_extension_data(network, "scada_db") print(db) - scada_db = '' + scada_db = "" if db: scada_db = db print(scada_db) - op['scada_db'] = scada_db - + op["scada_db"] = scada_db + close_project(network) return cs - + + @app.get("/getjson/") async def fastapi_get_json(): return JSONResponse( - status_code = status.HTTP_400_BAD_REQUEST, + status_code=status.HTTP_400_BAD_REQUEST, content={ - 'code': 400, - 'message': "this is message", - 'data': 123, - } + "code": 400, + "message": "this is message", + "data": 123, + }, ) @@ -2352,36 +2800,40 @@ async def fastapi_get_realtimedata(): data = [random.randint(0, 100) for _ in range(100)] return data + @app.get("/getsimulationresult/") async def fastapi_get_simulationresult(): data = [random.randint(0, 100) for _ in range(100)] return data + # 下面几个query 函数,都是从 influxdb 中查询的,不与 network 绑定,用固定的network 名字 + # DingZQ 2025-01-31 # def query_latest_record_by_ID(ID: str, type: str, bucket: str="realtime_data", client: InfluxDBClient=client) -> dict: @app.get("/querynodelatestrecordbyid/") async def fastapi_query_node_latest_record_by_id(id: str): - return influxdb_api.query_latest_record_by_ID(id, type='node') + return influxdb_api.query_latest_record_by_ID(id, type="node") + @app.get("/querylinklatestrecordbyid/") async def fastapi_query_link_latest_record_by_id(id: str): - return influxdb_api.query_latest_record_by_ID(id, type='link') + return influxdb_api.query_latest_record_by_ID(id, type="link") + # query scada @app.get("/queryscadalatestrecordbyid/") async def fastapi_query_scada_latest_record_by_id(id: str): - return influxdb_api.query_latest_record_by_ID(id, type='scada') - + return influxdb_api.query_latest_record_by_ID(id, type="scada") # def query_all_record_by_time(query_time: str, bucket: str="realtime_data", client: InfluxDBClient=client) -> tuple: @app.get("/queryallrecordsbytime/") async def fastapi_query_all_records_by_time(querytime: str) -> dict[str, list]: results: tuple = influxdb_api.query_all_records_by_time(query_time=querytime) - return { "nodes": results[0], - "links": results[1] } + return {"nodes": results[0], "links": results[1]} + @app.get("/queryallrecordsbydate/") async def fastapi_query_all_records_by_date(querydate: str) -> dict: @@ -2406,8 +2858,7 @@ async def fastapi_query_all_records_by_date(querydate: str) -> dict: logger.info(f"query from influxdb") nodes_links: tuple = influxdb_api.query_all_records_by_date(query_date=querydate) - results = { "nodes": nodes_links[0], - "links": nodes_links[1] } + results = {"nodes": nodes_links[0], "links": nodes_links[1]} # 今天的不要去缓存 if not is_today_or_future: @@ -2418,8 +2869,11 @@ async def fastapi_query_all_records_by_date(querydate: str) -> dict: return results + @app.get("/queryallrecordsbytimerange/") -async def fastapi_query_all_records_by_time_range(starttime: str, endtime: str) -> dict[str, list]: +async def fastapi_query_all_records_by_time_range( + starttime: str, endtime: str +) -> dict[str, list]: # 缓存查询结果提高性能 global redis_client @@ -2432,9 +2886,10 @@ async def fastapi_query_all_records_by_time_range(starttime: str, endtime: str) loaded_dict = msgpack.unpackb(data, object_hook=decode_datetime) return loaded_dict - nodes_links: tuple = influxdb_api.query_all_records_by_time_range(starttime=starttime, endtime=endtime) - results = { "nodes": nodes_links[0], - "links": nodes_links[1] } + nodes_links: tuple = influxdb_api.query_all_records_by_time_range( + starttime=starttime, endtime=endtime + ) + results = {"nodes": nodes_links[0], "links": nodes_links[1]} # 今天的不要去缓存 if not time_api.is_today_or_future(starttime): @@ -2442,9 +2897,12 @@ async def fastapi_query_all_records_by_time_range(starttime: str, endtime: str) return results -#2025-03-15, DingZQ + +# 2025-03-15, DingZQ @app.get("/queryallrecordsbydatewithtype/") -async def fastapi_query_all_records_by_date_with_type(querydate: str, querytype: str) -> list: +async def fastapi_query_all_records_by_date_with_type( + querydate: str, querytype: str +) -> list: # 缓存查询结果提高性能 global redis_client cache_key = f"queryallrecordsbydatewithtype_{querydate}_{querytype}" @@ -2454,15 +2912,20 @@ async def fastapi_query_all_records_by_date_with_type(querydate: str, querytype: loaded_dict = msgpack.unpackb(data, object_hook=decode_datetime) return loaded_dict - results = influxdb_api.query_all_records_by_date_with_type(query_date=querydate, query_type=querytype) + results = influxdb_api.query_all_records_by_date_with_type( + query_date=querydate, query_type=querytype + ) - packed = msgpack.packb(results, default=encode_datetime) + packed = msgpack.packb(results, default=encode_datetime) redis_client.set(cache_key, packed) return results + @app.get("/queryallrecordsbyidsdatetype/") -async def fastapi_query_all_records_by_ids_date_type(ids:str, querydate: str, querytype: str) -> list: +async def fastapi_query_all_records_by_ids_date_type( + ids: str, querydate: str, querytype: str +) -> list: # 缓存查询结果提高性能 global redis_client cache_key = f"queryallrecordsbydatewithtype_{querydate}_{querytype}" @@ -2472,13 +2935,15 @@ async def fastapi_query_all_records_by_ids_date_type(ids:str, querydate: str, qu # 使用自定义的反序列化函数 results = msgpack.unpackb(data, object_hook=decode_datetime) else: - results = influxdb_api.query_all_records_by_date_with_type(query_date=querydate, query_type=querytype) - packed = msgpack.packb(results, default=encode_datetime) + results = influxdb_api.query_all_records_by_date_with_type( + query_date=querydate, query_type=querytype + ) + packed = msgpack.packb(results, default=encode_datetime) redis_client.set(cache_key, packed) query_ids = ids.split(",") e_results = py_linq.Enumerable(results) - lst_results = e_results.where(lambda x: x['ID'] in query_ids).to_list() + lst_results = e_results.where(lambda x: x["ID"] in query_ids).to_list() return lst_results @@ -2486,7 +2951,9 @@ async def fastapi_query_all_records_by_ids_date_type(ids:str, querydate: str, qu # 查询指定日期、类型、属性的所有记录 # 返回 [{'time': '2024-01-01T00:00:00Z', 'ID': '1', 'value': 1.0}, {'time': '2024-01-01T00:00:00Z', 'ID': '2', 'value': 2.0}] @app.get("/queryallrecordsbydateproperty/") -async def fastapi_query_all_records_by_date_property(querydate: str, querytype: str, property: str) -> list[dict]: +async def fastapi_query_all_records_by_date_property( + querydate: str, querytype: str, property: str +) -> list[dict]: # 缓存查询结果提高性能 global redis_client cache_key = f"queryallrecordsbydateproperty_{querydate}_{querytype}_{property}" @@ -2496,8 +2963,10 @@ async def fastapi_query_all_records_by_date_property(querydate: str, querytype: loaded_dict = msgpack.unpackb(data, object_hook=decode_datetime) return loaded_dict - result_dict = influxdb_api.query_all_record_by_date_property(query_date=querydate, type=querytype, property=property) - packed = msgpack.packb(result_dict, default=encode_datetime) + result_dict = influxdb_api.query_all_record_by_date_property( + query_date=querydate, type=querytype, property=property + ) + packed = msgpack.packb(result_dict, default=encode_datetime) redis_client.set(cache_key, packed) return result_dict @@ -2505,81 +2974,113 @@ async def fastapi_query_all_records_by_date_property(querydate: str, querytype: # def query_curve_by_ID_property_daterange(ID: str, type: str, property: str, start_date: str, end_date: str, bucket: str="realtime_data", client: InfluxDBClient=client) -> list: @app.get("/querynodecurvebyidpropertydaterange/") -async def fastapi_query_node_curve_by_id_property_daterange(id: str, prop: str, startdate: str, enddate: str): - return influxdb_api.query_curve_by_ID_property_daterange(id, type='node', property=prop, start_date=startdate, end_date=enddate) +async def fastapi_query_node_curve_by_id_property_daterange( + id: str, prop: str, startdate: str, enddate: str +): + return influxdb_api.query_curve_by_ID_property_daterange( + id, type="node", property=prop, start_date=startdate, end_date=enddate + ) + @app.get("/querylinkcurvebyidpropertydaterange/") -async def fastapi_query_link_curve_by_id_property_daterange(id: str, prop: str, startdate: str, enddate: str): - return influxdb_api.query_curve_by_ID_property_daterange(id, type='link', property=prop, start_date=startdate, end_date=enddate) +async def fastapi_query_link_curve_by_id_property_daterange( + id: str, prop: str, startdate: str, enddate: str +): + return influxdb_api.query_curve_by_ID_property_daterange( + id, type="link", property=prop, start_date=startdate, end_date=enddate + ) + # ids 用,隔开 # 返回 { 'id': value1, 'id2': value2 } # def query_SCADA_data_by_device_ID_and_time(query_ids_list: List[str], query_time: str, bucket: str="SCADA_data", client: InfluxDBClient=client) -> Dict[str, float]: @app.get("/queryscadadatabydeviceidandtime/") async def fastapi_query_scada_data_by_device_id_and_time(ids: str, querytime: str): - query_ids = ids.split(',') + query_ids = ids.split(",") logger.info(querytime) - return influxdb_api.query_SCADA_data_by_device_ID_and_time(query_ids_list=query_ids, query_time=querytime) + return influxdb_api.query_SCADA_data_by_device_ID_and_time( + query_ids_list=query_ids, query_time=querytime + ) + # 2025/05/04 DingZQ -# 对于SCAD的曲线数据,我们需要有4 套数据值 -# 1. 原始数据 +# 对于SCADA的曲线数据,我们需要有4 套数据值 +# 1. 原始数据 # 2. 补充的数据 (补充前面第一步缺失的数据) # 3. 清洗后的数据点 (用五角星表示) -# 4. 模拟曲线 +# 4. 模拟曲线 + # 查询到的SCADA原始数据 # 数据1 @app.get("/queryscadadatabydeviceidandtimerange/") -async def fastapi_query_scada_data_by_device_id_and_time_range(ids: str, starttime: str, endtime: str): +async def fastapi_query_scada_data_by_device_id_and_time_range( + ids: str, starttime: str, endtime: str +): - print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") + print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") + + query_ids = ids.split(",") + return influxdb_api.query_SCADA_data_by_device_ID_and_timerange( + query_ids_list=query_ids, start_time=starttime, end_time=endtime + ) - query_ids = ids.split(',') - return influxdb_api.query_SCADA_data_by_device_ID_and_timerange(query_ids_list=query_ids, start_time=starttime, end_time=endtime) # 查询到的SCADA补充的数据 # 数据2 # 注意: 这里的id是 scada_info中的 api_query_id @app.get("/queryfillingscadadatabydeviceidandtimerange/") -async def fastapi_query_filling_scada_data_by_device_id_and_time_range(ids: str, starttime: str, endtime: str): +async def fastapi_query_filling_scada_data_by_device_id_and_time_range( + ids: str, starttime: str, endtime: str +): - print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") + print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") + + query_ids = ids.split(",") + return influxdb_api.query_filling_SCADA_data_by_device_ID_and_timerange( + query_ids_list=query_ids, start_time=starttime, end_time=endtime + ) - query_ids = ids.split(',') - return influxdb_api.query_filling_SCADA_data_by_device_ID_and_timerange(query_ids_list=query_ids, start_time=starttime, end_time=endtime) # 查询到的SCADA清洗后的数据点 # 数据3 # 注意: 这里的id是 scada_info中的 api_query_id @app.get("/querycleaningscadadatabydeviceidandtimerange/") -async def fastapi_query_cleaning_scada_data_by_device_id_and_time_range(ids: str, starttime: str, endtime: str): - - print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") - - query_ids = ids.split(',') - return influxdb_api.query_cleaning_SCADA_data_by_device_ID_and_timerange(query_ids_list=query_ids, start_time=starttime, end_time=endtime) +async def fastapi_query_cleaning_scada_data_by_device_id_and_time_range( + ids: str, starttime: str, endtime: str +): + print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") + query_ids = ids.split(",") + return influxdb_api.query_cleaning_SCADA_data_by_device_ID_and_timerange( + query_ids_list=query_ids, start_time=starttime, end_time=endtime + ) # 查询指定时间范围内,多个SCADA设备的清洗后的数据 # DingZQ, 2025-04-19 # 2025/05/04 DingZQ 这个是将原始数据跟清洗后的数据合并到一起,暂时不需要用这个API @app.get("/querycleanedscadadatabydeviceidandtimerange/") -async def fastapi_query_cleaned_scada_data_by_device_id_and_time_range(ids: str, starttime: str, endtime: str): +async def fastapi_query_cleaned_scada_data_by_device_id_and_time_range( + ids: str, starttime: str, endtime: str +): - print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") - - query_ids = ids.split(',') - return influxdb_api.query_cleaned_SCADA_data_by_device_ID_and_timerange(query_ids_list=query_ids, start_time=starttime, end_time=endtime) + print(f"query_ids: {ids}, starttime: {starttime}, endtime: {endtime}") + query_ids = ids.split(",") + return influxdb_api.query_cleaned_SCADA_data_by_device_ID_and_timerange( + query_ids_list=query_ids, start_time=starttime, end_time=endtime + ) @app.get("/queryscadadatabydeviceidanddate/") async def fastapi_query_scada_data_by_device_id_and_date(ids: str, querydate: str): - query_ids = ids.split(',') - return influxdb_api.query_SCADA_data_by_device_ID_and_date(query_ids_list=query_ids, query_date=querydate) + query_ids = ids.split(",") + return influxdb_api.query_SCADA_data_by_device_ID_and_date( + query_ids_list=query_ids, query_date=querydate + ) + # DingZQ, 2025-03-08 # 返回所有SCADA设备在指定日期的所有记录 @@ -2606,17 +3107,20 @@ async def fastapi_query_all_scada_records_by_date(querydate: str): # 今天的不要去缓存 if not is_today_or_future: logger.info(f"save to cache redis") - packed = msgpack.packb(result_dict, default=encode_datetime) + packed = msgpack.packb(result_dict, default=encode_datetime) redis_client.set(cache_key, packed) logger.info(f"return results") return result_dict + # DingZQ, 2025-03-15 # Scheme @app.get("/queryallschemeallrecords/") -async def fastapi_query_all_scheme_all_records(schemetype: str, schemename: str, querydate: str) -> tuple: +async def fastapi_query_all_scheme_all_records( + schemetype: str, schemename: str, querydate: str +) -> tuple: # 缓存查询结果提高性能 global redis_client cache_key = f"queryallschemeallrecords_{schemetype}_{schemename}_{querydate}" @@ -2626,16 +3130,21 @@ async def fastapi_query_all_scheme_all_records(schemetype: str, schemename: str, loaded_dict = msgpack.unpackb(data, object_hook=decode_datetime) return loaded_dict - results = influxdb_api.query_scheme_all_record(scheme_Type=schemetype, scheme_Name=schemename, query_date=querydate) - packed = msgpack.packb(results, default=encode_datetime) + results = influxdb_api.query_scheme_all_record( + scheme_Type=schemetype, scheme_Name=schemename, query_date=querydate + ) + packed = msgpack.packb(results, default=encode_datetime) redis_client.set(cache_key, packed) return results + # DingZQ, 2025-03-21 # 缓存是用的queryallschemeallrecords的缓存 @app.get("/queryschemeallrecordsproperty/") -async def fastapi_query_all_scheme_all_records_property(schemetype: str, schemename: str, querydate: str, querytype: str, queryproperty: str) -> list: +async def fastapi_query_all_scheme_all_records_property( + schemetype: str, schemename: str, querydate: str, querytype: str, queryproperty: str +) -> list: # 缓存查询结果提高性能 global redis_client cache_key = f"queryallschemeallrecords_{schemetype}_{schemename}_{querydate}" @@ -2645,23 +3154,27 @@ async def fastapi_query_all_scheme_all_records_property(schemetype: str, schemen # 使用自定义的反序列化函数 all_results = msgpack.unpackb(data, object_hook=decode_datetime) else: - all_results = influxdb_api.query_scheme_all_record(scheme_Type=schemetype, scheme_Name=schemename, query_date=querydate) - packed = msgpack.packb(all_results, default=encode_datetime) + all_results = influxdb_api.query_scheme_all_record( + scheme_Type=schemetype, scheme_Name=schemename, query_date=querydate + ) + packed = msgpack.packb(all_results, default=encode_datetime) redis_client.set(cache_key, packed) results = None - if querytype == 'node': + if querytype == "node": results = all_results[0] elif querytype == "link": results = all_results[1] return results - + + @app.post("/clearrediskey/") async def fastapi_clear_redis_key(key: str): redis_client.delete(key) return True + @app.post("/clearrediskeys/") async def fastapi_clear_redis_keys(keys: str): # delete keys contains the key @@ -2670,11 +3183,13 @@ async def fastapi_clear_redis_keys(keys: str): return True + @app.post("/clearallredis/") async def fastapi_clear_all_redis(): redis_client.flushdb() return True + @app.get("/queryredis/") async def fastapi_query_redis(): return redis_client.keys("*") @@ -2684,12 +3199,12 @@ async def fastapi_query_redis(): async def fastapi_query_influxdb_buckets(): return influxdb_api.query_buckets() + @app.get("/queryinfluxdbbucketmeasurements/") async def fastapi_query_influxdb_bucket_measurements(bucket: str): return influxdb_api.query_measurements(bucket=bucket) - # DingZQ, 2024-12-31, generate openapi.json def generate_openapi_json(): openapi_json_path = "openapi.json" @@ -2697,8 +3212,6 @@ def generate_openapi_json(): json.dump(app.openapi(), file, indent=4) - - ############################################################ # real_time api 37 # example: http://127.0.0.1:8000/runsimulation?network=beibeizone&start_time=2024-04-01T08:00:00Z @@ -2740,27 +3253,38 @@ def generate_openapi_json(): # #os.rename(filename2, filename) # return result + # DingZQ, 2025-05-17 class Download_History_Data_Manually(BaseModel): """ download_date:样式如 datetime(2025, 5, 4) """ + download_date: datetime + # DingZQ, 2025-05-17 @app.post("/download_history_data_manually/") -async def fastapi_download_history_data_manually(data: Download_History_Data_Manually) -> None: +async def fastapi_download_history_data_manually( + data: Download_History_Data_Manually, +) -> None: item = data.dict() # 创建东八区时区对象 tz = timezone(timedelta(hours=8)) - begin_dt = datetime.combine(item['download_date'].date(), time.min).replace(tzinfo=tz) - end_dt = datetime.combine(item['download_date'].date(), time(23, 59, 59)).replace(tzinfo=tz) + begin_dt = datetime.combine(item["download_date"].date(), time.min).replace( + tzinfo=tz + ) + end_dt = datetime.combine(item["download_date"].date(), time(23, 59, 59)).replace( + tzinfo=tz + ) # 2. 转为字符串 begin_time = begin_dt.isoformat() end_time = end_dt.isoformat() - - influxdb_api.download_history_data_manually(begin_time=begin_time, end_time=end_time) + + influxdb_api.download_history_data_manually( + begin_time=begin_time, end_time=end_time + ) # DingZQ, 2025-05-17 @@ -2769,12 +3293,14 @@ class Run_Simulation_Manually_by_Date(BaseModel): name:数据库名称 simulation_date:样式如 2025-05-04 """ + name: str simulation_date: str + def run_simulation_manually_by_date(network_name: str, base_date: datetime) -> None: # 循环生成96个时间点(15分钟间隔) - for i in range(96): + for i in range(96): # 计算当前时间偏移 time_offset = timedelta(minutes=15 * i) @@ -2788,38 +3314,57 @@ def run_simulation_manually_by_date(network_name: str, base_date: datetime) -> N simulation.run_simulation( name=network_name, simulation_type="realtime", - modify_pattern_start_time=iso_time + modify_pattern_start_time=iso_time, ) + @app.post("/runsimulationmanuallybydate/") -async def fastapi_run_simulation_manually_by_date(data: Run_Simulation_Manually_by_Date) -> None: +async def fastapi_run_simulation_manually_by_date( + data: Run_Simulation_Manually_by_Date, +) -> None: item = data.dict() print(f"item: {item}") - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - simulation.query_corresponding_element_id_and_query_id(item['name']) - simulation.query_corresponding_pattern_id_and_query_id(item['name']) - region_result = simulation.query_non_realtime_region(item['name']) + print("file doesnt exists") + simulation.query_corresponding_element_id_and_query_id(item["name"]) + simulation.query_corresponding_pattern_id_and_query_id(item["name"]) + region_result = simulation.query_non_realtime_region(item["name"]) - globals.source_outflow_region_id = simulation.get_source_outflow_region_id(item['name'], region_result) - globals.realtime_region_pipe_flow_and_demand_id = simulation.query_realtime_region_pipe_flow_and_demand_id( - item['name'], region_result) - globals.pipe_flow_region_patterns = simulation.query_pipe_flow_region_patterns(item['name']) + globals.source_outflow_region_id = simulation.get_source_outflow_region_id( + item["name"], region_result + ) + globals.realtime_region_pipe_flow_and_demand_id = ( + simulation.query_realtime_region_pipe_flow_and_demand_id( + item["name"], region_result + ) + ) + globals.pipe_flow_region_patterns = simulation.query_pipe_flow_region_patterns( + item["name"] + ) - globals.non_realtime_region_patterns = simulation.query_non_realtime_region_patterns(item['name'], region_result) - globals.source_outflow_region_patterns, globals.realtime_region_pipe_flow_and_demand_patterns = \ - simulation.get_realtime_region_patterns( - item['name'], globals.source_outflow_region_id, globals.realtime_region_pipe_flow_and_demand_id) + globals.non_realtime_region_patterns = ( + simulation.query_non_realtime_region_patterns(item["name"], region_result) + ) + ( + globals.source_outflow_region_patterns, + globals.realtime_region_pipe_flow_and_demand_patterns, + ) = simulation.get_realtime_region_patterns( + item["name"], + globals.source_outflow_region_id, + globals.realtime_region_pipe_flow_and_demand_id, + ) - base_date = datetime.strptime(item['simulation_date'], "%Y-%m-%d") + base_date = datetime.strptime(item["simulation_date"], "%Y-%m-%d") - thread = threading.Thread(target=lambda: run_simulation_manually_by_date(item['name'], base_date)) + thread = threading.Thread( + target=lambda: run_simulation_manually_by_date(item["name"], base_date) + ) thread.start() # thread.join() @@ -2866,11 +3411,11 @@ async def fastapi_run_simulation_manually_by_date(data: Run_Simulation_Manually_ # #os.rename(filename2, filename) # return result - + ############################################################ # burst analysis api 38 -#example:http://127.0.0.1:8000/burst_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&burst_ID=ZBBGXSZW000001&burst_size=200&duration=1800 -############################################################ +# example:http://127.0.0.1:8000/burst_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&burst_ID=ZBBGXSZW000001&burst_size=200&duration=1800 +############################################################ # @app.get("/burst_analysis/", response_class = PlainTextResponse) # async def fastapi_burst_analysis(network: str,start_time:str,burst_ID:str,burst_size:float,burst_flow:float=None,duration:int=None) -> str: @@ -2914,28 +3459,30 @@ class BurstAnalysis(BaseModel): modify_valve_opening: Optional[dict[str, float]] = None scheme_Name: Optional[str] = None + @app.post("/burst_analysis/") async def fastapi_burst_analysis(data: BurstAnalysis) -> str: item = data.dict() - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - burst_analysis(name=item['name'], - modify_pattern_start_time=item['modify_pattern_start_time'], - burst_ID=item['burst_ID'], - burst_size=item['burst_size'], - modify_total_duration=item['modify_total_duration'], - modify_fixed_pump_pattern=item['modify_fixed_pump_pattern'], - modify_variable_pump_pattern=item['modify_variable_pump_pattern'], - modify_valve_opening=item['modify_valve_opening'], - scheme_Name=item['scheme_Name'] + print("file doesnt exists") + # os.rename(filename, filename2) + burst_analysis( + name=item["name"], + modify_pattern_start_time=item["modify_pattern_start_time"], + burst_ID=item["burst_ID"], + burst_size=item["burst_size"], + modify_total_duration=item["modify_total_duration"], + modify_fixed_pump_pattern=item["modify_fixed_pump_pattern"], + modify_variable_pump_pattern=item["modify_variable_pump_pattern"], + modify_valve_opening=item["modify_valve_opening"], + scheme_Name=item["scheme_Name"], ) - #os.rename(filename2, filename) + # os.rename(filename2, filename) """ # 将 时间转换成日期,然后缓存这个计算结果 @@ -2959,83 +3506,120 @@ async def fastapi_burst_analysis(data: BurstAnalysis) -> str: return "success" + ############################################################ # valve close analysis api 39 -#example:http://127.0.0.1:8000/valve_close_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&valves=GSD2307192058577780A3287D78&valves=GSD2307192058572E953B707226(S2)&duration=1800 -############################################################ +# example:http://127.0.0.1:8000/valve_close_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&valves=GSD2307192058577780A3287D78&valves=GSD2307192058572E953B707226(S2)&duration=1800 +############################################################ -@app.get("/valve_close_analysis/", response_class = PlainTextResponse) -async def fastapi_valve_close_analysis(network: str,start_time:str,valves:Annotated[list[str], Query()],duration:int=None) -> str: - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + +@app.get("/valve_close_analysis/", response_class=PlainTextResponse) +async def fastapi_valve_close_analysis( + network: str, + start_time: str, + valves: Annotated[list[str], Query()], + duration: int = None, +) -> str: + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') - raise HTTPException(status_code=409, detail="is in simulation") + print("file exists") + raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = valve_close_analysis(network,start_time,valves,duration) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = valve_close_analysis(network, start_time, valves, duration) + # os.rename(filename2, filename) return result + ############################################################ # pipe flushing analysis api 40 -#example:http://127.0.0.1:8000/flushing_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&valves=GSD230719205857733F8F5214FF&valves=GSD230719205857C0AF65B6A170&valves_k=0.5&valves_k=0.5&drainage_node_ID=GSD2307192058570DEDF28E4F73&flush_flow=0&duration=1800 -############################################################ +# example:http://127.0.0.1:8000/flushing_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&valves=GSD230719205857733F8F5214FF&valves=GSD230719205857C0AF65B6A170&valves_k=0.5&valves_k=0.5&drainage_node_ID=GSD2307192058570DEDF28E4F73&flush_flow=0&duration=1800 +############################################################ -@app.get("/flushing_analysis/", response_class = PlainTextResponse) -async def fastapi_flushing_analysis(network: str,start_time:str,valves:Annotated[list[str], Query()],valves_k:Annotated[list[float], Query()],drainage_node_ID:str,flush_flow:float=0,duration:int=None) -> str: - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + +@app.get("/flushing_analysis/", response_class=PlainTextResponse) +async def fastapi_flushing_analysis( + network: str, + start_time: str, + valves: Annotated[list[str], Query()], + valves_k: Annotated[list[float], Query()], + drainage_node_ID: str, + flush_flow: float = 0, + duration: int = None, +) -> str: + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') - raise HTTPException(status_code=409, detail="is in simulation") + print("file exists") + raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = flushing_analysis(network,start_time,valves,valves_k,drainage_node_ID,flush_flow,duration) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = flushing_analysis( + network, + start_time, + valves, + valves_k, + drainage_node_ID, + flush_flow, + duration, + ) + # os.rename(filename2, filename) return result - ############################################################ # contaminant_simulation api 41 -#example:http://127.0.0.1:8000/contaminant_simulation?network=beibeizone&start_time=2024-04-01T08:00:00Z&source=ZBBDTZDP002677&concentration=100&duration=1800 -############################################################ +# example:http://127.0.0.1:8000/contaminant_simulation?network=beibeizone&start_time=2024-04-01T08:00:00Z&source=ZBBDTZDP002677&concentration=100&duration=1800 +############################################################ -@app.get("/contaminant_simulation/", response_class = PlainTextResponse) -async def fastapi_contaminant_simulation(network: str,start_time:str,source:str,concentration:float,duration:int=900,pattern:str=None) -> str: - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + +@app.get("/contaminant_simulation/", response_class=PlainTextResponse) +async def fastapi_contaminant_simulation( + network: str, + start_time: str, + source: str, + concentration: float, + duration: int = 900, + pattern: str = None, +) -> str: + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') - raise HTTPException(status_code=409, detail="is in simulation") + print("file exists") + raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = contaminant_simulation(network,start_time,source,concentration,duration,pattern) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = contaminant_simulation( + network, start_time, source, concentration, duration, pattern + ) + # os.rename(filename2, filename) return result + ############################################################ # age analysis api 42 -#example:http://127.0.0.1:8000/age_analysis/?network=bb&start_time=2024-04-01T00:00:00Z&end_time=2024-04-01T08:00:00Z&duration=28800 +# example:http://127.0.0.1:8000/age_analysis/?network=bb&start_time=2024-04-01T00:00:00Z&end_time=2024-04-01T08:00:00Z&duration=28800 ############################################################ -@app.get("/age_analysis/", response_class = PlainTextResponse) -async def fastapi_age_analysis(network: str, start_time:str, end_time:str, duration:int) -> str: - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' +@app.get("/age_analysis/", response_class=PlainTextResponse) +async def fastapi_age_analysis( + network: str, start_time: str, end_time: str, duration: int +) -> str: + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = age_analysis(network,start_time,end_time,duration) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = age_analysis(network, start_time, end_time, duration) + # os.rename(filename2, filename) return result @@ -3056,18 +3640,23 @@ class SchedulingAnalysis(BaseModel): @app.post("/scheduling_analysis/") async def fastapi_scheduling_analysis(data: SchedulingAnalysis) -> str: data = data.dict() - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = scheduling_simulation(data['network'], data['start_time'], - data['pump_control'], data['tank_id'], - data['water_plant_output_id'], data['time_delta']) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = scheduling_simulation( + data["network"], + data["start_time"], + data["pump_control"], + data["tank_id"], + data["water_plant_output_id"], + data["time_delta"], + ) + # os.rename(filename2, filename) return result @@ -3094,19 +3683,21 @@ class PressureRegulation(BaseModel): @app.post("/pressure_regulation/") async def fastapi_pressure_regulation(data: PressureRegulation) -> str: item = data.dict() - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = pressure_regulation(prj_name=item['network'], - start_datetime=item['start_time'], - pump_control=item['pump_control'], - tank_initial_level_control=item['tank_init_level']) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = pressure_regulation( + prj_name=item["network"], + start_datetime=item["start_time"], + pump_control=item["pump_control"], + tank_initial_level_control=item["tank_init_level"], + ) + # os.rename(filename2, filename) return result @@ -3136,20 +3727,22 @@ class ProjectManagement(BaseModel): @app.post("/project_management/") async def fastapi_project_management(data: ProjectManagement) -> str: item = data.dict() - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = project_management(prj_name=item['network'], - start_datetime=item['start_time'], - pump_control=item['pump_control'], - tank_initial_level_control=item['tank_init_level'], - region_demand_control=item['region_demand']) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = project_management( + prj_name=item["network"], + start_datetime=item["start_time"], + pump_control=item["pump_control"], + tank_initial_level_control=item["tank_init_level"], + region_demand_control=item["region_demand"], + ) + # os.rename(filename2, filename) return result @@ -3164,25 +3757,25 @@ async def fastapi_project_management(data: ProjectManagement) -> str: @app.post("/network_project/") async def fastapi_network_project(file: UploadFile = File()) -> str: - temp_file_path = './inp/' + temp_file_path = "./inp/" if not os.path.exists(temp_file_path): os.mkdir(temp_file_path) temp_file_name = f'network_project_{datetime.now().strftime("%Y%m%d")}' - temp_file_path = f'{temp_file_path}{temp_file_name}.inp' + temp_file_path = f"{temp_file_path}{temp_file_name}.inp" with open(temp_file_path, "wb") as buffer: shutil.copyfileobj(file.file, buffer) buffer.close() - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') + print("file doesnt exists") result = run_inp(temp_file_name) - #os.rename(filename2, filename) + # os.rename(filename2, filename) return result @@ -3204,18 +3797,23 @@ class DailySchedulingAnalysis(BaseModel): @app.post("/daily_scheduling_analysis/") async def fastapi_daily_scheduling_analysis(data: DailySchedulingAnalysis) -> str: data = data.dict() - filename = 'c:/lock.simulation' - filename2 = 'c:/lock.simulation2' + filename = "c:/lock.simulation" + filename2 = "c:/lock.simulation2" if os.path.exists(filename2): - print('file exists') + print("file exists") raise HTTPException(status_code=409, detail="is in simulation") else: - print('file doesnt exists') - #os.rename(filename, filename2) - result = daily_scheduling_simulation(data['network'], data['start_time'], - data['pump_control'], data['reservoir_id'], data['tank_id'], - data['water_plant_output_id']) - #os.rename(filename2, filename) + print("file doesnt exists") + # os.rename(filename, filename2) + result = daily_scheduling_simulation( + data["network"], + data["start_time"], + data["pump_control"], + data["reservoir_id"], + data["tank_id"], + data["water_plant_output_id"], + ) + # os.rename(filename2, filename) return result @@ -3227,7 +3825,7 @@ async def fastapi_daily_scheduling_analysis(data: DailySchedulingAnalysis) -> st @app.post("/network_update/") async def fastapi_network_update(file: UploadFile = File()) -> str: # 默认文件夹 - default_folder = './' + default_folder = "./" # 使用当前时间生成临时文件名 temp_file_name = f'network_update_{datetime.now().strftime("%Y%m%d")}' @@ -3264,32 +3862,43 @@ class PumpFailureState(BaseModel): async def fastapi_pump_failure(data: PumpFailureState) -> str: item = data.dict() - with open('./pump_failure_message.txt', 'a', encoding='utf-8-sig') as f1: - f1.write('[{}] {}\n'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), item)) # save message + with open("./pump_failure_message.txt", "a", encoding="utf-8-sig") as f1: + f1.write( + "[{}] {}\n".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), item) + ) # save message status_info = item.copy() - with open('./pump_failure_status.txt', 'r', encoding='utf-8-sig') as f2: + with open("./pump_failure_status.txt", "r", encoding="utf-8-sig") as f2: lines = f2.readlines() first_stage_pump_status_dict = json.loads(json.dumps(eval(lines[0]))) - second_stage_pump_status_dict = json.loads(json.dumps(eval(lines[-1]))) # read local file - pump_status_dict = {'first': first_stage_pump_status_dict, # first-stage pump - 'second': second_stage_pump_status_dict} # second-stage pump - for pump_type in status_info['pump_status'].keys(): # 'first' or 'second' + second_stage_pump_status_dict = json.loads( + json.dumps(eval(lines[-1])) + ) # read local file + pump_status_dict = { + "first": first_stage_pump_status_dict, # first-stage pump + "second": second_stage_pump_status_dict, + } # second-stage pump + for pump_type in status_info["pump_status"].keys(): # 'first' or 'second' if pump_type in pump_status_dict.keys(): # the type of pumps exists - if all(pump_id in pump_status_dict[pump_type].keys() - for pump_id in status_info['pump_status'][pump_type].keys()): # all pump IDs exist - for pump_id in status_info['pump_status'][pump_type].keys(): + if all( + pump_id in pump_status_dict[pump_type].keys() + for pump_id in status_info["pump_status"][pump_type].keys() + ): # all pump IDs exist + for pump_id in status_info["pump_status"][pump_type].keys(): pump_status_dict[pump_type][pump_id] = int( - status_info['pump_status'][pump_type][pump_id]) # modify status dict + status_info["pump_status"][pump_type][pump_id] + ) # modify status dict else: - return json.dumps('ERROR: Wrong Pump ID') + return json.dumps("ERROR: Wrong Pump ID") else: - return json.dumps('ERROR: Wrong Pump Type') + return json.dumps("ERROR: Wrong Pump Type") - with open('./pump_failure_status.txt', 'w', encoding='utf-8-sig') as f2_: - f2_.write('{}\n{}'.format(pump_status_dict['first'], pump_status_dict['second'])) # save local file + with open("./pump_failure_status.txt", "w", encoding="utf-8-sig") as f2_: + f2_.write( + "{}\n{}".format(pump_status_dict["first"], pump_status_dict["second"]) + ) # save local file - return json.dumps('SUCCESS') + return json.dumps("SUCCESS") ############################################################ @@ -3305,20 +3914,19 @@ class Pressure_Sensor_Placement_Sensitivity(BaseModel): @app.post("/pressure_sensor_placement_sensitivity/") -async def fastapi_pressure_sensor_placement_sensitivity(data: Pressure_Sensor_Placement_Sensitivity) -> None: +async def fastapi_pressure_sensor_placement_sensitivity( + data: Pressure_Sensor_Placement_Sensitivity, +) -> None: item = data.dict() - pressure_sensor_placement_sensitivity(name=item['name'], - scheme_name=item['scheme_name'], - sensor_number=item['sensor_number'], - min_diameter=item['min_diameter'], - username=item['username'] + pressure_sensor_placement_sensitivity( + name=item["name"], + scheme_name=item["scheme_name"], + sensor_number=item["sensor_number"], + min_diameter=item["min_diameter"], + username=item["username"], ) - - - - class Item(BaseModel): str_info: str dict_info: Optional[dict] = None @@ -3331,8 +3939,9 @@ async def get_dict(item: Item): if __name__ == "__main__": - #uvicorn.run(app, host="0.0.0.0", port=8000) - #url='http://127.0.0.1:8000/valve_close_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&valve_IDs=GSD2307192058577780A3287D78&valve_IDs=GSD2307192058572E953B707226(S2)&duration=1800' - url='http://127.0.0.1:8000/burst_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&burst_ID=ZBBGXSZW000001&duration=1800' - Request.get(url,) - + # uvicorn.run(app, host="0.0.0.0", port=8000) + # url='http://127.0.0.1:8000/valve_close_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&valve_IDs=GSD2307192058577780A3287D78&valve_IDs=GSD2307192058572E953B707226(S2)&duration=1800' + url = "http://127.0.0.1:8000/burst_analysis?network=beibeizone&start_time=2024-04-01T08:00:00Z&burst_ID=ZBBGXSZW000001&duration=1800" + Request.get( + url, + )