- 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>
143 lines
5.2 KiB
JavaScript
143 lines
5.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Check the deployed Node-RED flow for correctness after changes.
|
|
*/
|
|
const http = require('http');
|
|
|
|
function fetch(url) {
|
|
return new Promise((resolve, reject) => {
|
|
http.get(url, res => {
|
|
const chunks = [];
|
|
res.on('data', c => chunks.push(c));
|
|
res.on('end', () => resolve(JSON.parse(Buffer.concat(chunks))));
|
|
}).on('error', reject);
|
|
});
|
|
}
|
|
|
|
(async () => {
|
|
let errors = 0;
|
|
|
|
// 1. Check deployed flow structure
|
|
console.log('=== Checking deployed flow structure ===');
|
|
const flow = await fetch('http://localhost:1880/flows');
|
|
console.log('Total deployed nodes:', flow.length);
|
|
|
|
// Check MGC exists
|
|
const mgc = flow.find(n => n.id === 'demo_mgc_west');
|
|
if (mgc) {
|
|
console.log('PASS: MGC West exists, position:', mgc.positionVsParent);
|
|
} else {
|
|
console.log('FAIL: MGC West missing from deployed flow');
|
|
errors++;
|
|
}
|
|
|
|
// Check reactor speedUpFactor
|
|
const reactor = flow.find(n => n.id === 'demo_reactor');
|
|
if (reactor && reactor.speedUpFactor === 1) {
|
|
console.log('PASS: Reactor speedUpFactor = 1');
|
|
} else {
|
|
console.log('FAIL: Reactor speedUpFactor =', reactor?.speedUpFactor);
|
|
errors++;
|
|
}
|
|
|
|
// Check sim mode on measurements
|
|
const simMeasIds = [
|
|
'demo_meas_flow', 'demo_meas_do', 'demo_meas_nh4',
|
|
'demo_meas_ft_n1', 'demo_meas_eff_flow', 'demo_meas_eff_do',
|
|
'demo_meas_eff_nh4', 'demo_meas_eff_no3', 'demo_meas_eff_tss'
|
|
];
|
|
let simOk = 0;
|
|
simMeasIds.forEach(id => {
|
|
const n = flow.find(x => x.id === id);
|
|
if (n && n.simulator === true) simOk++;
|
|
else { console.log('FAIL: simulator not true on', id); errors++; }
|
|
});
|
|
console.log(`PASS: ${simOk}/9 measurement nodes have simulator=true`);
|
|
|
|
// Check pressure nodes exist
|
|
const ptIds = ['demo_meas_pt_w_up','demo_meas_pt_w_down','demo_meas_pt_n_up','demo_meas_pt_n_down','demo_meas_pt_s_up','demo_meas_pt_s_down'];
|
|
let ptOk = 0;
|
|
ptIds.forEach(id => {
|
|
const n = flow.find(x => x.id === id);
|
|
if (n && n.type === 'measurement') ptOk++;
|
|
else { console.log('FAIL: pressure node missing:', id); errors++; }
|
|
});
|
|
console.log(`PASS: ${ptOk}/6 pressure measurement nodes present`);
|
|
|
|
// Check removed nodes are gone
|
|
const removedIds = [
|
|
'demo_inj_meas_flow', 'demo_fn_sim_flow', 'demo_inj_meas_do', 'demo_fn_sim_do',
|
|
'demo_inj_meas_nh4', 'demo_fn_sim_nh4', 'demo_inj_ft_n1', 'demo_fn_sim_ft_n1',
|
|
'demo_inj_eff_flow', 'demo_fn_sim_eff_flow', 'demo_inj_eff_do', 'demo_fn_sim_eff_do',
|
|
'demo_inj_eff_nh4', 'demo_fn_sim_eff_nh4', 'demo_inj_eff_no3', 'demo_fn_sim_eff_no3',
|
|
'demo_inj_eff_tss', 'demo_fn_sim_eff_tss',
|
|
'demo_inj_w1_startup', 'demo_inj_w1_setpoint', 'demo_inj_w2_startup', 'demo_inj_w2_setpoint',
|
|
'demo_inj_n1_startup', 'demo_inj_s1_startup'
|
|
];
|
|
const stillPresent = removedIds.filter(id => flow.find(x => x.id === id));
|
|
if (stillPresent.length === 0) {
|
|
console.log('PASS: All 24 removed nodes are gone');
|
|
} else {
|
|
console.log('FAIL: These removed nodes are still present:', stillPresent);
|
|
errors++;
|
|
}
|
|
|
|
// Check kept nodes still exist
|
|
const keptIds = [
|
|
'demo_inj_west_flow', 'demo_fn_west_flow_sim',
|
|
'demo_inj_north_flow', 'demo_fn_north_flow_sim',
|
|
'demo_inj_south_flow', 'demo_fn_south_flow_sim',
|
|
'demo_inj_w1_mode', 'demo_inj_w2_mode', 'demo_inj_n1_mode', 'demo_inj_s1_mode',
|
|
'demo_inj_west_mode', 'demo_inj_north_mode', 'demo_inj_south_mode'
|
|
];
|
|
const keptMissing = keptIds.filter(id => !flow.find(x => x.id === id));
|
|
if (keptMissing.length === 0) {
|
|
console.log('PASS: All kept nodes still present');
|
|
} else {
|
|
console.log('FAIL: These nodes should exist but are missing:', keptMissing);
|
|
errors++;
|
|
}
|
|
|
|
// Check wiring: W1/W2 register to MGC, MGC registers to PS West
|
|
const w1 = flow.find(n => n.id === 'demo_pump_w1');
|
|
const w2 = flow.find(n => n.id === 'demo_pump_w2');
|
|
if (w1 && w1.wires[2] && w1.wires[2].includes('demo_mgc_west')) {
|
|
console.log('PASS: W1 port 2 wired to MGC');
|
|
} else {
|
|
console.log('FAIL: W1 port 2 not wired to MGC, got:', w1?.wires?.[2]);
|
|
errors++;
|
|
}
|
|
if (w2 && w2.wires[2] && w2.wires[2].includes('demo_mgc_west')) {
|
|
console.log('PASS: W2 port 2 wired to MGC');
|
|
} else {
|
|
console.log('FAIL: W2 port 2 not wired to MGC, got:', w2?.wires?.[2]);
|
|
errors++;
|
|
}
|
|
if (mgc && mgc.wires[2] && mgc.wires[2].includes('demo_ps_west')) {
|
|
console.log('PASS: MGC port 2 wired to PS West');
|
|
} else {
|
|
console.log('FAIL: MGC port 2 not wired to PS West');
|
|
errors++;
|
|
}
|
|
|
|
// Check PS outputs wire to level-to-pressure functions
|
|
const psWest = flow.find(n => n.id === 'demo_ps_west');
|
|
if (psWest && psWest.wires[0] && psWest.wires[0].includes('demo_fn_level_to_pressure_w')) {
|
|
console.log('PASS: PS West port 0 wired to level-to-pressure function');
|
|
} else {
|
|
console.log('FAIL: PS West port 0 missing level-to-pressure wire');
|
|
errors++;
|
|
}
|
|
|
|
console.log('\n=== RESULT ===');
|
|
if (errors === 0) {
|
|
console.log('ALL CHECKS PASSED');
|
|
} else {
|
|
console.log(`${errors} FAILURE(S)`);
|
|
process.exit(1);
|
|
}
|
|
})().catch(err => {
|
|
console.error('Failed to connect to Node-RED:', err.message);
|
|
process.exit(1);
|
|
});
|