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>
68 lines
2.3 KiB
JavaScript
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;
|