diff --git a/src/control/manual.js b/src/control/manual.js index 4d9cc44..e86f890 100644 --- a/src/control/manual.js +++ b/src/control/manual.js @@ -4,13 +4,14 @@ async function run() { } async function forwardDemand(ctx, demand) { - const { machineGroups, machines, logger } = ctx; + const { machineGroups, machines, unitPolicy, logger } = ctx; logger?.info?.(`Manual demand forwarded: ${demand}`); if (machineGroups && Object.keys(machineGroups).length > 0) { + const groupDemand = unitPolicy.convert(demand, 'm3/h', 'm3/s', 'manual demand to machineGroups'); await Promise.all( Object.values(machineGroups).map((group) => - group.handleInput('parent', demand).catch((err) => { + group.handleInput('parent', groupDemand).catch((err) => { logger?.error?.(`Failed to forward demand to group: ${err.message}`); }) ) diff --git a/src/specificClass.js b/src/specificClass.js index fc46a2d..d34170d 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -146,6 +146,7 @@ class PumpingStation extends BaseDomain { levelVariants: this.levelVariants, volVariants: this.volVariants, flowThreshold: this.flowThreshold, + unitPolicy: this.unitPolicy, host: this, }; Object.defineProperty(ctx, 'machines', { enumerable: true, get: () => host.machines }); @@ -262,7 +263,7 @@ class PumpingStation extends BaseDomain { }; const { arrow = '❔', fill = 'grey' } = STYLES[this.state?.direction] || {}; const pct = this.measurements.type('volumePercent').variant('predicted').position('atequipment').getCurrentValue() ?? 0; - const netFlowM3h = (this.state?.netFlow ?? 0) * 3600; + const netFlowM3h = this.unitPolicy.convert(this.state?.netFlow ?? 0, 'm3/s', 'm3/h', 'status badge netFlow'); const mode = this.mode || '?'; const manualPart = this.mode === 'manual' && Number.isFinite(this._manualDemand) ? `Qd=${this._manualDemand.toFixed(0)} m³/h` : null; @@ -289,6 +290,10 @@ class PumpingStation extends BaseDomain { this.logger.debug( `Measurement update ${eventName} <- ${eventData.childName || child.config.general.name}: ${eventData.value} ${eventData.unit}` ); + if (measurementType === 'level') { + this.measurementRouter.route(measurementType, eventData.value, position, eventData); + return; + } this.measurements.type(measurementType).variant('measured').position(position) .value(eventData.value, eventData.timestamp, eventData.unit); this.measurementRouter.route(measurementType, eventData.value, position, eventData); diff --git a/test/basic/control-manual.basic.test.js b/test/basic/control-manual.basic.test.js index c2b8267..36ef444 100644 --- a/test/basic/control-manual.basic.test.js +++ b/test/basic/control-manual.basic.test.js @@ -4,8 +4,15 @@ const test = require('node:test'); const assert = require('node:assert/strict'); +const { UnitPolicy } = require('generalFunctions'); const manual = require('../../src/control/manual'); +const unitPolicy = UnitPolicy.declare({ + canonical: { flow: 'm3/s' }, + output: { flow: 'm3/s' }, + requireUnitForTypes: [], +}); + function makeGroup(name) { const calls = { handleInput: [] }; return { @@ -28,15 +35,15 @@ function makeLogger() { return { info: () => {}, debug: () => {}, warn: () => {}, error: () => {} }; } -test('forwardDemand calls handleInput("parent", demand) on every machine group', async () => { +test('forwardDemand calls handleInput("parent", canonical m3/s demand) on every machine group', async () => { const groups = { a: makeGroup('A'), b: makeGroup('B'), c: makeGroup('C') }; - const ctx = { machineGroups: groups, machines: {}, logger: makeLogger() }; + const ctx = { machineGroups: groups, machines: {}, unitPolicy, logger: makeLogger() }; - await manual.forwardDemand(ctx, 50); + await manual.forwardDemand(ctx, 360); for (const g of Object.values(groups)) { assert.equal(g._calls.handleInput.length, 1); - assert.deepEqual(g._calls.handleInput[0], ['parent', 50]); + assert.deepEqual(g._calls.handleInput[0], ['parent', 0.1]); } }); @@ -54,7 +61,7 @@ test('forwardDemand with no machineGroups but direct machines splits demand even test('run() is a no-op (manual mode is event-driven)', async () => { const groups = { a: makeGroup('A') }; - const ctx = { machineGroups: groups, machines: {}, logger: makeLogger() }; + const ctx = { machineGroups: groups, machines: {}, unitPolicy, logger: makeLogger() }; await manual.run(ctx, { percControl: 0 }); assert.equal(groups.a._calls.handleInput.length, 0); });