Generate dashboards for an entire parent-child subtree from a single root
registration (pre-order, cycle/diamond-safe), so wiring only the subtree root
(e.g. pumpingStation) to dashboardAPI yields dashboards for every descendant.
Fix two contract drifts that left generated panels blank against live telemetry:
- _measurement var now mirrors outputUtils.formatMsg (general.name ||
<softwareType>_<id>); previously it always used the fallback form, so any
named node's dashboard queried a non-existent series.
- pumpingStation template field keys realigned to emitted telemetry
(flow.*.{upstream,out,overflow}, netFlowRate.measured, inflowLevel/
outflowLevel/overflowLevel, maxVolAtOverflow/minVolAt{Inflow,Outflow}).
Adds template alias resolution (softwareType -> shared template file) and
locks parity with slice44/45/46 tests + output manifest. 67/67 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
1.9 KiB
JavaScript
51 lines
1.9 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const DashboardApi = require('../../src/specificClass.js');
|
|
|
|
// softwareType (as reported at runtime, lowercased) -> the template that must resolve.
|
|
const CASES = [
|
|
['rotatingmachine', 'machine.json'],
|
|
['machinegroupcontrol', 'machineGroup.json'],
|
|
['pumpingstation', 'pumpingStation.json'],
|
|
['valvegroupcontrol', 'valveGroupControl.json'],
|
|
['diffuser', 'aeration.json'],
|
|
['measurement', 'measurement.json'],
|
|
['reactor', 'reactor.json'],
|
|
['settler', 'settler.json'],
|
|
['valve', 'valve.json'],
|
|
['monster', 'monster.json'],
|
|
];
|
|
|
|
for (const [softwareType, file] of CASES) {
|
|
test(`softwareType '${softwareType}' resolves to ${file}`, () => {
|
|
const api = new DashboardApi({});
|
|
const resolved = api._templateFileForSoftwareType(softwareType);
|
|
assert.ok(resolved, `expected a template path for ${softwareType}`);
|
|
assert.ok(resolved.endsWith(file), `expected ${file}, got ${resolved}`);
|
|
});
|
|
}
|
|
|
|
test('resolution is case-insensitive (camelCase softwareType still resolves)', () => {
|
|
const api = new DashboardApi({});
|
|
assert.ok(api._templateFileForSoftwareType('rotatingMachine').endsWith('machine.json'));
|
|
assert.ok(api._templateFileForSoftwareType('machineGroupControl').endsWith('machineGroup.json'));
|
|
});
|
|
|
|
test('rotatingmachine now builds a dashboard (was: no template found)', () => {
|
|
const api = new DashboardApi({});
|
|
const built = api.buildDashboard({
|
|
nodeConfig: { general: { id: 'rm-1', name: 'Pump A' }, functionality: { softwareType: 'rotatingmachine' } },
|
|
positionVsParent: 'downstream',
|
|
});
|
|
assert.ok(built, 'expected a built dashboard, not null');
|
|
assert.equal(built.softwareType, 'rotatingmachine');
|
|
});
|
|
|
|
test('unknown softwareType still returns null (no template)', () => {
|
|
const api = new DashboardApi({});
|
|
assert.equal(api._templateFileForSoftwareType('totally-unknown-type'), null);
|
|
});
|