#!/usr/bin/env node /** * Fix layout of demo-flow.json so nodes are nicely grouped and don't overlap. * * Layout structure (on demo_tab_wwtp): * * Row 1 (y=40-300): PS West section (comment, mode injects, pumps, MGC, PS, q_in sim) * Row 2 (y=340-500): PS North section * Row 3 (y=520-680): PS South section * Row 4 (y=720-920): Biological Treatment (measurements, reactor, settler, monster) * Row 5 (y=960-1120): Pressure Measurements section * Row 6 (y=1140-1440): Effluent measurements * Row 7 (y=1460+): Telemetry & Dashboard API * * Column layout: * x=140: Inject nodes (left) * x=370: Function nodes * x=580: Intermediate nodes (measurements feeding other nodes) * x=700: Main equipment nodes (PS, pumps, measurement nodes) * x=935: Link out nodes * x=1050+: Right side (reactor, settler, telemetry) */ const fs = require('fs'); const path = require('path'); const flowPath = path.join(__dirname, '..', 'docker', 'demo-flow.json'); const flow = JSON.parse(fs.readFileSync(flowPath, 'utf8')); function setPos(id, x, y) { const node = flow.find(n => n.id === id); if (node) { node.x = x; node.y = y; } else { console.warn('Layout: node not found:', id); } } // === PS West section (y: 40-300) === setPos('demo_comment_ps', 340, 40); // Mode + q_in injects (left column) setPos('demo_inj_w1_mode', 140, 80); setPos('demo_inj_w2_mode', 140, 260); setPos('demo_inj_west_mode', 140, 160); setPos('demo_inj_west_flow', 140, 200); // q_in function node setPos('demo_fn_west_flow_sim', 370, 200); // MGC sits between PS and pumps setPos('demo_pump_w1', 700, 100); setPos('demo_mgc_west', 700, 180); setPos('demo_pump_w2', 700, 260); setPos('demo_ps_west', 940, 180); // === PS North section (y: 340-500) === setPos('demo_comment_ps_north', 330, 340); setPos('demo_inj_n1_mode', 140, 380); setPos('demo_inj_north_mode', 140, 420); setPos('demo_inj_north_flow', 140, 460); setPos('demo_fn_north_flow_sim', 370, 460); // North outflow measurement setPos('demo_comment_north_outflow', 200, 500); setPos('demo_meas_ft_n1', 580, 500); setPos('demo_pump_n1', 700, 400); setPos('demo_ps_north', 940, 440); // === PS South section (y: 540-680) === setPos('demo_comment_ps_south', 320, 540); setPos('demo_inj_s1_mode', 140, 580); setPos('demo_inj_south_mode', 140, 620); setPos('demo_inj_south_flow', 140, 660); setPos('demo_fn_south_flow_sim', 370, 660); setPos('demo_pump_s1', 700, 580); setPos('demo_ps_south', 940, 620); // === Biological Treatment (y: 720-920) === setPos('demo_comment_treatment', 200, 720); setPos('demo_meas_flow', 700, 760); setPos('demo_meas_do', 700, 820); setPos('demo_meas_nh4', 700, 880); setPos('demo_reactor', 1100, 820); setPos('demo_inj_reactor_tick', 900, 760); setPos('demo_settler', 1100, 920); setPos('demo_monster', 1100, 1000); setPos('demo_inj_monster_flow', 850, 1000); setPos('demo_fn_monster_flow', 930, 1040); // === Pressure Measurements (y: 960-1120) — new section === setPos('demo_comment_pressure', 320, 960); // West pressure (grouped together) setPos('demo_fn_level_to_pressure_w', 370, 1000); setPos('demo_meas_pt_w_up', 580, 1000); setPos('demo_meas_pt_w_down', 580, 1040); // North pressure setPos('demo_fn_level_to_pressure_n', 370, 1080); setPos('demo_meas_pt_n_up', 580, 1080); setPos('demo_meas_pt_n_down', 580, 1120); // South pressure setPos('demo_fn_level_to_pressure_s', 370, 1160); setPos('demo_meas_pt_s_up', 580, 1160); setPos('demo_meas_pt_s_down', 580, 1200); // === Effluent Measurements (y: 1240-1520) === setPos('demo_comment_effluent_meas', 300, 1240); setPos('demo_meas_eff_flow', 700, 1280); setPos('demo_meas_eff_do', 700, 1340); setPos('demo_meas_eff_nh4', 700, 1400); setPos('demo_meas_eff_no3', 700, 1460); setPos('demo_meas_eff_tss', 700, 1520); // === Telemetry section (right side, y: 40-240) === setPos('demo_comment_telemetry', 1300, 40); setPos('demo_link_influx_out', 1135, 500); setPos('demo_link_influx_in', 1175, 100); setPos('demo_fn_influx_convert', 1350, 100); setPos('demo_http_influx', 1560, 100); setPos('demo_fn_influx_count', 1740, 100); // Process debug setPos('demo_comment_process_out', 1300, 160); setPos('demo_link_process_out', 1135, 540); setPos('demo_link_process_in', 1175, 200); setPos('demo_dbg_process', 1360, 200); setPos('demo_dbg_registration', 1370, 240); // Dashboard link outs setPos('demo_link_ps_west_dash', 1135, 160); setPos('demo_link_ps_north_dash', 1135, 420); setPos('demo_link_ps_south_dash', 1135, 600); setPos('demo_link_reactor_dash', 1300, 820); setPos('demo_link_meas_dash', 1135, 860); setPos('demo_link_eff_meas_dash', 1135, 1300); // Dashboard API setPos('demo_dashapi', 1100, 1100); setPos('demo_inj_dashapi', 850, 1100); setPos('demo_http_grafana', 1300, 1100); setPos('demo_dbg_grafana', 1500, 1100); // InfluxDB status link setPos('demo_link_influx_status_out', 1940, 100); fs.writeFileSync(flowPath, JSON.stringify(flow, null, 2) + '\n'); console.log('Layout fixed. Deploying...');