2026-05-10 22:00:34 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
const { BaseNodeAdapter, convert } = require('generalFunctions');
|
|
|
|
|
const Machine = require('./specificClass');
|
|
|
|
|
const commands = require('./commands');
|
|
|
|
|
|
|
|
|
|
// Event-driven: state + measurement events drive recomputes via the
|
|
|
|
|
// domain emitter. No tick loop. Status badge polled every second.
|
|
|
|
|
class nodeClass extends BaseNodeAdapter {
|
|
|
|
|
static DomainClass = Machine;
|
|
|
|
|
static commands = commands;
|
|
|
|
|
static tickInterval = null;
|
|
|
|
|
static statusInterval = 1000;
|
|
|
|
|
|
|
|
|
|
buildDomainConfig(uiConfig) {
|
|
|
|
|
const flowUnit = _resolveUnit(uiConfig.unit, 'volumeFlowRate', 'm3/h');
|
|
|
|
|
// Stash extras on the Machine class so its constructor (called by
|
|
|
|
|
// BaseNodeAdapter via DomainClass) picks them up alongside the
|
|
|
|
|
// machineConfig. Single-threaded JS makes the hand-off race-free.
|
|
|
|
|
Machine._pendingExtras = {
|
|
|
|
|
stateConfig: {
|
|
|
|
|
general: { logging: { enabled: uiConfig.enableLog, logLevel: uiConfig.logLevel } },
|
|
|
|
|
movement: { speed: Number(uiConfig.speed), mode: uiConfig.movementMode },
|
|
|
|
|
time: {
|
|
|
|
|
starting: Number(uiConfig.startup), warmingup: Number(uiConfig.warmup),
|
|
|
|
|
stopping: Number(uiConfig.shutdown), coolingdown: Number(uiConfig.cooldown),
|
2025-06-25 17:26:13 +02:00
|
|
|
},
|
2026-05-10 22:00:34 +02:00
|
|
|
},
|
|
|
|
|
errorMetricsConfig: {},
|
|
|
|
|
};
|
|
|
|
|
return {
|
|
|
|
|
asset: {
|
|
|
|
|
uuid: uiConfig.assetUuid || uiConfig.uuid || null,
|
|
|
|
|
tagCode: uiConfig.assetTagCode || uiConfig.assetTagNumber || null,
|
|
|
|
|
tagNumber: uiConfig.assetTagNumber || null,
|
|
|
|
|
unit: flowUnit,
|
|
|
|
|
curveUnits: {
|
|
|
|
|
pressure: _resolveUnit(uiConfig.curvePressureUnit, 'pressure', 'mbar'),
|
|
|
|
|
flow: _resolveUnit(uiConfig.curveFlowUnit || flowUnit, 'volumeFlowRate', flowUnit),
|
|
|
|
|
power: _resolveUnit(uiConfig.curvePowerUnit, 'power', 'kW'),
|
|
|
|
|
control: (typeof uiConfig.curveControlUnit === 'string' && uiConfig.curveControlUnit.trim()) || '%',
|
2025-06-25 17:26:13 +02:00
|
|
|
},
|
2026-05-10 22:00:34 +02:00
|
|
|
},
|
|
|
|
|
general: { unit: flowUnit },
|
|
|
|
|
flowNumber: uiConfig.flowNumber,
|
|
|
|
|
};
|
2025-06-25 17:26:13 +02:00
|
|
|
}
|
2026-05-10 22:00:34 +02:00
|
|
|
}
|
2025-06-25 17:26:13 +02:00
|
|
|
|
2026-05-10 22:00:34 +02:00
|
|
|
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; }
|
2025-06-25 17:26:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = nodeClass;
|