Accept Merge Request #61: (api -> master)
Merge Request: Merge many apis Created By: @王琼钰 Accepted By: @王琼钰 URL: https://tjwater.coding.net/p/tjwatercloud/d/TJWaterServer/git/merge/61
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
# vscode
|
||||
.vscode/
|
||||
|
||||
# python cache
|
||||
__pycache__/
|
||||
|
||||
@@ -7,4 +10,6 @@ __pycache__/
|
||||
# epanet
|
||||
*.rpt
|
||||
*.opt
|
||||
.vscode/
|
||||
|
||||
# dev_demo
|
||||
dev_demo.py
|
||||
|
||||
@@ -13,7 +13,7 @@ from .operation import pick_operation, sync_with_server
|
||||
|
||||
from .command import execute_batch_commands
|
||||
|
||||
from .s0_base import JUNCTION, RESERVOIR, TANK, PIPE, PUMP, VALVE
|
||||
from .s0_base import JUNCTION, RESERVOIR, TANK, PIPE, PUMP, VALVE, PATTERN, CURVE
|
||||
from .s0_base import is_node, is_junction, is_reservoir, is_tank
|
||||
from .s0_base import is_link, is_pipe, is_pump, is_valve
|
||||
from .s0_base import is_curve
|
||||
@@ -38,4 +38,25 @@ from .s6_pumps import get_pump_schema, add_pump, get_pump, set_pump, delete_pump
|
||||
from .s7_valves import VALVES_TYPE_PRV, VALVES_TYPE_PSV, VALVES_TYPE_PBV, VALVES_TYPE_FCV, VALVES_TYPE_TCV, VALVES_TYPE_GPV
|
||||
from .s7_valves import get_valve_schema, add_valve, get_valve, set_valve, delete_valve
|
||||
|
||||
from .s9_demands import get_demand_schema, get_demand, set_demand
|
||||
|
||||
from .s10_status import LINK_STATUS_OPEN, LINK_STATUS_CLOSED, LINK_STATUS_ACTIVE
|
||||
from .s10_status import get_status_schema, get_status, set_status
|
||||
|
||||
from .s11_patterns import get_pattern_schema, get_pattern, set_pattern
|
||||
|
||||
from .s12_curves import get_curve_schema, get_curve, set_curve
|
||||
|
||||
from .s16_emitters import get_emitter_schema, get_emitter, set_emitter
|
||||
|
||||
from .s21_times import TIME_STATISTIC_NONE, TIME_STATISTIC_AVERAGED, TIME_STATISTIC_MINIMUM, TIME_STATISTIC_MAXIMUM, TIME_STATISTIC_RANGE
|
||||
from .s21_times import get_time_schema, get_time, set_time
|
||||
|
||||
from .s23_options import OPTION_UNITS_CFS, OPTION_UNITS_GPM, OPTION_UNITS_MGD, OPTION_UNITS_IMGD, OPTION_UNITS_AFD, OPTION_UNITS_LPS, OPTION_UNITS_LPM, OPTION_UNITS_MLD, OPTION_UNITS_CMH, OPTION_UNITS_CMD
|
||||
from .s23_options import OPTION_HEADLOSS_HW, OPTION_HEADLOSS_DW, OPTION_HEADLOSS_CM
|
||||
from .s23_options import OPTION_UNBALANCED_STOP, OPTION_UNBALANCED_CONTINUE
|
||||
from .s23_options import OPTION_DEMAND_MODEL_DDA, OPTION_DEMAND_MODEL_PDA
|
||||
from .s23_options import OPTION_QUALITY_NONE, OPTION_QUALITY_CHEMICAL, OPTION_QUALITY_AGE, OPTION_QUALITY_TRACE
|
||||
from .s23_options import get_option_schema, get_option, set_option
|
||||
|
||||
from .s24_coordinates import get_node_coord
|
||||
|
||||
@@ -5,6 +5,13 @@ from .s4_tanks import *
|
||||
from .s5_pipes import *
|
||||
from .s6_pumps import *
|
||||
from .s7_valves import *
|
||||
from .s9_demands import *
|
||||
from .s10_status import *
|
||||
from .s11_patterns import *
|
||||
from .s12_curves import *
|
||||
from .s16_emitters import *
|
||||
from .s21_times import *
|
||||
from .s23_options import *
|
||||
|
||||
|
||||
def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
@@ -43,6 +50,20 @@ def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return set_pump(name, cs)
|
||||
elif type == VALVE:
|
||||
return set_valve(name, cs)
|
||||
elif type == 'demand':
|
||||
return set_demand(name, cs)
|
||||
elif type == 'status':
|
||||
return set_status(name, cs)
|
||||
elif type == PATTERN:
|
||||
return set_pattern(name, cs)
|
||||
elif type == CURVE:
|
||||
return set_curve(name, cs)
|
||||
elif type == 'emitter':
|
||||
return set_emitter(name, cs)
|
||||
elif type == 'time':
|
||||
return set_time(name, cs)
|
||||
elif type == 'option':
|
||||
return set_option(name, cs)
|
||||
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
@@ -51,6 +51,18 @@ def read(name: str, sql: str) -> Row:
|
||||
return row
|
||||
|
||||
|
||||
def read_all(name: str, sql: str) -> list[Row]:
|
||||
with conn[name].cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(sql)
|
||||
return cur.fetchall()
|
||||
|
||||
|
||||
def try_read(name: str, sql: str) -> Row | None:
|
||||
with conn[name].cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(sql)
|
||||
return cur.fetchone()
|
||||
|
||||
|
||||
def write(name: str, sql: str) -> None:
|
||||
with conn[name].cursor() as cur:
|
||||
cur.execute(sql)
|
||||
|
||||
178
api/parser.py
178
api/parser.py
@@ -7,6 +7,14 @@ from .s4_tanks import *
|
||||
from .s5_pipes import *
|
||||
from .s6_pumps import *
|
||||
from .s7_valves import *
|
||||
from .s9_demands import *
|
||||
from .s10_status import *
|
||||
from .s11_patterns import *
|
||||
from .s12_curves import *
|
||||
from .s16_emitters import *
|
||||
from .s21_times import *
|
||||
from .s23_options import *
|
||||
|
||||
|
||||
def read_inp(name: str, inp: str):
|
||||
if is_project_open(name):
|
||||
@@ -18,19 +26,30 @@ def read_inp(name: str, inp: str):
|
||||
create_project(name)
|
||||
open_project(name)
|
||||
|
||||
section = ''
|
||||
|
||||
title : str = ''
|
||||
junctions : dict[str, dict[str, Any]] = {}
|
||||
reservoirs : dict[str, dict[str, Any]] = {}
|
||||
tanks : dict[str, dict[str, Any]] = {}
|
||||
pipes : dict[str, dict[str, Any]] = {}
|
||||
pumps : dict[str, dict[str, Any]] = {}
|
||||
valves : dict[str, dict[str, Any]] = {}
|
||||
section = ''
|
||||
demands : dict[str, list[dict[str, Any]]] = {}
|
||||
status : dict[str, dict[str, Any]] = {}
|
||||
patterns : dict[str, list[float]] = {}
|
||||
curves : dict[str, list[dict[str, float]]] = {}
|
||||
emitters : dict[str, float] = {}
|
||||
times : dict[str, str] = {}
|
||||
options : dict[str, str] = {}
|
||||
|
||||
for line in open(inp):
|
||||
line = line.lstrip()
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith(';'):
|
||||
continue
|
||||
if line.endswith(';'):
|
||||
line = line.removesuffix(';')
|
||||
|
||||
if line.startswith('[TITLE'):
|
||||
section = 'title'
|
||||
@@ -53,6 +72,27 @@ def read_inp(name: str, inp: str):
|
||||
if line.startswith('[VALVE'):
|
||||
section = VALVE
|
||||
continue
|
||||
if line.startswith('[DEMAND'):
|
||||
section = 'demand'
|
||||
continue
|
||||
if line.startswith('[STATUS'):
|
||||
section = 'status'
|
||||
continue
|
||||
if line.startswith('[PATTERN'):
|
||||
section = PATTERN
|
||||
continue
|
||||
if line.startswith('[CURVE'):
|
||||
section = CURVE
|
||||
continue
|
||||
if line.startswith('[EMITTER'):
|
||||
section = 'emitter'
|
||||
continue
|
||||
if line.startswith('[TIME'):
|
||||
section = 'time'
|
||||
continue
|
||||
if line.startswith('[OPTION'):
|
||||
section = 'option'
|
||||
continue
|
||||
if line.startswith('[COORDINATE'):
|
||||
section = 'coordinate'
|
||||
continue
|
||||
@@ -60,38 +100,98 @@ def read_inp(name: str, inp: str):
|
||||
section = ''
|
||||
continue
|
||||
|
||||
tokens = line.split()
|
||||
if len(tokens) == 0:
|
||||
tokens = []
|
||||
if section == 'time' or section == 'option':
|
||||
tokens = line.upper().split()
|
||||
else:
|
||||
tokens = line.split()
|
||||
tokens_len = len(tokens)
|
||||
if tokens_len == 0:
|
||||
continue
|
||||
|
||||
if section == 'title':
|
||||
# set_title(name, ChangeSet({'value': tokens[0]}))
|
||||
if title == '':
|
||||
title += '\n'
|
||||
title += line
|
||||
continue
|
||||
elif section == JUNCTION:
|
||||
if tokens[0] not in junctions:
|
||||
junctions[tokens[0]] = {}
|
||||
junctions[tokens[0]] |= {'id': tokens[0], 'elevation': tokens[1]}
|
||||
junction_demand = float(tokens[2]) if tokens_len >= 3 else None
|
||||
junction_pattern = tokens[3] if tokens_len == 4 else None
|
||||
junctions[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'demand': junction_demand, 'pattern': junction_pattern}
|
||||
continue
|
||||
elif section == RESERVOIR:
|
||||
if tokens[0] not in reservoirs:
|
||||
reservoirs[tokens[0]] = {}
|
||||
reservoirs[tokens[0]] |= {'id': tokens[0], 'head': tokens[1]}
|
||||
reservoir_pattern = tokens[2] if tokens_len == 3 else None
|
||||
reservoirs[tokens[0]] = {'id': tokens[0], 'head': tokens[1], 'pattern': reservoir_pattern}
|
||||
continue
|
||||
elif section == TANK:
|
||||
if tokens[0] not in tanks:
|
||||
tanks[tokens[0]] = {}
|
||||
tanks[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'init_level': tokens[2], 'min_level': tokens[3], 'max_level': tokens[4], 'diameter': tokens[5], 'min_vol': tokens[6]}
|
||||
tank_vol_curve = tokens[7] if tokens_len >= 8 else None
|
||||
tank_overflow = tokens[8].upper() if tokens_len == 9 else None
|
||||
tanks[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'init_level': tokens[2], 'min_level': tokens[3], 'max_level': tokens[4], 'diameter': tokens[5], 'min_vol': tokens[6], 'vol_curve': tank_vol_curve, 'overflow': tank_overflow}
|
||||
continue
|
||||
elif section == PIPE:
|
||||
if len(tokens) == 7:
|
||||
tokens.append(PIPE_STATUS_OPEN)
|
||||
pipes[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'length': tokens[3], 'diameter': tokens[4], 'roughness': tokens[5], 'minor_loss': tokens[6], 'status': tokens[7].lower()}
|
||||
# status is must-have, here fix input
|
||||
pipe_status = tokens[7].upper() if tokens_len == 8 else PIPE_STATUS_OPEN
|
||||
pipes[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'length': tokens[3], 'diameter': tokens[4], 'roughness': tokens[5], 'minor_loss': tokens[6], 'status': pipe_status}
|
||||
continue
|
||||
elif section == PUMP:
|
||||
pumps[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2]}
|
||||
for i in range(3, tokens_len, 2):
|
||||
pumps[tokens[0]] |= { tokens[i].lower(): tokens[i + 1] }
|
||||
continue
|
||||
elif section == VALVE:
|
||||
valves[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'diameter': tokens[3], 'v_type': tokens[4].lower(), 'setting': tokens[5], 'minor_loss': tokens[6]}
|
||||
valves[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'diameter': tokens[3], 'v_type': tokens[4], 'setting': tokens[5], 'minor_loss': tokens[6]}
|
||||
continue
|
||||
elif section == 'demand':
|
||||
demand_pattern = tokens[2] if tokens_len >= 3 else None
|
||||
demand_category = tokens[3] if tokens_len == 4 else None
|
||||
demands[tokens[0]].append({'demand': tokens[1], 'pattern': demand_pattern, 'category': demand_category})
|
||||
continue
|
||||
elif section == 'status':
|
||||
if tokens[0] not in status:
|
||||
status[tokens[0]] = {}
|
||||
setting = None
|
||||
try:
|
||||
setting = float(tokens[1])
|
||||
except:
|
||||
setting = None
|
||||
if setting != None:
|
||||
status[tokens[0]]['setting'] = setting
|
||||
else:
|
||||
status[tokens[0]]['status'] = tokens[1].upper()
|
||||
continue
|
||||
elif section == PATTERN:
|
||||
if tokens[0] not in patterns:
|
||||
patterns[tokens[0]] = []
|
||||
for i in range(1, tokens_len):
|
||||
patterns[tokens[0]].append(float(tokens[i]))
|
||||
continue
|
||||
elif section == CURVE:
|
||||
if tokens[0] not in curves:
|
||||
curves[tokens[0]] = []
|
||||
for i in range(1, tokens_len, 2):
|
||||
curves[tokens[0]].append({ 'x': float(tokens[i]), 'y': float(tokens[i + 1]) })
|
||||
continue
|
||||
elif section == 'emitter':
|
||||
emitters[tokens[0]] = float(tokens[1])
|
||||
continue
|
||||
elif section == 'time':
|
||||
if tokens_len == 2:
|
||||
times[tokens[0]] = tokens[1]
|
||||
elif tokens_len == 3:
|
||||
times[tokens[0] + ' ' + tokens[1]] = tokens[2]
|
||||
elif tokens_len == 4:
|
||||
times[tokens[0] + ' ' + tokens[1]] = tokens[2] + ' ' + tokens[3]
|
||||
continue
|
||||
elif section == 'option':
|
||||
if tokens[0] == 'HYDRAULICS' or tokens[0] == 'MAP':
|
||||
continue
|
||||
if tokens_len == 2:
|
||||
options[tokens[0]] = tokens[1]
|
||||
elif tokens_len == 3:
|
||||
if tokens[0] == 'UNBALANCED' or tokens[0] == 'QUALITY':
|
||||
options[tokens[0]] = tokens[1] + ' ' + tokens[2]
|
||||
else:
|
||||
options[tokens[0] + ' ' + tokens[1]] = tokens[2]
|
||||
continue
|
||||
elif section == 'coordinate':
|
||||
if tokens[0] in junctions:
|
||||
@@ -102,27 +202,69 @@ def read_inp(name: str, inp: str):
|
||||
tanks[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
continue
|
||||
|
||||
# title
|
||||
set_title(name, ChangeSet({ 'value': title }))
|
||||
|
||||
# pattern
|
||||
for key, value in patterns.items():
|
||||
set_pattern(name, ChangeSet({'id': key, 'factors': value}))
|
||||
|
||||
# curve
|
||||
for key, value in curves.items():
|
||||
set_curve(name, ChangeSet({'id': key, 'coords': value}))
|
||||
|
||||
# junction
|
||||
for value in junctions.values():
|
||||
if 'x' not in value:
|
||||
value['x'] = 0.0
|
||||
if 'y' not in value:
|
||||
value['y'] = 0.0
|
||||
add_junction(name, ChangeSet(value))
|
||||
|
||||
# reservoir
|
||||
for value in reservoirs.values():
|
||||
if 'x' not in value:
|
||||
value['x'] = 0.0
|
||||
if 'y' not in value:
|
||||
value['y'] = 0.0
|
||||
add_reservoir(name, ChangeSet(value))
|
||||
|
||||
# tank
|
||||
for value in tanks.values():
|
||||
if 'x' not in value:
|
||||
value['x'] = 0.0
|
||||
if 'y' not in value:
|
||||
value['y'] = 0.0
|
||||
add_tank(name, ChangeSet(value))
|
||||
|
||||
# pipe
|
||||
for value in pipes.values():
|
||||
add_pipe(name, ChangeSet(value))
|
||||
|
||||
# pump
|
||||
for value in pumps.values():
|
||||
add_pump(name, ChangeSet(value))
|
||||
|
||||
# valve
|
||||
for value in valves.values():
|
||||
add_valve(name, ChangeSet(value))
|
||||
|
||||
# demand
|
||||
for key, value in demands.items():
|
||||
set_demand(name, ChangeSet({'junction': key, 'demands': value}))
|
||||
|
||||
# status
|
||||
for key, value in status.items():
|
||||
set_status(name, ChangeSet({'link': key} | value))
|
||||
|
||||
# emitter
|
||||
for key, value in emitters.items():
|
||||
set_emitter(name, ChangeSet({'junction': key, 'coefficient': value}))
|
||||
|
||||
# time
|
||||
set_time(name, ChangeSet(times))
|
||||
|
||||
# option
|
||||
set_option(name, ChangeSet(options))
|
||||
|
||||
close_project(name)
|
||||
|
||||
@@ -3,17 +3,20 @@ from .connection import g_conn_dict as conn
|
||||
from .operation import *
|
||||
|
||||
|
||||
_NODE = "_node"
|
||||
_LINK = "_link"
|
||||
_CURVE = "_curve"
|
||||
_PATTERN = "_pattern"
|
||||
_NODE = '_node'
|
||||
_LINK = '_link'
|
||||
_CURVE = '_curve'
|
||||
_PATTERN = '_pattern'
|
||||
|
||||
JUNCTION = "junction"
|
||||
RESERVOIR = "reservoir"
|
||||
TANK = "tank"
|
||||
PIPE = "pipe"
|
||||
PUMP = "pump"
|
||||
VALVE = "valve"
|
||||
JUNCTION = 'junction'
|
||||
RESERVOIR = 'reservoir'
|
||||
TANK = 'tank'
|
||||
PIPE = 'pipe'
|
||||
PUMP = 'pump'
|
||||
VALVE = 'valve'
|
||||
|
||||
PATTERN = 'pattern'
|
||||
CURVE = 'curve'
|
||||
|
||||
|
||||
def _get_from(name: str, id: str, base_type: str) -> Row | None:
|
||||
|
||||
64
api/s10_status.py
Normal file
64
api/s10_status.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from .operation import *
|
||||
|
||||
|
||||
LINK_STATUS_OPEN = 'OPEN'
|
||||
LINK_STATUS_CLOSED = 'CLOSED'
|
||||
LINK_STATUS_ACTIVE = 'ACTIVE'
|
||||
|
||||
|
||||
def get_status_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'link' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'status' : {'type': 'str' , 'optional': True , 'readonly': False},
|
||||
'setting' : {'type': 'float' , 'optional': True , 'readonly': False} }
|
||||
|
||||
|
||||
def get_status(name: str, link: str) -> dict[str, Any]:
|
||||
s = try_read(name, f"select * from status where link = '{link}'")
|
||||
if s == None:
|
||||
return { 'link': link, 'status': None, 'setting': None }
|
||||
d = {}
|
||||
d['link'] = str(s['link'])
|
||||
d['status'] = str(s['status']) if s['status'] != None else None
|
||||
d['setting'] = float(s['setting']) if s['setting'] != None else None
|
||||
return d
|
||||
|
||||
|
||||
class Status(object):
|
||||
def __init__(self, input: dict[str, Any]) -> None:
|
||||
self.type = 'status'
|
||||
self.link = str(input['link'])
|
||||
self.status = str(input['status']) if 'status' in input and input['status'] != None else None
|
||||
self.setting = float(input['setting']) if 'setting' in input and input['setting'] != None else None
|
||||
|
||||
self.f_type = f"'{self.type}'"
|
||||
self.f_link = f"'{self.link}'"
|
||||
self.f_status = f"'{self.status}'" if self.status != None else 'null'
|
||||
self.f_setting = self.setting if self.setting != None else 'null'
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return { 'type': self.type, 'link': self.link, 'status': self.status, 'setting': self.setting }
|
||||
|
||||
|
||||
def set_status(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
old = Status(get_status(name, cs.operations[0]['link']))
|
||||
raw_new = get_status(name, cs.operations[0]['link'])
|
||||
|
||||
new_dict = cs.operations[0]
|
||||
schema = get_status_schema(name)
|
||||
for key, value in schema.items():
|
||||
if key in new_dict and not value['readonly']:
|
||||
raw_new[key] = new_dict[key]
|
||||
new = Status(raw_new)
|
||||
|
||||
redo_sql = f"delete from status where link = {new.f_link};"
|
||||
if new.status != None or new.setting != None:
|
||||
redo_sql += f"\ninsert into status (link, status, setting) values ({new.f_link}, {new.f_status}, {new.f_setting});"
|
||||
|
||||
undo_sql = f"delete from status where link = {old.f_link};"
|
||||
if old.status != None or old.setting != None:
|
||||
undo_sql += f"\ninsert into status (link, status, setting) values ({old.f_link}, {old.f_status}, {old.f_setting});"
|
||||
|
||||
redo_cs = g_update_prefix | new.as_dict()
|
||||
undo_cs = g_update_prefix | old.as_dict()
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
45
api/s11_patterns.py
Normal file
45
api/s11_patterns.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from .operation import *
|
||||
|
||||
|
||||
def get_pattern_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'factors' : {'type': 'float_list' , 'optional': False , 'readonly': False } }
|
||||
|
||||
|
||||
def get_pattern(name: str, id: str) -> dict[str, Any]:
|
||||
pas = read_all(name, f"select * from patterns where id = '{id}'")
|
||||
ps = []
|
||||
for r in pas:
|
||||
ps.append(float(r['factor']))
|
||||
return { 'id': id, 'factors': ps }
|
||||
|
||||
|
||||
def set_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
|
||||
old = get_pattern(name, id)
|
||||
new = { 'id': id, 'factors': [] }
|
||||
|
||||
f_id = f"'{id}'"
|
||||
|
||||
# TODO: transaction ?
|
||||
redo_sql = f"delete from patterns where id = {f_id};"
|
||||
redo_sql += f"\ndelete from _pattern where id = {f_id};"
|
||||
if len(cs.operations[0]['factors']) > 0:
|
||||
redo_sql += f"\ninsert into _pattern (id) values ({f_id});"
|
||||
for factor in cs.operations[0]['factors']:
|
||||
f_factor = float(factor)
|
||||
redo_sql += f"\ninsert into patterns (id, factor) values ({f_id}, {f_factor});"
|
||||
new['factors'].append(factor)
|
||||
|
||||
undo_sql = f"delete from patterns where id = {f_id};"
|
||||
undo_sql += f"\ndelete from _pattern where id = {f_id};"
|
||||
if len(old['factors']) > 0:
|
||||
undo_sql += f"\ninsert into _pattern (id) values ({f_id});"
|
||||
for f_factor in old['factors']:
|
||||
undo_sql += f"\ninsert into patterns (id, factor) values ({f_id}, {f_factor});"
|
||||
|
||||
redo_cs = g_update_prefix | { 'type': 'pattern' } | new
|
||||
undo_cs = g_update_prefix | { 'type': 'pattern' } | old
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
49
api/s12_curves.py
Normal file
49
api/s12_curves.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from .operation import *
|
||||
|
||||
|
||||
def get_curve_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'coords' : {'type': 'list' , 'optional': False , 'readonly': False,
|
||||
'element': { 'x' : {'type': 'float' , 'optional': False , 'readonly': False },
|
||||
'y' : {'type': 'float' , 'optional': False , 'readonly': False } }}}
|
||||
|
||||
|
||||
def get_curve(name: str, id: str) -> dict[str, Any]:
|
||||
cus = read_all(name, f"select * from curves where id = '{id}'")
|
||||
cs = []
|
||||
for r in cus:
|
||||
cs.append({ 'x': float(r['x']), 'y': float(r['y']) })
|
||||
return { 'id': id, 'coords': cs }
|
||||
|
||||
|
||||
def set_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
|
||||
old = get_curve(name, id)
|
||||
new = { 'id': id, 'coords': [] }
|
||||
|
||||
f_id = f"'{id}'"
|
||||
|
||||
# TODO: transaction ?
|
||||
redo_sql = f"delete from curves where id = {f_id};"
|
||||
redo_sql += f"\ndelete from _curve where id = {f_id};"
|
||||
if len(cs.operations[0]['coords']) > 0:
|
||||
redo_sql += f"\ninsert into _curve (id) values ({f_id});"
|
||||
for xy in cs.operations[0]['coords']:
|
||||
x, y = float(xy['x']), float(xy['y'])
|
||||
f_x, f_y = x, y
|
||||
redo_sql += f"\ninsert into curves (id, x, y) values ({f_id}, {f_x}, {f_y});"
|
||||
new['coords'].append({ 'x': x, 'y': y })
|
||||
|
||||
undo_sql = f"delete from curves where id = {f_id};"
|
||||
undo_sql += f"\ndelete from _curve where id = {f_id};"
|
||||
if len(old['coords']) > 0:
|
||||
undo_sql += f"\ninsert into _curve (id) values ({f_id});"
|
||||
for xy in old['coords']:
|
||||
f_x, f_y = xy['x'], xy['y']
|
||||
undo_sql += f"\ninsert into curves (id, x, y) values ({f_id}, {f_x}, {f_y});"
|
||||
|
||||
redo_cs = g_update_prefix | { 'type': 'curve' } | new
|
||||
undo_cs = g_update_prefix | { 'type': 'curve' } | old
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
55
api/s16_emitters.py
Normal file
55
api/s16_emitters.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from .operation import *
|
||||
|
||||
|
||||
def get_emitter_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'junction' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'coefficient' : {'type': 'float' , 'optional': True , 'readonly': False} }
|
||||
|
||||
|
||||
def get_emitter(name: str, junction: str) -> dict[str, Any]:
|
||||
e = try_read(name, f"select * from emitters where junction = '{junction}'")
|
||||
if e == None:
|
||||
return { 'junction': junction, 'coefficient': None }
|
||||
d = {}
|
||||
d['junction'] = str(e['junction'])
|
||||
d['coefficient'] = float(e['coefficient']) if e['coefficient'] != None else None
|
||||
return d
|
||||
|
||||
|
||||
class Emitter(object):
|
||||
def __init__(self, input: dict[str, Any]) -> None:
|
||||
self.type = 'emitter'
|
||||
self.junction = str(input['junction'])
|
||||
self.coefficient = float(input['coefficient']) if 'coefficient' in input and input['coefficient'] != None else None
|
||||
|
||||
self.f_type = f"'{self.type}'"
|
||||
self.f_junction = f"'{self.junction}'"
|
||||
self.f_coefficient = self.coefficient if self.coefficient != None else 'null'
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return { 'type': self.type, 'junction': self.junction, 'coefficient': self.coefficient }
|
||||
|
||||
|
||||
def set_emitter(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
old = Emitter(get_emitter(name, cs.operations[0]['junction']))
|
||||
raw_new = get_emitter(name, cs.operations[0]['junction'])
|
||||
|
||||
new_dict = cs.operations[0]
|
||||
schema = get_emitter_schema(name)
|
||||
for key, value in schema.items():
|
||||
if key in new_dict and not value['readonly']:
|
||||
raw_new[key] = new_dict[key]
|
||||
new = Emitter(raw_new)
|
||||
|
||||
redo_sql = f"delete from emitters where junction = {new.f_junction};"
|
||||
if new.coefficient != None:
|
||||
redo_sql += f"\ninsert into emitters (junction, coefficient) values ({new.f_junction}, {new.f_coefficient});"
|
||||
|
||||
undo_sql = f"delete from emitters where junction = {old.f_junction};"
|
||||
if old.coefficient != None:
|
||||
undo_sql += f"\ninsert into emitters (junction, coefficient) values ({old.f_junction}, {old.f_coefficient});"
|
||||
|
||||
redo_cs = g_update_prefix | new.as_dict()
|
||||
undo_cs = g_update_prefix | old.as_dict()
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
63
api/s21_times.py
Normal file
63
api/s21_times.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from .operation import *
|
||||
|
||||
TIME_STATISTIC_NONE = 'NONE'
|
||||
TIME_STATISTIC_AVERAGED = 'AVERAGED'
|
||||
TIME_STATISTIC_MINIMUM = 'MINIMUM'
|
||||
TIME_STATISTIC_MAXIMUM = 'MAXIMUM'
|
||||
TIME_STATISTIC_RANGE = 'RANGE'
|
||||
|
||||
element_schema = {'type': 'str' , 'optional': True , 'readonly': False}
|
||||
|
||||
def get_time_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'DURATION' : element_schema,
|
||||
'HYDRAULIC TIMESTEP' : element_schema,
|
||||
'QUALITY TIMESTEP' : element_schema,
|
||||
'RULE TIMESTEP' : element_schema,
|
||||
'PATTERN TIMESTEP' : element_schema,
|
||||
'PATTERN START' : element_schema,
|
||||
'REPORT TIMESTEP' : element_schema,
|
||||
'REPORT START' : element_schema,
|
||||
'START CLOCKTIME' : element_schema,
|
||||
'STATISTIC' : element_schema}
|
||||
|
||||
|
||||
def get_time(name: str) -> dict[str, Any]:
|
||||
ts = read_all(name, f"select * from times")
|
||||
d = {}
|
||||
for e in ts:
|
||||
d[e['key']] = str(e['value'])
|
||||
return d
|
||||
|
||||
|
||||
def set_time(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
raw_old = get_time(name)
|
||||
|
||||
old = {}
|
||||
new = {}
|
||||
|
||||
new_dict = cs.operations[0]
|
||||
schema = get_time_schema(name)
|
||||
for key in schema.keys():
|
||||
if key in new_dict:
|
||||
old[key] = str(raw_old[key])
|
||||
new[key] = str(new_dict[key])
|
||||
|
||||
redo_cs = g_update_prefix | { 'type' : 'time' }
|
||||
|
||||
redo_sql = ''
|
||||
for key, value in new.items():
|
||||
if redo_sql != '':
|
||||
redo_sql += '\n'
|
||||
redo_sql += f"update times set value = '{value}' where key = '{key}';"
|
||||
redo_cs |= { key: value }
|
||||
|
||||
undo_cs = g_update_prefix | { 'type' : 'time' }
|
||||
|
||||
undo_sql = ''
|
||||
for key, value in old.items():
|
||||
if undo_sql != '':
|
||||
undo_sql += '\n'
|
||||
undo_sql += f"update times set value = '{value}' where key = '{key}';"
|
||||
undo_cs |= { key: value }
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
101
api/s23_options.py
Normal file
101
api/s23_options.py
Normal file
@@ -0,0 +1,101 @@
|
||||
from .operation import *
|
||||
|
||||
OPTION_UNITS_CFS = 'CFS'
|
||||
OPTION_UNITS_GPM = 'GPM'
|
||||
OPTION_UNITS_MGD = 'MGD'
|
||||
OPTION_UNITS_IMGD = 'IMGD'
|
||||
OPTION_UNITS_AFD = 'AFD'
|
||||
OPTION_UNITS_LPS = 'LPS'
|
||||
OPTION_UNITS_LPM = 'LPM'
|
||||
OPTION_UNITS_MLD = 'MLD'
|
||||
OPTION_UNITS_CMH = 'CMH'
|
||||
OPTION_UNITS_CMD = 'CMD'
|
||||
|
||||
OPTION_HEADLOSS_HW = 'H-W'
|
||||
OPTION_HEADLOSS_DW = 'D-W'
|
||||
OPTION_HEADLOSS_CM = 'C-M'
|
||||
|
||||
#OPTION_HYDRAULICS_USE = 'USE'
|
||||
#OPTION_HYDRAULICS_SAVE = 'SAVE'
|
||||
|
||||
OPTION_UNBALANCED_STOP = 'STOP'
|
||||
OPTION_UNBALANCED_CONTINUE = 'CONTINUE'
|
||||
|
||||
OPTION_DEMAND_MODEL_DDA = 'DDA'
|
||||
OPTION_DEMAND_MODEL_PDA = 'PDA'
|
||||
|
||||
OPTION_QUALITY_NONE = 'NONE'
|
||||
OPTION_QUALITY_CHEMICAL = 'CHEMICAL'
|
||||
OPTION_QUALITY_AGE = 'AGE'
|
||||
OPTION_QUALITY_TRACE = 'TRACE'
|
||||
|
||||
element_schema = {'type': 'str' , 'optional': True , 'readonly': False}
|
||||
|
||||
def get_option_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'UNITS' : element_schema,
|
||||
'HEADLOSS' : element_schema,
|
||||
#'HYDRAULICS' : element_schema,
|
||||
'VISCOSITY' : element_schema,
|
||||
'SPECIFIC GRAVITY' : element_schema,
|
||||
'TRIALS' : element_schema,
|
||||
'ACCURACY' : element_schema,
|
||||
'FLOWCHANGE' : element_schema,
|
||||
'HEADERROR' : element_schema,
|
||||
'CHECKFREQ' : element_schema,
|
||||
'MAXCHECK' : element_schema,
|
||||
'DAMPLIMIT' : element_schema,
|
||||
'UNBALANCED' : element_schema,
|
||||
'DEMAND MODEL' : element_schema,
|
||||
'MINIMUM PRESSURE' : element_schema,
|
||||
'REQUIRED PRESSURE' : element_schema,
|
||||
'PRESSURE EXPONENT' : element_schema,
|
||||
'PATTERN' : element_schema,
|
||||
'DEMAND MULTIPLIER' : element_schema,
|
||||
'EMITTER EXPONENT' : element_schema,
|
||||
'QUALITY' : element_schema,
|
||||
'DIFFUSIVITY' : element_schema,
|
||||
'TOLERANCE' : element_schema,
|
||||
#'QUALITY' : element_schema,
|
||||
}
|
||||
|
||||
|
||||
def get_option(name: str) -> dict[str, Any]:
|
||||
ts = read_all(name, f"select * from options")
|
||||
d = {}
|
||||
for e in ts:
|
||||
d[e['key']] = str(e['value'])
|
||||
return d
|
||||
|
||||
|
||||
def set_option(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
raw_old = get_option(name)
|
||||
|
||||
old = {}
|
||||
new = {}
|
||||
|
||||
new_dict = cs.operations[0]
|
||||
schema = get_option_schema(name)
|
||||
for key in schema.keys():
|
||||
if key in new_dict:
|
||||
old[key] = str(raw_old[key])
|
||||
new[key] = str(new_dict[key])
|
||||
|
||||
redo_cs = g_update_prefix | { 'type' : 'option' }
|
||||
|
||||
redo_sql = ''
|
||||
for key, value in new.items():
|
||||
if redo_sql != '':
|
||||
redo_sql += '\n'
|
||||
redo_sql += f"update options set value = '{value}' where key = '{key}';"
|
||||
redo_cs |= { key: value }
|
||||
|
||||
undo_cs = g_update_prefix | { 'type' : 'option' }
|
||||
|
||||
undo_sql = ''
|
||||
for key, value in old.items():
|
||||
if undo_sql != '':
|
||||
undo_sql += '\n'
|
||||
undo_sql += f"update options set value = '{value}' where key = '{key}';"
|
||||
undo_cs |= { key: value }
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
@@ -7,10 +7,10 @@ def get_junction_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'x' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'y' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'elevation' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'demand' : {'type': "float" , 'optional': True , 'readonly': False},
|
||||
'pattern' : {'type': "str" , 'optional': True , 'readonly': False},
|
||||
'links' : {'type': "str_list" , 'optional': False , 'readonly': True } }
|
||||
'elevation' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'demand' : {'type': 'float' , 'optional': True , 'readonly': False},
|
||||
'pattern' : {'type': 'str' , 'optional': True , 'readonly': False},
|
||||
'links' : {'type': 'str_list' , 'optional': False , 'readonly': True } }
|
||||
|
||||
|
||||
def get_junction(name: str, id: str) -> dict[str, Any]:
|
||||
|
||||
@@ -7,9 +7,9 @@ def get_reservoir_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'x' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'y' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'head' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'pattern' : {'type': "str" , 'optional': True , 'readonly': False},
|
||||
'links' : {'type': "str_list" , 'optional': False , 'readonly': True } }
|
||||
'head' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'pattern' : {'type': 'str' , 'optional': True , 'readonly': False},
|
||||
'links' : {'type': 'str_list' , 'optional': False , 'readonly': True } }
|
||||
|
||||
|
||||
def get_reservoir(name: str, id: str) -> dict[str, Any]:
|
||||
|
||||
@@ -3,23 +3,23 @@ from .s0_base import *
|
||||
from .s24_coordinates import *
|
||||
|
||||
|
||||
OVERFLOW_YES = 'yes'
|
||||
OVERFLOW_NO = 'no'
|
||||
OVERFLOW_YES = 'YES'
|
||||
OVERFLOW_NO = 'NO'
|
||||
|
||||
|
||||
def get_tank_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'x' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'y' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'elevation' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'init_level' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'min_level' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'max_level' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'diameter' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'min_vol' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'vol_curve' : {'type': "str" , 'optional': True , 'readonly': False},
|
||||
'overflow' : {'type': "str" , 'optional': True , 'readonly': False},
|
||||
'links' : {'type': "str_list" , 'optional': False , 'readonly': True } }
|
||||
'elevation' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'init_level' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'min_level' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'max_level' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'diameter' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'min_vol' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'vol_curve' : {'type': 'str' , 'optional': True , 'readonly': False},
|
||||
'overflow' : {'type': 'str' , 'optional': True , 'readonly': False},
|
||||
'links' : {'type': 'str_list' , 'optional': False , 'readonly': True } }
|
||||
|
||||
|
||||
def get_tank(name: str, id: str) -> dict[str, Any]:
|
||||
|
||||
@@ -2,20 +2,20 @@ from .operation import *
|
||||
from .s0_base import *
|
||||
|
||||
|
||||
PIPE_STATUS_OPEN = 'open'
|
||||
PIPE_STATUS_CLOSED = 'closed'
|
||||
PIPE_STATUS_CV = 'cv'
|
||||
PIPE_STATUS_OPEN = 'OPEN'
|
||||
PIPE_STATUS_CLOSED = 'CLOSED'
|
||||
PIPE_STATUS_CV = 'CV'
|
||||
|
||||
|
||||
def get_pipe_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'node1' : {'type': "str" , 'optional': False , 'readonly': False},
|
||||
'node2' : {'type': "str" , 'optional': False , 'readonly': False},
|
||||
'length' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'diameter' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'roughness' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'minor_loss' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'status' : {'type': "str" , 'optional': False , 'readonly': False} }
|
||||
'node1' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'node2' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'length' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'diameter' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'roughness' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'minor_loss' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'status' : {'type': 'str' , 'optional': False , 'readonly': False} }
|
||||
|
||||
|
||||
def get_pipe(name: str, id: str) -> dict[str, Any]:
|
||||
|
||||
@@ -3,9 +3,13 @@ from .s0_base import *
|
||||
|
||||
|
||||
def get_pump_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'node1' : {'type': "str" , 'optional': False , 'readonly': False},
|
||||
'node2' : {'type': "str" , 'optional': False , 'readonly': False} }
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'node1' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'node2' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'power' : {'type': 'float' , 'optional': True , 'readonly': False},
|
||||
'head' : {'type': 'str' , 'optional': True , 'readonly': False},
|
||||
'speed' : {'type': 'float' , 'optional': True , 'readonly': False},
|
||||
'pattern' : {'type': 'str' , 'optional': True , 'readonly': False} }
|
||||
|
||||
|
||||
def get_pump(name: str, id: str) -> dict[str, Any]:
|
||||
@@ -14,6 +18,10 @@ def get_pump(name: str, id: str) -> dict[str, Any]:
|
||||
d['id'] = str(p['id'])
|
||||
d['node1'] = str(p['node1'])
|
||||
d['node2'] = str(p['node2'])
|
||||
d['power'] = float(p['power']) if p['power'] != None else None
|
||||
d['head'] = str(p['head']) if p['head'] != None else None
|
||||
d['speed'] = float(p['speed']) if p['speed'] != None else None
|
||||
d['pattern'] = str(p['pattern']) if p['pattern'] != None else None
|
||||
return d
|
||||
|
||||
|
||||
@@ -23,14 +31,22 @@ class Pump(object):
|
||||
self.id = str(input['id'])
|
||||
self.node1 = str(input['node1'])
|
||||
self.node2 = str(input['node2'])
|
||||
self.power = float(input['power']) if 'power' in input and input['power'] != None else None
|
||||
self.head = str(input['head']) if 'head' in input and input['head'] != None else None
|
||||
self.speed = float(input['speed']) if 'speed' in input and input['speed'] != None else None
|
||||
self.pattern = str(input['pattern']) if 'pattern' in input and input['pattern'] != None else None
|
||||
|
||||
self.f_type = f"'{self.type}'"
|
||||
self.f_id = f"'{self.id}'"
|
||||
self.f_node1 = f"'{self.node1}'"
|
||||
self.f_node2 = f"'{self.node2}'"
|
||||
self.f_power = self.power if self.power != None else 'null'
|
||||
self.f_head = f"'{self.head}'" if self.head != None else 'null'
|
||||
self.f_speed = self.speed if self.speed != None else 'null'
|
||||
self.f_pattern = f"'{self.pattern}'" if self.pattern != None else 'null'
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return { 'type': self.type, 'id': self.id, 'node1': self.node1, 'node2': self.node2 }
|
||||
return { 'type': self.type, 'id': self.id, 'node1': self.node1, 'node2': self.node2, 'power': self.power, 'head': self.head, 'speed': self.speed, 'pattern': self.pattern }
|
||||
|
||||
def as_id_dict(self) -> dict[str, Any]:
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
@@ -47,8 +63,8 @@ def set_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
raw_new[key] = new_dict[key]
|
||||
new = Pump(raw_new)
|
||||
|
||||
redo_sql = f"update pumps set node1 = {new.f_node1}, node2 = {new.f_node2} where id = {new.f_id};"
|
||||
undo_sql = f"update pumps set node1 = {old.f_node1}, node2 = {old.f_node2} where id = {old.f_id};"
|
||||
redo_sql = f"update pumps set node1 = {new.f_node1}, node2 = {new.f_node2}, power = {new.f_power}, head = {new.f_head}, speed = {new.f_speed}, pattern = {new.f_pattern} where id = {new.f_id};"
|
||||
undo_sql = f"update pumps set node1 = {old.f_node1}, node2 = {old.f_node2}, power = {old.f_power}, head = {old.f_head}, speed = {old.f_speed}, pattern = {old.f_pattern} where id = {old.f_id};"
|
||||
|
||||
redo_cs = g_update_prefix | new.as_dict()
|
||||
undo_cs = g_update_prefix | old.as_dict()
|
||||
@@ -60,7 +76,7 @@ def add_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
new = Pump(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _link (id, type) values ({new.f_id}, {new.f_type});"
|
||||
redo_sql += f"\ninsert into pumps (id, node1, node2) values ({new.f_id}, {new.f_node1}, {new.f_node2});"
|
||||
redo_sql += f"\ninsert into pumps (id, node1, node2, power, head, speed, pattern) values ({new.f_id}, {new.f_node1}, {new.f_node2}, {new.f_power}, {new.f_head}, {new.f_speed}, {new.f_pattern});"
|
||||
|
||||
undo_sql = f"delete from pumps where id = {new.f_id};"
|
||||
undo_sql += f"\ndelete from _link where id = {new.f_id};"
|
||||
@@ -78,7 +94,7 @@ def delete_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
redo_sql += f"\ndelete from _link where id = {old.f_id};"
|
||||
|
||||
undo_sql = f"insert into _link (id, type) values ({old.f_id}, {old.f_type});"
|
||||
undo_sql += f"\ninsert into pumps (id, node1, node2) values ({old.f_id}, {old.f_node1}, {old.f_node2});"
|
||||
undo_sql += f"\ninsert into pumps (id, node1, node2, power, head, speed, pattern) values ({old.f_id}, {old.f_node1}, {old.f_node2}, {old.f_power}, {old.f_head}, {old.f_speed}, {old.f_pattern});"
|
||||
|
||||
redo_cs = g_delete_prefix | old.as_id_dict()
|
||||
undo_cs = g_add_prefix | old.as_dict()
|
||||
|
||||
@@ -2,22 +2,22 @@ from .operation import *
|
||||
from .s0_base import *
|
||||
|
||||
|
||||
VALVES_TYPE_PRV = 'prv'
|
||||
VALVES_TYPE_PSV = 'psv'
|
||||
VALVES_TYPE_PBV = 'pbv'
|
||||
VALVES_TYPE_FCV = 'fcv'
|
||||
VALVES_TYPE_TCV = 'tcv'
|
||||
VALVES_TYPE_GPV = 'gpv'
|
||||
VALVES_TYPE_PRV = 'PRV'
|
||||
VALVES_TYPE_PSV = 'PSV'
|
||||
VALVES_TYPE_PBV = 'PBV'
|
||||
VALVES_TYPE_FCV = 'FCV'
|
||||
VALVES_TYPE_TCV = 'TCV'
|
||||
VALVES_TYPE_GPV = 'GPV'
|
||||
|
||||
|
||||
def get_valve_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'node1' : {'type': "str" , 'optional': False , 'readonly': False},
|
||||
'node2' : {'type': "str" , 'optional': False , 'readonly': False},
|
||||
'diameter' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'v_type' : {'type': "str" , 'optional': False , 'readonly': False},
|
||||
'setting' : {'type': "float" , 'optional': False , 'readonly': False},
|
||||
'minor_loss' : {'type': "float" , 'optional': False , 'readonly': False} }
|
||||
'node1' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'node2' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'diameter' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'v_type' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
'setting' : {'type': 'float' , 'optional': False , 'readonly': False},
|
||||
'minor_loss' : {'type': 'float' , 'optional': False , 'readonly': False} }
|
||||
|
||||
|
||||
def get_valve(name: str, id: str) -> dict[str, Any]:
|
||||
|
||||
56
api/s9_demands.py
Normal file
56
api/s9_demands.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from .operation import *
|
||||
|
||||
|
||||
def get_demand_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'junction' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'demands' : {'type': 'list' , 'optional': False , 'readonly': False,
|
||||
'element': { 'demand' : {'type': 'float' , 'optional': False , 'readonly': False },
|
||||
'patten' : {'type': 'str' , 'optional': True , 'readonly': False },
|
||||
'category': {'type': 'str' , 'optional': True , 'readonly': False }}}}
|
||||
|
||||
|
||||
def get_demand(name: str, junction: str) -> dict[str, Any]:
|
||||
des = read_all(name, f"select * from demands where junction = '{junction}'")
|
||||
ds = []
|
||||
for r in des:
|
||||
d = {}
|
||||
d['demand'] = float(r['demand'])
|
||||
d['pattern'] = str(r['pattern']) if r['pattern'] != None else None
|
||||
d['category'] = str(r['category']) if r['category'] != None else None
|
||||
ds.append(d)
|
||||
return { 'junction': junction, 'demands': ds }
|
||||
|
||||
# { 'operation': 'update', 'type': 'demand', 'junction': 'j1', 'demands': [{'demand': 0.0, 'patten': None, 'category': None}] }
|
||||
def set_demand(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
junction = cs.operations[0]['junction']
|
||||
old = get_demand(name, junction)
|
||||
new = { 'junction': junction, 'demands': [] }
|
||||
|
||||
f_junction = f"'{junction}'"
|
||||
|
||||
# TODO: transaction ?
|
||||
redo_sql = f"delete from demands where junction = {f_junction};"
|
||||
for r in cs.operations[0]['demands']:
|
||||
demand = float(r['demand'])
|
||||
pattern = str(r['pattern']) if 'pattern' in r and r['pattern'] != None else None
|
||||
category = str(r['category']) if 'category' in r and r['category'] != None else None
|
||||
f_demand = demand
|
||||
f_pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
f_category = f"'{category}'" if category != None else 'null'
|
||||
redo_sql += f"\ninsert into demands (junction, demand, pattern, category) values ({f_junction}, {f_demand}, {f_pattern}, {f_category});"
|
||||
new['demands'].append({ 'demand': demand, 'pattern': pattern, 'category': category })
|
||||
|
||||
undo_sql = f"delete from demands where junction = {f_junction};"
|
||||
for r in old['demands']:
|
||||
demand = float(r['demand'])
|
||||
pattern = str(r['pattern'])
|
||||
category = str(r['category'])
|
||||
f_demand = demand
|
||||
f_pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
f_category = f"'{category}'" if category != None else 'null'
|
||||
undo_sql += f"\ninsert into demands (junction, demand, pattern, category) values ({f_junction}, {f_demand}, {f_pattern}, {f_category});"
|
||||
|
||||
redo_cs = g_update_prefix | { 'type': 'demand' } | new
|
||||
undo_cs = g_update_prefix | { 'type': 'demand' } | old
|
||||
|
||||
return execute_command(name, redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
@@ -1,7 +1,7 @@
|
||||
from tjnetwork import *
|
||||
|
||||
def inp2db():
|
||||
read_inp('changshu', './inp/v-16常熟模型.inp')
|
||||
read_inp('net3', './inp/net3.inp')
|
||||
|
||||
if __name__ == '__main__':
|
||||
inp2db()
|
||||
@@ -1,29 +1,11 @@
|
||||
-- [STATUS]
|
||||
|
||||
create type status_pipe_pump_status as enum ('open', 'closed');
|
||||
create type link_status as enum ('OPEN', 'CLOSED', 'ACTIVE');
|
||||
|
||||
create table status_pipe
|
||||
create table status
|
||||
(
|
||||
id varchar(32) primary key references pipes(id)
|
||||
, status status_pipe_pump_status not null
|
||||
);
|
||||
|
||||
create table status_pump
|
||||
(
|
||||
id varchar(32) primary key references pumps(id)
|
||||
, status status_pipe_pump_status not null
|
||||
);
|
||||
|
||||
create type status_valve_status as enum ('open', 'closed', 'active');
|
||||
|
||||
create table status_valve
|
||||
(
|
||||
id varchar(32) primary key references valves(id)
|
||||
, status status_valve_status not null
|
||||
);
|
||||
|
||||
create table status_link
|
||||
(
|
||||
id varchar(32) primary key references _link(id)
|
||||
, setting numeric not null
|
||||
link varchar(32) primary key references _link(id)
|
||||
, status link_status
|
||||
, setting numeric
|
||||
, check (status is not null or setting is not null)
|
||||
);
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
create table patterns
|
||||
(
|
||||
id varchar(32) references _pattern(id) not null
|
||||
, multipliers numeric not null
|
||||
, factor numeric not null
|
||||
);
|
||||
|
||||
@@ -1,30 +1,6 @@
|
||||
-- [CONTROLS]
|
||||
|
||||
create type controls_1_prep as enum ('above', 'below');
|
||||
|
||||
-- LINK linkID status IF NODE nodeID ABOVE / BELOW value
|
||||
create table controls_1
|
||||
create table controls
|
||||
(
|
||||
linkid varchar(32) primary key references _link(id)
|
||||
, status text not null -- open / closed, a pump speed setting, or a control valve setting
|
||||
, nodeid varchar(32) references _node(id) not null
|
||||
, prep controls_1_prep not null
|
||||
, value numeric not null
|
||||
);
|
||||
|
||||
-- LINK linkID status AT TIME time
|
||||
create table controls_2
|
||||
(
|
||||
linkid varchar(32) primary key references _link(id)
|
||||
, status text not null -- open / closed, a pump speed setting, or a control valve setting
|
||||
, time interval hour
|
||||
);
|
||||
|
||||
-- LINK linkID status AT CLOCKTIME clocktime AM / PM
|
||||
create table controls_3
|
||||
(
|
||||
linkid varchar(32) primary key references _link(id)
|
||||
, status text not null -- open / closed, a pump speed setting, or a control valve setting
|
||||
, clock_time_hour interval hour -- get am/pm from it
|
||||
, clock_time_min interval minute
|
||||
control text primary key
|
||||
);
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
create table rules
|
||||
(
|
||||
content text primary key
|
||||
rule text primary key
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [ENERGY]
|
||||
|
||||
create type energy_param as enum ('price', 'pattern', 'effic');
|
||||
create type energy_param as enum ('PRICE', 'PATTERN', 'EFFIC');
|
||||
|
||||
-- GLOBAL PRICE / PATTERN / EFFIC value
|
||||
create table energy_global
|
||||
@@ -22,3 +22,12 @@ create table energy_demand_charge
|
||||
(
|
||||
value numeric not null
|
||||
);
|
||||
|
||||
insert into energy_global (param, value) values
|
||||
('PRICE', 0.0)
|
||||
, ('EFFIC', 75)
|
||||
;
|
||||
|
||||
insert into energy_demand_charge values
|
||||
(0.0)
|
||||
;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [SOURCES]
|
||||
|
||||
create type sources_type as enum ('concen', 'mass', 'flowpaced', 'setpoint');
|
||||
create type sources_type as enum ('CONCEN', 'MASS', 'FLOWPACED', 'SETPOINT');
|
||||
|
||||
create table sources
|
||||
(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [REACTIONS]
|
||||
|
||||
create type reactions_order_param as enum ('bulk', 'wall', 'tank');
|
||||
create type reactions_order_param as enum ('BULK', 'WALL', 'TANK');
|
||||
|
||||
create table reactions_order
|
||||
(
|
||||
@@ -8,7 +8,7 @@ create table reactions_order
|
||||
, value numeric not null
|
||||
);
|
||||
|
||||
create type reactions_global_param as enum ('bulk', 'wall');
|
||||
create type reactions_global_param as enum ('BULK', 'WALL');
|
||||
|
||||
create table reactions_global
|
||||
(
|
||||
@@ -16,7 +16,7 @@ create table reactions_global
|
||||
, value numeric not null
|
||||
);
|
||||
|
||||
create type reactions_pipe_param as enum ('bulk', 'wall');
|
||||
create type reactions_pipe_param as enum ('BULK', 'WALL');
|
||||
|
||||
create table reactions_pipe
|
||||
(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [MIXING]
|
||||
|
||||
create type mixing_model as enum ('mixed', '2comp', 'fifo', 'lifo');
|
||||
create type mixing_model as enum ('MIXED', '2COMP', 'FIFO', 'LIFO');
|
||||
|
||||
create table mixing
|
||||
(
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
-- [TIMES]
|
||||
|
||||
-- TODO: constraint
|
||||
|
||||
create table times
|
||||
(
|
||||
key text not null
|
||||
, value text not null
|
||||
);
|
||||
|
||||
insert into times (key, value) values
|
||||
('DURATION', '0:00')
|
||||
, ('HYDRAULIC TIMESTEP', '1:00')
|
||||
, ('QUALITY TIMESTEP', '0:05')
|
||||
, ('RULE TIMESTEP', '0:05')
|
||||
, ('PATTERN TIMESTEP', '1:00')
|
||||
, ('PATTERN START', '0:00')
|
||||
, ('REPORT TIMESTEP', '1:00')
|
||||
, ('REPORT START', '0:00')
|
||||
, ('START CLOCKTIME', '12:00 AM')
|
||||
, ('STATISTIC', 'NONE') -- NONE / AVERAGED / MINIMUM / MAXIMUM / RANGE
|
||||
;
|
||||
|
||||
@@ -7,3 +7,14 @@ create table report
|
||||
key text not null
|
||||
, value text not null
|
||||
);
|
||||
|
||||
insert into report (key, value) values
|
||||
('PAGESIZE', '0')
|
||||
--, ('FILE', '')
|
||||
, ('STATUS', 'NO')
|
||||
, ('SUMMARY', 'YES')
|
||||
--, ('MESSAGES', 'NO')
|
||||
, ('ENERY', 'NO')
|
||||
, ('NODES', 'NONE')
|
||||
, ('LINKS', 'NONE')
|
||||
;
|
||||
|
||||
@@ -7,3 +7,30 @@ create table options
|
||||
key text not null
|
||||
, value text not null
|
||||
);
|
||||
|
||||
insert into options (key, value) values
|
||||
('UNITS', 'GPM')
|
||||
, ('HEADLOSS', 'H-W')
|
||||
--, ('HYDRAULICS', '')
|
||||
, ('VISCOSITY', '1.0')
|
||||
, ('SPECIFIC GRAVITY', '1.0')
|
||||
, ('TRIALS', '40')
|
||||
, ('ACCURACY', '0.001')
|
||||
, ('FLOWCHANGE', '0')
|
||||
, ('HEADERROR', '0')
|
||||
, ('CHECKFREQ', '2')
|
||||
, ('MAXCHECK', '10')
|
||||
, ('DAMPLIMIT', '0')
|
||||
, ('UNBALANCED', 'STOP')
|
||||
, ('DEMAND MODEL', 'DDA')
|
||||
, ('MINIMUM PRESSURE', '0')
|
||||
, ('REQUIRED PRESSURE', '0.1')
|
||||
, ('PRESSURE EXPONENT', '0.5')
|
||||
, ('PATTERN', '1')
|
||||
, ('DEMAND MULTIPLIER', '1.0')
|
||||
, ('EMITTER EXPONENT', '0.5')
|
||||
, ('QUALITY', 'NONE')
|
||||
, ('DIFFUSIVITY', '1.0')
|
||||
, ('TOLERANCE', '0.01')
|
||||
--, ('MAP', '')
|
||||
;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [TANKS]
|
||||
|
||||
create type tanks_overflow as enum ('yes', 'no');
|
||||
create type tanks_overflow as enum ('YES', 'NO');
|
||||
|
||||
create table tanks
|
||||
(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [PIPES]
|
||||
|
||||
create type pipes_status as enum ('open', 'closed', 'cv');
|
||||
create type pipes_status as enum ('OPEN', 'CLOSED', 'CV');
|
||||
|
||||
create table pipes
|
||||
(
|
||||
|
||||
@@ -5,28 +5,10 @@ create table pumps
|
||||
id varchar(32) primary key references _link(id)
|
||||
, node1 varchar(32) references _node(id) not null
|
||||
, node2 varchar(32) references _node(id) not null
|
||||
);
|
||||
|
||||
create table pumps_property_power
|
||||
(
|
||||
id varchar primary key references pumps(id)
|
||||
, value varchar(32) not null
|
||||
);
|
||||
|
||||
create table pumps_property_speed
|
||||
(
|
||||
id varchar primary key references pumps(id)
|
||||
, value varchar(32) not null
|
||||
);
|
||||
|
||||
create table pumps_property_head
|
||||
(
|
||||
id varchar primary key references pumps(id)
|
||||
, head varchar(32) references _curve(id) not null
|
||||
);
|
||||
|
||||
create table pumps_property_pattern
|
||||
(
|
||||
id varchar primary key references pumps(id)
|
||||
, pattern varchar(32) references _pattern(id) not null
|
||||
, power numeric
|
||||
, head varchar(32) references _curve(id)
|
||||
, speed numeric
|
||||
, pattern varchar(32) references _pattern(id)
|
||||
, check (power is not null or head is not null)
|
||||
, check ((power is not null and head is not null) is false)
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- [VALVES]
|
||||
|
||||
create type valves_type as enum ('prv', 'psv', 'pbv', 'fcv', 'tcv', 'gpv');
|
||||
create type valves_type as enum ('PRV', 'PSV', 'PBV', 'FCV', 'TCV', 'GPV');
|
||||
|
||||
create table valves
|
||||
(
|
||||
|
||||
@@ -5,5 +5,5 @@ create table demands
|
||||
junction varchar(32) references junctions(id) not null
|
||||
, demand numeric not null
|
||||
, pattern varchar(32) references _pattern(id)
|
||||
, category text not null
|
||||
, category text
|
||||
);
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
-- [STATUS]
|
||||
|
||||
drop table if exists status_link;
|
||||
drop table if exists status;
|
||||
|
||||
drop table if exists status_valve;
|
||||
|
||||
drop type if exists status_valve_status;
|
||||
|
||||
drop table if exists status_pump;
|
||||
|
||||
drop table if exists status_pipe;
|
||||
|
||||
drop type if exists status_pipe_pump_status;
|
||||
drop type if exists link_status;
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
-- [CONTROLS]
|
||||
|
||||
drop table if exists controls_3;
|
||||
|
||||
drop table if exists controls_2;
|
||||
|
||||
drop table if exists controls_1;
|
||||
|
||||
drop type if exists controls_1_prep;
|
||||
drop table if exists controls;
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
-- [PUMPS]
|
||||
|
||||
drop table if exists pumps_property_pattern;
|
||||
|
||||
drop table if exists pumps_property_head;
|
||||
|
||||
drop table if exists pumps_property_speed;
|
||||
|
||||
drop table if exists pumps_property_power;
|
||||
|
||||
drop table if exists pumps;
|
||||
|
||||
@@ -165,7 +165,7 @@ class TestApi:
|
||||
add_junction(p, ChangeSet({'id': 'j2', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
add_junction(p, ChangeSet({'id': 'j3', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
add_pipe(p, ChangeSet({'id': 'p1', 'node1': 'j1', 'node2': 'j2', 'length': 100.0, 'diameter': 10.0, 'roughness': 0.1, 'minor_loss': 0.5, 'status': PIPE_STATUS_OPEN }))
|
||||
add_pump(p, ChangeSet({'id': 'p2', 'node1': 'j1', 'node2': 'j2'}))
|
||||
add_pump(p, ChangeSet({'id': 'p2', 'node1': 'j1', 'node2': 'j2', 'power': 0.0}))
|
||||
add_valve(p, ChangeSet({'id': 'v1', 'node1': 'j2', 'node2': 'j3', 'diameter': 10.0, 'v_type': VALVES_TYPE_FCV, 'setting': 0.1, 'minor_loss': 0.5 }))
|
||||
assert get_junction(p, 'j1')['links'] == ['p1', 'p2']
|
||||
assert get_junction(p, 'j2')['links'] == ['p1', 'p2', 'v1']
|
||||
@@ -322,7 +322,7 @@ class TestApi:
|
||||
add_reservoir(p, ChangeSet({'id': 'r2', 'x': 0.0, 'y': 10.0, 'head': 20.0}))
|
||||
add_reservoir(p, ChangeSet({'id': 'r3', 'x': 0.0, 'y': 10.0, 'head': 20.0}))
|
||||
add_pipe(p, ChangeSet({'id': 'p1', 'node1': 'r1', 'node2': 'r2', 'length': 100.0, 'diameter': 10.0, 'roughness': 0.1, 'minor_loss': 0.5, 'status': PIPE_STATUS_OPEN }))
|
||||
add_pump(p, ChangeSet({'id': 'p2', 'node1': 'r1', 'node2': 'r2'}))
|
||||
add_pump(p, ChangeSet({'id': 'p2', 'node1': 'r1', 'node2': 'r2', 'power': 0.0}))
|
||||
add_valve(p, ChangeSet({'id': 'v1', 'node1': 'r2', 'node2': 'r3', 'diameter': 10.0, 'v_type': VALVES_TYPE_FCV, 'setting': 0.1, 'minor_loss': 0.5 }))
|
||||
assert get_reservoir(p, 'r1')['links'] == ['p1', 'p2']
|
||||
assert get_reservoir(p, 'r2')['links'] == ['p1', 'p2', 'v1']
|
||||
@@ -497,7 +497,7 @@ class TestApi:
|
||||
add_tank(p, ChangeSet({'id': 't2', 'x': 0.0, 'y': 10.0, 'elevation': 20.0, 'init_level': 1.0, 'min_level': 0.0, 'max_level': 2.0, 'diameter': 10.0, 'min_vol': 100.0, 'vol_curve': None, 'overflow': OVERFLOW_NO}))
|
||||
add_tank(p, ChangeSet({'id': 't3', 'x': 0.0, 'y': 10.0, 'elevation': 20.0, 'init_level': 1.0, 'min_level': 0.0, 'max_level': 2.0, 'diameter': 10.0, 'min_vol': 100.0, 'vol_curve': None, 'overflow': OVERFLOW_NO}))
|
||||
add_pipe(p, ChangeSet({'id': 'p1', 'node1': 't1', 'node2': 't2', 'length': 100.0, 'diameter': 10.0, 'roughness': 0.1, 'minor_loss': 0.5, 'status': PIPE_STATUS_OPEN }))
|
||||
add_pump(p, ChangeSet({'id': 'p2', 'node1': 't1', 'node2': 't2'}))
|
||||
add_pump(p, ChangeSet({'id': 'p2', 'node1': 't1', 'node2': 't2', 'power': 0.0}))
|
||||
add_valve(p, ChangeSet({'id': 'v1', 'node1': 't2', 'node2': 't3', 'diameter': 10.0, 'v_type': VALVES_TYPE_FCV, 'setting': 0.1, 'minor_loss': 0.5 }))
|
||||
assert get_tank(p, 't1')['links'] == ['p1', 'p2']
|
||||
assert get_tank(p, 't2')['links'] == ['p1', 'p2', 'v1']
|
||||
@@ -846,17 +846,25 @@ class TestApi:
|
||||
assert is_junction(p, 'j3')
|
||||
assert is_junction(p, 'j4')
|
||||
|
||||
add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2'}))
|
||||
add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'power': 0.0}))
|
||||
p0 = get_pump(p, 'p0')
|
||||
assert p0['node1'] == 'j1'
|
||||
assert p0['node2'] == 'j2'
|
||||
assert p0['power'] == 0.0
|
||||
assert p0['head'] == None
|
||||
assert p0['speed'] == None
|
||||
assert p0['pattern'] == None
|
||||
|
||||
set_pump(p, ChangeSet({'id': 'p0', 'node1': 'j3', 'node2': 'j4'}))
|
||||
p0 = get_pump(p, 'p0')
|
||||
assert p0['node1'] == 'j3'
|
||||
assert p0['node2'] == 'j4'
|
||||
|
||||
add_pump(p, ChangeSet({'id': 'p1', 'node1': 'j1', 'node2': 'j2'}))
|
||||
set_pump(p, ChangeSet({'id': 'p0', 'power': 100.0}))
|
||||
p0 = get_pump(p, 'p0')
|
||||
assert p0['power'] == 100.0
|
||||
|
||||
add_pump(p, ChangeSet({'id': 'p1', 'node1': 'j1', 'node2': 'j2', 'power': 0.0}))
|
||||
links = get_links(p)
|
||||
assert len(links) == 2
|
||||
assert links[0] == 'p0'
|
||||
@@ -889,12 +897,13 @@ class TestApi:
|
||||
assert is_junction(p, 'j3')
|
||||
assert is_junction(p, 'j4')
|
||||
|
||||
cs = add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2'})).operations[0]
|
||||
cs = add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'power': 0.0})).operations[0]
|
||||
assert cs['operation'] == 'add'
|
||||
assert cs['type'] == PUMP
|
||||
assert cs['id'] == 'p0'
|
||||
assert cs['node1'] == 'j1'
|
||||
assert cs['node2'] == 'j2'
|
||||
assert cs['power'] == 0.0
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == 'delete'
|
||||
@@ -919,7 +928,7 @@ class TestApi:
|
||||
links = get_links(p)
|
||||
assert len(links) == 0
|
||||
|
||||
add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2'}))
|
||||
add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'power': 0.0}))
|
||||
|
||||
links = get_links(p)
|
||||
assert len(links) == 1
|
||||
@@ -968,6 +977,18 @@ class TestApi:
|
||||
assert cs['node1'] == 'j1'
|
||||
assert cs['node2'] == 'j2'
|
||||
|
||||
cs = set_pump(p, ChangeSet({'id': 'p0', 'power': 100.0})).operations[0]
|
||||
assert cs['operation'] == 'update'
|
||||
assert cs['type'] == PUMP
|
||||
assert cs['id'] == 'p0'
|
||||
assert cs['power'] == 100.0
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == 'update'
|
||||
assert cs['type'] == PUMP
|
||||
assert cs['id'] == 'p0'
|
||||
assert cs['power'] == 0.0
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
@@ -1153,6 +1174,596 @@ class TestApi:
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_demand(self):
|
||||
p = 'test_demand'
|
||||
self.enter(p)
|
||||
|
||||
add_junction(p, ChangeSet({'id': 'j1', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
assert is_junction(p, 'j1')
|
||||
|
||||
d = get_demand(p, 'j1')
|
||||
assert d['junction'] == 'j1'
|
||||
assert d['demands'] == []
|
||||
|
||||
set_demand(p, ChangeSet({'junction': 'j1', 'demands': [{'demand': 10.0, 'pattern': None, 'category': 'x'},
|
||||
{'demand': 20.0, 'pattern': None, 'category': None}]}))
|
||||
|
||||
d = get_demand(p, 'j1')
|
||||
assert d['junction'] == 'j1'
|
||||
ds = d['demands']
|
||||
assert len(ds) == 2
|
||||
assert ds[0]['demand'] == 10.0
|
||||
assert ds[0]['pattern'] == None
|
||||
assert ds[0]['category'] == 'x'
|
||||
assert ds[1]['demand'] == 20.0
|
||||
assert ds[1]['pattern'] == None
|
||||
assert ds[1]['category'] == None
|
||||
|
||||
set_demand(p, ChangeSet({'junction': 'j1', 'demands': []}))
|
||||
|
||||
d = get_demand(p, 'j1')
|
||||
assert d['junction'] == 'j1'
|
||||
assert d['demands'] == []
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_demand_op(self):
|
||||
p = 'test_demand_op'
|
||||
self.enter(p)
|
||||
|
||||
add_junction(p, ChangeSet({'id': 'j1', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
assert is_junction(p, 'j1')
|
||||
|
||||
cs = set_demand(p, ChangeSet({'junction': 'j1', 'demands': [{'demand': 10.0, 'pattern': None, 'category': 'x'},
|
||||
{'demand': 20.0, 'pattern': None, 'category': None}]})).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'demand'
|
||||
assert cs['junction'] == 'j1'
|
||||
ds = cs['demands']
|
||||
assert len(ds) == 2
|
||||
assert ds[0]['demand'] == 10.0
|
||||
assert ds[0]['pattern'] == None
|
||||
assert ds[0]['category'] == 'x'
|
||||
assert ds[1]['demand'] == 20.0
|
||||
assert ds[1]['pattern'] == None
|
||||
assert ds[1]['category'] == None
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'demand'
|
||||
assert cs['junction'] == 'j1'
|
||||
assert len(cs['demands']) == 0
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'demand'
|
||||
assert cs['junction'] == 'j1'
|
||||
ds = cs['demands']
|
||||
assert len(ds) == 2
|
||||
assert ds[0]['demand'] == 10.0
|
||||
assert ds[0]['pattern'] == None
|
||||
assert ds[0]['category'] == 'x'
|
||||
assert ds[1]['demand'] == 20.0
|
||||
assert ds[1]['pattern'] == None
|
||||
assert ds[1]['category'] == None
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_status(self):
|
||||
p = 'test_status'
|
||||
self.enter(p)
|
||||
|
||||
add_junction(p, ChangeSet({'id': 'j1', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
add_junction(p, ChangeSet({'id': 'j2', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
assert is_junction(p, 'j1')
|
||||
assert is_junction(p, 'j2')
|
||||
|
||||
add_pipe(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'length': 100.0, 'diameter': 10.0, 'roughness': 0.1, 'minor_loss': 0.5, 'status': PIPE_STATUS_OPEN }))
|
||||
assert is_pipe(p, 'p0')
|
||||
|
||||
s = get_status(p, 'p0')
|
||||
assert s['link'] == 'p0'
|
||||
assert s['status'] == None
|
||||
assert s['setting'] == None
|
||||
|
||||
set_status(p, ChangeSet({'link': 'p0', 'status': LINK_STATUS_OPEN, 'setting': 10.0}))
|
||||
s = get_status(p, 'p0')
|
||||
assert s['link'] == 'p0'
|
||||
assert s['status'] == LINK_STATUS_OPEN
|
||||
assert s['setting'] == 10.0
|
||||
|
||||
set_status(p, ChangeSet({'link': 'p0', 'status': None, 'setting': None}))
|
||||
s = get_status(p, 'p0')
|
||||
assert s['link'] == 'p0'
|
||||
assert s['status'] == None
|
||||
assert s['setting'] == None
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_status_op(self):
|
||||
p = 'test_status_op'
|
||||
self.enter(p)
|
||||
|
||||
add_junction(p, ChangeSet({'id': 'j1', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
add_junction(p, ChangeSet({'id': 'j2', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
assert is_junction(p, 'j1')
|
||||
assert is_junction(p, 'j2')
|
||||
|
||||
add_pipe(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'length': 100.0, 'diameter': 10.0, 'roughness': 0.1, 'minor_loss': 0.5, 'status': PIPE_STATUS_OPEN }))
|
||||
assert is_pipe(p, 'p0')
|
||||
|
||||
s = get_status(p, 'p0')
|
||||
assert s['link'] == 'p0'
|
||||
assert s['status'] == None
|
||||
assert s['setting'] == None
|
||||
|
||||
cs = set_status(p, ChangeSet({'link': 'p0', 'status': LINK_STATUS_OPEN, 'setting': 10.0})).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'status'
|
||||
assert cs['link'] == 'p0'
|
||||
assert cs['status'] == LINK_STATUS_OPEN
|
||||
assert cs['setting'] == 10.0
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'status'
|
||||
assert cs['link'] == 'p0'
|
||||
assert cs['status'] == None
|
||||
assert cs['setting'] == None
|
||||
|
||||
s = get_status(p, 'p0')
|
||||
assert s['link'] == 'p0'
|
||||
assert s['status'] == None
|
||||
assert s['setting'] == None
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'status'
|
||||
assert cs['link'] == 'p0'
|
||||
assert cs['status'] == LINK_STATUS_OPEN
|
||||
assert cs['setting'] == 10.0
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_pattern(self):
|
||||
p = 'test_pattern'
|
||||
self.enter(p)
|
||||
|
||||
assert is_pattern(p, 'p0') == False
|
||||
p0 = get_pattern(p, 'p0')
|
||||
assert p0['id'] == 'p0'
|
||||
assert p0['factors'] == []
|
||||
|
||||
set_pattern(p, ChangeSet({'id' : 'p0', 'factors': [1.0, 2.0, 3.0]}))
|
||||
|
||||
assert is_pattern(p, 'p0')
|
||||
p0 = get_pattern(p, 'p0')
|
||||
assert p0['id'] == 'p0'
|
||||
assert p0['factors'] == [1.0, 2.0, 3.0]
|
||||
|
||||
set_pattern(p, ChangeSet({'id' : 'p0', 'factors': []}))
|
||||
|
||||
assert is_pattern(p, 'p0') == False
|
||||
p0 = get_pattern(p, 'p0')
|
||||
assert p0['id'] == 'p0'
|
||||
assert p0['factors'] == []
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_pattern_op(self):
|
||||
p = 'test_pattern_op'
|
||||
self.enter(p)
|
||||
|
||||
cs = set_pattern(p, ChangeSet({'id' : 'p0', 'factors': [1.0, 2.0, 3.0]})).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == PATTERN
|
||||
assert cs['id'] == 'p0'
|
||||
assert cs['factors'] == [1.0, 2.0, 3.0]
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == PATTERN
|
||||
assert cs['id'] == 'p0'
|
||||
assert cs['factors'] == []
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == PATTERN
|
||||
assert cs['id'] == 'p0'
|
||||
assert cs['factors'] == [1.0, 2.0, 3.0]
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_curve(self):
|
||||
p = 'test_curve'
|
||||
self.enter(p)
|
||||
|
||||
assert is_curve(p, 'c0') == False
|
||||
c0 = get_curve(p, 'c0')
|
||||
assert c0['id'] == 'c0'
|
||||
assert c0['coords'] == []
|
||||
|
||||
set_curve(p, ChangeSet({'id' : 'c0', 'coords': [{'x': 1.0, 'y': 2.0}, {'x': 2.0, 'y': 1.0}]}))
|
||||
|
||||
assert is_curve(p, 'c0')
|
||||
c0 = get_curve(p, 'c0')
|
||||
assert c0['id'] == 'c0'
|
||||
xys = c0['coords']
|
||||
assert len(xys) == 2
|
||||
assert xys[0]['x'] == 1.0
|
||||
assert xys[0]['y'] == 2.0
|
||||
assert xys[1]['x'] == 2.0
|
||||
assert xys[1]['y'] == 1.0
|
||||
|
||||
set_curve(p, ChangeSet({'id' : 'c0', 'coords': []}))
|
||||
|
||||
assert is_curve(p, 'c0') == False
|
||||
c0 = get_curve(p, 'c0')
|
||||
assert c0['id'] == 'c0'
|
||||
assert c0['coords'] == []
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_curve_op(self):
|
||||
p = 'test_curve_op'
|
||||
self.enter(p)
|
||||
|
||||
cs = set_curve(p, ChangeSet({'id' : 'c0', 'coords': [{'x': 1.0, 'y': 2.0}, {'x': 2.0, 'y': 1.0}]})).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == CURVE
|
||||
assert cs['id'] == 'c0'
|
||||
xys = cs['coords']
|
||||
assert len(xys) == 2
|
||||
assert xys[0]['x'] == 1.0
|
||||
assert xys[0]['y'] == 2.0
|
||||
assert xys[1]['x'] == 2.0
|
||||
assert xys[1]['y'] == 1.0
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == CURVE
|
||||
assert cs['id'] == 'c0'
|
||||
assert cs['coords'] == []
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == CURVE
|
||||
assert cs['id'] == 'c0'
|
||||
xys = cs['coords']
|
||||
assert len(xys) == 2
|
||||
assert xys[0]['x'] == 1.0
|
||||
assert xys[0]['y'] == 2.0
|
||||
assert xys[1]['x'] == 2.0
|
||||
assert xys[1]['y'] == 1.0
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_emitter(self):
|
||||
p = 'test_emitter'
|
||||
self.enter(p)
|
||||
|
||||
add_junction(p, ChangeSet({'id': 'j1', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
assert is_junction(p, 'j1')
|
||||
|
||||
e = get_emitter(p, 'j1')
|
||||
assert e['junction'] == 'j1'
|
||||
assert e['coefficient'] == None
|
||||
|
||||
set_emitter(p, ChangeSet({'junction': 'j1', 'coefficient': 10.0}))
|
||||
|
||||
e = get_emitter(p, 'j1')
|
||||
assert e['junction'] == 'j1'
|
||||
assert e['coefficient'] == 10.0
|
||||
|
||||
set_emitter(p, ChangeSet({'junction': 'j1', 'coefficient': None}))
|
||||
|
||||
e = get_emitter(p, 'j1')
|
||||
assert e['junction'] == 'j1'
|
||||
assert e['coefficient'] == None
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_emitter_op(self):
|
||||
p = 'test_emitter_op'
|
||||
self.enter(p)
|
||||
|
||||
add_junction(p, ChangeSet({'id': 'j1', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
|
||||
assert is_junction(p, 'j1')
|
||||
|
||||
cs = set_emitter(p, ChangeSet({'junction': 'j1', 'coefficient': 10.0})).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'emitter'
|
||||
assert cs['junction'] == 'j1'
|
||||
assert cs['coefficient'] == 10.0
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'emitter'
|
||||
assert cs['junction'] == 'j1'
|
||||
assert cs['coefficient'] == None
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'emitter'
|
||||
assert cs['junction'] == 'j1'
|
||||
assert cs['coefficient'] == 10.0
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_time(self):
|
||||
p = 'test_time'
|
||||
self.enter(p)
|
||||
|
||||
t = get_time(p)
|
||||
assert t['DURATION'] == '0:00'
|
||||
assert t['HYDRAULIC TIMESTEP'] == '1:00'
|
||||
assert t['QUALITY TIMESTEP'] == '0:05'
|
||||
assert t['RULE TIMESTEP'] == '0:05'
|
||||
assert t['PATTERN TIMESTEP'] == '1:00'
|
||||
assert t['PATTERN START'] == '0:00'
|
||||
assert t['REPORT TIMESTEP'] == '1:00'
|
||||
assert t['REPORT START'] == '0:00'
|
||||
assert t['START CLOCKTIME'] == '12:00 AM'
|
||||
assert t['STATISTIC'] == TIME_STATISTIC_NONE
|
||||
|
||||
t['STATISTIC'] = TIME_STATISTIC_AVERAGED
|
||||
set_time(p, ChangeSet(t))
|
||||
|
||||
t = get_time(p)
|
||||
assert t['DURATION'] == '0:00'
|
||||
assert t['HYDRAULIC TIMESTEP'] == '1:00'
|
||||
assert t['QUALITY TIMESTEP'] == '0:05'
|
||||
assert t['RULE TIMESTEP'] == '0:05'
|
||||
assert t['PATTERN TIMESTEP'] == '1:00'
|
||||
assert t['PATTERN START'] == '0:00'
|
||||
assert t['REPORT TIMESTEP'] == '1:00'
|
||||
assert t['REPORT START'] == '0:00'
|
||||
assert t['START CLOCKTIME'] == '12:00 AM'
|
||||
assert t['STATISTIC'] == TIME_STATISTIC_AVERAGED
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_time_op(self):
|
||||
p = 'test_time_op'
|
||||
self.enter(p)
|
||||
|
||||
t = get_time(p)
|
||||
assert t['DURATION'] == '0:00'
|
||||
assert t['HYDRAULIC TIMESTEP'] == '1:00'
|
||||
assert t['QUALITY TIMESTEP'] == '0:05'
|
||||
assert t['RULE TIMESTEP'] == '0:05'
|
||||
assert t['PATTERN TIMESTEP'] == '1:00'
|
||||
assert t['PATTERN START'] == '0:00'
|
||||
assert t['REPORT TIMESTEP'] == '1:00'
|
||||
assert t['REPORT START'] == '0:00'
|
||||
assert t['START CLOCKTIME'] == '12:00 AM'
|
||||
assert t['STATISTIC'] == TIME_STATISTIC_NONE
|
||||
|
||||
t['STATISTIC'] = TIME_STATISTIC_AVERAGED
|
||||
cs = set_time(p, ChangeSet(t)).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'time'
|
||||
assert cs['DURATION'] == '0:00'
|
||||
assert cs['HYDRAULIC TIMESTEP'] == '1:00'
|
||||
assert cs['QUALITY TIMESTEP'] == '0:05'
|
||||
assert cs['RULE TIMESTEP'] == '0:05'
|
||||
assert cs['PATTERN TIMESTEP'] == '1:00'
|
||||
assert cs['PATTERN START'] == '0:00'
|
||||
assert cs['REPORT TIMESTEP'] == '1:00'
|
||||
assert cs['REPORT START'] == '0:00'
|
||||
assert cs['START CLOCKTIME'] == '12:00 AM'
|
||||
assert cs['STATISTIC'] == TIME_STATISTIC_AVERAGED
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'time'
|
||||
assert cs['DURATION'] == '0:00'
|
||||
assert cs['HYDRAULIC TIMESTEP'] == '1:00'
|
||||
assert cs['QUALITY TIMESTEP'] == '0:05'
|
||||
assert cs['RULE TIMESTEP'] == '0:05'
|
||||
assert cs['PATTERN TIMESTEP'] == '1:00'
|
||||
assert cs['PATTERN START'] == '0:00'
|
||||
assert cs['REPORT TIMESTEP'] == '1:00'
|
||||
assert cs['REPORT START'] == '0:00'
|
||||
assert cs['START CLOCKTIME'] == '12:00 AM'
|
||||
assert cs['STATISTIC'] == TIME_STATISTIC_NONE
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'time'
|
||||
assert cs['DURATION'] == '0:00'
|
||||
assert cs['HYDRAULIC TIMESTEP'] == '1:00'
|
||||
assert cs['QUALITY TIMESTEP'] == '0:05'
|
||||
assert cs['RULE TIMESTEP'] == '0:05'
|
||||
assert cs['PATTERN TIMESTEP'] == '1:00'
|
||||
assert cs['PATTERN START'] == '0:00'
|
||||
assert cs['REPORT TIMESTEP'] == '1:00'
|
||||
assert cs['REPORT START'] == '0:00'
|
||||
assert cs['START CLOCKTIME'] == '12:00 AM'
|
||||
assert cs['STATISTIC'] == TIME_STATISTIC_AVERAGED
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_option(self):
|
||||
p = 'test_option'
|
||||
self.enter(p)
|
||||
|
||||
o = get_option(p)
|
||||
assert o['UNITS'] == OPTION_UNITS_GPM
|
||||
assert o['HEADLOSS'] == OPTION_HEADLOSS_HW
|
||||
assert o['VISCOSITY'] == '1.0'
|
||||
assert o['SPECIFIC GRAVITY'] == '1.0'
|
||||
assert o['TRIALS'] == '40'
|
||||
assert o['ACCURACY'] == '0.001'
|
||||
assert o['FLOWCHANGE'] == '0'
|
||||
assert o['HEADERROR'] == '0'
|
||||
assert o['CHECKFREQ'] == '2'
|
||||
assert o['MAXCHECK'] == '10'
|
||||
assert o['DAMPLIMIT'] == '0'
|
||||
assert o['UNBALANCED'] == OPTION_UNBALANCED_STOP
|
||||
assert o['DEMAND MODEL'] == OPTION_DEMAND_MODEL_DDA
|
||||
assert o['MINIMUM PRESSURE'] == '0'
|
||||
assert o['REQUIRED PRESSURE'] == '0.1'
|
||||
assert o['PRESSURE EXPONENT'] == '0.5'
|
||||
assert o['PATTERN'] == '1'
|
||||
assert o['DEMAND MULTIPLIER'] == '1.0'
|
||||
assert o['EMITTER EXPONENT'] == '0.5'
|
||||
assert o['QUALITY'] == OPTION_QUALITY_NONE
|
||||
assert o['DIFFUSIVITY'] == '1.0'
|
||||
assert o['TOLERANCE'] == '0.01'
|
||||
|
||||
o['UNITS'] = OPTION_UNITS_LPS
|
||||
set_option(p, ChangeSet(o))
|
||||
|
||||
o = get_option(p)
|
||||
assert o['UNITS'] == OPTION_UNITS_LPS
|
||||
assert o['HEADLOSS'] == OPTION_HEADLOSS_HW
|
||||
assert o['VISCOSITY'] == '1.0'
|
||||
assert o['SPECIFIC GRAVITY'] == '1.0'
|
||||
assert o['TRIALS'] == '40'
|
||||
assert o['ACCURACY'] == '0.001'
|
||||
assert o['FLOWCHANGE'] == '0'
|
||||
assert o['HEADERROR'] == '0'
|
||||
assert o['CHECKFREQ'] == '2'
|
||||
assert o['MAXCHECK'] == '10'
|
||||
assert o['DAMPLIMIT'] == '0'
|
||||
assert o['UNBALANCED'] == OPTION_UNBALANCED_STOP
|
||||
assert o['DEMAND MODEL'] == OPTION_DEMAND_MODEL_DDA
|
||||
assert o['MINIMUM PRESSURE'] == '0'
|
||||
assert o['REQUIRED PRESSURE'] == '0.1'
|
||||
assert o['PRESSURE EXPONENT'] == '0.5'
|
||||
assert o['PATTERN'] == '1'
|
||||
assert o['DEMAND MULTIPLIER'] == '1.0'
|
||||
assert o['EMITTER EXPONENT'] == '0.5'
|
||||
assert o['QUALITY'] == OPTION_QUALITY_NONE
|
||||
assert o['DIFFUSIVITY'] == '1.0'
|
||||
assert o['TOLERANCE'] == '0.01'
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_option_op(self):
|
||||
p = 'test_option_op'
|
||||
self.enter(p)
|
||||
|
||||
o = get_option(p)
|
||||
assert o['UNITS'] == OPTION_UNITS_GPM
|
||||
assert o['HEADLOSS'] == OPTION_HEADLOSS_HW
|
||||
assert o['VISCOSITY'] == '1.0'
|
||||
assert o['SPECIFIC GRAVITY'] == '1.0'
|
||||
assert o['TRIALS'] == '40'
|
||||
assert o['ACCURACY'] == '0.001'
|
||||
assert o['FLOWCHANGE'] == '0'
|
||||
assert o['HEADERROR'] == '0'
|
||||
assert o['CHECKFREQ'] == '2'
|
||||
assert o['MAXCHECK'] == '10'
|
||||
assert o['DAMPLIMIT'] == '0'
|
||||
assert o['UNBALANCED'] == OPTION_UNBALANCED_STOP
|
||||
assert o['DEMAND MODEL'] == OPTION_DEMAND_MODEL_DDA
|
||||
assert o['MINIMUM PRESSURE'] == '0'
|
||||
assert o['REQUIRED PRESSURE'] == '0.1'
|
||||
assert o['PRESSURE EXPONENT'] == '0.5'
|
||||
assert o['PATTERN'] == '1'
|
||||
assert o['DEMAND MULTIPLIER'] == '1.0'
|
||||
assert o['EMITTER EXPONENT'] == '0.5'
|
||||
assert o['QUALITY'] == OPTION_QUALITY_NONE
|
||||
assert o['DIFFUSIVITY'] == '1.0'
|
||||
assert o['TOLERANCE'] == '0.01'
|
||||
|
||||
o['UNITS'] = OPTION_UNITS_LPS
|
||||
cs = set_option(p, ChangeSet(o)).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'option'
|
||||
assert cs['UNITS'] == OPTION_UNITS_LPS
|
||||
assert cs['HEADLOSS'] == OPTION_HEADLOSS_HW
|
||||
assert cs['VISCOSITY'] == '1.0'
|
||||
assert cs['SPECIFIC GRAVITY'] == '1.0'
|
||||
assert cs['TRIALS'] == '40'
|
||||
assert cs['ACCURACY'] == '0.001'
|
||||
assert cs['FLOWCHANGE'] == '0'
|
||||
assert cs['HEADERROR'] == '0'
|
||||
assert cs['CHECKFREQ'] == '2'
|
||||
assert cs['MAXCHECK'] == '10'
|
||||
assert cs['DAMPLIMIT'] == '0'
|
||||
assert cs['UNBALANCED'] == OPTION_UNBALANCED_STOP
|
||||
assert cs['DEMAND MODEL'] == OPTION_DEMAND_MODEL_DDA
|
||||
assert cs['MINIMUM PRESSURE'] == '0'
|
||||
assert cs['REQUIRED PRESSURE'] == '0.1'
|
||||
assert cs['PRESSURE EXPONENT'] == '0.5'
|
||||
assert cs['PATTERN'] == '1'
|
||||
assert cs['DEMAND MULTIPLIER'] == '1.0'
|
||||
assert cs['EMITTER EXPONENT'] == '0.5'
|
||||
assert cs['QUALITY'] == OPTION_QUALITY_NONE
|
||||
assert cs['DIFFUSIVITY'] == '1.0'
|
||||
assert cs['TOLERANCE'] == '0.01'
|
||||
|
||||
cs = execute_undo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'option'
|
||||
assert cs['UNITS'] == OPTION_UNITS_GPM
|
||||
assert cs['HEADLOSS'] == OPTION_HEADLOSS_HW
|
||||
assert cs['VISCOSITY'] == '1.0'
|
||||
assert cs['SPECIFIC GRAVITY'] == '1.0'
|
||||
assert cs['TRIALS'] == '40'
|
||||
assert cs['ACCURACY'] == '0.001'
|
||||
assert cs['FLOWCHANGE'] == '0'
|
||||
assert cs['HEADERROR'] == '0'
|
||||
assert cs['CHECKFREQ'] == '2'
|
||||
assert cs['MAXCHECK'] == '10'
|
||||
assert cs['DAMPLIMIT'] == '0'
|
||||
assert cs['UNBALANCED'] == OPTION_UNBALANCED_STOP
|
||||
assert cs['DEMAND MODEL'] == OPTION_DEMAND_MODEL_DDA
|
||||
assert cs['MINIMUM PRESSURE'] == '0'
|
||||
assert cs['REQUIRED PRESSURE'] == '0.1'
|
||||
assert cs['PRESSURE EXPONENT'] == '0.5'
|
||||
assert cs['PATTERN'] == '1'
|
||||
assert cs['DEMAND MULTIPLIER'] == '1.0'
|
||||
assert cs['EMITTER EXPONENT'] == '0.5'
|
||||
assert cs['QUALITY'] == OPTION_QUALITY_NONE
|
||||
assert cs['DIFFUSIVITY'] == '1.0'
|
||||
assert cs['TOLERANCE'] == '0.01'
|
||||
|
||||
cs = execute_redo(p).operations[0]
|
||||
assert cs['operation'] == API_UPDATE
|
||||
assert cs['type'] == 'option'
|
||||
assert cs['UNITS'] == OPTION_UNITS_LPS
|
||||
assert cs['HEADLOSS'] == OPTION_HEADLOSS_HW
|
||||
assert cs['VISCOSITY'] == '1.0'
|
||||
assert cs['SPECIFIC GRAVITY'] == '1.0'
|
||||
assert cs['TRIALS'] == '40'
|
||||
assert cs['ACCURACY'] == '0.001'
|
||||
assert cs['FLOWCHANGE'] == '0'
|
||||
assert cs['HEADERROR'] == '0'
|
||||
assert cs['CHECKFREQ'] == '2'
|
||||
assert cs['MAXCHECK'] == '10'
|
||||
assert cs['DAMPLIMIT'] == '0'
|
||||
assert cs['UNBALANCED'] == OPTION_UNBALANCED_STOP
|
||||
assert cs['DEMAND MODEL'] == OPTION_DEMAND_MODEL_DDA
|
||||
assert cs['MINIMUM PRESSURE'] == '0'
|
||||
assert cs['REQUIRED PRESSURE'] == '0.1'
|
||||
assert cs['PRESSURE EXPONENT'] == '0.5'
|
||||
assert cs['PATTERN'] == '1'
|
||||
assert cs['DEMAND MULTIPLIER'] == '1.0'
|
||||
assert cs['EMITTER EXPONENT'] == '0.5'
|
||||
assert cs['QUALITY'] == OPTION_QUALITY_NONE
|
||||
assert cs['DIFFUSIVITY'] == '1.0'
|
||||
assert cs['TOLERANCE'] == '0.01'
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
def test_snapshot(self):
|
||||
p = "test_snapshot"
|
||||
self.enter(p)
|
||||
@@ -1199,7 +1810,7 @@ class TestApi:
|
||||
|
||||
|
||||
def test_batch_commands(self):
|
||||
p = 'test_valve_op'
|
||||
p = 'test_batch_commands'
|
||||
self.enter(p)
|
||||
|
||||
cs = ChangeSet()
|
||||
@@ -1210,6 +1821,16 @@ class TestApi:
|
||||
cs = execute_batch_commands(p, cs)
|
||||
assert len(cs.operations) == 2
|
||||
|
||||
cs = ChangeSet()
|
||||
cs.delete({'type': JUNCTION, 'id': 'j1'})
|
||||
cs.delete({'type': JUNCTION, 'id': 'j2'})
|
||||
|
||||
cs = execute_batch_commands(p, cs)
|
||||
assert len(cs.operations) == 2
|
||||
|
||||
cs = execute_undo(p)
|
||||
assert len(cs.operations) == 1
|
||||
|
||||
self.leave(p)
|
||||
|
||||
|
||||
|
||||
139
tjnetwork.py
139
tjnetwork.py
@@ -23,6 +23,8 @@ TANK = api.TANK
|
||||
PIPE = api.PIPE
|
||||
PUMP = api.PUMP
|
||||
VALVE = api.VALVE
|
||||
PATTERN = api.PATTERN
|
||||
CURVE = api.CURVE
|
||||
|
||||
OVERFLOW_YES = api.OVERFLOW_YES
|
||||
OVERFLOW_NO = api.OVERFLOW_NO
|
||||
@@ -38,6 +40,42 @@ VALVES_TYPE_FCV = api.VALVES_TYPE_FCV
|
||||
VALVES_TYPE_TCV = api.VALVES_TYPE_TCV
|
||||
VALVES_TYPE_GPV = api.VALVES_TYPE_GPV
|
||||
|
||||
LINK_STATUS_OPEN = api.LINK_STATUS_OPEN
|
||||
LINK_STATUS_CLOSED = api.LINK_STATUS_CLOSED
|
||||
LINK_STATUS_ACTIVE = api.LINK_STATUS_ACTIVE
|
||||
|
||||
TIME_STATISTIC_NONE = api.TIME_STATISTIC_NONE
|
||||
TIME_STATISTIC_AVERAGED = api.TIME_STATISTIC_AVERAGED
|
||||
TIME_STATISTIC_MINIMUM = api.TIME_STATISTIC_MINIMUM
|
||||
TIME_STATISTIC_MAXIMUM = api.TIME_STATISTIC_MAXIMUM
|
||||
TIME_STATISTIC_RANGE = api.TIME_STATISTIC_RANGE
|
||||
|
||||
OPTION_UNITS_CFS = api.OPTION_UNITS_CFS
|
||||
OPTION_UNITS_GPM = api.OPTION_UNITS_GPM
|
||||
OPTION_UNITS_MGD = api.OPTION_UNITS_MGD
|
||||
OPTION_UNITS_IMGD = api.OPTION_UNITS_IMGD
|
||||
OPTION_UNITS_AFD = api.OPTION_UNITS_AFD
|
||||
OPTION_UNITS_LPS = api.OPTION_UNITS_LPS
|
||||
OPTION_UNITS_LPM = api.OPTION_UNITS_LPM
|
||||
OPTION_UNITS_MLD = api.OPTION_UNITS_MLD
|
||||
OPTION_UNITS_CMH = api.OPTION_UNITS_CMH
|
||||
OPTION_UNITS_CMD = api.OPTION_UNITS_CMD
|
||||
|
||||
OPTION_HEADLOSS_HW = api.OPTION_HEADLOSS_HW
|
||||
OPTION_HEADLOSS_DW = api.OPTION_HEADLOSS_DW
|
||||
OPTION_HEADLOSS_CM = api.OPTION_HEADLOSS_CM
|
||||
|
||||
OPTION_UNBALANCED_STOP = api.OPTION_UNBALANCED_STOP
|
||||
OPTION_UNBALANCED_CONTINUE = api.OPTION_UNBALANCED_CONTINUE
|
||||
|
||||
OPTION_DEMAND_MODEL_DDA = api.OPTION_DEMAND_MODEL_DDA
|
||||
OPTION_DEMAND_MODEL_PDA = api.OPTION_DEMAND_MODEL_PDA
|
||||
|
||||
OPTION_QUALITY_NONE = api.OPTION_QUALITY_NONE
|
||||
OPTION_QUALITY_CHEMICAL = api.OPTION_QUALITY_CHEMICAL
|
||||
OPTION_QUALITY_AGE = api.OPTION_QUALITY_AGE
|
||||
OPTION_QUALITY_TRACE = api.OPTION_QUALITY_TRACE
|
||||
|
||||
|
||||
############################################################
|
||||
# project
|
||||
@@ -264,7 +302,7 @@ def get_pump(name: str, id: str) -> dict[str, Any]:
|
||||
def set_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_pump(name, cs)
|
||||
|
||||
# example: add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2'}))
|
||||
# example: add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'power': 0}))
|
||||
def add_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.add_pump(name, cs)
|
||||
|
||||
@@ -293,6 +331,105 @@ def delete_valve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.delete_valve(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# demand 9.[DEMANDS]
|
||||
############################################################
|
||||
|
||||
def get_demand_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_demand_schema(name)
|
||||
|
||||
def get_demand(name: str, junction: str) -> dict[str, Any]:
|
||||
return api.get_demand(name, junction)
|
||||
|
||||
# { 'operation': 'update', 'type': 'demand', 'junction': 'j1', 'demands': [{'demand': 0.0, 'patten': None, 'category': None}] }
|
||||
def set_demand(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_demand(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# status 10.[STATUS]
|
||||
############################################################
|
||||
|
||||
def get_status_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_status_schema(name)
|
||||
|
||||
def get_status(name: str, link: str) -> dict[str, Any]:
|
||||
return api.get_status(name, link)
|
||||
|
||||
def set_status(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_status(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# pattern 11.[PATTERNS]
|
||||
############################################################
|
||||
|
||||
def get_pattern_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_pattern_schema(name)
|
||||
|
||||
def get_pattern(name: str, id: str) -> dict[str, Any]:
|
||||
return api.get_pattern(name, id)
|
||||
|
||||
def set_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_pattern(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# curve 12.[CURVES]
|
||||
############################################################
|
||||
|
||||
def get_curve_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_curve_schema(name)
|
||||
|
||||
def get_curve(name: str, id: str) -> dict[str, Any]:
|
||||
return api.get_curve(name, id)
|
||||
|
||||
def set_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_curve(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# emitter 16.[EMITTERS]
|
||||
############################################################
|
||||
|
||||
def get_emitter_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_emitter_schema(name)
|
||||
|
||||
def get_emitter(name: str, junction: str) -> dict[str, Any]:
|
||||
return api.get_emitter(name, junction)
|
||||
|
||||
def set_emitter(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_emitter(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# time 21.[EMITTERS]
|
||||
############################################################
|
||||
|
||||
def get_time_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_time_schema(name)
|
||||
|
||||
def get_time(name: str) -> dict[str, Any]:
|
||||
return api.get_time(name)
|
||||
|
||||
def set_time(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_time(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# option 23.[OPTIONS]
|
||||
############################################################
|
||||
|
||||
def get_option_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_option_schema(name)
|
||||
|
||||
def get_option(name: str) -> dict[str, Any]:
|
||||
return api.get_option(name)
|
||||
|
||||
def set_option(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_option(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# coord 24.[COORDINATES]
|
||||
############################################################
|
||||
|
||||
Reference in New Issue
Block a user