From 9e58ca9254e15d0927cb099a15468ce7e13088f8 Mon Sep 17 00:00:00 2001 From: DingZQ Date: Sat, 22 Feb 2025 17:18:43 +0800 Subject: [PATCH] Refine --- main.py | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 213 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 747d931..c7f5de8 100644 --- a/main.py +++ b/main.py @@ -461,6 +461,23 @@ async def fastapi_is_pump(network: str, link: str) -> bool: 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/') +async def fastapi_get_link_type(network: str, link: str) -> str: + return get_link_type(network, link) + +@app.get('/getelementtype/') +async def fastapi_get_element_type(network: str, element: str) -> str: + return get_element_type(network, element) + +@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/') async def fastapi_is_curve(network: str, curve: str) -> bool: return is_curve(network, curve) @@ -489,6 +506,29 @@ async def fastapi_get_patterns(network: str) -> list[str]: 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/') +async def fast_get_node_properties(network: str, node: str) -> dict[str, Any]: + return get_node_properties(network, node) + +@app.get('/getlinkproperties/') +async def fast_get_link_properties(network: str, link: str) -> dict[str, Any]: + return get_link_properties(network, link) + +# type can be 'node' or 'link' or 'scada' +@app.get('/getelementpropertieswithtype/') +async def fast_get_element_properties_with_type(network: str, type: str, element: str) -> dict[str, Any]: + return get_element_properties(network, type, element) + +# type can be 'node' or 'link' or 'scada' +@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] ############################################################ @@ -1521,6 +1561,64 @@ 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 +# node type: junction, reservoir, tank +# link type: pipe, pump, valve +@app.get("/getnetworkgeometries/") +async def fastapi_get_network_geometries(network: str) -> dict[str, Any] | None: + coords = get_network_node_coords(network) + nodes = [] + 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) + + return { 'nodes': nodes, + 'links': links, + 'scadas': scadas } + +# 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: + start_time = time.time() + coords = get_major_node_coords(network, diameter) + end_time = time.time() + logger.info("get_major_node_coords: %s, time: %s", coords, end_time - start_time) + + result = [] + for node_id, coord in coords.items(): + 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: + 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 } + +# 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/") +async def fastapi_get_major_pipe_nodes(network: str, diameter: int) -> list[str] | None: + start_time = time.time() + result = get_major_pipe_nodes(network, diameter) + end_time = time.time() + logger.info("get_major_pipe_nodes: %s, time: %s", result, end_time - start_time) + return result + ############################################################ # vertex 25.[VERTICES] ############################################################ @@ -1682,7 +1780,7 @@ async def fastapi_get_scada_element_schema(network: str) -> dict[str, dict[str, @app.get('/getscadaelements/') async def fastapi_get_scada_elements(network: str) -> list[str]: - return get_scada_elements(network) + return get_all_scada_elements(network) @app.get('/getscadaelement/') async def fastapi_get_scada_element(network: str, id: str) -> dict[str, Any]: @@ -1932,6 +2030,35 @@ async def download_inp(name: str, response: Response): response.status_code = status.HTTP_400_BAD_REQUEST return True + +# DingZQ, 2024-12-28, convert v3 to v2 +@app.get("/convertv3tov2/",response_model=None) +async def fastapi_convert_v3_to_v2(req: Request) -> ChangeSet: + network = 'v3Tov2' + jo_root = await req.json() + 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') + + db = get_extension_data(network, 'scada_db') + print(db) + scada_db = '' + if db: + scada_db = db + print(scada_db) + op['scada_db'] = scada_db + + close_project(network) + + return cs + @app.get("/getjson/") async def get_json(): return JSONResponse( @@ -1943,6 +2070,91 @@ async def get_json(): } ) + +############################################################ +# DingZQ, 2024-12-09, Add sample API to return real time data/simulation result +# influx db operation +############################################################ +@app.get("/getrealtimedata/") +async def get_realtimedata(): + data = [random.randint(0, 100) for _ in range(100)] + return data + +@app.get("/getsimulationresult/") +async def 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 query_node_latest_record_by_id(id: str): + return influxdb_api.query_latest_record_by_ID(id, type='node', client=influx_client) + +@app.get("/querylinklatestrecordbyid/") +async def query_link_latest_record_by_id(id: str): + return influxdb_api.query_latest_record_by_ID(id, type='link', client=influx_client) + +# query scada +@app.get("/queryscadalatestrecordbyid/") +async def query_scada_latest_record_by_id(id: str): + return influxdb_api.query_latest_record_by_ID(id, type='scada', client=influx_client) + + + +# def query_all_record_by_time(query_time: str, bucket: str="realtime_data", client: InfluxDBClient=client) -> tuple: +@app.get("/queryallrecordbytime/") +async def query_all_record_by_time(querytime: str) -> dict[str, list]: + results: tuple = influxdb_api.query_all_record_by_time(query_time=querytime, client=influx_client) + return { "nodes": results[0], + "links": results[1] } + +# 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 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, client=influx_client) + +@app.get("/querylinkcurvebyidpropertydaterange/") +async def 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, client=influx_client) + +# 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 query_scada_data_by_device_id_and_time(ids: str, querytime: str): + 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, client=influx_client) + +@app.get("/queryscadadatabydeviceidandtimerange/") +async def query_scada_data_by_device_id_and_time_range(ids: str, starttime: str, endtime: str): + query_ids = ids.split(',') + return influxdb_api.query_SCADA_data_by_device_ID_and_time_range(query_ids_list=query_ids, start_time=starttime, end_time=endtime, client=influx_client) + + + +@app.get("/queryinfluxdbbuckets/") +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" + with open(openapi_json_path, "w") as file: + 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