fix(level): pass timestamp on level samples for level-rate fallback
MeasurementRouter.onLevelMeasurement was writing level samples via .value(value).unit(context.unit), which dropped the timestamp. The level-rate fallback in FlowAggregator derives netFlow from dlevel/dt, so without a timestamp on each sample it had nothing to differentiate. Switch to the positional .value(value, timestamp, unit) form so the fallback works. Add a basic test that drives two level samples 2 s apart and asserts the aggregator produces direction=filling with a finite dlevel/dt-derived netFlow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,7 +34,7 @@ class MeasurementRouter {
|
||||
|
||||
onLevelMeasurement(position, value, context = {}) {
|
||||
this.measurements.type('level').variant('measured').position(position)
|
||||
.value(value).unit(context.unit);
|
||||
.value(value, context.timestamp, context.unit);
|
||||
|
||||
const series = this.measurements.type('level').variant('measured').position(position);
|
||||
const levelMeters = series.getCurrentValue('m');
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const { MeasurementContainer } = require('generalFunctions');
|
||||
const PumpingStation = require('../../src/specificClass');
|
||||
|
||||
// machineGroups is a registry-backed getter (declareChildGetter) — direct
|
||||
@@ -84,6 +85,39 @@ function makeConfig(overrides = {}) {
|
||||
return base;
|
||||
}
|
||||
|
||||
function makeMeasurementChild({ type = 'level', position = 'atequipment', name = 'child-level' } = {}) {
|
||||
return {
|
||||
config: {
|
||||
general: { id: name, name },
|
||||
functionality: { positionVsParent: position },
|
||||
asset: { type },
|
||||
},
|
||||
measurements: new MeasurementContainer({
|
||||
autoConvert: true,
|
||||
preferredUnits: { level: 'm', flow: 'm3/s', pressure: 'Pa' },
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
test('level child subscription records one sample per event for level-rate fallback', async () => {
|
||||
const ps = new PumpingStation(makeConfig());
|
||||
const child = makeMeasurementChild();
|
||||
|
||||
ps._subscribeMeasurement(child);
|
||||
child.measurements.type('level').variant('measured').position('atequipment')
|
||||
.value(1.0, 1000, 'm');
|
||||
child.measurements.type('level').variant('measured').position('atequipment')
|
||||
.value(1.1, 3000, 'm');
|
||||
|
||||
const series = ps.measurements.type('level').variant('measured').position('atequipment').get();
|
||||
assert.deepEqual(series.values, [1.0, 1.1]);
|
||||
|
||||
const net = ps.flowAggregator.selectBestNetFlow();
|
||||
assert.equal(net.source, 'level:measured');
|
||||
assert.equal(net.direction, 'filling');
|
||||
assert.ok(Math.abs(net.value - 0.5) < 1e-9, `net flow was ${net.value}`);
|
||||
});
|
||||
|
||||
test('Basin geometry — derived values', async (t) => {
|
||||
const ps = new PumpingStation(makeConfig());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user