Files
valve/src/nodeClass.js
znetsixe 68ebe4ebce feat(valve): resolve supplier+type from asset registry, reject legacy asset fields
Mirrors the rotatingMachine cutover: assetResolver derives supplier/type/
units from the model id; nodeClass throws a clear "re-select model and
save" error if the saved node still carries denormalized supplier/
category/assetType strings. valve.html defaults trimmed accordingly.

14/14 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 17:12:47 +02:00

68 lines
2.3 KiB
JavaScript

'use strict';
const { BaseNodeAdapter, convert } = require('generalFunctions');
const Valve = require('./specificClass');
const commands = require('./commands');
class nodeClass extends BaseNodeAdapter {
static DomainClass = Valve;
static commands = commands;
static tickInterval = null;
static statusInterval = 1000;
buildDomainConfig(uiConfig) {
_rejectLegacyAssetFields(uiConfig);
const flowUnit = _resolveUnit(uiConfig.unit, 'volumeFlowRate', 'm3/h');
const asNum = (v) => { const n = Number(v); return Number.isFinite(n) ? n : undefined; };
Valve._pendingExtras = {
stateConfig: {
general: { logging: { enabled: uiConfig.enableLog, logLevel: uiConfig.logLevel } },
movement: { speed: asNum(uiConfig.speed) },
time: {
starting: asNum(uiConfig.startup), warmingup: asNum(uiConfig.warmup),
stopping: asNum(uiConfig.shutdown), coolingdown: asNum(uiConfig.cooldown),
},
},
runtimeOptions: {
serviceType: uiConfig.serviceType,
fluidDensity: asNum(uiConfig.fluidDensity),
fluidTemperatureK: asNum(uiConfig.fluidTemperatureK),
gasChokedRatioLimit: asNum(uiConfig.gasChokedRatioLimit),
},
};
return {
general: { unit: flowUnit },
asset: { model: uiConfig.model || null, unit: flowUnit },
};
}
}
// See rotatingMachine/src/nodeClass.js for the rationale. Same cutover rule.
function _rejectLegacyAssetFields(uiConfig) {
const offenders = ['supplier', 'category', 'assetType'].filter((k) => {
const v = uiConfig[k];
return typeof v === 'string' && v.trim() !== '';
});
if (offenders.length > 0) {
throw new Error(
`valve: legacy asset field(s) [${offenders.join(', ')}] are saved on this node. ` +
`After the AssetResolver refactor these are derived from the model id. ` +
`Open the node in the editor, re-select the model, and save to migrate.`,
);
}
}
function _resolveUnit(candidate, expectedMeasure, fallback) {
const raw = typeof candidate === 'string' ? candidate.trim() : '';
const fb = String(fallback || '').trim();
if (!raw) return fb;
try {
const desc = convert().describe(raw);
if (expectedMeasure && desc.measure !== expectedMeasure) return fb;
return raw;
} catch (_) { return fb; }
}
module.exports = nodeClass;