- Update all submodule URLs from gitea.centraal.wbd-rd.nl to gitea.wbd-rd.nl - Add settler as proper submodule in .gitmodules - Add agent skills, function anchors, decisions, and improvements - Add Docker configuration and scripts - Add manuals and third_party docs - Update .gitignore with secrets and build artifacts - Remove stale .tgz build artifact Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
104 lines
2.8 KiB
JavaScript
104 lines
2.8 KiB
JavaScript
#!/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.`);
|