Accept Merge Request #221: (region -> master)
Merge Request: Support region Created By: @王琼钰 Accepted By: @王琼钰 URL: https://tjwater.coding.net/p/tjwatercloud/d/TJWaterServer/git/merge/221?initial=true
This commit is contained in:
BIN
api/CClipper2.dll
Normal file
BIN
api/CClipper2.dll
Normal file
Binary file not shown.
BIN
api/CMetis.dll
Normal file
BIN
api/CMetis.dll
Normal file
Binary file not shown.
@@ -18,8 +18,9 @@ from .database import get_operation_by_snapshot, get_snapshot_by_operation
|
||||
from .database import pick_snapshot
|
||||
from .database import pick_operation, sync_with_server
|
||||
from .database import get_restore_operation, set_restore_operation, set_restore_operation_to_current, restore
|
||||
from .database import read, try_read, read_all, write
|
||||
|
||||
from .batch_cmds import execute_batch_commands, execute_batch_command
|
||||
from .batch_exe import execute_batch_commands, execute_batch_command
|
||||
|
||||
from .s0_base import JUNCTION, RESERVOIR, TANK, PIPE, PUMP, VALVE, PATTERN, CURVE
|
||||
from .s0_base import is_node, is_junction, is_reservoir, is_tank
|
||||
@@ -32,25 +33,25 @@ from .s0_base import get_node_links
|
||||
from .s1_title import get_title_schema, get_title, set_title
|
||||
|
||||
from .s2_junctions import get_junction_schema, add_junction, get_junction, set_junction
|
||||
from .del_cmd import delete_junction_cascade
|
||||
from .batch_api import delete_junction_cascade
|
||||
|
||||
from .s3_reservoirs import get_reservoir_schema, add_reservoir, get_reservoir, set_reservoir
|
||||
from .del_cmd import delete_reservoir_cascade
|
||||
from .batch_api import delete_reservoir_cascade
|
||||
|
||||
from .s4_tanks import OVERFLOW_YES, OVERFLOW_NO
|
||||
from .s4_tanks import get_tank_schema, add_tank, get_tank, set_tank
|
||||
from .del_cmd import delete_tank_cascade
|
||||
from .batch_api import delete_tank_cascade
|
||||
|
||||
from .s5_pipes import PIPE_STATUS_OPEN, PIPE_STATUS_CLOSED, PIPE_STATUS_CV
|
||||
from .s5_pipes import get_pipe_schema, add_pipe, get_pipe, set_pipe
|
||||
from .del_cmd import delete_pipe_cascade
|
||||
from .batch_api import delete_pipe_cascade
|
||||
|
||||
from .s6_pumps import get_pump_schema, add_pump, get_pump, set_pump
|
||||
from .del_cmd import delete_pump_cascade
|
||||
from .batch_api import delete_pump_cascade
|
||||
|
||||
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
|
||||
from .del_cmd import delete_valve_cascade
|
||||
from .batch_api import delete_valve_cascade
|
||||
|
||||
from .s8_tags import TAG_TYPE_NODE, TAG_TYPE_LINK
|
||||
from .s8_tags import get_tag_schema, get_tags, get_tag, set_tag
|
||||
@@ -61,11 +62,11 @@ 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, add_pattern
|
||||
from .del_cmd import delete_pattern_cascade
|
||||
from .batch_api import delete_pattern_cascade
|
||||
|
||||
from .s12_curves import CURVE_TYPE_PUMP, CURVE_TYPE_EFFICIENCY, CURVE_TYPE_VOLUME, CURVE_TYPE_HEADLOSS
|
||||
from .s12_curves import get_curve_schema, get_curve, set_curve, add_curve
|
||||
from .del_cmd import delete_curve_cascade
|
||||
from .batch_api import delete_curve_cascade
|
||||
|
||||
from .s13_controls import get_control_schema, get_control, set_control
|
||||
|
||||
@@ -98,7 +99,7 @@ from .s23_options_util import OPTION_UNBALANCED_STOP, OPTION_UNBALANCED_CONTINUE
|
||||
from .s23_options_util import OPTION_DEMAND_MODEL_DDA, OPTION_DEMAND_MODEL_PDA
|
||||
from .s23_options_util import OPTION_QUALITY_NONE, OPTION_QUALITY_CHEMICAL, OPTION_QUALITY_AGE, OPTION_QUALITY_TRACE
|
||||
from .s23_options_util import get_option_schema, get_option
|
||||
from .s23_options import set_option
|
||||
from .batch_api import set_option_ex
|
||||
|
||||
from .s23_options_util import OPTION_V3_FLOW_UNITS_CFS, OPTION_V3_FLOW_UNITS_GPM, OPTION_V3_FLOW_UNITS_MGD, OPTION_V3_FLOW_UNITS_IMGD, OPTION_V3_FLOW_UNITS_AFD, OPTION_V3_FLOW_UNITS_LPS, OPTION_V3_FLOW_UNITS_LPM, OPTION_V3_FLOW_UNITS_MLD, OPTION_V3_FLOW_UNITS_CMH, OPTION_V3_FLOW_UNITS_CMD
|
||||
from .s23_options_util import OPTION_V3_PRESSURE_UNITS_PSI, OPTION_V3_PRESSURE_UNITS_KPA, OPTION_V3_PRESSURE_UNITS_M
|
||||
@@ -110,7 +111,7 @@ from .s23_options_util import OPTION_V3_LEAKAGE_MODEL_NONE, OPTION_V3_LEAKAGE_MO
|
||||
from .s23_options_util import OPTION_V3_QUALITY_MODEL_NONE, OPTION_V3_QUALITY_MODEL_CHEMICAL, OPTION_V3_QUALITY_MODEL_AGE, OPTION_V3_QUALITY_MODEL_TRACE
|
||||
from .s23_options_util import OPTION_V3_QUALITY_UNITS_HRS, OPTION_V3_QUALITY_UNITS_PCNT, OPTION_V3_QUALITY_UNITS_MGL, OPTION_V3_QUALITY_UNITS_UGL
|
||||
from .s23_options_util import get_option_v3_schema, get_option_v3
|
||||
from .s23_options_v3 import set_option_v3
|
||||
from .batch_api import set_option_v3_ex
|
||||
|
||||
from .s24_coordinates import get_node_coord
|
||||
|
||||
@@ -122,12 +123,26 @@ from .s27_backdrop import get_backdrop_schema, get_backdrop, set_backdrop
|
||||
|
||||
from .s29_scada_device import SCADA_DEVICE_TYPE_PRESSURE, SCADA_DEVICE_TYPE_DEMAND, SCADA_DEVICE_TYPE_QUALITY, SCADA_DEVICE_TYPE_LEVEL, SCADA_DEVICE_TYPE_FLOW
|
||||
from .s29_scada_device import get_scada_device_schema, get_scada_devices, get_scada_device, set_scada_device, add_scada_device, delete_scada_device
|
||||
from .del_cmd import clean_scada_device
|
||||
from .clean_api import clean_scada_device
|
||||
|
||||
from .s30_scada_device_data import get_scada_device_data_schema, get_scada_device_data, set_scada_device_data, add_scada_device_data, delete_scada_device_data
|
||||
from .del_cmd import clean_scada_device_data
|
||||
from .clean_api import clean_scada_device_data
|
||||
|
||||
from .s31_scada_element import SCADA_MODEL_TYPE_JUNCTION, SCADA_MODEL_TYPE_RESERVOIR, SCADA_MODEL_TYPE_TANK, SCADA_MODEL_TYPE_PIPE, SCADA_MODEL_TYPE_PUMP, SCADA_MODEL_TYPE_VALVE
|
||||
from .s31_scada_element import SCADA_ELEMENT_STATUS_OFFLINE, SCADA_ELEMENT_STATUS_ONLINE
|
||||
from .s31_scada_element import get_scada_element_schema, get_scada_elements, get_scada_element, set_scada_element, add_scada_element, delete_scada_element
|
||||
from .del_cmd import clean_scada_element
|
||||
from .clean_api import clean_scada_element
|
||||
|
||||
from .s32_region_util import get_nodes_in_boundary, get_nodes_in_region, calculate_convex_hull, calculate_boundary, inflate_boundary, inflate_region
|
||||
|
||||
from .s33_region import get_region_schema, get_region, set_region, add_region, delete_region
|
||||
|
||||
from .s34_water_distribution import DISTRIBUTION_TYPE_ADD, DISTRIBUTION_TYPE_OVERRIDE
|
||||
from .s34_water_distribution import distribute_demand_to_nodes, distribute_demand_to_region
|
||||
|
||||
from .s35_district_metering_area import PARTITION_TYPE_RB, PARTITION_TYPE_KWAY
|
||||
from .s35_district_metering_area import calculate_district_metering_area
|
||||
|
||||
from .s36_service_area import calculate_service_area
|
||||
|
||||
from .s37_virtual_district import calculate_virtual_district
|
||||
|
||||
53
api/batch_api.py
Normal file
53
api/batch_api.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from .sections import *
|
||||
from .database import ChangeSet, API_DELETE, API_UPDATE
|
||||
from .batch_exe import execute_batch_command
|
||||
|
||||
|
||||
def delete_junction_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s2_junction }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_reservoir_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s3_reservoir }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_tank_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s4_tank }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_pipe_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s5_pipe }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_pump_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s6_pump }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_valve_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s7_valve }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_pattern_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s11_pattern }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_curve_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : s12_curve }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def set_option_ex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_UPDATE, 'type' : s23_option }
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def set_option_v3_ex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_UPDATE, 'type' : s23_option_v3 }
|
||||
return execute_batch_command(name, cs)
|
||||
@@ -18,8 +18,10 @@ from .s20_mixing import delete_mixing_by_tank
|
||||
from .s25_vertices import delete_vertex_by_link
|
||||
from .s26_labels import unset_label_by_node
|
||||
|
||||
from .s23_options_util import generate_v2, generate_v3
|
||||
|
||||
def delete_junction_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
|
||||
def delete_junction_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -31,11 +33,11 @@ def delete_junction_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
|
||||
for link in links:
|
||||
if is_pipe(name, link):
|
||||
result.merge(delete_pipe_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'pipe', 'id': link})))
|
||||
result.merge(delete_pipe_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'pipe', 'id': link})))
|
||||
if is_pump(name, link):
|
||||
result.merge(delete_pump_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'pump', 'id': link})))
|
||||
result.merge(delete_pump_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'pump', 'id': link})))
|
||||
if is_valve(name, link):
|
||||
result.merge(delete_valve_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'valve', 'id': link})))
|
||||
result.merge(delete_valve_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'valve', 'id': link})))
|
||||
|
||||
result.merge(delete_tag_by_node(name, id))
|
||||
result.merge(delete_demand_by_junction(name, id))
|
||||
@@ -48,7 +50,7 @@ def delete_junction_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_reservoir_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_reservoir_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -60,11 +62,11 @@ def delete_reservoir_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
|
||||
for link in links:
|
||||
if is_pipe(name, link):
|
||||
result.merge(delete_pipe_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'pipe', 'id': link})))
|
||||
result.merge(delete_pipe_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'pipe', 'id': link})))
|
||||
if is_pump(name, link):
|
||||
result.merge(delete_pump_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'pump', 'id': link})))
|
||||
result.merge(delete_pump_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'pump', 'id': link})))
|
||||
if is_valve(name, link):
|
||||
result.merge(delete_valve_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'valve', 'id': link})))
|
||||
result.merge(delete_valve_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'valve', 'id': link})))
|
||||
|
||||
result.merge(delete_tag_by_node(name, id))
|
||||
result.merge(delete_quality_by_node(name, id))
|
||||
@@ -75,7 +77,7 @@ def delete_reservoir_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_tank_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_tank_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -87,11 +89,11 @@ def delete_tank_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
|
||||
for link in links:
|
||||
if is_pipe(name, link):
|
||||
result.merge(delete_pipe_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'pipe', 'id': link})))
|
||||
result.merge(delete_pipe_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'pipe', 'id': link})))
|
||||
if is_pump(name, link):
|
||||
result.merge(delete_pump_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'pump', 'id': link})))
|
||||
result.merge(delete_pump_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'pump', 'id': link})))
|
||||
if is_valve(name, link):
|
||||
result.merge(delete_valve_cascade_batch_cmd(name, ChangeSet(g_delete_prefix | {'type': 'valve', 'id': link})))
|
||||
result.merge(delete_valve_cascade_batch_cs(name, ChangeSet(g_delete_prefix | {'type': 'valve', 'id': link})))
|
||||
|
||||
result.merge(delete_tag_by_node(name, id))
|
||||
result.merge(delete_quality_by_node(name, id))
|
||||
@@ -104,7 +106,7 @@ def delete_tank_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_pipe_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_pipe_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -121,7 +123,7 @@ def delete_pipe_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_pump_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_pump_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -138,7 +140,7 @@ def delete_pump_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_valve_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_valve_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -155,7 +157,7 @@ def delete_valve_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_pattern_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_pattern_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -173,7 +175,7 @@ def delete_pattern_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def delete_curve_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def delete_curve_cascade_batch_cs(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = ChangeSet()
|
||||
|
||||
id = cs.operations[0]['id']
|
||||
@@ -189,24 +191,48 @@ def delete_curve_cascade_batch_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return result
|
||||
|
||||
|
||||
def del_cascade_cmd(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
def set_option_cs(cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0]['operation'] = API_UPDATE
|
||||
cs.operations[0]['type'] = 'option'
|
||||
new_cs = cs
|
||||
new_cs.merge(generate_v3(cs))
|
||||
return new_cs
|
||||
|
||||
if type == s2_junction:
|
||||
return delete_junction_cascade_batch_cmd(name, cs)
|
||||
elif type == s3_reservoir:
|
||||
return delete_reservoir_cascade_batch_cmd(name, cs)
|
||||
elif type == s4_tank:
|
||||
return delete_tank_cascade_batch_cmd(name, cs)
|
||||
elif type == s5_pipe:
|
||||
return delete_pipe_cascade_batch_cmd(name, cs)
|
||||
elif type == s6_pump:
|
||||
return delete_pump_cascade_batch_cmd(name, cs)
|
||||
elif type == s7_valve:
|
||||
return delete_valve_cascade_batch_cmd(name, cs)
|
||||
elif type == s11_pattern:
|
||||
return delete_pattern_cascade_batch_cmd(name, cs)
|
||||
elif type == s12_curve:
|
||||
return delete_curve_cascade_batch_cmd(name, cs)
|
||||
|
||||
def set_option_v3_cs(cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0]['operation'] = API_UPDATE
|
||||
cs.operations[0]['type'] = 'option_v3'
|
||||
new_cs = cs
|
||||
new_cs.merge(generate_v2(cs))
|
||||
return new_cs
|
||||
|
||||
|
||||
def rewrite_batch_api(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
op = cs.operations[0]
|
||||
api = op['operation']
|
||||
type = op['type']
|
||||
|
||||
if api == API_DELETE:
|
||||
if type == s2_junction:
|
||||
return delete_junction_cascade_batch_cs(name, cs)
|
||||
elif type == s3_reservoir:
|
||||
return delete_reservoir_cascade_batch_cs(name, cs)
|
||||
elif type == s4_tank:
|
||||
return delete_tank_cascade_batch_cs(name, cs)
|
||||
elif type == s5_pipe:
|
||||
return delete_pipe_cascade_batch_cs(name, cs)
|
||||
elif type == s6_pump:
|
||||
return delete_pump_cascade_batch_cs(name, cs)
|
||||
elif type == s7_valve:
|
||||
return delete_valve_cascade_batch_cs(name, cs)
|
||||
elif type == s11_pattern:
|
||||
return delete_pattern_cascade_batch_cs(name, cs)
|
||||
elif type == s12_curve:
|
||||
return delete_curve_cascade_batch_cs(name, cs)
|
||||
elif api == API_UPDATE:
|
||||
if type == s23_option:
|
||||
return set_option_cs(cs)
|
||||
elif type == s23_option_v3:
|
||||
return set_option_v3_cs(cs)
|
||||
|
||||
return cs
|
||||
304
api/batch_cmd.py
304
api/batch_cmd.py
@@ -1,304 +0,0 @@
|
||||
from .sections import *
|
||||
from .database import API_ADD, API_UPDATE, API_DELETE, ChangeSet, DbChangeSet, execute_command
|
||||
from .s1_title import set_title_cmd
|
||||
from .s2_junctions import set_junction_cmd, add_junction_cmd, delete_junction_cmd
|
||||
from .s3_reservoirs import set_reservoir_cmd, add_reservoir_cmd, delete_reservoir_cmd
|
||||
from .s4_tanks import set_tank_cmd, add_tank_cmd, delete_tank_cmd
|
||||
from .s5_pipes import set_pipe_cmd, add_pipe_cmd, delete_pipe_cmd
|
||||
from .s6_pumps import set_pump_cmd, add_pump_cmd, delete_pump_cmd
|
||||
from .s7_valves import set_valve_cmd, add_valve_cmd, delete_valve_cmd
|
||||
from .s8_tags import set_tag_cmd
|
||||
from .s9_demands import set_demand_cmd
|
||||
from .s10_status import set_status_cmd
|
||||
from .s11_patterns import set_pattern_cmd, add_pattern_cmd, delete_pattern_cmd
|
||||
from .s12_curves import set_curve_cmd, add_curve_cmd, delete_curve_cmd
|
||||
from .s13_controls import set_control_cmd
|
||||
from .s14_rules import set_rule_cmd
|
||||
from .s15_energy import set_energy_cmd, set_pump_energy_cmd
|
||||
from .s16_emitters import set_emitter_cmd
|
||||
from .s17_quality import set_quality_cmd
|
||||
from .s18_sources import set_source_cmd, add_source_cmd, delete_source_cmd
|
||||
from .s19_reactions import set_reaction_cmd, set_pipe_reaction_cmd, set_tank_reaction_cmd
|
||||
from .s20_mixing import set_mixing_cmd, add_mixing_cmd, delete_mixing_cmd
|
||||
from .s21_times import set_time_cmd
|
||||
#from .s22_report import *
|
||||
from .s23_options_util import set_option_cmd, set_option_v3_cmd
|
||||
#from .s24_coordinates import *
|
||||
from .s25_vertices import set_vertex_cmd, add_vertex_cmd, delete_vertex_cmd
|
||||
from .s26_labels import set_label_cmd, add_label_cmd, delete_label_cmd
|
||||
from .s27_backdrop import set_backdrop_cmd
|
||||
# from .s28_end import *
|
||||
from .s29_scada_device import set_scada_device_cmd, add_scada_device_cmd, delete_scada_device_cmd
|
||||
from .s30_scada_device_data import set_scada_device_data_cmd, add_scada_device_data_cmd, delete_scada_device_data_cmd
|
||||
from .s31_scada_element import set_scada_element_cmd, add_scada_element_cmd, delete_scada_element_cmd
|
||||
from .del_cmd_raw import del_cascade_cmd
|
||||
|
||||
|
||||
def add_cmd(name: str, cs: ChangeSet) -> DbChangeSet | None:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == s1_title:
|
||||
return None
|
||||
if type == s2_junction:
|
||||
return add_junction_cmd(name, cs)
|
||||
elif type == s3_reservoir:
|
||||
return add_reservoir_cmd(name, cs)
|
||||
elif type == s4_tank:
|
||||
return add_tank_cmd(name, cs)
|
||||
elif type == s5_pipe:
|
||||
return add_pipe_cmd(name, cs)
|
||||
elif type == s6_pump:
|
||||
return add_pump_cmd(name, cs)
|
||||
elif type == s7_valve:
|
||||
return add_valve_cmd(name, cs)
|
||||
elif type == s8_tag:
|
||||
return None
|
||||
elif type == s9_demand:
|
||||
return None
|
||||
elif type == s10_status:
|
||||
return None
|
||||
elif type == s11_pattern:
|
||||
return add_pattern_cmd(name, cs)
|
||||
elif type == s12_curve:
|
||||
return add_curve_cmd(name, cs)
|
||||
elif type == s13_control:
|
||||
return None
|
||||
elif type == s14_rule:
|
||||
return None
|
||||
elif type == s15_energy:
|
||||
return None
|
||||
elif type == s15_pump_energy:
|
||||
return None
|
||||
elif type == s16_emitter:
|
||||
return None
|
||||
elif type == s17_quality:
|
||||
return None
|
||||
elif type == s18_source:
|
||||
return add_source_cmd(name, cs)
|
||||
elif type == s19_reaction:
|
||||
return None
|
||||
elif type == s19_pipe_reaction:
|
||||
return None
|
||||
elif type == s19_tank_reaction:
|
||||
return None
|
||||
elif type == s20_mixing:
|
||||
return add_mixing_cmd(name, cs)
|
||||
elif type == s21_time:
|
||||
return None
|
||||
elif type == s22_report:
|
||||
return None
|
||||
elif type == s23_option:
|
||||
return None
|
||||
elif type == s23_option_v3:
|
||||
return None
|
||||
elif type == s24_coordinate:
|
||||
return None
|
||||
elif type == s25_vertex:
|
||||
return add_vertex_cmd(name, cs)
|
||||
elif type == s26_label:
|
||||
return add_label_cmd(name, cs)
|
||||
elif type == s27_backdrop:
|
||||
return None
|
||||
elif type == s28_end:
|
||||
return None
|
||||
elif type == s29_scada_device:
|
||||
return add_scada_device_cmd(name, cs)
|
||||
elif type == s30_scada_device_data:
|
||||
return add_scada_device_data_cmd(name, cs)
|
||||
elif type == s31_scada_element:
|
||||
return add_scada_element_cmd(name, cs)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def set_cmd(name: str, cs: ChangeSet) -> DbChangeSet | None:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == s1_title:
|
||||
return set_title_cmd(name, cs)
|
||||
if type == s2_junction:
|
||||
return set_junction_cmd(name, cs)
|
||||
elif type == s3_reservoir:
|
||||
return set_reservoir_cmd(name, cs)
|
||||
elif type == s4_tank:
|
||||
return set_tank_cmd(name, cs)
|
||||
elif type == s5_pipe:
|
||||
return set_pipe_cmd(name, cs)
|
||||
elif type == s6_pump:
|
||||
return set_pump_cmd(name, cs)
|
||||
elif type == s7_valve:
|
||||
return set_valve_cmd(name, cs)
|
||||
elif type == s8_tag:
|
||||
return set_tag_cmd(name, cs)
|
||||
elif type == s9_demand:
|
||||
return set_demand_cmd(name, cs)
|
||||
elif type == s10_status:
|
||||
return set_status_cmd(name, cs)
|
||||
elif type == s11_pattern:
|
||||
return set_pattern_cmd(name, cs)
|
||||
elif type == s12_curve:
|
||||
return set_curve_cmd(name, cs)
|
||||
elif type == s13_control:
|
||||
return set_control_cmd(name, cs)
|
||||
elif type == s14_rule:
|
||||
return set_rule_cmd(name, cs)
|
||||
elif type == s15_energy:
|
||||
return set_energy_cmd(name, cs)
|
||||
elif type == s15_pump_energy:
|
||||
return set_pump_energy_cmd(name, cs)
|
||||
elif type == s16_emitter:
|
||||
return set_emitter_cmd(name, cs)
|
||||
elif type == s17_quality:
|
||||
return set_quality_cmd(name, cs)
|
||||
elif type == s18_source:
|
||||
return set_source_cmd(name, cs)
|
||||
elif type == s19_reaction:
|
||||
return set_reaction_cmd(name, cs)
|
||||
elif type == s19_pipe_reaction:
|
||||
return set_pipe_reaction_cmd(name, cs)
|
||||
elif type == s19_tank_reaction:
|
||||
return set_tank_reaction_cmd(name, cs)
|
||||
elif type == s20_mixing:
|
||||
return set_mixing_cmd(name, cs)
|
||||
elif type == s21_time:
|
||||
return set_time_cmd(name, cs)
|
||||
elif type == s22_report: # no api now
|
||||
return None
|
||||
elif type == s23_option:
|
||||
return set_option_cmd(name, cs)
|
||||
elif type == s23_option_v3:
|
||||
return set_option_v3_cmd(name, cs)
|
||||
elif type == s24_coordinate: # do not support update here
|
||||
return None
|
||||
elif type == s25_vertex:
|
||||
return set_vertex_cmd(name, cs)
|
||||
elif type == s26_label:
|
||||
return set_label_cmd(name, cs)
|
||||
elif type == s27_backdrop:
|
||||
return set_backdrop_cmd(name, cs)
|
||||
elif type == s28_end: # end
|
||||
return None
|
||||
elif type == s29_scada_device:
|
||||
return set_scada_device_cmd(name, cs)
|
||||
elif type == s30_scada_device_data:
|
||||
return set_scada_device_data_cmd(name, cs)
|
||||
elif type == s31_scada_element:
|
||||
return set_scada_element_cmd(name, cs)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def del_cmd(name: str, cs: ChangeSet) -> DbChangeSet | None:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == s1_title:
|
||||
return None
|
||||
if type == s2_junction:
|
||||
return delete_junction_cmd(name, cs)
|
||||
elif type == s3_reservoir:
|
||||
return delete_reservoir_cmd(name, cs)
|
||||
elif type == s4_tank:
|
||||
return delete_tank_cmd(name, cs)
|
||||
elif type == s5_pipe:
|
||||
return delete_pipe_cmd(name, cs)
|
||||
elif type == s6_pump:
|
||||
return delete_pump_cmd(name, cs)
|
||||
elif type == s7_valve:
|
||||
return delete_valve_cmd(name, cs)
|
||||
elif type == s8_tag:
|
||||
return None
|
||||
elif type == s9_demand:
|
||||
return None
|
||||
elif type == s10_status:
|
||||
return None
|
||||
elif type == s11_pattern:
|
||||
return delete_pattern_cmd(name, cs)
|
||||
elif type == s12_curve:
|
||||
return delete_curve_cmd(name, cs)
|
||||
elif type == s13_control:
|
||||
return None
|
||||
elif type == s14_rule:
|
||||
return None
|
||||
elif type == s15_energy:
|
||||
return None
|
||||
elif type == s15_pump_energy:
|
||||
return None
|
||||
elif type == s16_emitter:
|
||||
return None
|
||||
elif type == s17_quality:
|
||||
return None
|
||||
elif type == s18_source:
|
||||
return delete_source_cmd(name, cs)
|
||||
elif type == s19_reaction:
|
||||
return None
|
||||
elif type == s19_pipe_reaction:
|
||||
return None
|
||||
elif type == s19_tank_reaction:
|
||||
return None
|
||||
elif type == s20_mixing:
|
||||
return delete_mixing_cmd(name, cs)
|
||||
elif type == s21_time:
|
||||
return None
|
||||
elif type == s22_report:
|
||||
return None
|
||||
elif type == s23_option:
|
||||
return None
|
||||
elif type == s23_option_v3:
|
||||
return None
|
||||
elif type == s24_coordinate:
|
||||
return None
|
||||
elif type == s25_vertex:
|
||||
return delete_vertex_cmd(name, cs)
|
||||
elif type == s26_label:
|
||||
return delete_label_cmd(name, cs)
|
||||
elif type == s27_backdrop:
|
||||
return None
|
||||
elif type == s28_end:
|
||||
return None
|
||||
elif type == s29_scada_device:
|
||||
return delete_scada_device_cmd(name, cs)
|
||||
elif type == s30_scada_device_data:
|
||||
return delete_scada_device_data_cmd(name, cs)
|
||||
elif type == s31_scada_element:
|
||||
return delete_scada_element_cmd(name, cs)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def execute_batch_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
css: list[DbChangeSet] = []
|
||||
|
||||
# for delete, generate cascade command
|
||||
new_cs = ChangeSet()
|
||||
for op in cs.operations:
|
||||
if op['operation'] == API_DELETE:
|
||||
new_cs.merge(del_cascade_cmd(name, ChangeSet(op)))
|
||||
else:
|
||||
new_cs.merge(ChangeSet(op))
|
||||
|
||||
try:
|
||||
for op in new_cs.operations:
|
||||
operation = op['operation']
|
||||
|
||||
r = None
|
||||
|
||||
if operation == API_ADD:
|
||||
r = add_cmd(name, ChangeSet(op))
|
||||
elif operation == API_UPDATE:
|
||||
r = set_cmd(name, ChangeSet(op))
|
||||
elif operation == API_DELETE:
|
||||
r = del_cmd(name, ChangeSet(op))
|
||||
|
||||
if r == None:
|
||||
print(f'ERROR: Build [{op}] returns None')
|
||||
return ChangeSet()
|
||||
|
||||
css.append(r)
|
||||
|
||||
except:
|
||||
return ChangeSet()
|
||||
|
||||
try:
|
||||
return execute_command(name, DbChangeSet.from_list(css))
|
||||
except:
|
||||
return ChangeSet()
|
||||
@@ -22,21 +22,17 @@ from .s18_sources import set_source, add_source, delete_source
|
||||
from .s19_reactions import set_reaction, set_pipe_reaction, set_tank_reaction
|
||||
from .s20_mixing import set_mixing, add_mixing, delete_mixing
|
||||
from .s21_times import set_time
|
||||
#from .s22_report import *
|
||||
from .s23_options import set_option
|
||||
from .s23_options_v3 import set_option_v3
|
||||
#from .s24_coordinates import *
|
||||
from .s23_options_util import set_option, set_option_v3
|
||||
from .s25_vertices import set_vertex, add_vertex, delete_vertex
|
||||
from .s26_labels import set_label, add_label, delete_label
|
||||
from .s27_backdrop import set_backdrop
|
||||
# from .s28_end import *
|
||||
from .s29_scada_device import set_scada_device, add_scada_device, delete_scada_device
|
||||
from .s30_scada_device_data import set_scada_device_data, add_scada_device_data, delete_scada_device_data
|
||||
from .s31_scada_element import set_scada_element, add_scada_element, delete_scada_element
|
||||
from .del_cmd_raw import del_cascade_cmd
|
||||
from .batch_api_cs import rewrite_batch_api
|
||||
|
||||
|
||||
def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def _execute_add_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == s1_title:
|
||||
@@ -113,7 +109,7 @@ def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def _execute_update_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == s1_title:
|
||||
@@ -190,7 +186,7 @@ def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
|
||||
|
||||
def execute_delete_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def _execute_delete_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == s1_title:
|
||||
@@ -268,13 +264,9 @@ def execute_delete_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
|
||||
|
||||
def execute_batch_commands(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
# for delete, generate cascade command
|
||||
new_cs = ChangeSet()
|
||||
for op in cs.operations:
|
||||
if op['operation'] == API_DELETE:
|
||||
new_cs.merge(del_cascade_cmd(name, ChangeSet(op)))
|
||||
else:
|
||||
new_cs.merge(ChangeSet(op))
|
||||
new_cs.merge(rewrite_batch_api(name, ChangeSet(op)))
|
||||
|
||||
result = ChangeSet()
|
||||
|
||||
@@ -285,11 +277,11 @@ def execute_batch_commands(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
todo = op
|
||||
operation = op['operation']
|
||||
if operation == API_ADD:
|
||||
result.merge(execute_add_command(name, ChangeSet(op)))
|
||||
result.merge(_execute_add_command(name, ChangeSet(op)))
|
||||
elif operation == API_UPDATE:
|
||||
result.merge(execute_update_command(name, ChangeSet(op)))
|
||||
result.merge(_execute_update_command(name, ChangeSet(op)))
|
||||
elif operation == API_DELETE:
|
||||
result.merge(execute_delete_command(name, ChangeSet(op)))
|
||||
result.merge(_execute_delete_command(name, ChangeSet(op)))
|
||||
except:
|
||||
print(f'ERROR: Fail to execute {todo}')
|
||||
|
||||
@@ -300,13 +292,9 @@ def execute_batch_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
write(name, 'delete from batch_operation where id > 0')
|
||||
write(name, "update operation_table set option = 'batch_operation' where option = 'operation'")
|
||||
|
||||
# for delete, generate cascade command
|
||||
new_cs = ChangeSet()
|
||||
for op in cs.operations:
|
||||
if op['operation'] == API_DELETE:
|
||||
new_cs.merge(del_cascade_cmd(name, ChangeSet(op)))
|
||||
else:
|
||||
new_cs.merge(ChangeSet(op))
|
||||
new_cs.merge(rewrite_batch_api(name, ChangeSet(op)))
|
||||
|
||||
result = ChangeSet()
|
||||
|
||||
@@ -317,11 +305,11 @@ def execute_batch_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
todo = op
|
||||
operation = op['operation']
|
||||
if operation == API_ADD:
|
||||
result.merge(execute_add_command(name, ChangeSet(op)))
|
||||
result.merge(_execute_add_command(name, ChangeSet(op)))
|
||||
elif operation == API_UPDATE:
|
||||
result.merge(execute_update_command(name, ChangeSet(op)))
|
||||
result.merge(_execute_update_command(name, ChangeSet(op)))
|
||||
elif operation == API_DELETE:
|
||||
result.merge(execute_delete_command(name, ChangeSet(op)))
|
||||
result.merge(_execute_delete_command(name, ChangeSet(op)))
|
||||
except:
|
||||
print(f'ERROR: Fail to execute {todo}')
|
||||
|
||||
45
api/clean_api.py
Normal file
45
api/clean_api.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from .database import ChangeSet, read_all
|
||||
from .batch_exe import execute_batch_command
|
||||
|
||||
# TODO: merge to batch_api
|
||||
|
||||
def clean_scada_device_cs(name: str) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
rows = read_all(name, 'select id from scada_device acs')
|
||||
for row in rows:
|
||||
cs.delete({ 'type': 'scada_device', 'id': row['id'] })
|
||||
|
||||
return cs
|
||||
|
||||
|
||||
def clean_scada_device_data_cs(name: str) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
rows = read_all(name, 'select distinct device_id from scada_device_data acs')
|
||||
for row in rows:
|
||||
cs.update({ 'type': 'scada_device_data', 'device_id': row['device_id'], 'data': [] })
|
||||
|
||||
return cs
|
||||
|
||||
|
||||
def clean_scada_element_cs(name: str) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
rows = read_all(name, 'select id from scada_element acs')
|
||||
for row in rows:
|
||||
cs.delete({ 'type': 'scada_element', 'id': row['id'] })
|
||||
|
||||
return cs
|
||||
|
||||
|
||||
def clean_scada_device(name: str) -> ChangeSet:
|
||||
return execute_batch_command(name, clean_scada_device_cs(name))
|
||||
|
||||
|
||||
def clean_scada_device_data(name: str) -> ChangeSet:
|
||||
return execute_batch_command(name, clean_scada_device_data_cs(name))
|
||||
|
||||
|
||||
def clean_scada_element(name: str) -> ChangeSet:
|
||||
return execute_batch_command(name, clean_scada_element_cs(name))
|
||||
@@ -1,65 +0,0 @@
|
||||
from .del_cmd_raw import *
|
||||
from .batch_cmd import execute_batch_command
|
||||
from .s29_scada_device import clean_scada_device_cmd
|
||||
from .s30_scada_device_data import clean_scada_device_data_cmd
|
||||
from .s31_scada_element import clean_scada_element_cmd
|
||||
|
||||
|
||||
def delete_junction_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'junction' }
|
||||
#raw_cmd = delete_junction_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_reservoir_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'reservoir' }
|
||||
#raw_cmd = delete_reservoir_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_tank_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'tank' }
|
||||
#raw_cmd = delete_tank_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_pipe_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'pipe' }
|
||||
#raw_cmd = delete_pipe_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_pump_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'pump' }
|
||||
#raw_cmd = delete_pump_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_valve_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'valve' }
|
||||
#raw_cmd = delete_valve_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_pattern_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'pattern' }
|
||||
#raw_cmd = delete_pattern_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def delete_curve_cascade(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0] |= { 'operation' : API_DELETE, 'type' : 'curve' }
|
||||
#raw_cmd = delete_curve_cascade_batch_cmd(name, cs)
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def clean_scada_device(name: str) -> ChangeSet:
|
||||
return execute_batch_command(name, clean_scada_device_cmd(name))
|
||||
|
||||
|
||||
def clean_scada_device_data(name: str) -> ChangeSet:
|
||||
return execute_batch_command(name, clean_scada_device_data_cmd(name))
|
||||
|
||||
|
||||
def clean_scada_element(name: str) -> ChangeSet:
|
||||
return execute_batch_command(name, clean_scada_element_cmd(name))
|
||||
@@ -40,7 +40,9 @@ def dump_inp(project: str, inp: str, version: str = '3'):
|
||||
if not have_project(project):
|
||||
return
|
||||
|
||||
if not is_project_open(project):
|
||||
project_open = is_project_open(project)
|
||||
|
||||
if not project_open:
|
||||
open_project(project)
|
||||
|
||||
dir = os.getcwd()
|
||||
@@ -154,7 +156,8 @@ def dump_inp(project: str, inp: str, version: str = '3'):
|
||||
|
||||
file.close()
|
||||
|
||||
close_project(project)
|
||||
if not project_open:
|
||||
close_project(project)
|
||||
|
||||
|
||||
def export_inp(project: str, version: str = '3') -> ChangeSet:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from psycopg.rows import dict_row, Row
|
||||
from .connection import g_conn_dict as conn
|
||||
from .database import read
|
||||
|
||||
|
||||
_NODE = '_node'
|
||||
@@ -105,3 +106,14 @@ def get_node_links(name: str, id: str) -> list[str]:
|
||||
for p in cur.execute(f"select id from valves where node1 = '{id}' or node2 = '{id}'").fetchall():
|
||||
links.append(p['id'])
|
||||
return links
|
||||
|
||||
|
||||
def get_link_nodes(name: str, id: str) -> list[str]:
|
||||
row = {}
|
||||
if is_pipe(name, id):
|
||||
row = read(name, f"select node1, node2 from pipes where id = '{id}'")
|
||||
elif is_pump(name, id):
|
||||
row = read(name, f"select node1, node2 from pumps where id = '{id}'")
|
||||
elif is_valve(name, id):
|
||||
row = read(name, f"select node1, node2 from valves where id = '{id}'")
|
||||
return [str(row['node1']), str(row['node2'])]
|
||||
|
||||
@@ -39,7 +39,7 @@ class Status(object):
|
||||
return { 'type': self.type, 'link': self.link, 'status': self.status, 'setting': self.setting }
|
||||
|
||||
|
||||
def set_status_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_status(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Status(get_status(name, cs.operations[0]['link']))
|
||||
raw_new = get_status(name, cs.operations[0]['link'])
|
||||
|
||||
@@ -65,7 +65,7 @@ def set_status_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_status(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_status_cmd(name, cs))
|
||||
return execute_command(name, _set_status(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -21,7 +21,7 @@ def get_pattern(name: str, id: str) -> dict[str, Any]:
|
||||
return { 'id': id, 'factors': ps }
|
||||
|
||||
|
||||
def set_pattern_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_pattern(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
f_id = f"'{id}'"
|
||||
|
||||
@@ -53,10 +53,10 @@ def set_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pattern(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_pattern_cmd(name, cs))
|
||||
return execute_command(name, _set_pattern(name, cs))
|
||||
|
||||
|
||||
def add_pattern_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_pattern(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
f_id = f"'{id}'"
|
||||
|
||||
@@ -81,10 +81,10 @@ def add_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pattern(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_pattern_cmd(name, cs))
|
||||
return execute_command(name, _add_pattern(name, cs))
|
||||
|
||||
|
||||
def delete_pattern_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_pattern(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
f_id = f"'{id}'"
|
||||
|
||||
@@ -109,7 +109,7 @@ def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pattern(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_pattern_cmd(name, cs))
|
||||
return execute_command(name, _delete_pattern(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -30,7 +30,7 @@ def get_curve(name: str, id: str) -> dict[str, Any]:
|
||||
return d
|
||||
|
||||
|
||||
def set_curve_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_curve(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
f_id = f"'{id}'"
|
||||
|
||||
@@ -72,10 +72,10 @@ def set_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_curve(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_curve_cmd(name, cs))
|
||||
return execute_command(name, _set_curve(name, cs))
|
||||
|
||||
|
||||
def add_curve_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_curve(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
f_id = f"'{id}'"
|
||||
|
||||
@@ -104,10 +104,10 @@ def add_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_curve(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_curve_cmd(name, cs))
|
||||
return execute_command(name, _add_curve(name, cs))
|
||||
|
||||
|
||||
def delete_curve_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_curve(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
f_id = f"'{id}'"
|
||||
|
||||
@@ -134,7 +134,7 @@ def delete_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_curve(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_curve_cmd(name, cs))
|
||||
return execute_command(name, _delete_curve(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -13,7 +13,7 @@ def get_control(name: str) -> dict[str, Any]:
|
||||
return { 'controls': ds }
|
||||
|
||||
|
||||
def set_control_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_control(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = get_control(name)
|
||||
|
||||
redo_sql = 'delete from controls;'
|
||||
@@ -31,7 +31,7 @@ def set_control_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_control(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_control_cmd(name, cs))
|
||||
return execute_command(name, _set_control(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -13,7 +13,7 @@ def get_rule(name: str) -> dict[str, Any]:
|
||||
return { 'rules': ds }
|
||||
|
||||
|
||||
def set_rule_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_rule(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = get_rule(name)
|
||||
|
||||
redo_sql = 'delete from rules;'
|
||||
@@ -31,7 +31,7 @@ def set_rule_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_rule(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_rule_cmd(name, cs))
|
||||
return execute_command(name, _set_rule(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -19,7 +19,7 @@ def get_energy(name: str) -> dict[str, Any]:
|
||||
return d
|
||||
|
||||
|
||||
def set_energy_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_energy(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
raw_old = get_energy(name)
|
||||
|
||||
old = {}
|
||||
@@ -54,7 +54,7 @@ def set_energy_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_energy(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_energy_cmd(name, cs))
|
||||
return execute_command(name, _set_energy(name, cs))
|
||||
|
||||
|
||||
def get_pump_energy_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
@@ -94,7 +94,7 @@ class PumpEnergy(object):
|
||||
return { 'type': self.type, 'pump': self.pump, 'price': self.price, 'pattern': self.pattern, 'effic': self.effic }
|
||||
|
||||
|
||||
def set_pump_energy_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_pump_energy(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = PumpEnergy(get_pump_energy(name, cs.operations[0]['pump']))
|
||||
raw_new = get_pump_energy(name, cs.operations[0]['pump'])
|
||||
|
||||
@@ -128,7 +128,7 @@ def set_pump_energy_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_pump_energy(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_pump_energy_cmd(name, cs))
|
||||
return execute_command(name, _set_pump_energy(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -30,7 +30,7 @@ class Emitter(object):
|
||||
return { 'type': self.type, 'junction': self.junction, 'coefficient': self.coefficient }
|
||||
|
||||
|
||||
def set_emitter_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_emitter(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Emitter(get_emitter(name, cs.operations[0]['junction']))
|
||||
raw_new = get_emitter(name, cs.operations[0]['junction'])
|
||||
|
||||
@@ -56,7 +56,7 @@ def set_emitter_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_emitter(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_emitter_cmd(name, cs))
|
||||
return execute_command(name, _set_emitter(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -30,7 +30,7 @@ class Quality(object):
|
||||
return { 'type': self.type, 'node': self.node, 'quality': self.quality }
|
||||
|
||||
|
||||
def set_quality_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_quality(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Quality(get_quality(name, cs.operations[0]['node']))
|
||||
raw_new = get_quality(name, cs.operations[0]['node'])
|
||||
|
||||
@@ -56,7 +56,7 @@ def set_quality_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_quality(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_quality_cmd(name, cs))
|
||||
return execute_command(name, _set_quality(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -46,7 +46,7 @@ class Source(object):
|
||||
return { 'type': self.type, 'node': self.node }
|
||||
|
||||
|
||||
def set_source_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_source(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Source(get_source(name, cs.operations[0]['node']))
|
||||
raw_new = get_source(name, cs.operations[0]['node'])
|
||||
|
||||
@@ -67,10 +67,10 @@ def set_source_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_source(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_source_cmd(name, cs))
|
||||
return execute_command(name, _set_source(name, cs))
|
||||
|
||||
|
||||
def add_source_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_source(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Source(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into sources (node, type, strength, pattern) values ({new.f_node}, {new.f_s_type}, {new.f_strength}, {new.f_pattern});"
|
||||
@@ -83,10 +83,10 @@ def add_source_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def add_source(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, add_source_cmd(name, cs))
|
||||
return execute_command(name, _add_source(name, cs))
|
||||
|
||||
|
||||
def delete_source_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_source(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Source(get_source(name, cs.operations[0]['node']))
|
||||
|
||||
redo_sql = f"delete from sources where node = {old.f_node};"
|
||||
@@ -99,7 +99,7 @@ def delete_source_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def delete_source(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_source_cmd(name, cs))
|
||||
return execute_command(name, _delete_source(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -22,7 +22,7 @@ def get_reaction(name: str) -> dict[str, Any]:
|
||||
return d
|
||||
|
||||
|
||||
def set_reaction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_reaction(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
raw_old = get_reaction(name)
|
||||
|
||||
old = {}
|
||||
@@ -57,7 +57,7 @@ def set_reaction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_reaction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_reaction_cmd(name, cs))
|
||||
return execute_command(name, _set_reaction(name, cs))
|
||||
|
||||
|
||||
def get_pipe_reaction_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
@@ -92,7 +92,7 @@ class PipeReaction(object):
|
||||
return { 'type': self.type, 'pipe': self.pipe, 'bulk': self.bulk, 'wall': self.wall }
|
||||
|
||||
|
||||
def set_pipe_reaction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_pipe_reaction(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = PipeReaction(get_pipe_reaction(name, cs.operations[0]['pipe']))
|
||||
raw_new = get_pipe_reaction(name, cs.operations[0]['pipe'])
|
||||
|
||||
@@ -122,7 +122,7 @@ def set_pipe_reaction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_pipe_reaction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_pipe_reaction_cmd(name, cs))
|
||||
return execute_command(name, _set_pipe_reaction(name, cs))
|
||||
|
||||
|
||||
def get_tank_reaction_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
@@ -152,7 +152,7 @@ class TankReaction(object):
|
||||
return { 'type': self.type, 'tank': self.tank, 'value': self.value }
|
||||
|
||||
|
||||
def set_tank_reaction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_tank_reaction(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = TankReaction(get_tank_reaction(name, cs.operations[0]['tank']))
|
||||
raw_new = get_tank_reaction(name, cs.operations[0]['tank'])
|
||||
|
||||
@@ -178,7 +178,7 @@ def set_tank_reaction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_tank_reaction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_tank_reaction_cmd(name, cs))
|
||||
return execute_command(name, _set_tank_reaction(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -10,7 +10,7 @@ def get_title(name: str) -> dict[str, Any]:
|
||||
return { 'value': title['value'] }
|
||||
|
||||
|
||||
def set_title_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_title(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = cs.operations[0]['value']
|
||||
old = get_title(name)['value']
|
||||
|
||||
@@ -24,7 +24,7 @@ def set_title_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_title(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_title_cmd(name ,cs))
|
||||
return execute_command(name, _set_title(name ,cs))
|
||||
|
||||
|
||||
def inp_in_title(section: list[str]) -> str:
|
||||
|
||||
@@ -42,7 +42,7 @@ class Mixing(object):
|
||||
return { 'type': self.type, 'tank': self.tank }
|
||||
|
||||
|
||||
def set_mixing_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_mixing(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Mixing(get_mixing(name, cs.operations[0]['tank']))
|
||||
raw_new = get_mixing(name, cs.operations[0]['tank'])
|
||||
|
||||
@@ -67,10 +67,10 @@ def set_mixing(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_mixing(name, cs.operations[0]['tank']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_mixing_cmd(name, cs))
|
||||
return execute_command(name, _set_mixing(name, cs))
|
||||
|
||||
|
||||
def add_mixing_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_mixing(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Mixing(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into mixing (tank, model, value) values ({new.f_tank}, {new.f_model}, {new.f_value});"
|
||||
@@ -87,10 +87,10 @@ def add_mixing(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_mixing(name, cs.operations[0]['tank']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_mixing_cmd(name, cs))
|
||||
return execute_command(name, _add_mixing(name, cs))
|
||||
|
||||
|
||||
def delete_mixing_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_mixing(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Mixing(get_mixing(name, cs.operations[0]['tank']))
|
||||
|
||||
redo_sql = f"delete from mixing where tank = {old.f_tank};"
|
||||
@@ -107,7 +107,7 @@ def delete_mixing(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_mixing(name, cs.operations[0]['tank']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_mixing_cmd(name, cs))
|
||||
return execute_command(name, _delete_mixing(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -29,7 +29,7 @@ def get_time(name: str) -> dict[str, Any]:
|
||||
return d
|
||||
|
||||
|
||||
def set_time_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_time(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
raw_old = get_time(name)
|
||||
|
||||
old = {}
|
||||
@@ -64,7 +64,7 @@ def set_time_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_time(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_time_cmd(name, cs))
|
||||
return execute_command(name, _set_time(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
from .database import *
|
||||
from .s23_options_util import get_option_schema, generate_v3
|
||||
from .batch_cmd import execute_batch_command
|
||||
|
||||
|
||||
def set_option(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0]['operation'] = API_UPDATE
|
||||
cs.operations[0]['type'] = 'option'
|
||||
new_cs = cs
|
||||
new_cs.merge(generate_v3(cs))
|
||||
return execute_batch_command(name, new_cs)
|
||||
|
||||
|
||||
def _inp_in_option(section: list[str]) -> ChangeSet:
|
||||
|
||||
@@ -106,7 +106,7 @@ def get_option(name: str) -> dict[str, Any]:
|
||||
return d
|
||||
|
||||
|
||||
def set_option_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_option(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
raw_old = get_option(name)
|
||||
|
||||
old = {}
|
||||
@@ -140,9 +140,8 @@ def set_option_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs])
|
||||
|
||||
|
||||
def set_option_only(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
v2_cmd = set_option_cmd(name, cs)
|
||||
return execute_command(name, v2_cmd)
|
||||
def set_option(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, _set_option(name, cs))
|
||||
|
||||
|
||||
OPTION_V3_FLOW_UNITS_CFS = OPTION_UNITS_CFS
|
||||
@@ -231,7 +230,7 @@ def get_option_v3(name: str) -> dict[str, Any]:
|
||||
return d
|
||||
|
||||
|
||||
def set_option_v3_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_option_v3(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
raw_old = get_option_v3(name)
|
||||
|
||||
old = {}
|
||||
@@ -265,9 +264,8 @@ def set_option_v3_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs])
|
||||
|
||||
|
||||
def set_option_v3_only(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
v3_cmd = set_option_v3_cmd(name, cs)
|
||||
return execute_command(name, v3_cmd)
|
||||
def set_option_v3(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, _set_option_v3(name, cs))
|
||||
|
||||
|
||||
_key_map_23 = {
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
from .database import *
|
||||
from .s23_options_util import get_option_schema, get_option_v3_schema, generate_v2, generate_v3
|
||||
from .batch_cmd import execute_batch_command
|
||||
|
||||
|
||||
def set_option_v3(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
cs.operations[0]['operation'] = API_UPDATE
|
||||
cs.operations[0]['type'] = 'option_v3'
|
||||
new_cs = cs
|
||||
new_cs.merge(generate_v2(cs))
|
||||
return execute_batch_command(name, new_cs)
|
||||
|
||||
|
||||
def _parse_v2(v2_lines: list[str]) -> dict[str, str]:
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
from .database import *
|
||||
|
||||
|
||||
def _to_client_point(coord: str) -> dict[str, float]:
|
||||
xy = coord.removeprefix('(').removesuffix(')').split(',')
|
||||
def sql_update_coord(node: str, x: float, y: float) -> str:
|
||||
coord = f"st_geomfromtext('point({x} {y})')"
|
||||
return f"update coordinates set coord = {coord} where node = '{node}';"
|
||||
|
||||
|
||||
def sql_insert_coord(node: str, x: float, y: float) -> str:
|
||||
coord = f"st_geomfromtext('point({x} {y})')"
|
||||
return f"insert into coordinates (node, coord) values ('{node}', {coord});"
|
||||
|
||||
|
||||
def sql_delete_coord(node: str) -> str:
|
||||
return f"delete from coordinates where node = '{node}';"
|
||||
|
||||
|
||||
def from_postgis_point(coord: str) -> dict[str, float]:
|
||||
xy = coord.lower().removeprefix('point(').removesuffix(')').split(' ')
|
||||
return { 'x': float(xy[0]), 'y': float(xy[1]) }
|
||||
|
||||
|
||||
def get_node_coord(name: str, id: str) -> dict[str, float]:
|
||||
row = try_read(name, f"select * from coordinates where node = '{id}'")
|
||||
def get_node_coord(name: str, node: str) -> dict[str, float]:
|
||||
row = try_read(name, f"select st_astext(coord) as coord_geom from coordinates where node = '{node}'")
|
||||
if row == None:
|
||||
write(name, f"insert into coordinates (node, coord) values ('{id}', '(0.0,0.0)');")
|
||||
write(name, sql_insert_coord(node, 0.0, 0.0))
|
||||
return {'x': 0.0, 'y': 0.0}
|
||||
return _to_client_point(row['coord'])
|
||||
return from_postgis_point(row['coord_geom'])
|
||||
|
||||
|
||||
def node_has_coord(name: str, node: str) -> bool:
|
||||
return try_read(name, f"select node from coordinates where node = '{node}'") != None
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
@@ -24,16 +42,16 @@ def get_node_coord(name: str, id: str) -> dict[str, float]:
|
||||
def inp_in_coord(line: str) -> str:
|
||||
tokens = line.split()
|
||||
node = tokens[0]
|
||||
coord = f"'({tokens[1]}, {tokens[2]})'"
|
||||
coord = f"st_geomfromtext('point({tokens[1]} {tokens[2]})')"
|
||||
return f"insert into coordinates (node, coord) values ('{node}', {coord});"
|
||||
|
||||
|
||||
def inp_out_coord(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from coordinates')
|
||||
objs = read_all(name, 'select node, st_astext(coord) as coord_geom from coordinates')
|
||||
for obj in objs:
|
||||
node = obj['node']
|
||||
coord = _to_client_point(obj['coord'])
|
||||
coord = from_postgis_point(obj['coord_geom'])
|
||||
x = coord['x']
|
||||
y = coord['y']
|
||||
lines.append(f'{node} {x} {y}')
|
||||
|
||||
@@ -16,7 +16,7 @@ def get_vertex(name: str, link: str) -> dict[str, Any]:
|
||||
return { 'link': link, 'coords': cs }
|
||||
|
||||
|
||||
def set_vertex_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_vertex(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
link = cs.operations[0]['link']
|
||||
|
||||
old = get_vertex(name, link)
|
||||
@@ -44,34 +44,34 @@ def set_vertex_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_vertex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = set_vertex_cmd(name, cs)
|
||||
result = _set_vertex(name, cs)
|
||||
result.redo_cs[0] |= g_update_prefix
|
||||
result.undo_cs[0] |= g_update_prefix
|
||||
return execute_command(name, result)
|
||||
|
||||
|
||||
def add_vertex_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
result = set_vertex_cmd(name, cs)
|
||||
def _add_vertex(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
result = _set_vertex(name, cs)
|
||||
result.redo_cs[0] |= g_add_prefix
|
||||
result.undo_cs[0] |= g_delete_prefix
|
||||
return result
|
||||
|
||||
|
||||
def delete_vertex_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_vertex(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
cs.operations[0]['coords'] = []
|
||||
result = set_vertex_cmd(name, cs)
|
||||
result = _set_vertex(name, cs)
|
||||
result.redo_cs[0] |= g_delete_prefix
|
||||
result.undo_cs[0] |= g_add_prefix
|
||||
return result
|
||||
|
||||
|
||||
def add_vertex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = add_vertex_cmd(name, cs)
|
||||
result = _add_vertex(name, cs)
|
||||
return execute_command(name, result)
|
||||
|
||||
|
||||
def delete_vertex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = delete_vertex_cmd(name, cs)
|
||||
result = _delete_vertex(name, cs)
|
||||
return execute_command(name, result)
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class Label(object):
|
||||
return { 'type': self.type, 'x': self.x, 'y': self.y }
|
||||
|
||||
|
||||
def set_label_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_label(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Label(get_label(name, cs.operations[0]['x'], cs.operations[0]['y']))
|
||||
raw_new = get_label(name, cs.operations[0]['x'], cs.operations[0]['y'])
|
||||
|
||||
@@ -64,10 +64,10 @@ def set_label_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_label(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_label_cmd(name, cs))
|
||||
return execute_command(name, _set_label(name, cs))
|
||||
|
||||
|
||||
def add_label_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_label(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Label(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into labels (x, y, label, node) values ({new.f_x}, {new.f_y}, {new.f_label}, {new.f_node});"
|
||||
@@ -80,10 +80,10 @@ def add_label_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def add_label(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, add_label_cmd(name, cs))
|
||||
return execute_command(name, _add_label(name, cs))
|
||||
|
||||
|
||||
def delete_label_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_label(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Label(get_label(name, cs.operations[0]['x'], cs.operations[0]['y']))
|
||||
|
||||
redo_sql = f"delete from labels where x = {old.f_x} and y = {old.f_y};"
|
||||
@@ -96,7 +96,7 @@ def delete_label_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def delete_label(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_label_cmd(name, cs))
|
||||
return execute_command(name, _delete_label(name, cs))
|
||||
|
||||
|
||||
def inp_in_label(line: str) -> str:
|
||||
|
||||
@@ -10,7 +10,7 @@ def get_backdrop(name: str) -> dict[str, Any]:
|
||||
return { 'content': e['content'] }
|
||||
|
||||
|
||||
def set_backdrop_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_backdrop(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = get_backdrop(name)
|
||||
|
||||
redo_sql = f"update backdrop set content = '{cs.operations[0]['content']}' where content = '{old['content']}';"
|
||||
@@ -23,7 +23,7 @@ def set_backdrop_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_backdrop(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_backdrop_cmd(name, cs))
|
||||
return execute_command(name, _set_backdrop(name, cs))
|
||||
|
||||
|
||||
def inp_in_backdrop(section: list[str]) -> str:
|
||||
|
||||
@@ -56,7 +56,7 @@ class ScadaDevice(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_scada_device_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_scada_device(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = ScadaDevice(get_scada_device(name, cs.operations[0]['id']))
|
||||
raw_new = get_scada_device(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -79,10 +79,10 @@ def set_scada_device_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def set_scada_device(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if get_scada_device(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_scada_device_cmd(name, cs))
|
||||
return execute_command(name, _set_scada_device(name, cs))
|
||||
|
||||
|
||||
def add_scada_device_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_scada_device(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = ScadaDevice(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into scada_device (id, name, address, type) values ({new.f_id}, {new.f_name}, {new.f_address}, {new.f_sd_type});"
|
||||
@@ -97,10 +97,10 @@ def add_scada_device_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def add_scada_device(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if get_scada_device(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_scada_device_cmd(name, cs))
|
||||
return execute_command(name, _add_scada_device(name, cs))
|
||||
|
||||
|
||||
def delete_scada_device_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_scada_device(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = ScadaDevice(get_scada_device(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from scada_device where id = {old.f_id};"
|
||||
@@ -115,14 +115,4 @@ def delete_scada_device_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def delete_scada_device(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if get_scada_device(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_scada_device_cmd(name, cs))
|
||||
|
||||
|
||||
def clean_scada_device_cmd(name: str) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
rows = read_all(name, 'select id from scada_device acs')
|
||||
for row in rows:
|
||||
cs.delete({ 'type': 'scada_device', 'id': row['id'] })
|
||||
|
||||
return cs
|
||||
return execute_command(name, _delete_scada_device(name, cs))
|
||||
|
||||
@@ -35,7 +35,6 @@ class Junction(object):
|
||||
|
||||
self.f_type = f"'{self.type}'"
|
||||
self.f_id = f"'{self.id}'"
|
||||
self.f_coord = f"'({self.x}, {self.y})'"
|
||||
self.f_elevation = self.elevation
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
@@ -45,7 +44,7 @@ class Junction(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_junction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_junction(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Junction(get_junction(name, cs.operations[0]['id']))
|
||||
raw_new = get_junction(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -57,9 +56,9 @@ def set_junction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Junction(raw_new)
|
||||
|
||||
redo_sql = f"update junctions set elevation = {new.f_elevation} where id = {new.f_id};"
|
||||
redo_sql += f"\nupdate coordinates set coord = {new.f_coord} where node = {new.f_id};"
|
||||
redo_sql += f"\n{sql_update_coord(new.id, new.x, new.y)}"
|
||||
|
||||
undo_sql = f"update coordinates set coord = {old.f_coord} where node = {old.f_id};"
|
||||
undo_sql = sql_update_coord(old.id, old.x, old.y)
|
||||
undo_sql += f"\nupdate junctions set elevation = {old.f_elevation} where id = {old.f_id};"
|
||||
|
||||
redo_cs = g_update_prefix | new.as_dict()
|
||||
@@ -73,17 +72,17 @@ def set_junction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_junction(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_junction_cmd(name, cs))
|
||||
return execute_command(name, _set_junction(name, cs))
|
||||
|
||||
|
||||
def add_junction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_junction(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Junction(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _node (id, type) values ({new.f_id}, {new.f_type});"
|
||||
redo_sql += f"\ninsert into junctions (id, elevation) values ({new.f_id}, {new.f_elevation});"
|
||||
redo_sql += f"\ninsert into coordinates (node, coord) values ({new.f_id}, {new.f_coord});"
|
||||
redo_sql += f"\n{sql_insert_coord(new.id, new.x, new.y)}"
|
||||
|
||||
undo_sql = f"delete from coordinates where node = {new.f_id};"
|
||||
undo_sql = sql_delete_coord(new.id)
|
||||
undo_sql += f"\ndelete from junctions where id = {new.f_id};"
|
||||
undo_sql += f"\ndelete from _node where id = {new.f_id};"
|
||||
|
||||
@@ -98,19 +97,19 @@ def add_junction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_junction(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_junction_cmd(name, cs))
|
||||
return execute_command(name, _add_junction(name, cs))
|
||||
|
||||
|
||||
def delete_junction_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_junction(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Junction(get_junction(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from coordinates where node = {old.f_id};"
|
||||
redo_sql = sql_delete_coord(old.id)
|
||||
redo_sql += f"\ndelete from junctions where id = {old.f_id};"
|
||||
redo_sql += f"\ndelete from _node where id = {old.f_id};"
|
||||
|
||||
undo_sql = f"insert into _node (id, type) values ({old.f_id}, {old.f_type});"
|
||||
undo_sql += f"\ninsert into junctions (id, elevation) values ({old.f_id}, {old.f_elevation});"
|
||||
undo_sql += f"\ninsert into coordinates (node, coord) values ({old.f_id}, {old.f_coord});"
|
||||
undo_sql += f"\n{sql_insert_coord(old.id, old.x, old.y)}"
|
||||
|
||||
redo_cs = g_delete_prefix | old.as_id_dict()
|
||||
undo_cs = g_add_prefix | old.as_dict()
|
||||
@@ -123,7 +122,7 @@ def delete_junction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_junction(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_junction_cmd(name, cs))
|
||||
return execute_command(name, _delete_junction(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -16,7 +16,7 @@ def get_scada_device_data(name: str, device_id: str) -> dict[str, Any]:
|
||||
return { 'device_id': device_id, 'data': ds }
|
||||
|
||||
|
||||
def set_scada_device_data_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_scada_device_data(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
device_id = cs.operations[0]['device_id']
|
||||
|
||||
old = get_scada_device_data(name, device_id)
|
||||
@@ -45,10 +45,10 @@ def set_scada_device_data_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_scada_device_data(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_scada_device_data_cmd(name, cs))
|
||||
return execute_command(name, _set_scada_device_data(name, cs))
|
||||
|
||||
|
||||
def add_scada_device_data_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_scada_device_data(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
values = cs.operations[0]
|
||||
device_id = values['device_id']
|
||||
time = values['time']
|
||||
@@ -66,10 +66,10 @@ def add_scada_device_data(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
row = try_read(name, f"select * from scada_device_data where device_id = '{cs.operations[0]['device_id']}' and time = '{cs.operations[0]['time']}'")
|
||||
if row != None:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_scada_device_data_cmd(name, cs))
|
||||
return execute_command(name, _add_scada_device_data(name, cs))
|
||||
|
||||
|
||||
def delete_scada_device_data_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_scada_device_data(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
values = cs.operations[0]
|
||||
device_id = values['device_id']
|
||||
time = values['time']
|
||||
@@ -87,14 +87,4 @@ def delete_scada_device_data(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
row = try_read(name, f"select * from scada_device_data where device_id = '{cs.operations[0]['device_id']}' and time = '{cs.operations[0]['time']}'")
|
||||
if row == None:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_scada_device_data_cmd(name, cs))
|
||||
|
||||
|
||||
def clean_scada_device_data_cmd(name: str) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
rows = read_all(name, 'select distinct device_id from scada_device_data acs')
|
||||
for row in rows:
|
||||
cs.update({ 'type': 'scada_device_data', 'device_id': row['device_id'], 'data': [] })
|
||||
|
||||
return cs
|
||||
return execute_command(name, _delete_scada_device_data(name, cs))
|
||||
|
||||
@@ -114,7 +114,7 @@ class ScadaModel(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_scada_element_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_scada_element(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = ScadaModel(get_scada_element(name, cs.operations[0]['id']))
|
||||
raw_new = get_scada_element(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -139,10 +139,10 @@ def set_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if _check_model(name, cs) == False:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_scada_element_cmd(name, cs))
|
||||
return execute_command(name, _set_scada_element(name, cs))
|
||||
|
||||
|
||||
def add_scada_element_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_scada_element(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = ScadaModel(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into scada_element (id, x, y, device_id, model_id, model_type, status) values ({new.f_id}, {new.f_x}, {new.f_y}, {new.f_device_id}, {new.f_model_id}, {new.f_model_type}, {new.f_status});"
|
||||
@@ -159,10 +159,10 @@ def add_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if _check_model(name, cs) == False:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_scada_element_cmd(name, cs))
|
||||
return execute_command(name, _add_scada_element(name, cs))
|
||||
|
||||
|
||||
def delete_scada_element_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_scada_element(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = ScadaModel(get_scada_element(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from scada_element where id = {old.f_id};"
|
||||
@@ -177,14 +177,4 @@ def delete_scada_element_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def delete_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if get_scada_element(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_scada_element_cmd(name, cs))
|
||||
|
||||
|
||||
def clean_scada_element_cmd(name: str) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
|
||||
rows = read_all(name, 'select id from scada_element acs')
|
||||
for row in rows:
|
||||
cs.delete({ 'type': 'scada_element', 'id': row['id'] })
|
||||
|
||||
return cs
|
||||
return execute_command(name, _delete_scada_element(name, cs))
|
||||
|
||||
248
api/s32_region_util.py
Normal file
248
api/s32_region_util.py
Normal file
@@ -0,0 +1,248 @@
|
||||
import ctypes
|
||||
import platform
|
||||
import os
|
||||
import math
|
||||
from typing import Any
|
||||
from .s0_base import get_node_links, get_link_nodes, is_pipe
|
||||
from .s5_pipes import get_pipe
|
||||
from .database import read, try_read, read_all, write
|
||||
from .s24_coordinates import node_has_coord, get_node_coord
|
||||
|
||||
|
||||
def from_postgis_polygon(polygon: str) -> list[tuple[float, float]]:
|
||||
boundary = polygon.lower().removeprefix('polygon((').removesuffix('))').split(',')
|
||||
xys = []
|
||||
for pt in boundary:
|
||||
xy = pt.split(' ')
|
||||
xys.append((float(xy[0]), float(xy[1])))
|
||||
return xys
|
||||
|
||||
|
||||
def to_postgis_polygon(boundary: list[tuple[float, float]]) -> str:
|
||||
polygon = ''
|
||||
for pt in boundary:
|
||||
polygon += f'{pt[0]} {pt[1]},'
|
||||
return f'polygon(({polygon[:-1]}))'
|
||||
|
||||
|
||||
def get_nodes_in_boundary(name: str, boundary: list[tuple[float, float]]) -> list[str]:
|
||||
api = 'get_nodes_in_boundary'
|
||||
write(name, f"delete from temp_region where id = '{api}'")
|
||||
write(name, f"insert into temp_region (id, boundary) values ('{api}', '{to_postgis_polygon(boundary)}')")
|
||||
|
||||
nodes: list[str] = []
|
||||
for row in read_all(name, f"select c.node from coordinates as c, temp_region as r where ST_Intersects(c.coord, r.boundary) and r.id = '{api}'"):
|
||||
nodes.append(row['node'])
|
||||
|
||||
write(name, f"delete from temp_region where id = '{api}'")
|
||||
|
||||
return nodes
|
||||
|
||||
|
||||
def get_nodes_in_region(name: str, region_id: str) -> list[str]:
|
||||
nodes: list[str] = []
|
||||
for row in read_all(name, f"select c.node from coordinates as c, region as r where ST_Intersects(c.coord, r.boundary) and r.id = '{region_id}'"):
|
||||
nodes.append(row['node'])
|
||||
return nodes
|
||||
|
||||
|
||||
def calculate_convex_hull(name: str, nodes: list[str]) -> list[tuple[float, float]]:
|
||||
write(name, f'delete from temp_node')
|
||||
for node in nodes:
|
||||
write(name, f"insert into temp_node values ('{node}')")
|
||||
|
||||
# TODO: check none
|
||||
polygon = read(name, f'select st_astext(st_convexhull(st_collect(array(select coord from coordinates where node in (select * from temp_node))))) as boundary' )['boundary']
|
||||
write(name, f'delete from temp_node')
|
||||
|
||||
return from_postgis_polygon(polygon)
|
||||
|
||||
|
||||
def _verify_platform():
|
||||
_platform = platform.system()
|
||||
if _platform != "Windows":
|
||||
raise Exception(f'Platform {_platform} unsupported (not yet)')
|
||||
|
||||
|
||||
def _normal(v: tuple[float, float]) -> tuple[float, float]:
|
||||
l = math.sqrt(v[0] * v[0] + v[1] * v[1])
|
||||
return (v[0] / l, v[1] / l)
|
||||
|
||||
|
||||
def _angle(v: tuple[float, float]) -> float:
|
||||
if v[0] >= 0 and v[1] >= 0:
|
||||
return math.asin(v[1])
|
||||
elif v[0] <= 0 and v[1] >= 0:
|
||||
return math.pi - math.asin(v[1])
|
||||
elif v[0] <= 0 and v[1] <= 0:
|
||||
return math.asin(-v[1]) + math.pi
|
||||
elif v[0] >= 0 and v[1] <= 0:
|
||||
return math.pi * 2 - math.asin(-v[1])
|
||||
return 0
|
||||
|
||||
|
||||
def _angle_of_node_link(node: str, link: str, nodes, links) -> float:
|
||||
n1 = node
|
||||
n2 = links[link]['node1'] if n1 == links[link]['node2'] else links[link]['node2']
|
||||
x1, y1 = nodes[n1]['x'], nodes[n1]['y']
|
||||
x2, y2 = nodes[n2]['x'], nodes[n2]['y']
|
||||
v = _normal((x2 - x1, y2 - y1))
|
||||
return _angle(v)
|
||||
|
||||
|
||||
class Topology:
|
||||
def __init__(self, db: str, nodes: list[str]) -> None:
|
||||
self._nodes: dict[str, Any] = {}
|
||||
self._max_x_node = ''
|
||||
self._node_list: list[str] = []
|
||||
for node in nodes:
|
||||
if not node_has_coord(db, node):
|
||||
continue
|
||||
if get_node_links(db, node) == 0:
|
||||
continue
|
||||
self._nodes[node] = get_node_coord(db, node) | { 'links': [] }
|
||||
self._node_list.append(node)
|
||||
if self._max_x_node == '' or self._nodes[node]['x'] > self._nodes[self._max_x_node]['x']:
|
||||
self._max_x_node = node
|
||||
|
||||
self._links = {}
|
||||
self._link_list: list[str] = []
|
||||
for node in self._nodes:
|
||||
for link in get_node_links(db, node):
|
||||
candidate = True
|
||||
link_nodes = get_link_nodes(db, link)
|
||||
for link_node in link_nodes:
|
||||
if link_node not in self._nodes:
|
||||
candidate = False
|
||||
break
|
||||
if candidate:
|
||||
length = get_pipe(db, link)['length'] if is_pipe(db, link) else 0.0
|
||||
self._links[link] = { 'node1' : link_nodes[0], 'node2' : link_nodes[1], 'length' : length }
|
||||
self._link_list.append(link)
|
||||
if link not in self._nodes[link_nodes[0]]['links']:
|
||||
self._nodes[link_nodes[0]]['links'].append(link)
|
||||
if link not in self._nodes[link_nodes[1]]['links']:
|
||||
self._nodes[link_nodes[1]]['links'].append(link)
|
||||
|
||||
def nodes(self):
|
||||
return self._nodes
|
||||
|
||||
def node_list(self):
|
||||
return self._node_list
|
||||
|
||||
def max_x_node(self):
|
||||
return self._max_x_node
|
||||
|
||||
def links(self):
|
||||
return self._links
|
||||
|
||||
def link_list(self):
|
||||
return self._link_list
|
||||
|
||||
|
||||
def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]:
|
||||
topology = Topology(name, nodes)
|
||||
t_nodes = topology.nodes()
|
||||
t_links = topology.links()
|
||||
|
||||
cursor = topology.max_x_node()
|
||||
in_angle = 0
|
||||
|
||||
paths: list[str] = []
|
||||
while True:
|
||||
#print(cursor)
|
||||
paths.append(cursor)
|
||||
sorted_links = []
|
||||
overlapped_link = ''
|
||||
for link in t_nodes[cursor]['links']:
|
||||
angle = _angle_of_node_link(cursor, link, t_nodes, t_links)
|
||||
if angle == in_angle:
|
||||
overlapped_link = link
|
||||
continue
|
||||
sorted_links.append((angle, link))
|
||||
|
||||
# work into a branch, return
|
||||
if len(sorted_links) == 0:
|
||||
cursor = paths[-2]
|
||||
in_angle = in_angle = _angle_of_node_link(cursor, overlapped_link, t_nodes, t_links)
|
||||
continue
|
||||
|
||||
sorted_links = sorted(sorted_links, key=lambda s:s[0])
|
||||
out_link = sorted_links[0][1]
|
||||
for angle, link in sorted_links:
|
||||
if angle > in_angle:
|
||||
out_link = link
|
||||
break
|
||||
|
||||
cursor = t_links[out_link]['node1'] if cursor == t_links[out_link]['node2'] else t_links[out_link]['node2']
|
||||
# end up trip :)
|
||||
if cursor == topology.max_x_node():
|
||||
paths.append(cursor)
|
||||
break
|
||||
|
||||
in_angle = _angle_of_node_link(cursor, out_link, t_nodes, t_links)
|
||||
|
||||
boundary: list[tuple[float, float]] = []
|
||||
for node in paths:
|
||||
boundary.append((t_nodes[node]['x'], t_nodes[node]['y']))
|
||||
|
||||
return boundary
|
||||
|
||||
|
||||
'''
|
||||
# CClipper2.dll
|
||||
# int inflate_paths(double* path, size_t size, double delta, int jt, int et, double miter_limit, int precision, double arc_tolerance, double** out_path, size_t* out_size);
|
||||
# int simplify_paths(double* path, size_t size, double epsilon, int is_closed_path, double** out_path, size_t* out_size);
|
||||
# void free_paths(double** paths);
|
||||
'''
|
||||
def inflate_boundary(name: str, boundary: list[tuple[float, float]], delta: float = 0.5) -> list[tuple[float, float]]:
|
||||
if boundary[0] == boundary[-1]:
|
||||
del(boundary[-1])
|
||||
|
||||
lib = ctypes.CDLL(os.path.join(os.getcwd(), 'api', 'CClipper2.dll'))
|
||||
|
||||
c_size = ctypes.c_size_t(len(boundary) * 2)
|
||||
c_path = (ctypes.c_double * c_size.value)()
|
||||
i = 0
|
||||
for xy in boundary:
|
||||
c_path[i] = xy[0]
|
||||
i += 1
|
||||
c_path[i] = xy[1]
|
||||
i += 1
|
||||
c_delta = ctypes.c_double(delta)
|
||||
JoinType_Square, JoinType_Round, JoinType_Miter = 0, 1, 2
|
||||
c_jt = ctypes.c_int(JoinType_Square)
|
||||
EndType_Polygon, EndType_Joined, EndType_Butt, EndType_Square, EndType_Round = 0, 1, 2, 3, 4
|
||||
c_et = ctypes.c_int(EndType_Polygon)
|
||||
c_miter_limit = ctypes.c_double(2.0)
|
||||
c_precision = ctypes.c_int(2)
|
||||
c_arc_tolerance = ctypes.c_double(0.0)
|
||||
c_out_path = ctypes.POINTER(ctypes.c_double)()
|
||||
c_out_size = ctypes.c_size_t(0)
|
||||
|
||||
lib.inflate_paths(c_path, c_size, c_delta, c_jt, c_et, c_miter_limit, c_precision, c_arc_tolerance, ctypes.byref(c_out_path), ctypes.byref(c_out_size))
|
||||
if c_out_size.value == 0:
|
||||
lib.free_paths(ctypes.byref(c_out_path))
|
||||
return []
|
||||
|
||||
# TODO: simplify_paths :)
|
||||
|
||||
result: list[tuple[float, float]] = []
|
||||
for i in range(0, c_out_size.value, 2):
|
||||
result.append((c_out_path[i], c_out_path[i + 1]))
|
||||
result.append(result[0])
|
||||
|
||||
lib.free_paths(ctypes.byref(c_out_path))
|
||||
return result
|
||||
|
||||
|
||||
def inflate_region(name: str, region_id: str, delta: float = 0.5) -> list[tuple[float, float]]:
|
||||
r = try_read(name, f"select id, st_astext(boundary) as boundary_geom from region where id = '{region_id}'")
|
||||
if r == None:
|
||||
return []
|
||||
boundary = from_postgis_polygon(str(r['boundary_geom']))
|
||||
return inflate_boundary(name, boundary, delta)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
_verify_platform()
|
||||
83
api/s33_region.py
Normal file
83
api/s33_region.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from .database import *
|
||||
from .s32_region_util import from_postgis_polygon, to_postgis_polygon
|
||||
|
||||
def get_region_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return { 'id' : {'type': 'str' , 'optional': False , 'readonly': True },
|
||||
'boundary' : {'type': 'tuple_list' , 'optional': False , 'readonly': False} }
|
||||
|
||||
|
||||
def get_region(name: str, id: str) -> dict[str, Any]:
|
||||
r = try_read(name, f"select id, st_astext(boundary) as boundary_geom from region where id = '{id}'")
|
||||
if r == None:
|
||||
return {}
|
||||
d = {}
|
||||
d['id'] = str(r['id'])
|
||||
d['boundary'] = from_postgis_polygon(str(r['boundary_geom']))
|
||||
return d
|
||||
|
||||
|
||||
def _set_region(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
new = cs.operations[0]['boundary']
|
||||
old = get_region(name, id)['boundary']
|
||||
|
||||
redo_sql = f"update region set boundary = st_geomfromtext('{to_postgis_polygon(new)}') where id = '{id}';"
|
||||
undo_sql = f"update region set boundary = st_geomfromtext('{to_postgis_polygon(old)}') where id = '{id}';"
|
||||
redo_cs = g_update_prefix | { 'type': 'region', 'id': id, 'boundary': new }
|
||||
undo_cs = g_update_prefix | { 'type': 'region', 'id': id, 'boundary': old }
|
||||
|
||||
return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs])
|
||||
|
||||
|
||||
def set_region(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if 'id' not in cs.operations[0] or 'boundary' not in cs.operations[0]:
|
||||
return ChangeSet()
|
||||
b = cs.operations[0]['boundary']
|
||||
if len(b) < 4 or b[0] != b[-1]:
|
||||
return ChangeSet()
|
||||
if get_region(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, _set_region(name, cs))
|
||||
|
||||
|
||||
def _add_region(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
new = cs.operations[0]['boundary']
|
||||
|
||||
redo_sql = f"insert into region (id, boundary) values ('{id}', '{to_postgis_polygon(new)}');"
|
||||
undo_sql = f"delete from region where id = '{id}';"
|
||||
redo_cs = g_add_prefix | { 'type': 'region', 'id': id, 'boundary': new }
|
||||
undo_cs = g_delete_prefix | { 'type': 'region', 'id': id }
|
||||
|
||||
return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs])
|
||||
|
||||
|
||||
def add_region(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if 'id' not in cs.operations[0] or 'boundary' not in cs.operations[0]:
|
||||
return ChangeSet()
|
||||
b = cs.operations[0]['boundary']
|
||||
if len(b) < 4 or b[0] != b[-1]:
|
||||
return ChangeSet()
|
||||
if get_region(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, _add_region(name, cs))
|
||||
|
||||
|
||||
def _delete_region(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
id = cs.operations[0]['id']
|
||||
old = get_region(name, id)['boundary']
|
||||
|
||||
redo_sql = f"delete from region where id = '{id}';"
|
||||
undo_sql = f"insert into region (id, boundary) values ('{id}', '{to_postgis_polygon(old)}');"
|
||||
redo_cs = g_delete_prefix | { 'type': 'region', 'id': id }
|
||||
undo_cs = g_add_prefix | { 'type': 'region', 'id': id, 'boundary': old }
|
||||
|
||||
return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs])
|
||||
|
||||
|
||||
def delete_region(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if 'id' not in cs.operations[0]:
|
||||
return ChangeSet()
|
||||
if get_region(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, _delete_region(name, cs))
|
||||
52
api/s34_water_distribution.py
Normal file
52
api/s34_water_distribution.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from .database import ChangeSet
|
||||
from .s0_base import is_junction
|
||||
from .s9_demands import get_demand
|
||||
from .s32_region_util import Topology, get_nodes_in_region
|
||||
from .batch_exe import execute_batch_command
|
||||
|
||||
DISTRIBUTION_TYPE_ADD = 'ADD'
|
||||
DISTRIBUTION_TYPE_OVERRIDE = 'OVERRIDE'
|
||||
|
||||
def distribute_demand_to_nodes(name: str, demand: float, nodes: list[str], type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet:
|
||||
if len(nodes) == 0 or demand == 0.0:
|
||||
return ChangeSet()
|
||||
if type != DISTRIBUTION_TYPE_ADD and type != DISTRIBUTION_TYPE_OVERRIDE:
|
||||
return ChangeSet()
|
||||
|
||||
topology = Topology(name, nodes)
|
||||
t_nodes = topology.nodes()
|
||||
t_links = topology.links()
|
||||
|
||||
length_sum = 0.0
|
||||
for value in t_links.values():
|
||||
length_sum += abs(value['length'])
|
||||
|
||||
if length_sum <= 0.0:
|
||||
return ChangeSet()
|
||||
|
||||
demand_per_length = demand / length_sum
|
||||
|
||||
cs = ChangeSet()
|
||||
|
||||
for node, value in t_nodes.items():
|
||||
if not is_junction(name, node):
|
||||
continue
|
||||
demand_per_node = 0.0
|
||||
for link in value['links']:
|
||||
demand_per_node += abs(t_links[link]['length']) * demand_per_length * 0.5
|
||||
|
||||
ds = get_demand(name, node)['demands']
|
||||
if len(ds) == 0:
|
||||
ds = [{'demand': demand_per_node, 'pattern': None, 'category': None}]
|
||||
elif type == DISTRIBUTION_TYPE_ADD:
|
||||
ds[0]['demand'] += demand_per_node
|
||||
else:
|
||||
ds[0]['demand'] = demand_per_node
|
||||
cs.update({'type': 'demand', 'junction': node, 'demands': ds})
|
||||
|
||||
return execute_batch_command(name, cs)
|
||||
|
||||
|
||||
def distribute_demand_to_region(name: str, demand: float, region: str, type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet:
|
||||
nodes = get_nodes_in_region(name, region)
|
||||
return distribute_demand_to_nodes(name, demand, nodes, type)
|
||||
85
api/s35_district_metering_area.py
Normal file
85
api/s35_district_metering_area.py
Normal file
@@ -0,0 +1,85 @@
|
||||
import ctypes
|
||||
import os
|
||||
from .database import *
|
||||
from .s32_region_util import Topology
|
||||
|
||||
|
||||
PARTITION_TYPE_RB = 0
|
||||
PARTITION_TYPE_KWAY = 1
|
||||
|
||||
|
||||
def calculate_district_metering_area(name: str, nodes: list[str], part_count: int = 1, part_type: int = PARTITION_TYPE_RB) -> list[list[str]]:
|
||||
if part_type != PARTITION_TYPE_RB and part_type != PARTITION_TYPE_KWAY:
|
||||
return []
|
||||
if part_count <= 0:
|
||||
return []
|
||||
elif part_count == 1:
|
||||
return [nodes]
|
||||
|
||||
lib = ctypes.CDLL(os.path.join(os.getcwd(), 'api', 'CMetis.dll'))
|
||||
|
||||
METIS_NOPTIONS = 40
|
||||
c_options = (ctypes.c_int64 * METIS_NOPTIONS)()
|
||||
|
||||
METIS_OK = 1
|
||||
result = lib.set_default_options(c_options)
|
||||
if result != METIS_OK:
|
||||
return []
|
||||
|
||||
METIS_OPTION_PTYPE , METIS_OPTION_CONTIG = 0, 13
|
||||
c_options[METIS_OPTION_PTYPE] = part_type
|
||||
c_options[METIS_OPTION_CONTIG] = 1
|
||||
|
||||
topology = Topology(name, nodes)
|
||||
t_nodes = topology.nodes()
|
||||
t_links = topology.links()
|
||||
t_node_list = topology.node_list()
|
||||
t_link_list = topology.link_list()
|
||||
|
||||
nedges = len(t_link_list) * 2
|
||||
|
||||
c_nvtxs = ctypes.c_int64(len(t_node_list))
|
||||
c_ncon = ctypes.c_int64(1)
|
||||
c_xadj = (ctypes.c_int64 * (c_nvtxs.value + 1))()
|
||||
c_adjncy = (ctypes.c_int64 * nedges)()
|
||||
c_vwgt = (ctypes.c_int64 * (c_ncon.value * c_nvtxs.value))()
|
||||
c_adjwgt = (ctypes.c_int64 * nedges)()
|
||||
c_vsize = (ctypes.c_int64 * c_nvtxs.value)()
|
||||
|
||||
c_xadj[0] = 0
|
||||
|
||||
l, n = 0, 0
|
||||
c_xadj_i = 1
|
||||
for node in t_node_list:
|
||||
links = t_nodes[node]['links']
|
||||
for link in links:
|
||||
node1 = t_links[link]['node1']
|
||||
node2 = t_links[link]['node2']
|
||||
c_adjncy[l] = t_node_list.index(node2) if node2 != node else t_node_list.index(node1)
|
||||
c_adjwgt[l] = 1
|
||||
l += 1
|
||||
if len(links) > 0:
|
||||
c_xadj[c_xadj_i] = l # adjncy.size()
|
||||
c_xadj_i += 1
|
||||
c_vwgt[n] = 1
|
||||
c_vsize[n] = 1
|
||||
n += 1
|
||||
|
||||
part_func = lib.part_graph_recursive if part_type == PARTITION_TYPE_RB else lib.part_graph_kway
|
||||
|
||||
c_nparts = ctypes.c_int64(part_count)
|
||||
c_tpwgts = ctypes.POINTER(ctypes.c_double)()
|
||||
c_ubvec = ctypes.POINTER(ctypes.c_double)()
|
||||
c_out_edgecut = ctypes.c_int64(0)
|
||||
c_out_part = (ctypes.c_int64 * c_nvtxs.value)()
|
||||
result = part_func(ctypes.byref(c_nvtxs), ctypes.byref(c_ncon), c_xadj, c_adjncy, c_vwgt, c_vsize, c_adjwgt, ctypes.byref(c_nparts), c_tpwgts, c_ubvec, c_options, ctypes.byref(c_out_edgecut), c_out_part)
|
||||
if result != METIS_OK:
|
||||
return []
|
||||
|
||||
dmas : list[list[str]]= []
|
||||
for i in range(part_count):
|
||||
dmas.append([])
|
||||
for i in range(c_nvtxs.value):
|
||||
dmas[c_out_part[i]].append(t_node_list[i])
|
||||
|
||||
return dmas
|
||||
119
api/s36_service_area.py
Normal file
119
api/s36_service_area.py
Normal file
@@ -0,0 +1,119 @@
|
||||
import sys
|
||||
import json
|
||||
from queue import Queue
|
||||
from .database import *
|
||||
from .s0_base import get_node_links, get_link_nodes
|
||||
|
||||
sys.path.append('..')
|
||||
from epanet.epanet import run_project
|
||||
|
||||
def calculate_service_area(name: str, time_index: int = 0) -> dict[str, Any]:
|
||||
inp = json.loads(run_project(name))
|
||||
|
||||
time_count = len(inp['node_results'][0]['result'])
|
||||
if time_index >= time_count:
|
||||
return {}
|
||||
|
||||
sources : dict[str, list[str]] = {}
|
||||
for node_result in inp['node_results']:
|
||||
result = node_result['result'][time_index]
|
||||
if result['demand'] < 0:
|
||||
sources[node_result['node']] = []
|
||||
|
||||
link_flows: dict[str, float] = {}
|
||||
for link_result in inp['link_results']:
|
||||
result = link_result['result'][time_index]
|
||||
link_flows[link_result['link']] = float(result['flow'])
|
||||
|
||||
# build source to nodes map
|
||||
for source in sources:
|
||||
queue = Queue()
|
||||
queue.put(source)
|
||||
|
||||
while not queue.empty():
|
||||
cursor = queue.get()
|
||||
if cursor not in sources[source]:
|
||||
sources[source].append(cursor)
|
||||
|
||||
links = get_node_links(name, cursor)
|
||||
for link in links:
|
||||
node1, node2 = get_link_nodes(name, link)
|
||||
if node1 == cursor and link_flows[link] > 0:
|
||||
queue.put(node2)
|
||||
elif node2 == cursor and link_flows[link] < 0:
|
||||
queue.put(node1)
|
||||
|
||||
# calculation concentration
|
||||
concentration_map: dict[str, dict[str, float]] = {}
|
||||
node_wip: list[str] = []
|
||||
for source, nodes in sources.items():
|
||||
for node in nodes:
|
||||
if node not in concentration_map:
|
||||
concentration_map[node] = {}
|
||||
concentration_map[node][source] = 0.0
|
||||
if node not in node_wip:
|
||||
node_wip.append(node)
|
||||
|
||||
# if only one source, done
|
||||
for node, concentrations in concentration_map.items():
|
||||
if len(concentrations) == 1:
|
||||
node_wip.remove(node)
|
||||
for key in concentrations.keys():
|
||||
concentration_map[node][key] = 1.0
|
||||
|
||||
node_upstream : dict[str, list[tuple[str, str]]] = {}
|
||||
for node in node_wip:
|
||||
if node not in node_upstream:
|
||||
node_upstream[node] = []
|
||||
|
||||
links = get_node_links(name, node)
|
||||
for link in links:
|
||||
node1, node2 = get_link_nodes(name, link)
|
||||
if node2 == node and link_flows[link] > 0:
|
||||
node_upstream[node].append((link, node1))
|
||||
elif node1 == node and link_flows[link] < 0:
|
||||
node_upstream[node].append((link, node2))
|
||||
|
||||
while len(node_wip) != 0:
|
||||
done = []
|
||||
for node in node_wip:
|
||||
up_link_nodes = node_upstream[node]
|
||||
ready = True
|
||||
for link_node in up_link_nodes:
|
||||
if link_node in node_wip:
|
||||
ready = False
|
||||
break
|
||||
if ready:
|
||||
for link_node in up_link_nodes:
|
||||
for source, concentration in concentration_map[link_node[1]].items():
|
||||
concentration_map[node][source] += concentration * abs(link_flows[link_node[0]])
|
||||
|
||||
# normalize
|
||||
sum = 0.0
|
||||
for source, concentration in concentration_map[node].items():
|
||||
sum += concentration
|
||||
for source in concentration_map[node].keys():
|
||||
concentration_map[node][source] /= sum
|
||||
|
||||
done.append(node)
|
||||
|
||||
for node in done:
|
||||
node_wip.remove(node)
|
||||
|
||||
source_to_main_node: dict[str, list[str]] = {}
|
||||
for node, value in concentration_map.items():
|
||||
max_source = ''
|
||||
max_concentration = 0.0
|
||||
for s, c in value.items():
|
||||
if c > max_concentration:
|
||||
max_concentration = c
|
||||
max_source = s
|
||||
if max_source not in source_to_main_node:
|
||||
source_to_main_node[max_source] = []
|
||||
source_to_main_node[max_source].append(node)
|
||||
|
||||
sas: list[dict[str, Any]] = []
|
||||
for source, nodes in source_to_main_node.items():
|
||||
sas.append({ 'source': source, 'nodes': nodes })
|
||||
|
||||
return { 'service_areas' : sas, 'concentrations': concentration_map }
|
||||
66
api/s37_virtual_district.py
Normal file
66
api/s37_virtual_district.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from .database import *
|
||||
from .s0_base import get_node_links
|
||||
|
||||
|
||||
def calculate_virtual_district(name: str, centers: list[str]) -> dict[str, list[Any]]:
|
||||
write(name, 'delete from temp_vd_topology')
|
||||
|
||||
# map node name to index
|
||||
i = 0
|
||||
isolated_nodes = []
|
||||
node_index: dict[str, int] = {}
|
||||
for row in read_all(name, 'select id from _node'):
|
||||
node = str(row['id'])
|
||||
if get_node_links(name, node) == []:
|
||||
isolated_nodes.append(node)
|
||||
continue
|
||||
i += 1
|
||||
node_index[node] = i
|
||||
|
||||
# build topology graph
|
||||
pipes = read_all(name, 'select node1, node2, length from pipes')
|
||||
for pipe in pipes:
|
||||
source = node_index[str(pipe['node1'])]
|
||||
target = node_index[str(pipe['node2'])]
|
||||
cost = float(pipe['length'])
|
||||
write(name, f"insert into temp_vd_topology (source, target, cost) values ({source}, {target}, {cost})")
|
||||
pumps = read_all(name, 'select node1, node2 from pumps')
|
||||
for pump in pumps:
|
||||
source = node_index[str(pump['node1'])]
|
||||
target = node_index[str(pump['node2'])]
|
||||
write(name, f"insert into temp_vd_topology (source, target, cost) values ({source}, {target}, 0.0)")
|
||||
valves = read_all(name, 'select node1, node2 from valves')
|
||||
for valve in valves:
|
||||
source = node_index[str(valve['node1'])]
|
||||
target = node_index[str(valve['node2'])]
|
||||
write(name, f"insert into temp_vd_topology (source, target, cost) values ({source}, {target}, 0.0)")
|
||||
|
||||
# dijkstra distance
|
||||
node_distance: dict[str, dict[str, Any]] = {}
|
||||
for center in centers:
|
||||
for node, index in node_index.items():
|
||||
if node == center:
|
||||
node_distance[node] = { 'center': center, 'distance' : 0.0 }
|
||||
continue
|
||||
# TODO: check none
|
||||
distance = float(read(name, f"select max(agg_cost) as distance from pgr_dijkstraCost('select id, source, target, cost from temp_vd_topology', {index}, {node_index[center]}, false)")['distance'])
|
||||
if node not in node_distance:
|
||||
node_distance[node] = { 'center': center, 'distance' : distance }
|
||||
elif distance < node_distance[node]['distance']:
|
||||
node_distance[node] = { 'center': center, 'distance' : distance }
|
||||
|
||||
write(name, 'delete from temp_vd_topology')
|
||||
|
||||
# reorganize the distance result
|
||||
center_node: dict[str, list[str]] = {}
|
||||
for node, value in node_distance.items():
|
||||
if value['center'] not in center_node:
|
||||
center_node[value['center']] = []
|
||||
center_node[value['center']].append(node)
|
||||
|
||||
vds: list[dict[str, Any]] = []
|
||||
|
||||
for center, value in center_node.items():
|
||||
vds.append({ 'center': center, 'nodes': value })
|
||||
|
||||
return { 'virtual_districts': vds, 'isolated_nodes': isolated_nodes }
|
||||
@@ -38,7 +38,6 @@ class Reservoir(object):
|
||||
|
||||
self.f_type = f"'{self.type}'"
|
||||
self.f_id = f"'{self.id}'"
|
||||
self.f_coord = f"'({self.x}, {self.y})'"
|
||||
self.f_head = self.head
|
||||
self.f_pattern = f"'{self.pattern}'" if self.pattern != None else 'null'
|
||||
|
||||
@@ -49,7 +48,7 @@ class Reservoir(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_reservoir_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_reservoir(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Reservoir(get_reservoir(name, cs.operations[0]['id']))
|
||||
raw_new = get_reservoir(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -61,9 +60,9 @@ def set_reservoir_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Reservoir(raw_new)
|
||||
|
||||
redo_sql = f"update reservoirs set head = {new.f_head}, pattern = {new.f_pattern} where id = {new.f_id};"
|
||||
redo_sql += f"\nupdate coordinates set coord = {new.f_coord} where node = {new.f_id};"
|
||||
redo_sql += f"\n{sql_update_coord(new.id, new.x, new.y)}"
|
||||
|
||||
undo_sql = f"update coordinates set coord = {old.f_coord} where node = {old.f_id};"
|
||||
undo_sql = sql_update_coord(old.id, old.x, old.y)
|
||||
undo_sql += f"\nupdate reservoirs set head = {old.f_head}, pattern = {old.f_pattern} where id = {old.f_id};"
|
||||
|
||||
redo_cs = g_update_prefix | new.as_dict()
|
||||
@@ -77,17 +76,17 @@ def set_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_reservoir(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_reservoir_cmd(name, cs))
|
||||
return execute_command(name, _set_reservoir(name, cs))
|
||||
|
||||
|
||||
def add_reservoir_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_reservoir(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Reservoir(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _node (id, type) values ({new.f_id}, {new.f_type});"
|
||||
redo_sql += f"\ninsert into reservoirs (id, head, pattern) values ({new.f_id}, {new.f_head}, {new.f_pattern});"
|
||||
redo_sql += f"\ninsert into coordinates (node, coord) values ({new.f_id}, {new.f_coord});"
|
||||
redo_sql += f"\n{sql_insert_coord(new.id, new.x, new.y)}"
|
||||
|
||||
undo_sql = f"delete from coordinates where node = {new.f_id};"
|
||||
undo_sql = sql_delete_coord(new.id)
|
||||
undo_sql += f"\ndelete from reservoirs where id = {new.f_id};"
|
||||
undo_sql += f"\ndelete from _node where id = {new.f_id};"
|
||||
|
||||
@@ -102,19 +101,19 @@ def add_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_reservoir(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_reservoir_cmd(name, cs))
|
||||
return execute_command(name, _add_reservoir(name, cs))
|
||||
|
||||
|
||||
def delete_reservoir_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_reservoir(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Reservoir(get_reservoir(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from coordinates where node = {old.f_id};"
|
||||
redo_sql = sql_delete_coord(old.id)
|
||||
redo_sql += f"\ndelete from reservoirs where id = {old.f_id};"
|
||||
redo_sql += f"\ndelete from _node where id = {old.f_id};"
|
||||
|
||||
undo_sql = f"insert into _node (id, type) values ({old.f_id}, {old.f_type});"
|
||||
undo_sql += f"\ninsert into reservoirs (id, head, pattern) values ({old.f_id}, {old.f_head}, {old.f_pattern});"
|
||||
undo_sql += f"\ninsert into coordinates (node, coord) values ({old.f_id}, {old.f_coord});"
|
||||
undo_sql += f"\n{sql_insert_coord(old.id, old.x, old.y)}"
|
||||
|
||||
redo_cs = g_delete_prefix | old.as_id_dict()
|
||||
undo_cs = g_add_prefix | old.as_dict()
|
||||
@@ -127,7 +126,7 @@ def delete_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_reservoir(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_reservoir_cmd(name, cs))
|
||||
return execute_command(name, _delete_reservoir(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -60,7 +60,6 @@ class Tank(object):
|
||||
|
||||
self.f_type = f"'{self.type}'"
|
||||
self.f_id = f"'{self.id}'"
|
||||
self.f_coord = f"'({self.x}, {self.y})'"
|
||||
self.f_elevation = self.elevation
|
||||
self.f_init_level = self.init_level
|
||||
self.f_min_level = self.min_level
|
||||
@@ -77,7 +76,7 @@ class Tank(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_tank_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_tank(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Tank(get_tank(name, cs.operations[0]['id']))
|
||||
raw_new = get_tank(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -89,9 +88,9 @@ def set_tank_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Tank(raw_new)
|
||||
|
||||
redo_sql = f"update tanks set elevation = {new.f_elevation}, init_level = {new.f_init_level}, min_level = {new.f_min_level}, max_level = {new.f_max_level}, diameter = {new.f_diameter}, min_vol = {new.f_min_vol}, vol_curve = {new.f_vol_curve}, overflow = {new.f_overflow} where id = {new.f_id};"
|
||||
redo_sql += f"\nupdate coordinates set coord = {new.f_coord} where node = {new.f_id};"
|
||||
redo_sql += f"\n{sql_update_coord(new.id, new.x, new.y)}"
|
||||
|
||||
undo_sql = f"update coordinates set coord = {old.f_coord} where node = {old.f_id};"
|
||||
undo_sql = sql_update_coord(old.id, old.x, old.y)
|
||||
undo_sql += f"\nupdate tanks set elevation = {old.f_elevation}, init_level = {old.f_init_level}, min_level = {old.f_min_level}, max_level = {old.f_max_level}, diameter = {old.f_diameter}, min_vol = {old.f_min_vol}, vol_curve = {old.f_vol_curve}, overflow = {old.f_overflow} where id = {old.f_id};"
|
||||
|
||||
redo_cs = g_update_prefix | new.as_dict()
|
||||
@@ -105,17 +104,17 @@ def set_tank(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_tank(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_tank_cmd(name, cs))
|
||||
return execute_command(name, _set_tank(name, cs))
|
||||
|
||||
|
||||
def add_tank_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_tank(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Tank(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _node (id, type) values ({new.f_id}, {new.f_type});"
|
||||
redo_sql += f"\ninsert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ({new.f_id}, {new.f_elevation}, {new.f_init_level}, {new.f_min_level}, {new.f_max_level}, {new.f_diameter}, {new.f_min_vol}, {new.f_vol_curve}, {new.f_overflow});"
|
||||
redo_sql += f"\ninsert into coordinates (node, coord) values ({new.f_id}, {new.f_coord});"
|
||||
redo_sql += f"\n{sql_insert_coord(new.id, new.x, new.y)}"
|
||||
|
||||
undo_sql = f"delete from coordinates where node = {new.f_id};"
|
||||
undo_sql = sql_delete_coord(new.id)
|
||||
undo_sql += f"\ndelete from tanks where id = {new.f_id};"
|
||||
undo_sql += f"\ndelete from _node where id = {new.f_id};"
|
||||
|
||||
@@ -130,19 +129,19 @@ def add_tank(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_tank(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_tank_cmd(name, cs))
|
||||
return execute_command(name, _add_tank(name, cs))
|
||||
|
||||
|
||||
def delete_tank_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_tank(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Tank(get_tank(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from coordinates where node = {old.f_id};"
|
||||
redo_sql = sql_delete_coord(old.id)
|
||||
redo_sql += f"\ndelete from tanks where id = {old.f_id};"
|
||||
redo_sql += f"\ndelete from _node where id = {old.f_id};"
|
||||
|
||||
undo_sql = f"insert into _node (id, type) values ({old.f_id}, {old.f_type});"
|
||||
undo_sql += f"\ninsert into tanks (id, elevation, init_level, min_level, max_level, diameter, min_vol, vol_curve, overflow) values ({old.f_id}, {old.f_elevation}, {old.f_init_level}, {old.f_min_level}, {old.f_max_level}, {old.f_diameter}, {old.f_min_vol}, {old.f_vol_curve}, {old.f_overflow});"
|
||||
undo_sql += f"\ninsert into coordinates (node, coord) values ({old.f_id}, {old.f_coord});"
|
||||
undo_sql += f"\n{sql_insert_coord(old.id, old.x, old.y)}"
|
||||
|
||||
redo_cs = g_delete_prefix | old.as_id_dict()
|
||||
undo_cs = g_add_prefix | old.as_dict()
|
||||
@@ -155,7 +154,7 @@ def delete_tank(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_tank(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_tank_cmd(name, cs))
|
||||
return execute_command(name, _delete_tank(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -63,7 +63,7 @@ class Pipe(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_pipe_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_pipe(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Pipe(get_pipe(name, cs.operations[0]['id']))
|
||||
raw_new = get_pipe(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -88,10 +88,10 @@ def set_pipe(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pipe(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_pipe_cmd(name, cs))
|
||||
return execute_command(name, _set_pipe(name, cs))
|
||||
|
||||
|
||||
def add_pipe_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_pipe(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Pipe(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _link (id, type) values ({new.f_id}, {new.f_type});"
|
||||
@@ -111,10 +111,10 @@ def add_pipe(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pipe(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_pipe_cmd(name, cs))
|
||||
return execute_command(name, _add_pipe(name, cs))
|
||||
|
||||
|
||||
def delete_pipe_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_pipe(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Pipe(get_pipe(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from pipes where id = {old.f_id};"
|
||||
@@ -134,7 +134,7 @@ def delete_pipe(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pipe(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_pipe_cmd(name, cs))
|
||||
return execute_command(name, _delete_pipe(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -54,7 +54,7 @@ class Pump(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_pump_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_pump(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Pump(get_pump(name, cs.operations[0]['id']))
|
||||
raw_new = get_pump(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -79,10 +79,10 @@ def set_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pump(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_pump_cmd(name, cs))
|
||||
return execute_command(name, _set_pump(name, cs))
|
||||
|
||||
|
||||
def add_pump_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_pump(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Pump(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _link (id, type) values ({new.f_id}, {new.f_type});"
|
||||
@@ -102,10 +102,10 @@ def add_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pump(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_pump_cmd(name, cs))
|
||||
return execute_command(name, _add_pump(name, cs))
|
||||
|
||||
|
||||
def delete_pump_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_pump(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Pump(get_pump(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from pumps where id = {old.f_id};"
|
||||
@@ -125,7 +125,7 @@ def delete_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_pump(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_pump_cmd(name, cs))
|
||||
return execute_command(name, _delete_pump(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -62,7 +62,7 @@ class Valve(object):
|
||||
return { 'type': self.type, 'id': self.id }
|
||||
|
||||
|
||||
def set_valve_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_valve(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Valve(get_valve(name, cs.operations[0]['id']))
|
||||
raw_new = get_valve(name, cs.operations[0]['id'])
|
||||
|
||||
@@ -87,10 +87,10 @@ def set_valve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_valve(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_valve_cmd(name, cs))
|
||||
return execute_command(name, _set_valve(name, cs))
|
||||
|
||||
|
||||
def add_valve_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _add_valve(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
new = Valve(cs.operations[0])
|
||||
|
||||
redo_sql = f"insert into _link (id, type) values ({new.f_id}, {new.f_type});"
|
||||
@@ -110,10 +110,10 @@ def add_valve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_valve(name, cs.operations[0]['id']) != {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, add_valve_cmd(name, cs))
|
||||
return execute_command(name, _add_valve(name, cs))
|
||||
|
||||
|
||||
def delete_valve_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _delete_valve(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Valve(get_valve(name, cs.operations[0]['id']))
|
||||
|
||||
redo_sql = f"delete from valves where id = {old.f_id};"
|
||||
@@ -133,7 +133,7 @@ def delete_valve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return ChangeSet()
|
||||
if get_valve(name, cs.operations[0]['id']) == {}:
|
||||
return ChangeSet()
|
||||
return execute_command(name, delete_valve_cmd(name, cs))
|
||||
return execute_command(name, _delete_valve(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -53,7 +53,7 @@ class Tag(object):
|
||||
return { 'type': self.type, 't_type': self.t_type, 'id': self.id, 'tag': self.tag }
|
||||
|
||||
|
||||
def set_tag_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_tag(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
old = Tag(get_tag(name, cs.operations[0]['t_type'], cs.operations[0]['id']))
|
||||
raw_new = get_tag(name, cs.operations[0]['t_type'], cs.operations[0]['id'])
|
||||
|
||||
@@ -89,7 +89,7 @@ def set_tag_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def set_tag(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
if 't_type' not in cs.operations[0] or 'id' not in cs.operations[0] or 'tag' not in cs.operations[0]:
|
||||
return ChangeSet()
|
||||
return execute_command(name, set_tag_cmd(name, cs))
|
||||
return execute_command(name, _set_tag(name, cs))
|
||||
|
||||
|
||||
def inp_in_tag(line: str) -> str:
|
||||
|
||||
@@ -20,7 +20,7 @@ def get_demand(name: str, junction: str) -> dict[str, Any]:
|
||||
return { 'junction': junction, 'demands': ds }
|
||||
|
||||
|
||||
def set_demand_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
def _set_demand(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
junction = cs.operations[0]['junction']
|
||||
old = get_demand(name, junction)
|
||||
new = { 'junction': junction, 'demands': [] }
|
||||
@@ -56,7 +56,7 @@ def set_demand_cmd(name: str, cs: ChangeSet) -> DbChangeSet:
|
||||
|
||||
|
||||
def set_demand(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_demand_cmd(name, cs))
|
||||
return execute_command(name, _set_demand(name, cs))
|
||||
|
||||
|
||||
#--------------------------------------------------------------
|
||||
|
||||
@@ -33,11 +33,13 @@ sql_create = [
|
||||
"script/sql/create/29.scada_device.sql",
|
||||
"script/sql/create/30.scada_device_data.sql",
|
||||
"script/sql/create/31.scada_element.sql",
|
||||
"script/sql/create/32.region.sql",
|
||||
"script/sql/create/operation.sql"
|
||||
]
|
||||
|
||||
sql_drop = [
|
||||
"script/sql/drop/operation.sql",
|
||||
"script/sql/drop/32.region.sql",
|
||||
"script/sql/drop/31.scada_element.sql",
|
||||
"script/sql/drop/30.scada_device_data.sql",
|
||||
"script/sql/drop/29.scada_device.sql",
|
||||
@@ -78,6 +80,8 @@ def create_template():
|
||||
cur.execute("create database project")
|
||||
with pg.connect(conninfo="dbname=project host=127.0.0.1") as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute('create extension postgis cascade')
|
||||
cur.execute('create extension pgrouting cascade')
|
||||
for sql in sql_create:
|
||||
with open(sql, "r") as f:
|
||||
cur.execute(f.read())
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
create table coordinates
|
||||
(
|
||||
node varchar(32) primary key references _node(id)
|
||||
, coord point not null
|
||||
, coord geometry
|
||||
);
|
||||
|
||||
-- delete when delete node
|
||||
|
||||
create index coordinates_spgist on coordinates using spgist(coord);
|
||||
create index coordinates_gist on coordinates using gist(coord);
|
||||
|
||||
37
script/sql/create/32.region.sql
Normal file
37
script/sql/create/32.region.sql
Normal file
@@ -0,0 +1,37 @@
|
||||
create table region
|
||||
(
|
||||
id text primary key
|
||||
, boundary geometry not null unique
|
||||
);
|
||||
|
||||
create index region_gist on region using gist(boundary);
|
||||
|
||||
|
||||
create table temp_region
|
||||
(
|
||||
id text primary key
|
||||
, boundary geometry not null unique
|
||||
);
|
||||
|
||||
create index temp_region_gist on temp_region using gist(boundary);
|
||||
|
||||
|
||||
create table temp_node
|
||||
(
|
||||
node varchar(32) primary key references _node(id)
|
||||
);
|
||||
|
||||
|
||||
create table temp_link
|
||||
(
|
||||
link varchar(32) primary key references _link(id)
|
||||
);
|
||||
|
||||
|
||||
create table temp_vd_topology
|
||||
(
|
||||
id serial
|
||||
, source integer
|
||||
, target integer
|
||||
, cost numeric
|
||||
);
|
||||
@@ -2,6 +2,4 @@
|
||||
|
||||
drop index if exists coordinates_gist;
|
||||
|
||||
drop index if exists coordinates_spgist;
|
||||
|
||||
drop table if exists coordinates;
|
||||
|
||||
13
script/sql/drop/32.region.sql
Normal file
13
script/sql/drop/32.region.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
drop table if exists temp_vd_topology;
|
||||
|
||||
drop table if exists temp_link;
|
||||
|
||||
drop table if exists temp_node;
|
||||
|
||||
drop index if exists temp_region_gist;
|
||||
|
||||
drop table if exists temp_region;
|
||||
|
||||
drop index if exists region_gist;
|
||||
|
||||
drop table if exists region;
|
||||
File diff suppressed because one or more lines are too long
113
tjnetwork.py
113
tjnetwork.py
@@ -151,18 +151,26 @@ SCADA_DEVICE_TYPE_LEVEL = api.SCADA_DEVICE_TYPE_LEVEL
|
||||
SCADA_DEVICE_TYPE_FLOW = api.SCADA_DEVICE_TYPE_FLOW
|
||||
|
||||
|
||||
SCADA_MODEL_TYPE_JUNCTION = api.SCADA_MODEL_TYPE_JUNCTION
|
||||
SCADA_MODEL_TYPE_JUNCTION = api.SCADA_MODEL_TYPE_JUNCTION
|
||||
SCADA_MODEL_TYPE_RESERVOIR = api.SCADA_MODEL_TYPE_RESERVOIR
|
||||
SCADA_MODEL_TYPE_TANK = api.SCADA_MODEL_TYPE_TANK
|
||||
SCADA_MODEL_TYPE_PIPE = api.SCADA_MODEL_TYPE_PIPE
|
||||
SCADA_MODEL_TYPE_PUMP = api.SCADA_MODEL_TYPE_PUMP
|
||||
SCADA_MODEL_TYPE_VALVE = api.SCADA_MODEL_TYPE_VALVE
|
||||
SCADA_MODEL_TYPE_TANK = api.SCADA_MODEL_TYPE_TANK
|
||||
SCADA_MODEL_TYPE_PIPE = api.SCADA_MODEL_TYPE_PIPE
|
||||
SCADA_MODEL_TYPE_PUMP = api.SCADA_MODEL_TYPE_PUMP
|
||||
SCADA_MODEL_TYPE_VALVE = api.SCADA_MODEL_TYPE_VALVE
|
||||
|
||||
|
||||
SCADA_ELEMENT_STATUS_ONLINE = api.SCADA_ELEMENT_STATUS_ONLINE
|
||||
SCADA_ELEMENT_STATUS_OFFLINE = api.SCADA_ELEMENT_STATUS_OFFLINE
|
||||
|
||||
|
||||
DISTRIBUTION_TYPE_ADD = api.DISTRIBUTION_TYPE_ADD
|
||||
DISTRIBUTION_TYPE_OVERRIDE = api.DISTRIBUTION_TYPE_OVERRIDE
|
||||
|
||||
|
||||
PARTITION_TYPE_RB = api.PARTITION_TYPE_RB
|
||||
PARTITION_TYPE_KWAY = api.PARTITION_TYPE_KWAY
|
||||
|
||||
|
||||
############################################################
|
||||
# project
|
||||
############################################################
|
||||
@@ -300,6 +308,18 @@ def set_restore_operation_to_current(name: str) -> None:
|
||||
def restore(name: str, discard: bool = False) -> ChangeSet:
|
||||
return api.restore(name, discard)
|
||||
|
||||
def read(name: str, sql: str):
|
||||
return api.read(name, sql)
|
||||
|
||||
def try_read(name: str, sql: str):
|
||||
return api.try_read(name, sql)
|
||||
|
||||
def read_all(name: str, sql: str):
|
||||
return api.read_all(name, sql)
|
||||
|
||||
def write(name: str, sql: str):
|
||||
return api.write(name, sql)
|
||||
|
||||
|
||||
############################################################
|
||||
# type
|
||||
@@ -772,7 +792,7 @@ 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)
|
||||
return api.set_option_ex(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
@@ -786,7 +806,7 @@ def get_option_v3(name: str) -> dict[str, Any]:
|
||||
return api.get_option_v3(name)
|
||||
|
||||
def set_option_v3(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_option_v3(name, cs)
|
||||
return api.set_option_v3_ex(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
@@ -933,3 +953,82 @@ def delete_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
|
||||
def clean_scada_element(name: str) -> ChangeSet:
|
||||
return api.clean_scada_element(name)
|
||||
|
||||
|
||||
############################################################
|
||||
# region_util 32
|
||||
############################################################
|
||||
|
||||
def get_nodes_in_boundary(name: str, boundary: list[tuple[float, float]]) -> list[str]:
|
||||
return api.get_nodes_in_boundary(name, boundary)
|
||||
|
||||
def get_nodes_in_region(name: str, region_id: str) -> list[str]:
|
||||
return api.get_nodes_in_region(name, region_id)
|
||||
|
||||
def calculate_convex_hull(name: str, nodes: list[str]) -> list[tuple[float, float]]:
|
||||
return api.calculate_convex_hull(name, nodes)
|
||||
|
||||
def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]:
|
||||
return api.calculate_boundary(name, nodes)
|
||||
|
||||
def inflate_boundary(name: str, boundary: list[tuple[float, float]], delta: float = 0.5) -> list[tuple[float, float]]:
|
||||
return api.inflate_boundary(name, boundary, delta)
|
||||
|
||||
def inflate_region(name: str, region_id: str, delta: float = 0.5) -> list[tuple[float, float]]:
|
||||
return api.inflate_region(name, region_id, delta)
|
||||
|
||||
|
||||
############################################################
|
||||
# general_region 33
|
||||
############################################################
|
||||
|
||||
def get_region_schema(name: str) -> dict[str, dict[str, Any]]:
|
||||
return api.get_region_schema(name)
|
||||
|
||||
def get_region(name: str, id: str) -> dict[str, Any]:
|
||||
return api.get_region(name, id)
|
||||
|
||||
def set_region(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.set_region(name, cs)
|
||||
|
||||
# example: add_region(p, ChangeSet({'id': 'r', 'boundary': [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]}))
|
||||
def add_region(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.add_region(name, cs)
|
||||
|
||||
def delete_region(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return api.delete_region(name, cs)
|
||||
|
||||
|
||||
############################################################
|
||||
# water_distribution 34
|
||||
############################################################
|
||||
|
||||
def distribute_demand_to_nodes(name: str, demand: float, nodes: list[str], type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet:
|
||||
return api.distribute_demand_to_nodes(name, demand, nodes, type)
|
||||
|
||||
def distribute_demand_to_region(name: str, demand: float, region: str, type: str = DISTRIBUTION_TYPE_ADD) -> ChangeSet:
|
||||
return api.distribute_demand_to_region(name, demand, region, type)
|
||||
|
||||
|
||||
############################################################
|
||||
# district_metering_area 35
|
||||
############################################################
|
||||
|
||||
def calculate_district_metering_area(name: str, nodes: list[str], part_count: int = 1, part_type: int = PARTITION_TYPE_RB) -> list[list[str]]:
|
||||
return api.calculate_district_metering_area(name, nodes, part_count, part_type)
|
||||
|
||||
|
||||
############################################################
|
||||
# service_area 36
|
||||
############################################################
|
||||
|
||||
def calculate_service_area(name: str, time_index: int = 0) -> dict[str, Any]:
|
||||
return api.calculate_service_area(name, time_index)
|
||||
|
||||
|
||||
############################################################
|
||||
# virtual_district 37
|
||||
############################################################
|
||||
|
||||
def calculate_virtual_district(name: str, centers: list[str]) -> dict[str, list[Any]]:
|
||||
return api.calculate_virtual_district(name, centers)
|
||||
|
||||
Reference in New Issue
Block a user