diff --git a/api/s23_options.py b/api/s23_options.py index b0580ed..ffcb46d 100644 --- a/api/s23_options.py +++ b/api/s23_options.py @@ -1,4 +1,5 @@ from .database import * +from .s23_options_util import generate_v3 OPTION_UNITS_CFS = 'CFS' @@ -144,10 +145,6 @@ def set_option(name: str, cs: ChangeSet) -> ChangeSet: #-------------------------------------------------------------- -def _sync_to_v3() -> ChangeSet: - return ChangeSet() - - def inp_in_option(section: list[str]) -> ChangeSet: if len(section) <= 0: return ChangeSet() @@ -173,7 +170,7 @@ def inp_in_option(section: list[str]) -> ChangeSet: cs |= { key : value } result = ChangeSet(cs) - result.merge(_sync_to_v3()) + result.merge(generate_v3(result)) return result @@ -183,5 +180,6 @@ def inp_out_option(name: str) -> list[str]: for obj in objs: key = obj['key'] value = obj['value'] - lines.append(f'{key} {value}') + if value != '': + lines.append(f'{key} {value}') return lines diff --git a/api/s23_options_util.py b/api/s23_options_util.py new file mode 100644 index 0000000..2244c25 --- /dev/null +++ b/api/s23_options_util.py @@ -0,0 +1,129 @@ +from .database import * + +_key_map_23 = { + 'UNITS' : 'FLOW_UNITS', + 'PRESSURE' : 'PRESSURE_UNITS', + 'HEADLOSS' : 'HEADLOSS_MODEL', + 'QUALITY' : 'QUALITY_MODEL', + 'UNBALANCED' : 'IF_UNBALANCED', + 'PATTERN' : 'DEMAND_PATTERN', + 'DEMAND MODEL' : 'DEMAND_MODEL', + 'DEMAND MULTIPLIER' : 'DEMAND_MULTIPLIER', + 'EMITTER EXPONENT' : 'EMITTER_EXPONENT', + 'VISCOSITY' : 'SPECIFIC_VISCOSITY', + 'DIFFUSIVITY' : 'SPECIFIC_DIFFUSIVITY', + 'SPECIFIC GRAVITY' : 'SPECIFIC_GRAVITY', + 'TRIALS' : 'MAXIMUM_TRIALS', + 'ACCURACY' : 'RELATIVE_ACCURACY', + #'HEADERROR' : '', + 'FLOWCHANGE' : 'FLOW_CHANGE_LIMIT', + 'MINIMUM PRESSURE' : 'MINIMUM_PRESSURE', + 'REQUIRED PRESSURE' : 'SERVICE_PRESSURE', + 'PRESSURE EXPONENT' : 'PRESSURE_EXPONENT', + 'TOLERANCE' : 'QUALITY_TOLERANCE', + 'HTOL' : 'HEAD_TOLERANCE', + 'QTOL' : 'FLOW_TOLERANCE', + #'RQTOL' : '', + #'CHECKFREQ' : '', + #'MAXCHECK' : '', + #'DAMPLIMIT' : '', +} + + +_key_map_32 = { + 'FLOW_UNITS' : 'UNITS', + 'PRESSURE_UNITS' : 'PRESSURE', + 'HEADLOSS_MODEL' : 'HEADLOSS', + 'SPECIFIC_GRAVITY' : 'SPECIFIC GRAVITY', + 'SPECIFIC_VISCOSITY' : 'VISCOSITY', + 'MAXIMUM_TRIALS' : 'TRIALS', + 'HEAD_TOLERANCE' : 'HTOL', + 'FLOW_TOLERANCE' : 'QTOL', + 'FLOW_CHANGE_LIMIT' : 'FLOWCHANGE', + 'RELATIVE_ACCURACY' : 'ACCURACY', + #'TIME_WEIGHT' : '', + #'STEP_SIZING' : '', + 'IF_UNBALANCED' : 'UNBALANCED', + 'DEMAND_MODEL' : 'DEMAND MODEL', + 'DEMAND_PATTERN' : 'PATTERN', + 'DEMAND_MULTIPLIER' : 'DEMAND MULTIPLIER', + 'MINIMUM_PRESSURE' : 'MINIMUM PRESSURE', + 'SERVICE_PRESSURE' : 'REQUIRED PRESSURE', + 'PRESSURE_EXPONENT' : 'PRESSURE EXPONENT', + #'LEAKAGE_MODEL' : '', + #'LEAKAGE_COEFF1' : '', + #'LEAKAGE_COEFF2' : '', + 'EMITTER_EXPONENT' : 'EMITTER EXPONENT', + 'QUALITY_MODEL' : 'QUALITY', + #'QUALITY_NAME' : '', + #'QUALITY_UNITS' : '', + #'TRACE_NODE' : '', + 'SPECIFIC_DIFFUSIVITY' : 'DIFFUSIVITY', + 'QUALITY_TOLERANCE' : 'TOLERANCE' +} + + +def generate_v2(cs: ChangeSet) -> ChangeSet: + op = cs.operations[0] + + if op['type'] == 'option': + return cs + + map = _key_map_32 + + cs_v2 = {} + for key in op: + if key == 'operation' or key == 'type': + continue + + if key in map.keys(): + if key != 'QUALITY_MODEL' and key != 'DEMAND_MODEL': + cs_v2 |= { map[key] : op[key] } + elif key == 'QUALITY_MODEL': + if str(op[key]).upper() == 'TRACE' and 'TRACE_NODE' in op.keys(): + cs_v2 |= { map[key] : f"TRACE {op['TRACE_NODE']}" } + else: + cs_v2 |= { map[key] : str(op[key]).upper() } + elif key == 'DEMAND_MODEL': + if op[key] == 'FIXED': + cs_v2 |= { map[key] : 'DDA' } + else: + cs_v2 |= { map[key] : 'PDA' } + + if len(cs_v2) > 0: + cs_v2 |= g_update_prefix | { 'type' : 'option' } + return ChangeSet(cs_v2) + + return ChangeSet() + + +def generate_v3(cs: ChangeSet) -> ChangeSet: + op = cs.operations[0] + + if op['type'] == 'option_v3': + return cs + + map = _key_map_23 + + cs_v3 = {} + for key in op: + if key == 'operation' or key == 'type': + continue + + if key in map.keys(): + if key != 'QUALITY' and key != 'DEMAND MODEL': + cs_v3 |= { map[key] : op[key] } + elif key == 'QUALITY': + tokens = str(op[key]).split() + if len(tokens) >= 1: + cs_v3 |= { map[key] : tokens[0].upper() } + if tokens[0].upper() == 'TRACE' and len(tokens) >= 2: + cs_v3 |= { 'TRACE_NODE' : tokens[1] } + elif key == 'DEMAND MODEL': + cs_v3 |= { map[key] : 'POWER' } + + if len(cs_v3) > 0: + cs_v3 |= g_update_prefix | { 'type' : 'option_v3' } + return ChangeSet(cs_v3) + + return ChangeSet() diff --git a/api/s23_options_v3.py b/api/s23_options_v3.py index e1e9c50..fdd233f 100644 --- a/api/s23_options_v3.py +++ b/api/s23_options_v3.py @@ -5,6 +5,8 @@ from .s23_options import OPTION_HEADLOSS_HW, OPTION_HEADLOSS_DW, OPTION_HEADLOSS from .s23_options import OPTION_UNBALANCED_STOP, OPTION_UNBALANCED_CONTINUE from .s23_options import OPTION_QUALITY_NONE, OPTION_QUALITY_CHEMICAL, OPTION_QUALITY_AGE, OPTION_QUALITY_TRACE from .s23_options import element_schema +from .s23_options import get_option_schema +from .s23_options_util import generate_v2, generate_v3 OPTION_V3_FLOW_UNITS_CFS = OPTION_UNITS_CFS OPTION_V3_FLOW_UNITS_GPM = OPTION_UNITS_GPM @@ -130,15 +132,31 @@ def set_option_v3(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, set_option_v3_cmd(name, cs)) -def _sync_to_v2() -> ChangeSet: - return ChangeSet() +def _parse_v2(v2_lines: list[str]) -> dict[str, str]: + cs_v2 = g_update_prefix | { 'type' : 'option' } + for s in v2_lines: + tokens = s.split() + if tokens[0].upper() == 'PATTERN': # can not upper id + cs_v2 |= { 'PATTERN' : tokens[1] } + elif tokens[0].upper() == 'QUALITY': # can not upper trace node + value = tokens[1] + if len(tokens) > 2: + value += f' {tokens[2]}' + cs_v2 |= { 'QUALITY' : value } + else: + line = s.upper().strip() + for key in get_option_schema('').keys(): + if line.startswith(key): + value = line.removeprefix(key).strip() + cs_v2 |= { key : value } + return cs_v2 def inp_in_option_v3(section: list[str]) -> ChangeSet: if len(section) <= 0: return ChangeSet() - cs = g_update_prefix | { 'type' : 'option_v3' } + cs_v3 = g_update_prefix | { 'type' : 'option_v3' } v2_lines = [] for s in section: if s.startswith(';'): @@ -148,15 +166,16 @@ def inp_in_option_v3(section: list[str]) -> ChangeSet: key = tokens[0] if key in get_option_v3_schema('').keys(): value = tokens[1] if len(tokens) >= 2 else '' - cs |= { key : value } + cs_v3 |= { key : value } else: v2_lines.append(s.strip()) - for line in v2_lines: - pass + # unlikely... + cs_v2 = _parse_v2(v2_lines) - result = ChangeSet(cs) - result.merge(_sync_to_v2()) + result = ChangeSet(cs_v3) + result.merge(generate_v3(ChangeSet(cs_v2))) + result.merge(generate_v2(result)) return result @@ -166,5 +185,6 @@ def inp_out_option_v3(name: str) -> list[str]: for obj in objs: key = obj['key'] value = obj['value'] - lines.append(f'{key} {value}') + if value != '': + lines.append(f'{key} {value}') return lines