refactor(storage): route project DSNs and remove legacy backends

This commit is contained in:
2026-08-18 18:29:09 +08:00
parent b21eaffe40
commit 6b09662de6
51 changed files with 542 additions and 10951 deletions
-25
View File
@@ -1,25 +0,0 @@
import auto_realtime
import auto_store_non_realtime_SCADA_data
import asyncio
import influxdb_api
import influxdb_info
import project_info
# 为了让多个任务并发运行,我们可以用 asyncio.to_thread 分别启动它们
async def main():
task1 = asyncio.to_thread(auto_realtime.realtime_task)
task2 = asyncio.to_thread(auto_store_non_realtime_SCADA_data.store_non_realtime_SCADA_data_task)
await asyncio.gather(task1, task2)
if __name__ == "__main__":
url = influxdb_info.url
token = influxdb_info.token
org_name = influxdb_info.org
influxdb_api.query_pg_scada_info_realtime(project_info.name)
influxdb_api.query_pg_scada_info_non_realtime(project_info.name)
# 用 asyncio 并发启动两个任务
asyncio.run(main())
-115
View File
@@ -1,115 +0,0 @@
import schedule
import time
import datetime
import shutil
import redis
import urllib.request
import influxdb_api
import msgpack
import datetime
# 将 Query的信息 序列号到 redis/json 默认不支持datetime,需要自定义
# 自定义序列化函数
# 序列化处理器
def encode_datetime(obj):
"""将datetime转换为可序列化的字典结构"""
if isinstance(obj, datetime.datetime):
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.datetime.strptime(
obj['as_str'], "%Y%m%dT%H:%M:%S.%f"
)
return obj
##########################
# 需要用Python 3.12 来运行才能提高performance
##########################
def queryallrecordsbydate(querydate: str, redis_client: redis.Redis):
cache_key = f"queryallrecordsbydate_{querydate}"
exists = redis_client.exists(cache_key)
if not exists:
nodes_links: tuple = influxdb_api.query_all_records_by_date(query_date=querydate)
redis_client.set(cache_key, msgpack.packb(nodes_links, default=encode_datetime))
def queryallrecordsbydate_by_url(querydate: str):
print(f'queryallrecordsbydate: {querydate}')
try:
response = urllib.request.urlopen(
f"http://127.0.0.1/queryallrecordsbydate/?querydate={querydate}"
)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
print("Error")
def queryallscadarecordsbydate(querydate: str, redis_client: redis.Redis):
cache_key = f"queryallscadarecordsbydate_{querydate}"
exists = redis_client.exists(cache_key)
if not exists:
result_dict = influxdb_api.query_all_SCADA_records_by_date(query_date=querydate)
redis_client.set(cache_key, msgpack.packb(result_dict, default=encode_datetime))
def queryallscadarecordsbydate_by_url(querydate: str):
print(f'queryallscadarecordsbydate: {querydate}')
try:
response = urllib.request.urlopen(
f"http://127.0.0.1/queryallscadarecordsbydate/?querydate={querydate}"
)
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
print("Error")
def auto_cache_data():
# 初始化 Redis 连接
# 用redis 限制并发访u
redis_client = redis.Redis(host="127.0.0.1", port=6379, db=0)
# auto cache data for the last 3 days
today = datetime.date.today()
for i in range(1, 4):
prev_day = today - datetime.timedelta(days=i)
str_prev_day = prev_day.strftime('%Y-%m-%d')
print(str_prev_day)
queryallrecordsbydate(str_prev_day, redis_client)
queryallscadarecordsbydate(str_prev_day, redis_client)
redis_client.close()
def auto_cache_data_by_url():
# auto cache data for the last 3 days
today = datetime.date.today()
for i in range(1, 4):
prev_day = today - datetime.timedelta(days=i)
str_prev_day = prev_day.strftime('%Y-%m-%d')
print(str_prev_day)
queryallrecordsbydate_by_url(str_prev_day)
queryallscadarecordsbydate_by_url(str_prev_day)
if __name__ == "__main__":
auto_cache_data_by_url()
# auto run in the midnight
schedule.every().day.at("03:00").do(auto_cache_data_by_url)
while True:
schedule.run_pending()
time.sleep(1)
-156
View File
@@ -1,156 +0,0 @@
from logging.handlers import TimedRotatingFileHandler
import influxdb_api
import os
import logging
import globals
from datetime import datetime, timedelta, timezone
import schedule
import time
import shutil
from influxdb_client import InfluxDBClient, BucketsApi, WriteApi, OrganizationsApi, Point, QueryApi
import simulation
import influxdb_info
import project_info
def setup_logger():
# 创建日志目录
log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)
# 配置基础日志格式
log_format = "%(asctime)s - %(levelname)s - %(message)s"
formatter = logging.Formatter(log_format)
# 创建主 Logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 全局日志级别
# --- 1. 按日期分割的日志文件 Handler ---
log_file = os.path.join(log_dir, "simulation.log")
file_handler = TimedRotatingFileHandler(
filename=log_file,
when="midnight", # 每天午夜轮转
interval=1,
backupCount=7,
encoding="utf-8"
)
file_handler.suffix = "simulation-%Y-%m-%d.log" # 文件名格式
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.INFO) # 文件记录所有级别日志
# --- 2. 控制台实时输出 Handler ---
console_handler = logging.StreamHandler() # 默认输出到 sys.stderr (控制台)
console_handler.setFormatter(formatter)
console_handler.setLevel(logging.INFO) # 控制台仅显示 INFO 及以上级别
# 将 Handler 添加到 Logger
logger.addHandler(file_handler)
#logger.addHandler(console_handler)
return logger
logger = setup_logger()
# 2025/02/01
def get_next_time() -> str:
"""
获取下一个1分钟时间点,返回格式为字符串'YYYY-MM-DDTHH:MM:00+08:00'
:return: 返回字符串格式的时间,表示下一个1分钟的时间点
"""
# 获取当前时间,并设定为北京时间
now = datetime.now() # now 类型为 datetime,表示当前本地时间
# 获取当前的分钟,并且将秒和微秒置为零
current_time = now.replace(second=0, microsecond=0) # current_time 类型为 datetime,时间的秒和微秒部分被清除
return current_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
# 2025/02/06
def store_realtime_SCADA_data_job() -> None:
"""
定义的任务1,每分钟执行1次,每次执行时,更新get_real_value_time并调用store_realtime_SCADA_data_to_influxdb函数
:return: None
"""
# 获取当前时间并更新get_real_value_time,转换为字符串格式
get_real_value_time: str = get_next_time() # get_real_value_time 类型为 str,格式为'2025-02-01T18:45:00+08:00'
# 调用函数执行任务
influxdb_api.store_realtime_SCADA_data_to_influxdb(get_real_value_time)
logger.info('{} -- Successfully store realtime SCADA data.'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
# 2025/02/06
def get_next_15minute_time() -> str:
"""
获取下一个15分钟的时间点,返回格式为字符串'YYYY-MM-DDTHH:MM:00+08:00'
:return: 返回字符串格式的时间,表示下一个15分钟执行时间点
"""
now = datetime.now()
# 向上舍入到下一个15分钟
next_15minute = (now.minute // 15 + 1) * 15 - 15
if next_15minute == 60:
next_15minute = 0
now = now + timedelta(hours=1)
next_time = now.replace(minute=next_15minute, second=0, microsecond=0)
return next_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
# 2025/02/07
def run_simulation_job() -> None:
"""
定义的任务3,每15分钟执行一次在store_realtime_SCADA_data_to_influxdb之后执行run_simulation。
:return: None
"""
# 获取当前时间,并检查是否是整点15分钟
current_time = datetime.now()
if current_time.minute % 15 == 0:
print(f"{current_time.strftime('%Y-%m-%d %H:%M:%S')} -- Start simulation task.")
# 计算前,获取scada_info中的信息,按照设定的方法修改pg数据库
simulation.query_corresponding_element_id_and_query_id(project_info.name)
simulation.query_corresponding_pattern_id_and_query_id(project_info.name)
region_result = simulation.query_non_realtime_region(project_info.name)
globals.source_outflow_region_id = simulation.get_source_outflow_region_id(project_info.name, region_result)
globals.realtime_region_pipe_flow_and_demand_id = simulation.query_realtime_region_pipe_flow_and_demand_id(project_info.name, region_result)
globals.pipe_flow_region_patterns = simulation.query_pipe_flow_region_patterns(project_info.name)
globals.non_realtime_region_patterns = simulation.query_non_realtime_region_patterns(project_info.name, region_result)
globals.source_outflow_region_patterns, realtime_region_pipe_flow_and_demand_patterns = simulation.get_realtime_region_patterns(project_info.name,
globals.source_outflow_region_id,
globals.realtime_region_pipe_flow_and_demand_id)
modify_pattern_start_time: str = get_next_15minute_time() # 获取下一个15分钟时间点
# print(modify_pattern_start_time)
simulation.run_simulation(name=project_info.name, simulation_type="realtime", modify_pattern_start_time=modify_pattern_start_time)
logger.info('{} -- Successfully run simulation and store realtime simulation result.'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
else:
logger.info(f"{current_time.strftime('%Y-%m-%d %H:%M:%S')} -- Skipping the simulation task.")
# 2025/02/06
def realtime_task() -> None:
"""
定时执行任务1和,使用schedule库每1分钟执行一次store_realtime_SCADA_data_job函数。
该任务会一直运行,定期调用store_realtime_SCADA_data_job获取SCADA数据。
:return:
"""
# 等待到整分对齐
now = datetime.now()
wait_seconds = 60 - now.second
time.sleep(wait_seconds)
# 使用 .at(":00") 指定在每分钟的第0秒执行
schedule.every(1).minute.at(":00").do(store_realtime_SCADA_data_job)
# 每15分钟执行一次run_simulation_job
schedule.every(1).minute.at(":00").do(run_simulation_job)
# 持续执行任务,检查是否有待执行的任务
while True:
schedule.run_pending() # 执行所有待处理的定时任务
time.sleep(1) # 暂停1秒,避免过于频繁的任务检查
if __name__ == "__main__":
url = influxdb_info.url
token = influxdb_info.token
org_name = influxdb_info.org
client = InfluxDBClient(url=url, token=token)
# step2: 先查询pg数据库中scada_info的信息,然后存储SCADA数据到SCADA_data这个bucket里
influxdb_api.query_pg_scada_info_realtime(project_info.name)
# 自动执行
realtime_task()
@@ -1,139 +0,0 @@
import influxdb_api
import globals
from datetime import datetime, timedelta, timezone
import schedule
import os
import logging
from logging.handlers import TimedRotatingFileHandler
import time
from influxdb_client import InfluxDBClient, BucketsApi, WriteApi, OrganizationsApi, Point, QueryApi
import influxdb_info
import project_info
def setup_logger():
# 创建日志目录
log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)
# 配置基础日志格式
log_format = "%(asctime)s - %(levelname)s - %(message)s"
formatter = logging.Formatter(log_format)
# 创建主 Logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # 全局日志级别
# --- 1. 按日期分割的日志文件 Handler ---
log_file = os.path.join(log_dir, "scada.log")
file_handler = TimedRotatingFileHandler(
filename=log_file,
when="midnight", # 每天午夜轮转
interval=1,
backupCount=7,
encoding="utf-8"
)
file_handler.suffix = "scada-%Y-%m-%d.log" # 文件名格式
file_handler.setFormatter(formatter)
file_handler.setLevel(logging.INFO) # 文件记录 INFO 及以上级别
# --- 2. 控制台实时输出 Handler ---
console_handler = logging.StreamHandler() # 默认输出到 sys.stderr (控制台)
console_handler.setFormatter(formatter)
console_handler.setLevel(logging.INFO) # 控制台仅显示 INFO 及以上级别
# 将 Handler 添加到 Logger
logger.addHandler(file_handler)
# logger.addHandler(console_handler)
return logger
logger = setup_logger()
# 2025/02/01
def get_next_time() -> str:
"""
获取下一个1分钟时间点,返回格式为字符串'YYYY-MM-DDTHH:MM:00+08:00'
:return: 返回字符串格式的时间,表示下一个1分钟的时间点
"""
# 获取当前时间,并设定为北京时间
now = datetime.now() # now 类型为 datetime,表示当前本地时间
# 获取当前的分钟,并且将秒和微秒置为零
current_time = now.replace(second=0, microsecond=0) # current_time 类型为 datetime,时间的秒和微秒部分被清除
return current_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
# 2025/02/06
def get_next_period_time() -> str:
"""
获取下一个6小时时间点,返回格式为字符串'YYYY-MM-DDTHH:00:00+08:00'
:return: 返回字符串格式的时间,表示下一个6小时执行时间点
"""
# 获取当前时间,并设定为北京时间
now = datetime.now() # now 类型为 datetime,表示当前本地时间
# 获取当前的小时数并计算下一个6小时时间点
next_period_hour = (now.hour // 6 + 1) * 6 - 6 # next_period_hour 类型为 int,表示下一个6小时时间点的小时部分
# 如果计算的小时大于23,表示进入第二天,调整为00:00
if next_period_hour >= 24:
next_period_hour = 0
now = now + timedelta(days=1) # 如果超过24小时,日期增加1天
# 将秒和微秒部分清除,构建出下一个6小时点的datetime对象
next_period_time = now.replace(hour=next_period_hour, minute=0, second=0, microsecond=0)
return next_period_time.strftime('%Y-%m-%dT%H:%M:%S+08:00') # 格式化为指定的字符串格式并返回
# 2025/02/06
def store_non_realtime_SCADA_data_job() -> None:
"""
定义的任务2,每6小时执行一次,在0点、6点、12点、18点执行,执行时,更新get_history_data_end_time并调用store_non_realtime_SCADA_data_to_influxdb函数
:return: None
"""
# 获取当前时间
current_time = datetime.now()
# 只在0点、6点、12点、18点执行任务
# if current_time.hour % 6 == 0 and current_time.minute == 0:
if current_time.minute % 10 == 0:
logger.info(f"{current_time.strftime('%Y-%m-%d %H:%M:%S')} -- Start store non realtime SCADA data task.")
# 获取下一个6小时的时间点,并更新get_history_data_end_time
get_history_data_end_time: str = get_next_time() # get_history_data_end_time 类型为 str,格式为'2025-02-06T12:00:00+08:00'
# print(get_next_time)
# 调用函数执行任务
influxdb_api.store_non_realtime_SCADA_data_to_influxdb(get_history_data_end_time)
logger.info('{} -- Successfully store non realtime SCADA data.'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
else:
logger.info(f"{current_time.strftime('%Y-%m-%d %H:%M:%S')} -- Skipping store non realtime SCADA data task.")
# 2025/02/06
def store_non_realtime_SCADA_data_task() -> None:
"""
定时执行6小时的任务,使用schedule库每分钟执行一次store_non_realtime_SCADA_data_job函数。
该任务会一直运行,定期调用store_non_realtime_SCADA_data_job获取SCADA数据。
:return:
"""
# 等待到整分对齐
now = datetime.now()
wait_seconds = 60 - now.second
time.sleep(wait_seconds)
try:
# 每分钟检查一次,执行store_non_realtime_SCADA_data_job
schedule.every(1).minute.at(":00").do(store_non_realtime_SCADA_data_job)
# 持续执行任务,检查是否有待执行的任务
while True:
schedule.run_pending() # 执行所有待处理的定时任务
time.sleep(1) # 暂停1秒,避免过于频繁的任务检查
pass
except Exception as e:
logger.error(f"Error occurred in store_non_realtime_SCADA_data_task: {e}")
if __name__ == "__main__":
url = influxdb_info.url
token = influxdb_info.token
org_name = influxdb_info.org
client = InfluxDBClient(url=url, token=token)
# step2: 先查询pg数据库中scada_info的信息,然后存储SCADA数据到SCADA_data这个bucket里
influxdb_api.query_pg_scada_info_non_realtime(project_info.name)
# 自动执行
store_non_realtime_SCADA_data_task()
+1 -6
View File
@@ -2,9 +2,6 @@ from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize([
"main.py",
"auto_realtime.py",
"auto_store_non_realtime_SCADA_data.py",
"tjnetwork.py",
"online_Analysis.py",
"sensitivity.py",
@@ -15,10 +12,8 @@ setup(ext_modules=cythonize([
"get_data.py",
"get_current_total_Q.py",
"get_current_status.py",
"influxdb_api.py",
"influxdb_query_SCADA_data.py",
"simulation.py",
"time_api.py",
"api/*.py",
"epanet/*.py"
]))
]))
-2
View File
@@ -121,7 +121,6 @@ def get_history_data(
# print(data)
# # 定义 CSV 文件的路径
# csv_file_path = './influxdb_data_4984.csv'
# # 将数据写入 CSV 文件
# # with open(csv_file_path, mode='w', newline='') as file:
# # writer = csv.writer(file)
@@ -143,7 +142,6 @@ def get_history_data(
# #
# # print(f"数据已保存到 {csv_file_path}")
#
# filtered_csv_file_path = './filtered_influxdb_data_4984.csv'
# #
# # # # 读取并筛选数据
# data_list1 = []
-2
View File
@@ -18,14 +18,12 @@ def install():
packages = [
'"psycopg[binary]"',
'pytest',
'influxdb_client',
'numpy',
'fastapi',
"msgpack",
'schedule',
'pandas',
'openpyxl',
'redis',
'pydantic',
'python-dateutil',
'starlette',
-4481
View File
File diff suppressed because it is too large Load Diff
-395
View File
@@ -1,395 +0,0 @@
# API Endpoints (scripts/main.py)
Non-commented FastAPI routes defined in `scripts/main.py`.
- `POST /login/`
- `GET /getallextensiondatakeys/`
- `GET /getallextensiondata/`
- `GET /getextensiondata/`
- `POST /setextensiondata`
- `GET /listprojects/`
- `GET /haveproject/`
- `POST /createproject/`
- `POST /deleteproject/`
- `GET /isprojectopen/`
- `POST /openproject/`
- `POST /closeproject/`
- `POST /copyproject/`
- `POST /importinp/`
- `GET /exportinp/`
- `POST /readinp/`
- `GET /dumpinp/`
- `GET /runproject/`
- `GET /runprojectreturndict/`
- `GET /runinp/`
- `GET /dumpoutput/`
- `GET /isprojectlocked/`
- `GET /isprojectlockedbyme/`
- `POST /lockproject/`
- `POST /unlockproject/`
- `GET /getcurrentoperationid/`
- `POST /undo/`
- `POST /redo/`
- `GET /getsnapshots/`
- `GET /havesnapshot/`
- `GET /havesnapshotforoperation/`
- `GET /havesnapshotforcurrentoperation/`
- `POST /takesnapshotforoperation/`
- `POST takenapshotforcurrentoperation`
- `POST /takesnapshot/`
- `POST /picksnapshot/`
- `POST /pickoperation/`
- `GET /syncwithserver/`
- `POST /batch/`
- `POST /compressedbatch/`
- `GET /getrestoreoperation/`
- `POST /setrestoreoperation/`
- `GET /isnode/`
- `GET /isjunction/`
- `GET /isreservoir/`
- `GET /istank/`
- `GET /islink/`
- `GET /ispipe/`
- `GET /ispump/`
- `GET /isvalve/`
- `GET /getnodetype/`
- `GET /getlinktype/`
- `GET /getelementtype/`
- `GET /getelementtypevalue/`
- `GET /iscurve/`
- `GET /ispattern/`
- `GET /getnodes/`
- `GET /getlinks/`
- `GET /getcurves/`
- `GET /getpatterns/`
- `GET /getnodelinks/`
- `GET /getnodeproperties/`
- `GET /getlinkproperties/`
- `GET /getscadaproperties/`
- `GET /getallscadaproperties/`
- `GET /getelementpropertieswithtype/`
- `GET /getelementproperties/`
- `GET /gettitleschema/`
- `GET /gettitle/`
- `GET /settitle/`
- `GET /getjunctionschema`
- `POST /addjunction/`
- `POST /deletejunction/`
- `GET /getjunctionelevation/`
- `GET /getjunctionx/`
- `GET /getjunctiony/`
- `GET /getjunctioncoord/`
- `GET /getjunctiondemand/`
- `GET /getjunctionpattern/`
- `POST /setjunctionelevation/`
- `POST /setjunctionx/`
- `POST /setjunctiony/`
- `POST /setjunctioncoord/`
- `POST /setjunctiondemand/`
- `POST /setjunctionpattern/`
- `GET /getjunctionproperties/`
- `GET /getalljunctionproperties/`
- `POST /setjunctionproperties/`
- `GET /getreservoirschema`
- `POST /addreservoir/`
- `POST /deletereservoir/`
- `GET /getreservoirhead/`
- `GET /getreservoirpattern/`
- `GET /getreservoirx/`
- `GET /getreservoiry/`
- `GET /getreservoircoord/`
- `POST /setreservoirhead/`
- `POST /setreservoirpattern/`
- `POST /setreservoirx/`
- `POST /setreservoirx/`
- `POST /setreservoircoord/`
- `GET /getreservoirproperties/`
- `GET /getallreservoirproperties/`
- `POST /setreservoirproperties/`
- `GET /gettankschema`
- `POST /addtank/`
- `POST /deletetank/`
- `GET /gettankelevation/`
- `GET /gettankinitlevel/`
- `GET /gettankminlevel/`
- `GET /gettankmaxlevel/`
- `GET /gettankdiameter/`
- `GET /gettankminvol/`
- `GET /gettankvolcurve/`
- `GET /gettankoverflow/`
- `GET /gettankx/`
- `GET /gettanky/`
- `GET /gettankcoord/`
- `POST /settankelevation/`
- `POST /settankinitlevel/`
- `POST /settankminlevel/`
- `POST /settankmaxlevel/`
- `POST settankdiameter//`
- `POST /settankminvol/`
- `POST /settankvolcurve/`
- `POST /settankoverflow/`
- `POST /settankx/`
- `POST /settanky/`
- `POST /settankcoord/`
- `GET /gettankproperties/`
- `GET /getalltankproperties/`
- `POST /settankproperties/`
- `GET /getpipeschema`
- `POST /addpipe/`
- `POST /deletepipe/`
- `GET /getpipenode1/`
- `GET /getpipenode2/`
- `GET /getpipelength/`
- `GET /getpipediameter/`
- `GET /getpiperoughness/`
- `GET /getpipeminorloss/`
- `GET /getpipestatus/`
- `POST /setpipenode1/`
- `POST /setpipenode2/`
- `POST /setpipelength/`
- `POST /setpipediameter/`
- `POST /setpiperoughness/`
- `POST /setpipeminorloss/`
- `POST /setpipestatus/`
- `GET /getpipeproperties/`
- `GET /getallpipeproperties/`
- `POST /setpipeproperties/`
- `GET /getpumpschema`
- `POST /addpump/`
- `POST /deletepump/`
- `GET /getpumpnode1/`
- `GET /getpumpnode2/`
- `POST /setpumpnode1/`
- `POST /setpumpnode2/`
- `GET /getpumpproperties/`
- `GET /getallpumpproperties/`
- `POST /setpumpproperties/`
- `GET /getvalveschema`
- `POST /addvalve/`
- `POST /deletevalve/`
- `GET /getvalvenode1/`
- `GET /getvalvenode2/`
- `GET /getvalvediameter/`
- `GET /getvalvetype/`
- `GET /getvalvesetting/`
- `GET /getvalveminorloss/`
- `POST /setvalvenode1/`
- `POST /setvalvenode2/`
- `POST /setvalvenodediameter/`
- `POST /setvalvetype/`
- `POST /setvalvesetting/`
- `GET /getvalveproperties/`
- `GET /getallvalveproperties/`
- `POST /setvalveproperties/`
- `POST /deletenode/`
- `POST /deletelink/`
- `GET /gettagschema/`
- `GET /gettag/`
- `GET /gettags/`
- `POST /settag/`
- `GET /getdemandschema`
- `GET /getdemandproperties/`
- `POST /setdemandproperties/`
- `GET /getstatusschema`
- `GET /getstatus/`
- `POST /setstatus/`
- `GET /getpatternschema`
- `POST /addpattern/`
- `POST /deletepattern/`
- `GET /getpatternproperties/`
- `POST /setpatternproperties/`
- `GET /getcurveschema`
- `POST /addcurve/`
- `POST /deletecurve/`
- `GET /getcurveproperties/`
- `POST /setcurveproperties/`
- `GET /getcontrolschema/`
- `GET /getcontrolproperties/`
- `POST /setcontrolproperties/`
- `GET /getruleschema/`
- `GET /getruleproperties/`
- `POST /setruleproperties/`
- `GET /getenergyschema/`
- `GET /getenergyproperties/`
- `POST /setenergyproperties/`
- `GET /getpumpenergyschema/`
- `GET /getpumpenergyproperties//`
- `GET /setpumpenergyproperties//`
- `GET /getemitterschema`
- `GET /getemitterproperties/`
- `POST /setemitterproperties/`
- `GET /getqualityschema/`
- `GET /getqualityproperties/`
- `POST /setqualityproperties/`
- `GET /getsourcechema/`
- `GET /getsource/`
- `POST /setsource/`
- `POST /addsource/`
- `POST /deletesource/`
- `GET /getreactionschema/`
- `GET /getreaction/`
- `POST /setreaction/`
- `GET /getpipereactionschema/`
- `GET /getpipereaction/`
- `POST /setpipereaction/`
- `GET /gettankreactionschema/`
- `GET /gettankreaction/`
- `POST /settankreaction/`
- `GET /getmixingschema/`
- `GET /getmixing/`
- `POST /setmixing/`
- `POST /addmixing/`
- `POST /deletemixing/`
- `GET /gettimeschema`
- `GET /gettimeproperties/`
- `POST /settimeproperties/`
- `GET /getoptionschema/`
- `GET /getoptionproperties/`
- `POST /setoptionproperties/`
- `GET /getnodecoord/`
- `GET /getnetworkgeometries/`
- `GET /getmajornodecoords/`
- `GET /getnetworkinextent/`
- `GET /getnetworklinknodes/`
- `GET /getmajorpipenodes/`
- `GET /getvertexschema/`
- `GET /getvertexproperties/`
- `POST /setvertexproperties/`
- `POST /addvertex/`
- `POST /deletevertex/`
- `GET /getallvertexlinks/`
- `GET /getallvertices/`
- `GET /getlabelschema/`
- `GET /getlabelproperties/`
- `POST /setlabelproperties/`
- `POST /addlabel/`
- `POST /deletelabel/`
- `GET /getbackdropschema/`
- `GET /getbackdropproperties/`
- `POST /setbackdropproperties/`
- `GET /getscadadeviceschema/`
- `GET /getscadadevice/`
- `POST /setscadadevice/`
- `POST /addscadadevice/`
- `POST /deletescadadevice/`
- `POST /cleanscadadevice/`
- `GET /getallscadadeviceids/`
- `GET /getallscadadevices/`
- `GET /getscadadevicedataschema/`
- `GET /getscadadevicedata/`
- `POST /setscadadevicedata/`
- `POST /addscadadevicedata/`
- `POST /deletescadadevicedata/`
- `POST /cleanscadadevicedata/`
- `GET /getscadaelementschema/`
- `GET /getscadaelements/`
- `GET /getscadaelement/`
- `POST /setscadaelement/`
- `POST /addscadaelement/`
- `POST /deletescadaelement/`
- `POST /cleanscadaelement/`
- `GET /getregionschema/`
- `GET /getregion/`
- `POST /setregion/`
- `POST /addregion/`
- `POST /deleteregion/`
- `GET /calculatedistrictmeteringareafornodes/`
- `GET /calculatedistrictmeteringareaforregion/`
- `GET /calculatedistrictmeteringareafornetwork/`
- `GET /getdistrictmeteringareaschema/`
- `GET /getdistrictmeteringarea/`
- `POST /setdistrictmeteringarea/`
- `POST /adddistrictmeteringarea/`
- `POST /deletedistrictmeteringarea/`
- `GET /getalldistrictmeteringareaids/`
- `GET /getalldistrictmeteringareas/`
- `POST /generatedistrictmeteringarea/`
- `POST /generatesubdistrictmeteringarea/`
- `GET /calculateservicearea/`
- `GET /getserviceareaschema/`
- `GET /getservicearea/`
- `POST /setservicearea/`
- `POST /addservicearea/`
- `POST /deleteservicearea/`
- `GET /getallserviceareas/`
- `POST /generateservicearea/`
- `GET /calculatevirtualdistrict/`
- `GET /getvirtualdistrictschema/`
- `GET /getvirtualdistrict/`
- `POST /setvirtualdistrict/`
- `POST /addvirtualdistrict/`
- `POST /deletevirtualdistrict/`
- `GET /getallvirtualdistrict/`
- `POST /generatevirtualdistrict/`
- `GET /calculatedemandtonodes/`
- `GET /calculatedemandtoregion/`
- `GET /calculatedemandtonetwork/`
- `GET /getscadainfoschema/`
- `GET /getscadainfo/`
- `GET /getallscadainfo/`
- `GET /getschemeschema/`
- `GET /getscheme/`
- `GET /getallschemes/`
- `GET /getpiperiskprobabilitynow/`
- `GET /getpiperiskprobability/`
- `GET /getpipesriskprobability/`
- `GET /getnetworkpiperiskprobabilitynow/`
- `GET /getpiperiskprobabilitygeometries/`
- `GET /getallsensorplacements/`
- `GET /getallburstlocateresults/`
- `POST /uploadinp/`
- `GET /downloadinp/`
- `GET /convertv3tov2/`
- `GET /getjson/`
- `GET /getrealtimedata/`
- `GET /getsimulationresult/`
- `GET /querynodelatestrecordbyid/`
- `GET /querylinklatestrecordbyid/`
- `GET /queryscadalatestrecordbyid/`
- `GET /queryallrecordsbytime/`
- `GET /queryallrecordsbytimeproperty/`
- `GET /queryallschemerecordsbytimeproperty/`
- `GET /querysimulationrecordsbyidtime/`
- `GET /queryschemesimulationrecordsbyidtime/`
- `GET /queryallrecordsbydate/`
- `GET /queryallrecordsbytimerange/`
- `GET /queryallrecordsbydatewithtype/`
- `GET /queryallrecordsbyidsdatetype/`
- `GET /queryallrecordsbydateproperty/`
- `GET /querynodecurvebyidpropertydaterange/`
- `GET /querylinkcurvebyidpropertydaterange/`
- `GET /queryscadadatabydeviceidandtime/`
- `GET /queryscadadatabydeviceidandtimerange/`
- `GET /queryfillingscadadatabydeviceidandtimerange/`
- `GET /querycleaningscadadatabydeviceidandtimerange/`
- `GET /querysimulationscadadatabydeviceidandtimerange/`
- `GET /querycleanedscadadatabydeviceidandtimerange/`
- `GET /queryscadadatabydeviceidanddate/`
- `GET /queryallscadarecordsbydate/`
- `GET /queryallschemeallrecords/`
- `GET /queryschemeallrecordsproperty/`
- `POST /clearrediskey/`
- `POST /clearrediskeys/`
- `POST /clearallredis/`
- `GET /queryredis/`
- `GET /queryinfluxdbbuckets/`
- `GET /queryinfluxdbbucketmeasurements/`
- `POST /download_history_data_manually/`
- `POST /runsimulationmanuallybydate/`
- `POST /burst_analysis/`
- `GET /valve_close_analysis/`
- `GET /flushing_analysis/`
- `GET /contaminant_simulation/`
- `GET /age_analysis/`
- `POST /scheduling_analysis/`
- `POST /pressure_regulation/`
- `POST /project_management/`
- `POST /network_project/`
- `POST /daily_scheduling_analysis/`
- `POST /network_update/`
- `POST /pump_failure/`
- `POST /pressure_sensor_placement_sensitivity/`
- `POST /pressure_sensor_placement_kmeans/`
- `POST /sensorplacementscheme/create`
- `POST /scadadevicedatacleaning/`
- `POST /test_dict/`
-5
View File
@@ -1,5 +0,0 @@
import redis
redis_client = redis.Redis(host="127.0.0.1", port=6379, db=0)
matched_keys = redis_client.keys(f"**")
redis_client.delete(*matched_keys)