#!/usr/bin/env node /** * Add initial volume calibration inject nodes to the demo flow. * * Problem: All 3 pumping stations start with initial volume = minVol, * which is below the dryRun safety threshold. This causes the safety * guard to trigger immediately on every tick, preventing normal control. * * Fix: Add inject nodes that fire once at deploy, sending * calibratePredictedVolume to each PS with a reasonable starting volume. * * PS West: 500m3 basin, startLevel=2.5m → start at 200m3 (level 1.6m) * Below startLevel, pumps stay off. q_in fills basin naturally. * PS North: 200m3 basin, flowbased → start at 100m3 (50% fill) * PS South: 100m3 basin, manual → start at 50m3 (50% fill) */ 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')); // Check if calibration nodes already exist const existingCalib = flow.filter(n => n.id && n.id.startsWith('demo_inj_calib_')); if (existingCalib.length > 0) { console.log('Calibration nodes already exist:', existingCalib.map(n => n.id)); console.log('Removing existing calibration nodes first...'); for (const node of existingCalib) { const idx = flow.findIndex(n => n.id === node.id); if (idx !== -1) flow.splice(idx, 1); } } // Find the WWTP tab for positioning const wwtpTab = flow.find(n => n.id === 'demo_tab_wwtp'); if (!wwtpTab) { console.error('WWTP tab not found!'); process.exit(1); } // Calibration configs: { ps_id, name, volume, x, y } const calibrations = [ { id: 'demo_inj_calib_west', name: 'Cal: PS West → 200m3', target: 'demo_ps_west', volume: 200, x: 100, y: 50, }, { id: 'demo_inj_calib_north', name: 'Cal: PS North → 100m3', target: 'demo_ps_north', volume: 100, x: 100, y: 100, }, { id: 'demo_inj_calib_south', name: 'Cal: PS South → 50m3', target: 'demo_ps_south', volume: 50, x: 100, y: 150, }, ]; let added = 0; calibrations.forEach(cal => { const injectNode = { id: cal.id, type: 'inject', z: 'demo_tab_wwtp', name: cal.name, props: [ { p: 'payload', vt: 'num', }, { p: 'topic', vt: 'str', }, ], repeat: '', crontab: '', once: true, onceDelay: '0.5', topic: 'calibratePredictedVolume', payload: String(cal.volume), payloadType: 'num', x: cal.x, y: cal.y, wires: [[cal.target]], }; flow.push(injectNode); added++; console.log(`Added ${cal.id}: ${cal.name} → ${cal.target} (${cal.volume} m3)`); }); fs.writeFileSync(flowPath, JSON.stringify(flow, null, 2) + '\n'); console.log(`\nDone. ${added} calibration node(s) added.`);