Refactor of valve to use the platform infrastructure (BaseDomain, BaseNodeAdapter, ChildRouter, commandRegistry, statusBadge). Extracts concerns into focused modules per .claude/refactor/MODULE_SPLIT.md generic template. Tests stay green; CONTRACT.md generated; legacy aliases preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
2.9 KiB
JavaScript
74 lines
2.9 KiB
JavaScript
'use strict';
|
|
|
|
const { statusBadge } = require('generalFunctions');
|
|
|
|
const STATE_SYMBOLS = {
|
|
off: '⬛', idle: '⏸️', operational: '⏵️',
|
|
starting: '⏯️', warmingup: '🔄', accelerating: '⏩',
|
|
stopping: '⏹️', coolingdown: '❄️', decelerating: '⏪',
|
|
};
|
|
|
|
const STATE_FILL = {
|
|
off: 'red', idle: 'blue',
|
|
operational: 'green', warmingup: 'green',
|
|
starting: 'yellow', accelerating: 'yellow',
|
|
stopping: 'yellow', coolingdown: 'yellow', decelerating: 'yellow',
|
|
};
|
|
|
|
const SHOW_METRICS = new Set(['operational', 'warmingup', 'accelerating', 'decelerating']);
|
|
|
|
function buildOutput(host) {
|
|
const output = {};
|
|
Object.entries(host.measurements.measurements || {}).forEach(([type, variants]) => {
|
|
Object.entries(variants || {}).forEach(([variant, positions]) => {
|
|
Object.keys(positions || {}).forEach((position) => {
|
|
const unit = host._outputUnitForType(type);
|
|
const value = host._readMeasurement(type, variant, position, unit);
|
|
if (value != null) output[`${position}_${variant}_${type}`] = value;
|
|
});
|
|
});
|
|
});
|
|
output.state = host.state.getCurrentState();
|
|
output.percentageOpen = host.state.getCurrentPosition();
|
|
output.moveTimeleft = host.state.getMoveTimeLeft();
|
|
output.mode = host.currentMode;
|
|
return output;
|
|
}
|
|
|
|
function buildStatusBadge(host) {
|
|
try {
|
|
const mode = host.currentMode;
|
|
const stateName = host.state.getCurrentState();
|
|
const flowUnit = host.unitPolicyView.output.flow || 'm3/h';
|
|
const pressureUnit = host.unitPolicyView.output.pressure || 'mbar';
|
|
const flow = Math.round(host.measurements.type('flow').variant('predicted').position('downstream').getCurrentValue(flowUnit));
|
|
let deltaP = host.measurements.type('pressure').variant('predicted').position('delta').getCurrentValue(pressureUnit);
|
|
if (deltaP !== null && deltaP !== undefined) deltaP = parseFloat(deltaP.toFixed(0));
|
|
if (Number.isNaN(deltaP)) deltaP = '∞';
|
|
const pos = Math.round(host.state.getCurrentPosition() * 100) / 100;
|
|
const symbol = STATE_SYMBOLS[stateName] || '❔';
|
|
const fill = STATE_FILL[stateName] || 'grey';
|
|
|
|
let badge;
|
|
if (SHOW_METRICS.has(stateName)) {
|
|
badge = statusBadge.compose(
|
|
[`${mode}: ${symbol}`, `${pos}%`, `💨${flow}${flowUnit}`, `ΔP${deltaP} ${pressureUnit}`],
|
|
{ fill, shape: 'dot' }
|
|
);
|
|
} else {
|
|
badge = statusBadge.compose([`${mode}: ${symbol}`], { fill, shape: 'dot' });
|
|
}
|
|
|
|
const fc = typeof host.getFluidCompatibility === 'function' ? host.getFluidCompatibility() : null;
|
|
if (fc && (fc.status === 'mismatch' || fc.status === 'conflict')) {
|
|
return { fill: 'yellow', shape: 'ring', text: `${badge.text} | ⚠ ${fc.message}` };
|
|
}
|
|
return badge;
|
|
} catch (err) {
|
|
host.logger?.error?.(`getStatusBadge: ${err.message}`);
|
|
return statusBadge.error('Status Error');
|
|
}
|
|
}
|
|
|
|
module.exports = { buildOutput, buildStatusBadge };
|