Migrate to new Gitea instance (gitea.wbd-rd.nl)

- 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>
This commit is contained in:
znetsixe
2026-03-04 21:07:04 +01:00
parent fbd9e6ec11
commit 6a6c04d34b
169 changed files with 21332 additions and 1512 deletions

View File

@@ -0,0 +1,142 @@
#!/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);
});