Files
monster/src/rain/rainAggregator.js
znetsixe 2a6a0bc34b P6: convert monster to BaseDomain + BaseNodeAdapter + concern split
Refactor of monster 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>
2026-05-10 22:09:25 +02:00

59 lines
2.1 KiB
JavaScript

'use strict';
// Rain-data aggregator — sums per-location hourly precipitation, weighted
// by per-hour probability, and stores both the raw and probability-weighted
// values keyed by timestamp. sumRain/avgRain feed parameters.getRainIndex
// which scales the predicted flow rate between nominalFlowMin and flowMax.
class RainAggregator {
constructor({ logger } = {}) {
this.logger = logger;
this.aggregatedOutput = {};
this.sumRain = 0;
this.avgRain = 0;
}
// Returns the aggregated per-location object so callers can chain.
// Mutates this.aggregatedOutput / sumRain / avgRain in place.
update(value) {
if (!value) return this.aggregatedOutput;
const totalRaw = {};
const totalProb = {};
let numberOfLocations = 0;
Object.entries(value).forEach(([locationKey, location]) => {
numberOfLocations++;
const slot = (this.aggregatedOutput[locationKey] = {
tag: { latitude: location.latitude, longitude: location.longitude },
precipationRaw: {},
precipationProb: {},
});
Object.entries(location.hourly.time).forEach(([key, time]) => {
const currTimestamp = new Date(time).getTime();
let probability = 100;
if (typeof location.hourly.precipitation_probability !== 'undefined') {
probability = location.hourly.precipitation_probability[key];
}
if (probability > 0) probability /= 100;
if (totalRaw[currTimestamp] === undefined) totalRaw[currTimestamp] = 0;
if (totalProb[currTimestamp] === undefined) totalProb[currTimestamp] = 0;
totalRaw[currTimestamp] += location.hourly.precipitation[key];
totalProb[currTimestamp] += location.hourly.precipitation[key] * probability;
slot.precipationRaw[key] = { val: location.hourly.precipitation[key], time: currTimestamp };
slot.precipationProb[key] = { val: probability, time: currTimestamp };
});
});
this.sumRain = Object.values(totalProb).reduce((s, v) => s + v, 0);
this.avgRain = numberOfLocations > 0 ? this.sumRain / numberOfLocations : 0;
return this.aggregatedOutput;
}
}
module.exports = RainAggregator;