Accept Merge Request #184: (parse -> master)
Merge Request: Optimize read inp Created By: @王琼钰 Accepted By: @王琼钰 URL: https://tjwater.coding.net/p/tjwatercloud/d/TJWaterServer/git/merge/184?initial=true
This commit is contained in:
461
api/inp_in.py
461
api/inp_in.py
@@ -1,7 +1,8 @@
|
||||
import datetime
|
||||
import os
|
||||
from .project import *
|
||||
from .database import ChangeSet, get_current_operation, set_restore_operation
|
||||
from .sections import section_name
|
||||
from .batch_cmds import execute_batch_commands
|
||||
from .database import ChangeSet, write
|
||||
from .sections import *
|
||||
from .s1_title import inp_in_title
|
||||
from .s2_junctions import inp_in_junction
|
||||
from .s3_reservoirs import inp_in_reservoir
|
||||
@@ -12,8 +13,8 @@ from .s7_valves import inp_in_valve
|
||||
from .s8_tags import inp_in_tag
|
||||
from .s9_demands import inp_in_demand
|
||||
from .s10_status import inp_in_status
|
||||
from .s11_patterns import inp_in_pattern
|
||||
from .s12_curves import inp_in_curve
|
||||
from .s11_patterns import pattern_v3_types, inp_in_pattern
|
||||
from .s12_curves import curve_types, inp_in_curve
|
||||
from .s13_controls import inp_in_control
|
||||
from .s14_rules import inp_in_rule
|
||||
from .s15_energy import inp_in_energy
|
||||
@@ -25,220 +26,255 @@ from .s20_mixing import inp_in_mixing
|
||||
from .s21_times import inp_in_time
|
||||
from .s22_report import inp_in_report
|
||||
from .s23_options import inp_in_option
|
||||
from .s23_options_v3 import inp_in_option_v3
|
||||
from .s24_coordinates import inp_in_coord
|
||||
from .s25_vertices import inp_in_vertex
|
||||
from .s26_labels import inp_in_label
|
||||
from .s27_backdrop import inp_in_backdrop
|
||||
#from .s28_end import *
|
||||
|
||||
_S = 'S'
|
||||
_L = 'L'
|
||||
|
||||
def _inp_in_option(section: list[str], version: str = '3') -> str:
|
||||
return inp_in_option_v3(section) if version == '3' else inp_in_option(section)
|
||||
|
||||
_handler = {
|
||||
TITLE : (_S, inp_in_title),
|
||||
JUNCTIONS : (_L, inp_in_junction), # line, demand_outside
|
||||
RESERVOIRS : (_L, inp_in_reservoir),
|
||||
TANKS : (_L, inp_in_tank),
|
||||
PIPES : (_L, inp_in_pipe),
|
||||
PUMPS : (_L, inp_in_pump),
|
||||
VALVES : (_L, inp_in_valve),
|
||||
TAGS : (_L, inp_in_tag),
|
||||
DEMANDS : (_L, inp_in_demand),
|
||||
STATUS : (_L, inp_in_status),
|
||||
PATTERNS : (_L, inp_in_pattern), # line, fixed
|
||||
CURVES : (_L, inp_in_curve),
|
||||
CONTROLS : (_L, inp_in_control),
|
||||
RULES : (_L, inp_in_rule),
|
||||
ENERGY : (_L, inp_in_energy),
|
||||
EMITTERS : (_L, inp_in_emitter),
|
||||
QUALITY : (_L, inp_in_quality),
|
||||
SOURCES : (_L, inp_in_source),
|
||||
REACTIONS : (_L, inp_in_reaction),
|
||||
MIXING : (_L, inp_in_mixing),
|
||||
TIMES : (_S, inp_in_time),
|
||||
REPORT : (_S, inp_in_report),
|
||||
OPTIONS : (_S, _inp_in_option), # line, version
|
||||
COORDINATES : (_L, inp_in_coord),
|
||||
VERTICES : (_L, inp_in_vertex),
|
||||
LABELS : (_L, inp_in_label),
|
||||
BACKDROP : (_S, inp_in_backdrop),
|
||||
#END : 'END',
|
||||
}
|
||||
|
||||
_level_1 = [
|
||||
TITLE,
|
||||
PATTERNS,
|
||||
CURVES,
|
||||
CONTROLS,
|
||||
RULES,
|
||||
TIMES,
|
||||
REPORT,
|
||||
OPTIONS,
|
||||
BACKDROP,
|
||||
]
|
||||
|
||||
_level_2 = [
|
||||
JUNCTIONS,
|
||||
RESERVOIRS,
|
||||
TANKS,
|
||||
]
|
||||
|
||||
_level_3 = [
|
||||
PIPES,
|
||||
PUMPS,
|
||||
VALVES,
|
||||
DEMANDS,
|
||||
EMITTERS,
|
||||
QUALITY,
|
||||
SOURCES,
|
||||
MIXING,
|
||||
COORDINATES,
|
||||
LABELS,
|
||||
]
|
||||
|
||||
_level_4 = [
|
||||
TAGS,
|
||||
STATUS,
|
||||
ENERGY,
|
||||
REACTIONS,
|
||||
VERTICES,
|
||||
]
|
||||
|
||||
|
||||
def _parse_inp(inp: str) -> dict[str, list[str]]:
|
||||
file: dict[str, list[str]] = {}
|
||||
for s in section_name:
|
||||
file[s] = []
|
||||
class SQLBatch:
|
||||
def __init__(self, project: str, count: int = 100) -> None:
|
||||
self.batch: list[str] = []
|
||||
self.project = project
|
||||
self.count = count
|
||||
|
||||
section = ''
|
||||
def add(self, sql: str) -> None:
|
||||
self.batch.append(sql)
|
||||
if len(self.batch) == self.count:
|
||||
self.flush()
|
||||
|
||||
for line in open(inp):
|
||||
line = line.strip()
|
||||
if line == '':
|
||||
# skip empty line for control and rule
|
||||
if section == 'CONTROLS' or section == 'RULES':
|
||||
pass
|
||||
else:
|
||||
section = ''
|
||||
continue
|
||||
def flush(self) -> None:
|
||||
write(self.project, ''.join(self.batch))
|
||||
self.batch.clear()
|
||||
|
||||
if line.startswith('['):
|
||||
is_section = False
|
||||
for s in section_name:
|
||||
if line.startswith(f'[{s}'):
|
||||
section = s
|
||||
is_section = True
|
||||
break
|
||||
if is_section:
|
||||
|
||||
def _print_time(desc: str) -> datetime.datetime:
|
||||
now = datetime.datetime.now()
|
||||
time = now.strftime('%Y-%m-%d %H:%M:%S')
|
||||
print(f"{time}: {desc}")
|
||||
return now
|
||||
|
||||
|
||||
def _get_file_offset(inp: str) -> tuple[dict[str, list[int]], bool]:
|
||||
offset: dict[str, list[int]] = {}
|
||||
|
||||
current = ''
|
||||
demand_outside = False
|
||||
|
||||
with open(inp) as f:
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
break
|
||||
|
||||
line = line.strip()
|
||||
if line.startswith('['):
|
||||
for s in section_name:
|
||||
if line.startswith(f'[{s}'):
|
||||
if s not in offset:
|
||||
offset[s] = []
|
||||
offset[s].append(f.tell())
|
||||
current = s
|
||||
break
|
||||
elif line != '' and line.startswith(';') == False:
|
||||
if current == DEMANDS:
|
||||
demand_outside = True
|
||||
|
||||
return (offset, demand_outside)
|
||||
|
||||
|
||||
def parse_file(project: str, inp: str, version: str = '3') -> None:
|
||||
start = _print_time(f'Start reading file "{inp}"...')
|
||||
|
||||
_print_time("First scan...")
|
||||
offset, demand_outside = _get_file_offset(inp)
|
||||
|
||||
levels = _level_1 + _level_2 + _level_3 + _level_4
|
||||
|
||||
# parse the whole section rather than line
|
||||
sections : dict[str, list[str]]= {}
|
||||
for [s, t] in _handler.items():
|
||||
if t[0] == _S:
|
||||
sections[s] = []
|
||||
|
||||
variable_patterns = []
|
||||
current_pattern = None
|
||||
current_curve = None
|
||||
curve_type_desc_line = None
|
||||
|
||||
sql_batch = SQLBatch(project)
|
||||
|
||||
_print_time("Second scan...")
|
||||
with open(inp) as f:
|
||||
for s in levels:
|
||||
if s not in offset:
|
||||
continue
|
||||
|
||||
if section != '':
|
||||
file[section].append(line)
|
||||
|
||||
return file
|
||||
|
||||
|
||||
def _parse_cs(cs: ChangeSet) -> dict[str, list[str]]:
|
||||
file: dict[str, list[str]] = {}
|
||||
for s in section_name:
|
||||
file[s] = []
|
||||
|
||||
section = ''
|
||||
|
||||
for line in str(cs.operations[0]['inp']).split('\n'):
|
||||
line = line.strip()
|
||||
if line == '':
|
||||
# skip empty line for control and rule
|
||||
if section == 'CONTROLS' or section == 'RULES':
|
||||
pass
|
||||
else:
|
||||
section = ''
|
||||
continue
|
||||
|
||||
if line.startswith('['):
|
||||
is_section = False
|
||||
for s in section_name:
|
||||
if line.startswith(f'[{s}'):
|
||||
section = s
|
||||
is_section = True
|
||||
break
|
||||
if is_section:
|
||||
if s == DEMANDS and demand_outside == False:
|
||||
continue
|
||||
|
||||
if section != '':
|
||||
file[section].append(line)
|
||||
_print_time(f"[{s}]")
|
||||
|
||||
return file
|
||||
is_s = _handler[s][0] == _S
|
||||
handler = _handler[s][1]
|
||||
|
||||
for ptr in offset[s]:
|
||||
f.seek(ptr)
|
||||
|
||||
def _read_inp(file: dict[str, list[str]]) -> ChangeSet:
|
||||
file_cs: dict[str, ChangeSet] = {}
|
||||
for s in section_name:
|
||||
file_cs[s] = ChangeSet()
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
break
|
||||
|
||||
for name, section in file.items():
|
||||
if name == 'TITLE':
|
||||
file_cs[name].merge(inp_in_title(section))
|
||||
|
||||
elif name == 'JUNCTIONS': # + coords
|
||||
file_cs[name].merge(inp_in_junction(section))
|
||||
|
||||
elif name == 'RESERVOIRS': # + coords
|
||||
file_cs[name].merge(inp_in_reservoir(section))
|
||||
|
||||
elif name == 'TANKS': # + coords
|
||||
file_cs[name].merge(inp_in_tank(section))
|
||||
|
||||
elif name == 'PIPES':
|
||||
file_cs[name].merge(inp_in_pipe(section))
|
||||
|
||||
elif name == 'PUMPS':
|
||||
file_cs[name].merge(inp_in_pump(section))
|
||||
|
||||
elif name == 'VALVES':
|
||||
file_cs[name].merge(inp_in_valve(section))
|
||||
|
||||
elif name == 'TAGS':
|
||||
file_cs[name].merge(inp_in_tag(section))
|
||||
|
||||
elif name == 'DEMANDS':
|
||||
file_cs[name].merge(inp_in_demand(section))
|
||||
|
||||
elif name == 'STATUS':
|
||||
file_cs[name].merge(inp_in_status(section))
|
||||
|
||||
elif name == 'PATTERNS':
|
||||
file_cs[name].merge(inp_in_pattern(section))
|
||||
|
||||
elif name == 'CURVES':
|
||||
file_cs[name].merge(inp_in_curve(section))
|
||||
|
||||
elif name == 'CONTROLS':
|
||||
file_cs[name].merge(inp_in_control(section))
|
||||
|
||||
elif name == 'RULES':
|
||||
file_cs[name].merge(inp_in_rule(section))
|
||||
|
||||
elif name == 'ENERGY':
|
||||
file_cs[name].merge(inp_in_energy(section))
|
||||
|
||||
elif name == 'EMITTERS':
|
||||
file_cs[name].merge(inp_in_emitter(section))
|
||||
|
||||
elif name == 'QUALITY':
|
||||
file_cs[name].merge(inp_in_quality(section))
|
||||
|
||||
elif name == 'SOURCES':
|
||||
file_cs[name].merge(inp_in_source(section))
|
||||
|
||||
elif name == 'REACTIONS':
|
||||
file_cs[name].merge(inp_in_reaction(section))
|
||||
|
||||
elif name == 'MIXING':
|
||||
file_cs[name].merge(inp_in_mixing(section))
|
||||
|
||||
elif name == 'TIMES':
|
||||
file_cs[name].merge(inp_in_time(section))
|
||||
|
||||
elif name == 'REPORT':
|
||||
file_cs[name].merge(inp_in_report(section))
|
||||
|
||||
elif name == 'OPTIONS':
|
||||
file_cs[name].merge(inp_in_option(section))
|
||||
|
||||
elif name == 'COORDINATES':
|
||||
coords = inp_in_coord(section)
|
||||
for s in ['JUNCTIONS', 'RESERVOIRS', 'TANKS']:
|
||||
for node in file_cs[s].operations:
|
||||
if node['type'] == 'demand':
|
||||
line = line.strip()
|
||||
if line.startswith('['):
|
||||
break
|
||||
elif line == '':
|
||||
continue
|
||||
if node['id'] in coords:
|
||||
coord = coords[node['id']]
|
||||
node |= { 'x' : coord['x'], 'y' : coord['y'] }
|
||||
|
||||
if is_s:
|
||||
sections[s].append(line)
|
||||
else:
|
||||
print(f"WARNING: [{s}] {node['id']} has no coordinate, set it at origin!")
|
||||
node |= { 'x' : 0.0, 'y' : 0.0 }
|
||||
if line.startswith(';'):
|
||||
if version != '3': #v2
|
||||
line = line.removeprefix(';')
|
||||
if s == PATTERNS: # ;desc
|
||||
pass
|
||||
elif s == CURVES: # ;type: desc
|
||||
curve_type_desc_line = line
|
||||
continue
|
||||
|
||||
elif name == 'VERTICES':
|
||||
file_cs[name].merge(inp_in_vertex(section))
|
||||
if s == PATTERNS:
|
||||
tokens = line.split()
|
||||
|
||||
elif name == 'LABELS':
|
||||
file_cs[name].merge(inp_in_label(section))
|
||||
if tokens[1].upper() in pattern_v3_types: #v3
|
||||
sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');")
|
||||
current_pattern = tokens[0]
|
||||
if tokens[1].upper() == 'VARIABLE':
|
||||
variable_patterns.append(tokens[0])
|
||||
continue
|
||||
|
||||
elif name == 'BACKDROP':
|
||||
file_cs[name].merge(inp_in_backdrop(section))
|
||||
if current_pattern != tokens[0]:
|
||||
sql_batch.add(f"insert into _pattern (id) values ('{tokens[0]}');")
|
||||
current_pattern = tokens[0]
|
||||
|
||||
elif name == 'END':
|
||||
pass # :)
|
||||
elif s == CURVES:
|
||||
tokens = line.split()
|
||||
|
||||
# release file
|
||||
file = {}
|
||||
if tokens[1].upper() in curve_types: #v3
|
||||
sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{tokens[1].upper()}');")
|
||||
current_curve = tokens[0]
|
||||
continue
|
||||
|
||||
cs = ChangeSet()
|
||||
priorities = [
|
||||
'PATTERNS',
|
||||
'CURVES',
|
||||
'JUNCTIONS',
|
||||
'RESERVOIRS',
|
||||
'TANKS',
|
||||
'COORDINATES',
|
||||
'PIPES',
|
||||
'PUMPS',
|
||||
'VALVES',
|
||||
'DEMANDS',
|
||||
'STATUS',
|
||||
'OPTIONS',
|
||||
'TIMES',
|
||||
'EMITTERS',
|
||||
'QUALITY',
|
||||
'SOURCES',
|
||||
'REACTIONS',
|
||||
'MIXING',
|
||||
'ENERGY',
|
||||
'REPORT',
|
||||
'VERTICES',
|
||||
'CONTROLS',
|
||||
'RULES',
|
||||
'TITLE',
|
||||
'TAGS',
|
||||
'LABELS',
|
||||
'BACKDROP',
|
||||
'END',
|
||||
]
|
||||
for s in priorities:
|
||||
cs.merge(file_cs[s])
|
||||
if current_curve != tokens[0]:
|
||||
type = curve_types[0]
|
||||
if curve_type_desc_line != None:
|
||||
type = curve_type_desc_line.split(':')[0].strip()
|
||||
sql_batch.add(f"insert into _curve (id, type) values ('{tokens[0]}', '{type}');")
|
||||
current_curve = tokens[0]
|
||||
curve_type_desc_line = None
|
||||
|
||||
return cs
|
||||
if s == JUNCTIONS:
|
||||
sql_batch.add(handler(line, demand_outside))
|
||||
elif s == PATTERNS:
|
||||
sql_batch.add(handler(line, current_pattern not in variable_patterns))
|
||||
elif s == OPTIONS:
|
||||
sql_batch.add(handler(line, version))
|
||||
else:
|
||||
sql_batch.add(handler(line))
|
||||
|
||||
f.seek(0)
|
||||
|
||||
if is_s:
|
||||
sql_batch.add(handler(sections[s]))
|
||||
|
||||
sql_batch.flush()
|
||||
|
||||
end = _print_time(f'End reading file "{inp}"')
|
||||
print(f"Total (in second): {(end-start).seconds}(s)")
|
||||
|
||||
|
||||
def read_inp(project: str, inp: str):
|
||||
def read_inp(project: str, inp: str, version: str = '3') -> bool:
|
||||
if version != '3' and version != '2':
|
||||
version = '2'
|
||||
|
||||
if is_project_open(project):
|
||||
close_project(project)
|
||||
|
||||
@@ -248,34 +284,37 @@ def read_inp(project: str, inp: str):
|
||||
create_project(project)
|
||||
open_project(project)
|
||||
|
||||
file = _parse_inp(inp)
|
||||
cs = _read_inp(file)
|
||||
parse_file(project, inp, version)
|
||||
|
||||
execute_batch_commands(project, cs)
|
||||
op = get_current_operation(project)
|
||||
set_restore_operation(project, op)
|
||||
'''try:
|
||||
parse_file(project, inp, version)
|
||||
except:
|
||||
close_project(project)
|
||||
delete_project(project)
|
||||
return False'''
|
||||
|
||||
close_project(project)
|
||||
return True
|
||||
|
||||
|
||||
def import_inp(project: str, cs: ChangeSet) -> ChangeSet:
|
||||
if is_project_open(project):
|
||||
close_project(project)
|
||||
def import_inp(project: str, cs: ChangeSet, version: str = '3') -> bool:
|
||||
if version != '3' and version != '2':
|
||||
version = '2'
|
||||
|
||||
if have_project(project):
|
||||
delete_project(project)
|
||||
if 'inp' not in cs.operations[0]:
|
||||
return False
|
||||
|
||||
create_project(project)
|
||||
open_project(project)
|
||||
filename = f'inp/{project}_temp.inp'
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
|
||||
file = _parse_cs(cs)
|
||||
new_cs = _read_inp(file)
|
||||
_print_time(f'Start writing temp file "{filename}"...')
|
||||
with open(filename, 'w') as f:
|
||||
f.write(str(cs.operations[0]['inp']))
|
||||
_print_time(f'End writing temp file "{filename}"...')
|
||||
|
||||
success_cs = execute_batch_commands(project, new_cs)
|
||||
op = get_current_operation(project)
|
||||
set_restore_operation(project, op)
|
||||
result = read_inp(project, filename, version)
|
||||
|
||||
close_project(project)
|
||||
os.remove(filename)
|
||||
|
||||
# return ?
|
||||
return success_cs
|
||||
return result
|
||||
|
||||
163
api/inp_out.py
163
api/inp_out.py
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
from .project import *
|
||||
from .database import ChangeSet
|
||||
from .sections import section_name
|
||||
from .sections import *
|
||||
from .s1_title import inp_out_title
|
||||
from .s2_junctions import inp_out_junction
|
||||
from .s3_reservoirs import inp_out_reservoir
|
||||
@@ -12,8 +12,8 @@ from .s7_valves import inp_out_valve
|
||||
from .s8_tags import inp_out_tag
|
||||
from .s9_demands import inp_out_demand
|
||||
from .s10_status import inp_out_status
|
||||
from .s11_patterns import inp_out_pattern
|
||||
from .s12_curves import inp_out_curve
|
||||
from .s11_patterns import inp_out_pattern, inp_out_pattern_v3
|
||||
from .s12_curves import inp_out_curve, inp_out_curve_v3
|
||||
from .s13_controls import inp_out_control
|
||||
from .s14_rules import inp_out_rule
|
||||
from .s15_energy import inp_out_energy
|
||||
@@ -25,6 +25,7 @@ from .s20_mixing import inp_out_mixing
|
||||
from .s21_times import inp_out_time
|
||||
from .s22_report import inp_out_report
|
||||
from .s23_options import inp_out_option
|
||||
from .s23_options_v3 import inp_out_option_v3
|
||||
from .s24_coordinates import inp_out_coord
|
||||
from .s25_vertices import inp_out_vertex
|
||||
from .s26_labels import inp_out_label
|
||||
@@ -32,7 +33,10 @@ from .s27_backdrop import inp_out_backdrop
|
||||
#from .s28_end import *
|
||||
|
||||
|
||||
def dump_inp(project: str, inp: str):
|
||||
def dump_inp(project: str, inp: str, version: str = '3'):
|
||||
if version != '3' and version != '2':
|
||||
version = '2'
|
||||
|
||||
if not have_project(project):
|
||||
return
|
||||
|
||||
@@ -48,93 +52,102 @@ def dump_inp(project: str, inp: str):
|
||||
file = open(path, mode='w')
|
||||
|
||||
for name in section_name:
|
||||
if name == 'TITLE':
|
||||
if name == TITLE:
|
||||
file.write(f'[{name}]\n')
|
||||
else:
|
||||
file.write(f'\n[{name}]\n')
|
||||
|
||||
if name == 'TITLE':
|
||||
if name == TITLE:
|
||||
file.write('\n'.join(inp_out_title(project)))
|
||||
|
||||
elif name == 'JUNCTIONS': # + coords
|
||||
elif name == JUNCTIONS: # + coords
|
||||
file.write('\n'.join(inp_out_junction(project)))
|
||||
|
||||
elif name == 'RESERVOIRS': # + coords
|
||||
elif name == RESERVOIRS: # + coords
|
||||
file.write('\n'.join(inp_out_reservoir(project)))
|
||||
|
||||
elif name == 'TANKS': # + coords
|
||||
elif name == TANKS: # + coords
|
||||
file.write('\n'.join(inp_out_tank(project)))
|
||||
|
||||
elif name == 'PIPES':
|
||||
elif name == PIPES:
|
||||
file.write('\n'.join(inp_out_pipe(project)))
|
||||
|
||||
elif name == 'PUMPS':
|
||||
elif name == PUMPS:
|
||||
file.write('\n'.join(inp_out_pump(project)))
|
||||
|
||||
elif name == 'VALVES':
|
||||
elif name == VALVES:
|
||||
file.write('\n'.join(inp_out_valve(project)))
|
||||
|
||||
elif name == 'TAGS':
|
||||
elif name == TAGS:
|
||||
file.write('\n'.join(inp_out_tag(project)))
|
||||
|
||||
elif name == 'DEMANDS':
|
||||
elif name == DEMANDS:
|
||||
file.write('\n'.join(inp_out_demand(project)))
|
||||
|
||||
elif name == 'STATUS':
|
||||
elif name == STATUS:
|
||||
file.write('\n'.join(inp_out_status(project)))
|
||||
|
||||
elif name == 'PATTERNS':
|
||||
file.write('\n'.join(inp_out_pattern(project)))
|
||||
elif name == PATTERNS:
|
||||
if version == '3':
|
||||
file.write('\n'.join(inp_out_pattern_v3(project)))
|
||||
else:
|
||||
file.write('\n'.join(inp_out_pattern(project)))
|
||||
|
||||
elif name == 'CURVES':
|
||||
file.write('\n'.join(inp_out_curve(project)))
|
||||
elif name == CURVES:
|
||||
if version == '3':
|
||||
file.write('\n'.join(inp_out_curve_v3(project)))
|
||||
else:
|
||||
file.write('\n'.join(inp_out_curve(project)))
|
||||
|
||||
elif name == 'CONTROLS':
|
||||
elif name == CONTROLS:
|
||||
file.write('\n'.join(inp_out_control(project)))
|
||||
|
||||
elif name == 'RULES':
|
||||
elif name == RULES:
|
||||
file.write('\n'.join(inp_out_rule(project)))
|
||||
|
||||
elif name == 'ENERGY':
|
||||
elif name == ENERGY:
|
||||
file.write('\n'.join(inp_out_energy(project)))
|
||||
|
||||
elif name == 'EMITTERS':
|
||||
elif name == EMITTERS:
|
||||
file.write('\n'.join(inp_out_emitter(project)))
|
||||
|
||||
elif name == 'QUALITY':
|
||||
elif name == QUALITY:
|
||||
file.write('\n'.join(inp_out_quality(project)))
|
||||
|
||||
elif name == 'SOURCES':
|
||||
elif name == SOURCES:
|
||||
file.write('\n'.join(inp_out_source(project)))
|
||||
|
||||
elif name == 'REACTIONS':
|
||||
elif name == REACTIONS:
|
||||
file.write('\n'.join(inp_out_reaction(project)))
|
||||
|
||||
elif name == 'MIXING':
|
||||
elif name == MIXING:
|
||||
file.write('\n'.join(inp_out_mixing(project)))
|
||||
|
||||
elif name == 'TIMES':
|
||||
elif name == TIMES:
|
||||
file.write('\n'.join(inp_out_time(project)))
|
||||
|
||||
elif name == 'REPORT':
|
||||
elif name == REPORT:
|
||||
file.write('\n'.join(inp_out_report(project)))
|
||||
|
||||
elif name == 'OPTIONS':
|
||||
file.write('\n'.join(inp_out_option(project)))
|
||||
elif name == OPTIONS:
|
||||
if version == '3':
|
||||
file.write('\n'.join(inp_out_option_v3(project)))
|
||||
else:
|
||||
file.write('\n'.join(inp_out_option(project)))
|
||||
|
||||
elif name == 'COORDINATES':
|
||||
elif name == COORDINATES:
|
||||
file.write('\n'.join(inp_out_coord(project)))
|
||||
|
||||
elif name == 'VERTICES':
|
||||
elif name == VERTICES:
|
||||
file.write('\n'.join(inp_out_vertex(project)))
|
||||
|
||||
elif name == 'LABELS':
|
||||
elif name == LABELS:
|
||||
file.write('\n'.join(inp_out_label(project)))
|
||||
|
||||
elif name == 'BACKDROP':
|
||||
elif name == BACKDROP:
|
||||
file.write('\n'.join(inp_out_backdrop(project)))
|
||||
|
||||
elif name == 'END':
|
||||
elif name == END:
|
||||
pass # :)
|
||||
|
||||
file.write('\n')
|
||||
@@ -144,7 +157,10 @@ def dump_inp(project: str, inp: str):
|
||||
close_project(project)
|
||||
|
||||
|
||||
def export_inp(project: str) -> ChangeSet:
|
||||
def export_inp(project: str, version: str = '3') -> ChangeSet:
|
||||
if version != '3' and version != '2':
|
||||
version = '2'
|
||||
|
||||
if not have_project(project):
|
||||
return ChangeSet()
|
||||
|
||||
@@ -156,93 +172,102 @@ def export_inp(project: str) -> ChangeSet:
|
||||
inp = ''
|
||||
|
||||
for name in section_name:
|
||||
if name == 'TITLE':
|
||||
if name == TITLE:
|
||||
inp += f'[{name}]\n'
|
||||
else:
|
||||
inp += f'\n[{name}]\n'
|
||||
|
||||
if name == 'TITLE':
|
||||
if name == TITLE:
|
||||
inp += '\n'.join(inp_out_title(project))
|
||||
|
||||
elif name == 'JUNCTIONS': # + coords
|
||||
elif name == JUNCTIONS: # + coords
|
||||
inp += '\n'.join(inp_out_junction(project))
|
||||
|
||||
elif name == 'RESERVOIRS': # + coords
|
||||
elif name == RESERVOIRS: # + coords
|
||||
inp += '\n'.join(inp_out_reservoir(project))
|
||||
|
||||
elif name == 'TANKS': # + coords
|
||||
elif name == TANKS: # + coords
|
||||
inp += '\n'.join(inp_out_tank(project))
|
||||
|
||||
elif name == 'PIPES':
|
||||
elif name == PIPES:
|
||||
inp += '\n'.join(inp_out_pipe(project))
|
||||
|
||||
elif name == 'PUMPS':
|
||||
elif name == PUMPS:
|
||||
inp += '\n'.join(inp_out_pump(project))
|
||||
|
||||
elif name == 'VALVES':
|
||||
elif name == VALVES:
|
||||
inp += '\n'.join(inp_out_valve(project))
|
||||
|
||||
elif name == 'TAGS':
|
||||
elif name == TAGS:
|
||||
inp += '\n'.join(inp_out_tag(project))
|
||||
|
||||
elif name == 'DEMANDS':
|
||||
elif name == DEMANDS:
|
||||
inp += '\n'.join(inp_out_demand(project))
|
||||
|
||||
elif name == 'STATUS':
|
||||
elif name == STATUS:
|
||||
inp += '\n'.join(inp_out_status(project))
|
||||
|
||||
elif name == 'PATTERNS':
|
||||
inp += '\n'.join(inp_out_pattern(project))
|
||||
elif name == PATTERNS:
|
||||
if version == '3':
|
||||
inp += '\n'.join(inp_out_pattern_v3(project))
|
||||
else:
|
||||
inp += '\n'.join(inp_out_pattern(project))
|
||||
|
||||
elif name == 'CURVES':
|
||||
inp += '\n'.join(inp_out_curve(project))
|
||||
elif name == CURVES:
|
||||
if version == '3':
|
||||
inp += '\n'.join(inp_out_curve_v3(project))
|
||||
else:
|
||||
inp += '\n'.join(inp_out_curve(project))
|
||||
|
||||
elif name == 'CONTROLS':
|
||||
elif name == CONTROLS:
|
||||
inp += '\n'.join(inp_out_control(project))
|
||||
|
||||
elif name == 'RULES':
|
||||
elif name == RULES:
|
||||
inp += '\n'.join(inp_out_rule(project))
|
||||
|
||||
elif name == 'ENERGY':
|
||||
elif name == ENERGY:
|
||||
inp += '\n'.join(inp_out_energy(project))
|
||||
|
||||
elif name == 'EMITTERS':
|
||||
elif name == EMITTERS:
|
||||
inp += '\n'.join(inp_out_emitter(project))
|
||||
|
||||
elif name == 'QUALITY':
|
||||
elif name == QUALITY:
|
||||
inp += '\n'.join(inp_out_quality(project))
|
||||
|
||||
elif name == 'SOURCES':
|
||||
elif name == SOURCES:
|
||||
inp += '\n'.join(inp_out_source(project))
|
||||
|
||||
elif name == 'REACTIONS':
|
||||
elif name == REACTIONS:
|
||||
inp += '\n'.join(inp_out_reaction(project))
|
||||
|
||||
elif name == 'MIXING':
|
||||
elif name == MIXING:
|
||||
inp += '\n'.join(inp_out_mixing(project))
|
||||
|
||||
elif name == 'TIMES':
|
||||
elif name == TIMES:
|
||||
inp += '\n'.join(inp_out_time(project))
|
||||
|
||||
elif name == 'REPORT':
|
||||
elif name == REPORT:
|
||||
inp += '\n'.join(inp_out_report(project))
|
||||
|
||||
elif name == 'OPTIONS':
|
||||
inp += '\n'.join(inp_out_option(project))
|
||||
elif name == OPTIONS:
|
||||
if version == '3':
|
||||
inp += '\n'.join(inp_out_option_v3(project))
|
||||
else:
|
||||
inp += '\n'.join(inp_out_option(project))
|
||||
|
||||
elif name == 'COORDINATES':
|
||||
elif name == COORDINATES:
|
||||
inp += '\n'.join(inp_out_coord(project))
|
||||
|
||||
elif name == 'VERTICES':
|
||||
elif name == VERTICES:
|
||||
inp += '\n'.join(inp_out_vertex(project))
|
||||
|
||||
elif name == 'LABELS':
|
||||
elif name == LABELS:
|
||||
inp += '\n'.join(inp_out_label(project))
|
||||
|
||||
elif name == 'BACKDROP':
|
||||
elif name == BACKDROP:
|
||||
inp += '\n'.join(inp_out_backdrop(project))
|
||||
|
||||
elif name == 'END':
|
||||
elif name == END:
|
||||
pass # :)
|
||||
|
||||
inp += '\n'
|
||||
|
||||
@@ -72,45 +72,21 @@ def set_status(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA2][EPA3][IN][OUT]
|
||||
# link value
|
||||
#--------------------------------------------------------------
|
||||
class InpStatus:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.link = str(tokens[0])
|
||||
self.value = tokens[1].upper()
|
||||
self.is_status = True
|
||||
if self.value == LINK_STATUS_OPEN or self.value == LINK_STATUS_CLOSED or self.value == LINK_STATUS_ACTIVE:
|
||||
self.status = str(self.value)
|
||||
else:
|
||||
self.setting = float(self.value)
|
||||
self.is_status = False
|
||||
|
||||
|
||||
def inp_in_status(section: list[str]) -> ChangeSet:
|
||||
objs: dict[str, list[InpStatus]] = {}
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpStatus(s)
|
||||
if obj.link not in objs:
|
||||
objs[obj.link] = []
|
||||
objs[obj.link].append(obj)
|
||||
def inp_in_status(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
cs = ChangeSet()
|
||||
for link, values in objs.items():
|
||||
obj_cs : dict[str, Any] = g_update_prefix | {'type': 'status', 'link' : link, 'status': None, 'setting': None}
|
||||
for obj in values:
|
||||
if obj.is_status:
|
||||
obj_cs['status'] = obj.status
|
||||
else:
|
||||
obj_cs['setting'] = obj.setting
|
||||
cs.append(obj_cs)
|
||||
return cs
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
link = str(tokens[0])
|
||||
value = tokens[1].upper()
|
||||
if value == LINK_STATUS_OPEN or value == LINK_STATUS_CLOSED or value == LINK_STATUS_ACTIVE:
|
||||
return f"insert into status (link, status, setting) values ('{link}', '{value}', null);"
|
||||
else:
|
||||
return f"insert into status (link, status, setting) values ('{link}', null, {float(value)});"
|
||||
|
||||
|
||||
def inp_out_status(name: str) -> list[str]:
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
from .database import *
|
||||
|
||||
PATTERN_V3_TYPE_FIXED = 'FIXED'
|
||||
PATTERN_V3_TYPE_VARIABLE = 'VARIABLE'
|
||||
|
||||
pattern_v3_types = [PATTERN_V3_TYPE_FIXED, PATTERN_V3_TYPE_VARIABLE]
|
||||
|
||||
def get_pattern_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
@@ -98,32 +102,25 @@ def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# ;desc
|
||||
# id mult1 mult2 .....
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_pattern(section: list[str]) -> ChangeSet:
|
||||
descs = {}
|
||||
patterns: dict[str, list[float]] = {}
|
||||
#--------------------------------------------------------------
|
||||
# [EPA3][IN][OUT]
|
||||
# id FIXED (interval)
|
||||
# id factor1 factor2 ...
|
||||
# id VARIABLE
|
||||
# id time1 factor1 time2 factor2 ...
|
||||
#--------------------------------------------------------------
|
||||
|
||||
count = len(section)
|
||||
for i in range(0, count):
|
||||
if section[i].startswith(';'):
|
||||
# this is description
|
||||
next = i + 1
|
||||
if next < count and section[next].startswith(';') == False:
|
||||
next_tokens = section[next].split()
|
||||
descs[next_tokens[0]] = section[i].removeprefix(';')
|
||||
continue
|
||||
|
||||
tokens = section[i].split()
|
||||
if tokens[0] not in patterns:
|
||||
patterns[tokens[0]] = []
|
||||
def inp_in_pattern(line: str, fixed: bool = True) -> str:
|
||||
tokens = line.split()
|
||||
sql = ''
|
||||
if fixed:
|
||||
for token in tokens[1:]:
|
||||
patterns[tokens[0]].append(float(token))
|
||||
|
||||
cs = ChangeSet()
|
||||
for id, factors in patterns.items():
|
||||
cs.append(g_add_prefix | {'type': 'pattern', 'id' : id, 'factors' : factors})
|
||||
|
||||
#print(descs)
|
||||
return cs
|
||||
sql += f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});"
|
||||
else:
|
||||
for token in tokens[1::2]:
|
||||
sql += f"insert into patterns (id, factor) values ('{tokens[0]}', {float(token)});"
|
||||
return sql
|
||||
|
||||
|
||||
def inp_out_pattern(name: str) -> list[str]:
|
||||
@@ -136,49 +133,6 @@ def inp_out_pattern(name: str) -> list[str]:
|
||||
return lines
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# [EPA3][IN][OUT]
|
||||
# id FIXED (interval)
|
||||
# id factor1 factor2 ...
|
||||
# id VARIABLE
|
||||
# id time1 factor1 time2 factor2 ...
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_pattern_v3(section: list[str]) -> ChangeSet:
|
||||
patterns: dict[str, list[float]] = {}
|
||||
|
||||
variable_patterns: list[str] = []
|
||||
|
||||
count = len(section)
|
||||
for i in range(0, count):
|
||||
if section[i].startswith(';'):
|
||||
continue
|
||||
|
||||
tokens = section[i].split()
|
||||
|
||||
# for EPA3, ignore time of variable pattern...
|
||||
if tokens[1] == 'VARIABLE':
|
||||
variable_patterns.append(tokens[0])
|
||||
continue
|
||||
elif tokens[1] == 'FIXED':
|
||||
continue
|
||||
|
||||
if tokens[0] not in patterns:
|
||||
patterns[tokens[0]] = []
|
||||
if tokens[0] not in variable_patterns:
|
||||
for token in tokens[1:]:
|
||||
patterns[tokens[0]].append(float(token))
|
||||
else:
|
||||
for token in tokens[1::2]:
|
||||
patterns[tokens[0]].append(float(token))
|
||||
|
||||
cs = ChangeSet()
|
||||
for id, factors in patterns.items():
|
||||
cs.append(g_add_prefix | {'type': 'pattern', 'id' : id, 'factors' : factors})
|
||||
|
||||
#print(descs)
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_pattern_v3(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from patterns order by _order")
|
||||
|
||||
@@ -5,6 +5,8 @@ CURVE_TYPE_EFFICIENCY = 'EFFICIENCY'
|
||||
CURVE_TYPE_VOLUME = 'VOLUME'
|
||||
CURVE_TYPE_HEADLOSS = 'HEADLOSS'
|
||||
|
||||
curve_types = [CURVE_TYPE_PUMP, CURVE_TYPE_EFFICIENCY, CURVE_TYPE_VOLUME, CURVE_TYPE_HEADLOSS]
|
||||
|
||||
def get_curve_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'c_type' : {'type': 'str' , 'optional': False , 'readonly': False},
|
||||
@@ -126,37 +128,16 @@ def delete_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# ;type: desc
|
||||
# id x y
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_curve(section: list[str]) -> ChangeSet:
|
||||
types = {}
|
||||
descs = {}
|
||||
curves: dict[str, list[dict[str, float]]] = {}
|
||||
#--------------------------------------------------------------
|
||||
# [EPA3][IN][OUT]
|
||||
# id type
|
||||
# id x y
|
||||
#--------------------------------------------------------------
|
||||
|
||||
count = len(section)
|
||||
for i in range(0, count):
|
||||
if section[i].startswith(';'):
|
||||
# ;type: desc
|
||||
type_plus_desc = section[i].removeprefix(';')
|
||||
type_plus_desc_tokens = type_plus_desc.split(':')
|
||||
next = i + 1
|
||||
if next < count and section[next].startswith(';') == False:
|
||||
next_tokens = section[next].split()
|
||||
types[next_tokens[0]] = type_plus_desc_tokens[0].strip().upper()
|
||||
if len(type_plus_desc_tokens) > 1:
|
||||
descs[next_tokens[0]] = type_plus_desc_tokens[1].strip()
|
||||
continue
|
||||
|
||||
tokens = section[i].split()
|
||||
if tokens[0] not in curves:
|
||||
curves[tokens[0]] = []
|
||||
curves[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])})
|
||||
|
||||
cs = ChangeSet()
|
||||
for id, coords in curves.items():
|
||||
c_type = types[id] if id in types else CURVE_TYPE_PUMP
|
||||
cs.append(g_add_prefix | {'type': 'curve', 'id' : id, 'c_type': c_type, 'coords' : coords})
|
||||
|
||||
#print(descs)
|
||||
return cs
|
||||
def inp_in_curve(line: str) -> str:
|
||||
tokens = line.split()
|
||||
return f"insert into curves (id, x, y) values ('{tokens[0]}', {float(tokens[1])}, {float(tokens[2])});"
|
||||
|
||||
|
||||
def inp_out_curve(name: str) -> list[str]:
|
||||
@@ -175,40 +156,6 @@ def inp_out_curve(name: str) -> list[str]:
|
||||
return lines
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
# [EPA3][IN][OUT]
|
||||
# id type
|
||||
# id x y
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_curve_v3(section: list[str]) -> ChangeSet:
|
||||
types = {}
|
||||
curves: dict[str, list[dict[str, float]]] = {}
|
||||
|
||||
count = len(section)
|
||||
for i in range(0, count):
|
||||
if section[i].startswith(';'):
|
||||
continue
|
||||
|
||||
tokens = section[i].split()
|
||||
|
||||
# for EPA3
|
||||
if tokens[1] == 'PUMP' or tokens[1] == 'EFFICIENCY' or tokens[1] == 'VOLUME' or tokens[1] == 'HEADLOSS':
|
||||
types[tokens[0]] = tokens[1]
|
||||
continue
|
||||
|
||||
if tokens[0] not in curves:
|
||||
curves[tokens[0]] = []
|
||||
curves[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])})
|
||||
|
||||
cs = ChangeSet()
|
||||
for id, coords in curves.items():
|
||||
c_type = types[id] if id in types else CURVE_TYPE_PUMP
|
||||
cs.append(g_add_prefix | {'type': 'curve', 'id' : id, 'c_type': c_type, 'coords' : coords})
|
||||
|
||||
#print(descs)
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_curve_v3(name: str) -> list[str]:
|
||||
lines = []
|
||||
types = read_all(name, f"select * from _curve")
|
||||
|
||||
@@ -42,10 +42,10 @@ def set_control(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# (0) (1) (2) (3) (4) (5) (6) (7)
|
||||
# todo...
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_control(section: list[str]) -> ChangeSet:
|
||||
if len(section) > 0:
|
||||
return ChangeSet(g_update_prefix | {'type': 'control', 'controls' : section})
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
def inp_in_control(line: str) -> str:
|
||||
return f"insert into controls (line) values ('{line}');"
|
||||
|
||||
|
||||
def inp_out_control(name: str) -> list[str]:
|
||||
|
||||
@@ -38,10 +38,10 @@ def set_rule(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA2][EPA3]
|
||||
# TODO...
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_rule(section: list[str]) -> ChangeSet:
|
||||
if len(section) > 0:
|
||||
return ChangeSet(g_update_prefix | {'type': 'rule', 'rules' : section})
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
def inp_in_rule(line: str) -> str:
|
||||
return f"insert into rules (line) values ('{line}');"
|
||||
|
||||
|
||||
def inp_out_rule(name: str) -> list[str]:
|
||||
|
||||
@@ -137,36 +137,37 @@ def set_pump_energy(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# PUMP id {PRICE/PATTERN/EFFIC} value
|
||||
# DEMAND CHARGE value
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_energy(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
for s in section:
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
|
||||
tokens = s.strip().split()
|
||||
|
||||
if tokens[0].upper() == 'PUMP':
|
||||
pump = tokens[1]
|
||||
key = tokens[2].lower()
|
||||
value = tokens[3]
|
||||
if key == 'price':
|
||||
value = float(value)
|
||||
cs.append(g_update_prefix | { 'type' : 'pump_energy', 'pump' : pump, key: value })
|
||||
def inp_in_energy(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
if tokens[0].upper() == 'PUMP':
|
||||
pump = tokens[1]
|
||||
key = tokens[2].lower()
|
||||
value = tokens[3]
|
||||
if key == 'price':
|
||||
value = float(value)
|
||||
else:
|
||||
line = s.upper().strip()
|
||||
for key in get_energy_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
value = f"'{value}'"
|
||||
if key == 'efficiency':
|
||||
key = 'effic'
|
||||
|
||||
# exception here
|
||||
if line.startswith('GLOBAL EFFICIENCY'):
|
||||
value = line.removeprefix('GLOBAL EFFICIENCY').strip()
|
||||
|
||||
cs.append(g_update_prefix | { 'type' : 'energy', key : value })
|
||||
return f"insert into energy_pump_{key} (pump, {key}) values ('{pump}', {value});"
|
||||
|
||||
return cs
|
||||
else:
|
||||
line = line.upper().strip()
|
||||
for key in get_energy_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
|
||||
# exception here
|
||||
if line.startswith('GLOBAL EFFICIENCY'):
|
||||
value = line.removeprefix('GLOBAL EFFICIENCY').strip()
|
||||
|
||||
return f"update energy set value = '{value}' where key = '{key}';"
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def inp_out_energy(name: str) -> list[str]:
|
||||
|
||||
@@ -66,27 +66,19 @@ def set_emitter(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA3][IN][OUT]
|
||||
# node Ke (exponent pattern)
|
||||
#--------------------------------------------------------------
|
||||
class InpEmitter:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.junction = str(tokens[0])
|
||||
self.coefficient = float(tokens[1])
|
||||
|
||||
|
||||
def inp_in_emitter(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpEmitter(s)
|
||||
cs.append(g_update_prefix | {'type': 'emitter', 'junction': obj.junction, 'coefficient': obj.coefficient})
|
||||
return cs
|
||||
def inp_in_emitter(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
junction = str(tokens[0])
|
||||
coefficient = float(tokens[1])
|
||||
|
||||
return f"insert into emitters (junction, coefficient) values ('{junction}', {coefficient});"
|
||||
|
||||
|
||||
def inp_out_emitter(name: str) -> list[str]:
|
||||
|
||||
@@ -63,27 +63,19 @@ def set_quality(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA2][EPA3][IN][OUT]
|
||||
# node initqual
|
||||
#--------------------------------------------------------------
|
||||
class InpQuality:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.node = str(tokens[0])
|
||||
self.quality = float(tokens[1])
|
||||
|
||||
|
||||
def inp_in_quality(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpQuality(s)
|
||||
cs.append(g_update_prefix | {'type': 'quality', 'node': obj.node, 'quality': obj.quality})
|
||||
return cs
|
||||
def inp_in_quality(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
node = str(tokens[0])
|
||||
quality = float(tokens[1])
|
||||
|
||||
return f"insert into quality (node, quality) values ('{node}', {quality});"
|
||||
|
||||
|
||||
def inp_out_quality(name: str) -> list[str]:
|
||||
|
||||
@@ -106,29 +106,23 @@ def delete_source(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA2][EPA3][IN][OUT]
|
||||
# node sourcetype quality (pattern)
|
||||
#--------------------------------------------------------------
|
||||
class InpSource:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.node = str(tokens[0])
|
||||
self.s_type = str(tokens[1].upper())
|
||||
self.strength = float(tokens[2])
|
||||
self.pattern = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
|
||||
|
||||
def inp_in_source(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpSource(s)
|
||||
cs.append(g_add_prefix | {'type': 'source', 'node': obj.node, 's_type': obj.s_type, 'strength': obj.strength, 'pattern': obj.pattern})
|
||||
return cs
|
||||
def inp_in_source(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
node = str(tokens[0])
|
||||
s_type = str(tokens[1].upper())
|
||||
strength = float(tokens[2])
|
||||
pattern = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
|
||||
return f"insert into sources (node, type, strength, pattern) values ('{node}', '{s_type}', {strength}, {pattern});"
|
||||
|
||||
|
||||
|
||||
def inp_out_source(name: str) -> list[str]:
|
||||
|
||||
@@ -192,34 +192,30 @@ def set_tank_reaction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# LIMITING POTENTIAL value
|
||||
# ROUGHNESS CORRELATION value
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_reaction(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
for s in section:
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
|
||||
tokens = s.strip().split()
|
||||
token0 = tokens[0].upper()
|
||||
if token0 == 'BULK' or token0 == 'WALL':
|
||||
pipe = tokens[1]
|
||||
key = token0.lower()
|
||||
value = tokens[2]
|
||||
cs.append(g_update_prefix | { 'type' : 'pipe_reaction', 'pipe' : pipe, key: value })
|
||||
def inp_in_reaction(line: str) -> str:
|
||||
tokens = line.split()
|
||||
token0 = tokens[0].upper()
|
||||
if token0 == 'BULK' or token0 == 'WALL':
|
||||
pipe = tokens[1]
|
||||
key = token0.lower()
|
||||
value = tokens[2]
|
||||
return f"insert into reactions_pipe_{key} (pipe, value) values ('{pipe}', {value});"
|
||||
|
||||
elif token0 == 'TANK':
|
||||
tank = tokens[1]
|
||||
value = tokens[2]
|
||||
cs.append(g_update_prefix | { 'type' : 'tank_reaction', 'tank' : tank, 'value': value })
|
||||
elif token0 == 'TANK':
|
||||
tank = tokens[1]
|
||||
value = tokens[2]
|
||||
return f"insert into reactions_tank (tank, value) values ('{tank}', {value});"
|
||||
|
||||
else:
|
||||
line = s.upper().strip()
|
||||
for key in get_reaction_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
cs.append(g_update_prefix | { 'type' : 'reaction', key : value })
|
||||
else:
|
||||
line = line.upper().strip()
|
||||
for key in get_reaction_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
return f"update reactions set value = '{value}' where key = '{key}';"
|
||||
|
||||
return cs
|
||||
return ''
|
||||
|
||||
|
||||
def inp_out_reaction(name: str) -> list[str]:
|
||||
|
||||
@@ -27,17 +27,12 @@ def set_title(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_title_cmd(name ,cs))
|
||||
|
||||
|
||||
class InpTitle:
|
||||
def __init__(self, section) -> None:
|
||||
self.value = '\n'.join(section)
|
||||
|
||||
|
||||
def inp_in_title(section: list[str]) -> ChangeSet:
|
||||
def inp_in_title(section: list[str]) -> str:
|
||||
if section == []:
|
||||
return ChangeSet()
|
||||
return ''
|
||||
|
||||
obj = InpTitle(section)
|
||||
return ChangeSet(g_update_prefix | {'type': 'title', 'value' : obj.value})
|
||||
title = '\n'.join(section)
|
||||
return f"update title set value = '{title}';"
|
||||
|
||||
|
||||
def inp_out_title(name: str) -> list[str]:
|
||||
|
||||
@@ -101,28 +101,21 @@ def delete_mixing(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# TankID MixModel FractVolume
|
||||
# FractVolume if type == MIX2
|
||||
#--------------------------------------------------------------
|
||||
class InpMixing:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.tank = str(tokens[0])
|
||||
self.model = str(tokens[1].upper())
|
||||
self.value = float(tokens[3]) if num_without_desc >= 4 else None
|
||||
|
||||
|
||||
def inp_in_mixing(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpMixing(s)
|
||||
cs.append(g_add_prefix | {'type': 'mixing', 'tank': obj.tank, 'model': obj.model, 'value': obj.value})
|
||||
return cs
|
||||
def inp_in_mixing(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
tank = str(tokens[0])
|
||||
model = str(tokens[1].upper())
|
||||
value = float(tokens[3]) if num_without_desc >= 4 else None
|
||||
value = value if value != None else 'null'
|
||||
|
||||
return f"insert into mixing (tank, model, value) values ('{tank}', '{model}', {value});"
|
||||
|
||||
|
||||
def inp_out_mixing(name: str) -> list[str]:
|
||||
|
||||
@@ -81,20 +81,20 @@ def set_time(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# START CLOCKTIME value (AM PM)
|
||||
# [EPA3] supports [EPA2] keyword
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_time(section: list[str]) -> ChangeSet:
|
||||
if len(section) > 0:
|
||||
cs = g_update_prefix | { 'type' : 'time' }
|
||||
for s in section:
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
|
||||
line = s.upper().strip()
|
||||
for key in get_time_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
cs |= { key : value }
|
||||
return ChangeSet(cs)
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
def inp_in_time(section: list[str]) -> str:
|
||||
sql = ''
|
||||
for s in section:
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
|
||||
line = s.upper().strip()
|
||||
for key in get_time_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
sql += f"update times set value = '{value}' where key = '{key}';"
|
||||
return sql
|
||||
|
||||
|
||||
def inp_out_time(name: str) -> list[str]:
|
||||
|
||||
@@ -18,8 +18,10 @@ from .database import *
|
||||
# [EPA3][NOT SUPPORT]
|
||||
# TRIALS {YES/NO}
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_report(section: list[str]) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
def inp_in_report(section: list[str]) -> str:
|
||||
return ''
|
||||
|
||||
|
||||
def inp_out_report(name: str) -> list[str]:
|
||||
|
||||
@@ -11,7 +11,7 @@ def set_option(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_batch_command(name, new_cs)
|
||||
|
||||
|
||||
def inp_in_option(section: list[str]) -> ChangeSet:
|
||||
def _inp_in_option(section: list[str]) -> ChangeSet:
|
||||
if len(section) <= 0:
|
||||
return ChangeSet()
|
||||
|
||||
@@ -22,9 +22,10 @@ def inp_in_option(section: list[str]) -> ChangeSet:
|
||||
|
||||
tokens = s.strip().split()
|
||||
if tokens[0].upper() == 'PATTERN': # can not upper id
|
||||
cs |= { 'PATTERN' : tokens[1] }
|
||||
value = tokens[1] if len(tokens) > 1 else ''
|
||||
cs |= { 'PATTERN' : value }
|
||||
elif tokens[0].upper() == 'QUALITY': # can not upper trace node
|
||||
value = tokens[1]
|
||||
value = tokens[1] if len(tokens) > 1 else ''
|
||||
if len(tokens) > 2:
|
||||
value += f' {tokens[2]}'
|
||||
cs |= { 'QUALITY' : value }
|
||||
@@ -40,6 +41,20 @@ def inp_in_option(section: list[str]) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def inp_in_option(section: list[str]) -> str:
|
||||
sql = ''
|
||||
result = _inp_in_option(section)
|
||||
for op in result.operations:
|
||||
for key in op.keys():
|
||||
if key == 'operation' or key == 'type':
|
||||
continue
|
||||
if op['type'] == 'option':
|
||||
sql += f"update options set value = '{op[key]}' where key = '{key}';"
|
||||
else:
|
||||
sql += f"update options_v3 set value = '{op[key]}' where key = '{key}';"
|
||||
return sql
|
||||
|
||||
|
||||
def inp_out_option(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from options")
|
||||
|
||||
@@ -16,7 +16,8 @@ def _parse_v2(v2_lines: list[str]) -> dict[str, str]:
|
||||
for s in v2_lines:
|
||||
tokens = s.split()
|
||||
if tokens[0].upper() == 'PATTERN': # can not upper id
|
||||
cs_v2 |= { 'PATTERN' : tokens[1] }
|
||||
value = tokens[1] if len(tokens) > 1 else ''
|
||||
cs_v2 |= { 'PATTERN' : value }
|
||||
elif tokens[0].upper() == 'QUALITY': # can not upper trace node
|
||||
value = tokens[1]
|
||||
if len(tokens) > 2:
|
||||
@@ -31,7 +32,7 @@ def _parse_v2(v2_lines: list[str]) -> dict[str, str]:
|
||||
return cs_v2
|
||||
|
||||
|
||||
def inp_in_option_v3(section: list[str]) -> ChangeSet:
|
||||
def _inp_in_option_v3(section: list[str]) -> ChangeSet:
|
||||
if len(section) <= 0:
|
||||
return ChangeSet()
|
||||
|
||||
@@ -44,7 +45,11 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet:
|
||||
tokens = s.strip().split()
|
||||
key = tokens[0]
|
||||
if key in get_option_v3_schema('').keys():
|
||||
value = tokens[1] if len(tokens) >= 2 else ''
|
||||
value = ''
|
||||
if len(tokens) == 2:
|
||||
value = tokens[1]
|
||||
elif len(tokens) > 2:
|
||||
value = ' '.join(tokens[1:])
|
||||
cs_v3 |= { key : value }
|
||||
else:
|
||||
v2_lines.append(s.strip())
|
||||
@@ -58,6 +63,20 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def inp_in_option_v3(section: list[str]) -> str:
|
||||
sql = ''
|
||||
result = _inp_in_option_v3(section)
|
||||
for op in result.operations:
|
||||
for key in op.keys():
|
||||
if key == 'operation' or key == 'type':
|
||||
continue
|
||||
if op['type'] == 'option_v3':
|
||||
sql += f"update options_v3 set value = '{op[key]}' where key = '{key}';"
|
||||
else:
|
||||
sql += f"update options set value = '{op[key]}' where key = '{key}';"
|
||||
return sql
|
||||
|
||||
|
||||
def inp_out_option_v3(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from options_v3")
|
||||
|
||||
@@ -16,15 +16,13 @@ def get_node_coord(name: str, id: str) -> dict[str, float]:
|
||||
# id x y
|
||||
#--------------------------------------------------------------
|
||||
# exception ! need merge to node change set !
|
||||
def inp_in_coord(section: list[str]) -> dict[str, dict[str, float]]:
|
||||
coords = {}
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
tokens = s.split()
|
||||
coords[tokens[0]] = { 'x': tokens[1], 'y': tokens[2] }
|
||||
return coords
|
||||
|
||||
|
||||
def inp_in_coord(line: str) -> str:
|
||||
tokens = line.split()
|
||||
node = tokens[0]
|
||||
coord = f"'({tokens[1]}, {tokens[2]})'"
|
||||
return f"insert into coordinates (node, coord) values ('{node}', {coord});"
|
||||
|
||||
|
||||
def inp_out_coord(name: str) -> list[str]:
|
||||
|
||||
@@ -80,22 +80,14 @@ def delete_vertex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# id x y
|
||||
# [EPA3][NOT SUPPORT]
|
||||
#--------------------------------------------------------------
|
||||
def inp_in_vertex(section: list[str]) -> ChangeSet:
|
||||
vertices: dict[str, list[dict[str, float]]] = {}
|
||||
|
||||
for s in section:
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
|
||||
tokens = s.split()
|
||||
if tokens[0] not in vertices:
|
||||
vertices[tokens[0]] = []
|
||||
vertices[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])})
|
||||
|
||||
cs = ChangeSet()
|
||||
for link, coords in vertices.items():
|
||||
cs.append(g_add_prefix | {'type': 'vertex', 'link' : link, 'coords' : coords})
|
||||
return cs
|
||||
def inp_in_vertex(line: str) -> str:
|
||||
tokens = line.split()
|
||||
link = tokens[0]
|
||||
x = float(tokens[1])
|
||||
y = float(tokens[2])
|
||||
return f"insert into vertices (link, x, y) values ('{link}', {x}, {y});"
|
||||
|
||||
|
||||
def inp_out_vertex(name: str) -> list[str]:
|
||||
|
||||
@@ -99,29 +99,20 @@ def delete_label(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_label_cmd(name, cs))
|
||||
|
||||
|
||||
class InpLabel:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
def inp_in_label(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.x = float(tokens[0])
|
||||
self.y = float(tokens[1])
|
||||
self.label = str(tokens[2])
|
||||
self.node = str(tokens[3]) if num >= 4 else None
|
||||
x = float(tokens[0])
|
||||
y = float(tokens[1])
|
||||
label = str(tokens[2])
|
||||
node = str(tokens[3]) if num >= 4 else None
|
||||
node = f"'{node}'" if node != None else 'null'
|
||||
|
||||
|
||||
def inp_in_label(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpLabel(s)
|
||||
cs.append(g_add_prefix | {'type': 'label', 'x': obj.x, 'y': obj.y, 'label': obj.label, 'node': obj.node})
|
||||
return cs
|
||||
return f"insert into labels (x, y, label, node) values ({x}, {y}, '{label}', {node});"
|
||||
|
||||
|
||||
def inp_out_label(name: str) -> list[str]:
|
||||
|
||||
@@ -26,16 +26,12 @@ def set_backdrop(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_backdrop_cmd(name, cs))
|
||||
|
||||
|
||||
class InpBackdrop:
|
||||
def __init__(self, section) -> None:
|
||||
self.value = '\n'.join(section)
|
||||
def inp_in_backdrop(section: list[str]) -> str:
|
||||
if section == []:
|
||||
return ''
|
||||
|
||||
|
||||
def inp_in_backdrop(section: list[str]) -> ChangeSet:
|
||||
if len(section) > 0:
|
||||
obj = InpBackdrop(section)
|
||||
return ChangeSet(g_update_prefix | {'type': 'backdrop', 'content' : obj.value})
|
||||
return ChangeSet()
|
||||
content = '\n'.join(section)
|
||||
return f"update backdrop set content = '{content}';"
|
||||
|
||||
|
||||
def inp_out_backdrop(name: str) -> list[str]:
|
||||
|
||||
@@ -125,31 +125,27 @@ def delete_junction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [OUT]
|
||||
# id elev. * * minpressure fullpressure
|
||||
#--------------------------------------------------------------
|
||||
class InpJunction:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.elevation = float(tokens[1])
|
||||
self.demand = float(tokens[2]) if num_without_desc >= 3 else None
|
||||
self.pattern = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_junction(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpJunction(s)
|
||||
cs.append(g_add_prefix | {'type': 'junction', 'id': obj.id, 'elevation': obj.elevation, 'demand': obj.demand, 'pattern': obj.pattern})
|
||||
cs.append(g_update_prefix | { 'type': 'demand', 'junction': obj.id, 'demands': [{'demand': obj.demand, 'pattern': obj.pattern, 'category': None}] })
|
||||
return cs
|
||||
def inp_in_junction(line: str, demand_outside: bool) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
id = str(tokens[0])
|
||||
elevation = float(tokens[1])
|
||||
demand = float(tokens[2]) if num_without_desc >= 3 else None
|
||||
pattern = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
sql = f"insert into _node (id, type) values ('{id}', 'junction');insert into junctions (id, elevation) values ('{id}', {elevation});"
|
||||
if demand != None and demand_outside == False:
|
||||
sql += f"insert into demands (junction, demand, pattern) values ('{id}', {demand}, {pattern});"
|
||||
|
||||
return sql
|
||||
|
||||
|
||||
def inp_out_junction(name: str) -> list[str]:
|
||||
|
||||
@@ -120,29 +120,22 @@ def delete_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA2][EPA3][IN][OUT]
|
||||
# id elev (pattern) ;desc
|
||||
#--------------------------------------------------------------
|
||||
class InpReservoir:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.head = float(tokens[1])
|
||||
self.pattern = str(tokens[2]) if num_without_desc >= 3 else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_reservoir(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpReservoir(s)
|
||||
cs.append(g_add_prefix | {'type': 'reservoir', 'id': obj.id, 'head': obj.head, 'pattern': obj.pattern})
|
||||
return cs
|
||||
def inp_in_reservoir(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
id = str(tokens[0])
|
||||
head = float(tokens[1])
|
||||
pattern = str(tokens[2]) if num_without_desc >= 3 else None
|
||||
pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
return f"insert into _node (id, type) values ('{id}', 'reservoir');insert into reservoirs (id, head, pattern) values ('{id}', {head}, {pattern});"
|
||||
|
||||
|
||||
def inp_out_reservoir(name: str) -> list[str]:
|
||||
|
||||
@@ -156,35 +156,29 @@ def delete_tank(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA3]
|
||||
# id elev initlevel minlevel maxlevel diam minvol (vcurve)
|
||||
#--------------------------------------------------------------
|
||||
class InpTank:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.elevation = float(tokens[1])
|
||||
self.init_level = float(tokens[2])
|
||||
self.min_level = float(tokens[3])
|
||||
self.max_level = float(tokens[4])
|
||||
self.diameter = float(tokens[5])
|
||||
self.min_vol = float(tokens[6]) if num_without_desc >= 7 else 0.0
|
||||
self.vol_curve = str(tokens[7]) if num_without_desc >= 8 and tokens[7] != '*' else None
|
||||
self.overflow = str(tokens[8].upper()) if num_without_desc >= 9 else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_tank(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpTank(s)
|
||||
cs.append(g_add_prefix | {'type': 'tank', 'id': obj.id, 'elevation': obj.elevation, 'init_level': obj.init_level, 'min_level': obj.min_level, 'max_level': obj.max_level, 'diameter': obj.diameter, 'min_vol': obj.min_vol, 'vol_curve': obj.vol_curve, 'overflow': obj.overflow})
|
||||
return cs
|
||||
def inp_in_tank(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
id = str(tokens[0])
|
||||
elevation = float(tokens[1])
|
||||
init_level = float(tokens[2])
|
||||
min_level = float(tokens[3])
|
||||
max_level = float(tokens[4])
|
||||
diameter = float(tokens[5])
|
||||
min_vol = float(tokens[6]) if num_without_desc >= 7 else 0.0
|
||||
vol_curve = str(tokens[7]) if num_without_desc >= 8 and tokens[7] != '*' else None
|
||||
vol_curve = f"'{vol_curve}'" if vol_curve != None else 'null'
|
||||
overflow = str(tokens[8].upper()) if num_without_desc >= 9 else None
|
||||
overflow = f"'{overflow}'" if overflow != None else 'null'
|
||||
desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
return f"insert into _node (id, type) values ('{id}', 'tank');insert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ('{id}', {elevation}, {init_level}, {min_level}, {max_level}, {diameter}, {min_vol}, {vol_curve}, {overflow});"
|
||||
|
||||
|
||||
def inp_out_tank(name: str) -> list[str]:
|
||||
|
||||
@@ -130,35 +130,27 @@ def delete_pipe(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [OUT]
|
||||
# id node1 node2 length diam rcoeff lcoeff (status) ;desc
|
||||
#--------------------------------------------------------------
|
||||
class InpPipe:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.node1 = str(tokens[1])
|
||||
self.node2 = str(tokens[2])
|
||||
self.length = float(tokens[3])
|
||||
self.diameter = float(tokens[4])
|
||||
self.roughness = float(tokens[5])
|
||||
self.minor_loss = float(tokens[6])
|
||||
# status is must-have, here fix input
|
||||
self.status = str(tokens[7].upper()) if num_without_desc >= 8 else PIPE_STATUS_OPEN
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_pipe(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpPipe(s)
|
||||
cs.append(g_add_prefix | {'type': 'pipe', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'length': obj.length, 'diameter': obj.diameter, 'roughness': obj.roughness, 'minor_loss': obj.minor_loss, 'status': obj.status})
|
||||
return cs
|
||||
def inp_in_pipe(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
id = str(tokens[0])
|
||||
node1 = str(tokens[1])
|
||||
node2 = str(tokens[2])
|
||||
length = float(tokens[3])
|
||||
diameter = float(tokens[4])
|
||||
roughness = float(tokens[5])
|
||||
minor_loss = float(tokens[6])
|
||||
# status is must-have, here fix input
|
||||
status = str(tokens[7].upper()) if num_without_desc >= 8 else PIPE_STATUS_OPEN
|
||||
desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
return f"insert into _link (id, type) values ('{id}', 'pipe');insert into pipes (id, node1, node2, length, diameter, roughness, minor_loss, status) values ('{id}', '{node1}', '{node2}', {length}, {diameter}, {roughness}, {minor_loss}, '{status}');"
|
||||
|
||||
|
||||
def inp_out_pipe(name: str) -> list[str]:
|
||||
|
||||
@@ -119,36 +119,32 @@ def delete_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# id node1 node2 KEYWORD value {KEYWORD value ...} ;desc
|
||||
# where KEYWORD = [POWER,HEAD,PATTERN,SPEED]
|
||||
#--------------------------------------------------------------
|
||||
class InpPump:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.node1 = str(tokens[1])
|
||||
self.node2 = str(tokens[2])
|
||||
self.props = {}
|
||||
for i in range(3, num_without_desc, 2):
|
||||
self.props |= { tokens[i].lower(): tokens[i + 1] }
|
||||
self.power = float(self.props['power']) if 'power' in self.props else None
|
||||
self.head = str(self.props['head']) if 'head' in self.props else None
|
||||
self.speed = float(self.props['speed']) if 'speed' in self.props else None
|
||||
self.pattern = str(self.props['pattern']) if 'pattern' in self.props else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_pump(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpPump(s)
|
||||
cs.append(g_add_prefix | {'type': 'pump', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'power': obj.power, 'head': obj.head, 'speed': obj.speed, 'pattern': obj.pattern})
|
||||
return cs
|
||||
def inp_in_pump(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
id = str(tokens[0])
|
||||
node1 = str(tokens[1])
|
||||
node2 = str(tokens[2])
|
||||
props = {}
|
||||
for i in range(3, num_without_desc, 2):
|
||||
props |= { tokens[i].lower(): tokens[i + 1] }
|
||||
power = float(props['power']) if 'power' in props else None
|
||||
power = power if power != None else 'null'
|
||||
head = str(props['head']) if 'head' in props else None
|
||||
head = f"'{head}'" if head != None else 'null'
|
||||
speed = float(props['speed']) if 'speed' in props else None
|
||||
speed = speed if speed != None else 'null'
|
||||
pattern = str(props['pattern']) if 'pattern' in props else None
|
||||
pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
return f"insert into _link (id, type) values ('{id}', 'pump');insert into pumps (id, node1, node2, power, head, speed, pattern) values ('{id}', '{node1}', '{node2}', {power}, {head}, {speed}, {pattern});"
|
||||
|
||||
|
||||
def inp_out_pump(name: str) -> list[str]:
|
||||
|
||||
@@ -128,33 +128,25 @@ def delete_valve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# for GPV, setting is string = head curve id
|
||||
# [NOT SUPPORT] for PCV, add loss curve if present
|
||||
#--------------------------------------------------------------
|
||||
class InpValve:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.node1 = str(tokens[1])
|
||||
self.node2 = str(tokens[2])
|
||||
self.diameter = float(tokens[3])
|
||||
self.v_type = str(tokens[4].upper())
|
||||
self.setting = str(tokens[5])
|
||||
self.minor_loss = float(tokens[6])
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_valve(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpValve(s)
|
||||
cs.append(g_add_prefix | {'type': 'valve', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'diameter': obj.diameter, 'v_type': obj.v_type, 'setting': obj.setting, 'minor_loss': obj.minor_loss})
|
||||
return cs
|
||||
def inp_in_valve(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
id = str(tokens[0])
|
||||
node1 = str(tokens[1])
|
||||
node2 = str(tokens[2])
|
||||
diameter = float(tokens[3])
|
||||
v_type = str(tokens[4].upper())
|
||||
setting = str(tokens[5])
|
||||
minor_loss = float(tokens[6])
|
||||
desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
return f"insert into _link (id, type) values ('{id}', 'valve');insert into valves (id, node1, node2, diameter, type, setting, minor_loss) values ('{id}', '{node1}', '{node2}', {diameter}, '{v_type}', '{setting}', {minor_loss});"
|
||||
|
||||
|
||||
def inp_out_valve(name: str) -> list[str]:
|
||||
|
||||
@@ -79,28 +79,22 @@ def set_tag(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_tag_cmd(name, cs))
|
||||
|
||||
|
||||
class InpTag:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
def inp_in_tag(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.t_type = str(tokens[0].upper())
|
||||
self.id = str(tokens[1])
|
||||
self.tag = str(tokens[2])
|
||||
t_type = str(tokens[0].upper())
|
||||
id = str(tokens[1])
|
||||
tag = str(tokens[2])
|
||||
|
||||
|
||||
def inp_in_tag(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpTag(s)
|
||||
cs.append(g_update_prefix | {'type': 'tag', 't_type': obj.t_type, 'id': obj.id, 'tag': obj.tag})
|
||||
return cs
|
||||
if t_type == TAG_TYPE_NODE:
|
||||
return f"insert into tags_node (id, tag) values ('{id}', '{tag}');"
|
||||
elif t_type == TAG_TYPE_LINK:
|
||||
return f"insert into tags_link (id, tag) values ('{id}', '{tag}');"
|
||||
return ''
|
||||
|
||||
|
||||
def inp_out_tag(name: str) -> list[str]:
|
||||
|
||||
@@ -63,38 +63,23 @@ def set_demand(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# [EPA2][EPA3][IN][OUT]
|
||||
# node base_demand (pattern) ;category
|
||||
#--------------------------------------------------------------
|
||||
class InpDemand:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.junction = str(tokens[0])
|
||||
self.demand = float(tokens[1])
|
||||
self.pattern = str(tokens[2]) if num_without_desc >= 3 else None
|
||||
self.category = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
|
||||
|
||||
def inp_in_demand(section: list[str]) -> ChangeSet:
|
||||
objs: dict[str, list[InpDemand]] = {}
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpDemand(s)
|
||||
if obj.junction not in objs:
|
||||
objs[obj.junction] = []
|
||||
objs[obj.junction].append(obj)
|
||||
def inp_in_demand(line: str) -> str:
|
||||
tokens = line.split()
|
||||
|
||||
cs = ChangeSet()
|
||||
for junction, demands in objs.items():
|
||||
obj_cs : dict[str, Any] = g_update_prefix | {'type': 'demand', 'junction' : junction, 'demands' : []}
|
||||
for obj in demands:
|
||||
obj_cs['demands'].append({'demand': obj.demand, 'pattern' : obj.pattern, 'category': obj.category})
|
||||
cs.append(obj_cs)
|
||||
return cs
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
junction = str(tokens[0])
|
||||
demand = float(tokens[1])
|
||||
pattern = str(tokens[2]) if num_without_desc >= 3 else None
|
||||
pattern = f"'{pattern}'" if pattern != None else 'null'
|
||||
category = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
category = f"'{category}'" if category != None else 'null'
|
||||
|
||||
return f"insert into demands (junction, demand, pattern, category) values ('{junction}', {demand}, {pattern}, {category});"
|
||||
|
||||
|
||||
def inp_out_demand(name: str) -> list[str]:
|
||||
|
||||
@@ -34,9 +34,38 @@ s29_scada_device = 'scada_device'
|
||||
s30_scada_device_data = 'scada_device_data'
|
||||
s31_scada_element = 'scada_element'
|
||||
|
||||
section_name = ['TITLE', 'JUNCTIONS', 'RESERVOIRS', 'TANKS', 'PIPES',
|
||||
'PUMPS', 'VALVES', 'TAGS', 'DEMANDS', 'STATUS',
|
||||
'PATTERNS', 'CURVES', 'CONTROLS', 'RULES', 'ENERGY',
|
||||
'EMITTERS', 'QUALITY', 'SOURCES', 'REACTIONS', 'MIXING',
|
||||
'TIMES', 'REPORT', 'OPTIONS', 'COORDINATES', 'VERTICES',
|
||||
'LABELS', 'BACKDROP', 'END']
|
||||
TITLE = 'TITLE'
|
||||
JUNCTIONS = 'JUNCTIONS'
|
||||
RESERVOIRS = 'RESERVOIRS'
|
||||
TANKS = 'TANKS'
|
||||
PIPES = 'PIPES'
|
||||
PUMPS = 'PUMPS'
|
||||
VALVES = 'VALVES'
|
||||
TAGS = 'TAGS'
|
||||
DEMANDS = 'DEMANDS'
|
||||
STATUS = 'STATUS'
|
||||
PATTERNS = 'PATTERNS'
|
||||
CURVES = 'CURVES'
|
||||
CONTROLS = 'CONTROLS'
|
||||
RULES = 'RULES'
|
||||
ENERGY = 'ENERGY'
|
||||
EMITTERS = 'EMITTERS'
|
||||
QUALITY = 'QUALITY'
|
||||
SOURCES = 'SOURCES'
|
||||
REACTIONS = 'REACTIONS'
|
||||
MIXING = 'MIXING'
|
||||
TIMES = 'TIMES'
|
||||
REPORT = 'REPORT'
|
||||
OPTIONS = 'OPTIONS'
|
||||
COORDINATES = 'COORDINATES'
|
||||
VERTICES = 'VERTICES'
|
||||
LABELS = 'LABELS'
|
||||
BACKDROP = 'BACKDROP'
|
||||
END = 'END'
|
||||
|
||||
section_name = [TITLE, JUNCTIONS, RESERVOIRS, TANKS, PIPES,
|
||||
PUMPS, VALVES, TAGS, DEMANDS, STATUS,
|
||||
PATTERNS, CURVES, CONTROLS, RULES, ENERGY,
|
||||
EMITTERS, QUALITY, SOURCES, REACTIONS, MIXING,
|
||||
TIMES, REPORT, OPTIONS, COORDINATES, VERTICES,
|
||||
LABELS, BACKDROP, END]
|
||||
|
||||
18
build_db.py
18
build_db.py
@@ -1,14 +1,14 @@
|
||||
from tjnetwork import *
|
||||
|
||||
files = [
|
||||
#'bwsn',
|
||||
#'exnet',
|
||||
#'fengxian',
|
||||
#'jbh',
|
||||
#'nanjing',
|
||||
#'net3',
|
||||
#'zj',
|
||||
#'suzhouhe',
|
||||
'bwsn',
|
||||
'exnet',
|
||||
'fengxian',
|
||||
'jbh',
|
||||
'nanjing',
|
||||
'net3',
|
||||
'zj',
|
||||
'suzhouhe',
|
||||
]
|
||||
|
||||
def inp2db():
|
||||
@@ -20,7 +20,7 @@ def db2inp():
|
||||
dump_inp(file, f'./db_inp/{file}.db.inp')
|
||||
|
||||
if __name__ == '__main__':
|
||||
#inp2db()
|
||||
inp2db()
|
||||
#db2inp()
|
||||
#print(run_inp('net3'))
|
||||
pass
|
||||
|
||||
@@ -1 +1 @@
|
||||
from .epanet2 import run_project, run_inp, dump_output
|
||||
from .epanet import run_project, run_inp, dump_output
|
||||
@@ -227,17 +227,21 @@ def dump_output(path: str) -> str:
|
||||
return json.dumps(data)
|
||||
|
||||
|
||||
def run_project(name: str) -> str:
|
||||
def run_project(name: str, version: str = '2') -> str:
|
||||
if version != '3' and version != '2':
|
||||
version = '2'
|
||||
|
||||
if not project.have_project(name):
|
||||
raise Exception(f'Not found project [{name}]')
|
||||
|
||||
dir = os.path.abspath(os.getcwd())
|
||||
|
||||
db_inp = os.path.join(os.path.join(dir, 'db_inp'), name + '.db.inp')
|
||||
inp_out.dump_inp(name, db_inp)
|
||||
inp_out.dump_inp(name, db_inp, version)
|
||||
|
||||
input = name + '.db'
|
||||
exe = os.path.join(os.path.join(dir, 'epanet'), 'runepanet.exe')
|
||||
program = 'runepanet.exe' if version == '2' else 'run-epanet3.exe'
|
||||
exe = os.path.join(os.path.join(dir, 'epanet'), program)
|
||||
inp = os.path.join(os.path.join(dir, 'db_inp'), input + '.inp')
|
||||
rpt = os.path.join(os.path.join(dir, 'temp'), input + '.rpt')
|
||||
opt = os.path.join(os.path.join(dir, 'temp'), input + '.opt')
|
||||
@@ -250,17 +254,24 @@ def run_project(name: str) -> str:
|
||||
data['simulation_result'] = 'failed'
|
||||
else:
|
||||
data['simulation_result'] = 'successful'
|
||||
data |= _dump_output(opt)
|
||||
if version == '2':
|
||||
data |= _dump_output(opt)
|
||||
else:
|
||||
pass # TODO: epanet3 output format?
|
||||
|
||||
data['report'] = dump_report(rpt)
|
||||
|
||||
return json.dumps(data)
|
||||
|
||||
|
||||
def run_inp(name: str) -> str:
|
||||
def run_inp(name: str, version: str = '2') -> str:
|
||||
if version != '3' and version != '2':
|
||||
version = '2'
|
||||
|
||||
dir = os.path.abspath(os.getcwd())
|
||||
|
||||
exe = os.path.join(os.path.join(dir, 'epanet'), 'runepanet.exe')
|
||||
program = 'runepanet.exe' if version == '2' else 'run-epanet3.exe'
|
||||
exe = os.path.join(os.path.join(dir, 'epanet'), program)
|
||||
inp = os.path.join(os.path.join(dir, 'inp'), name + '.inp')
|
||||
rpt = os.path.join(os.path.join(dir, 'temp'), name + '.rpt')
|
||||
opt = os.path.join(os.path.join(dir, 'temp'), name + '.opt')
|
||||
@@ -273,7 +284,10 @@ def run_inp(name: str) -> str:
|
||||
data['simulation_result'] = 'failed'
|
||||
else:
|
||||
data['simulation_result'] = 'successful'
|
||||
data |= _dump_output(opt)
|
||||
if version == '2':
|
||||
data |= _dump_output(opt)
|
||||
else:
|
||||
pass # TODO: epanet3 output format?
|
||||
|
||||
data['report'] = dump_report(rpt)
|
||||
|
||||
24
tjnetwork.py
24
tjnetwork.py
@@ -185,24 +185,24 @@ def close_project(name: str) -> None:
|
||||
def copy_project(source: str, new: str) -> None:
|
||||
return api.copy_project(source, new)
|
||||
|
||||
def read_inp(name: str, inp: str) -> None:
|
||||
return api.read_inp(name, inp)
|
||||
def read_inp(name: str, inp: str, version: str = '3') -> bool:
|
||||
return api.read_inp(name, inp, version)
|
||||
|
||||
def dump_inp(name: str, inp: str) -> None:
|
||||
return api.dump_inp(name, inp)
|
||||
def dump_inp(name: str, inp: str, version: str = '3') -> None:
|
||||
return api.dump_inp(name, inp, version)
|
||||
|
||||
def import_inp(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.import_inp(name, cs)
|
||||
def import_inp(name: str, cs: ChangeSet, version: str = '3') -> bool:
|
||||
return api.import_inp(name, cs, version)
|
||||
|
||||
def export_inp(name: str) -> ChangeSet:
|
||||
return api.export_inp(name)
|
||||
def export_inp(name: str, version: str = '3') -> ChangeSet:
|
||||
return api.export_inp(name, version)
|
||||
|
||||
def run_project(name: str) -> str:
|
||||
return epanet.run_project(name)
|
||||
def run_project(name: str, version: str = '2') -> str:
|
||||
return epanet.run_project(name, version)
|
||||
|
||||
# put in inp folder, name without extension
|
||||
def run_inp(name: str) -> str:
|
||||
return epanet.run_inp(name)
|
||||
def run_inp(name: str, version: str = '2') -> str:
|
||||
return epanet.run_inp(name, version)
|
||||
|
||||
# path is absolute path
|
||||
def dump_output(path: str) -> str:
|
||||
|
||||
Reference in New Issue
Block a user