mirror of
https://github.com/MichMich/MagicMirror.git
synced 2026-06-03 09:51:14 +00:00
fix(weather): use nearest openmeteo hourly data (#4123)
Open-Meteo updates `current_weather` every 15 minutes, but the hourly array only has entries at full hours. The old code did an exact timestamp match - so at 14:15, 14:30 or 14:45 it never found a match and silently fell back to index 0, showing midnight values for humidity, feels-like temp, precipitation, etc. Fix: `findLastIndex((hour) => hour.time <= currentMs)` - the last hourly entry at or before the current time. While fixing the bug I found several dead branches left over from the #4032 refactor: a path for pre-transposed hourly data that `#parseWeatherApiResponse` makes unreachable, an `Array.isArray` guard that's always true, and a `Log.debug` inside the dead branch. Removing those accounts for most of the ~40 deleted lines - the actual fix is one line. Fixes #4122.
This commit is contained in:
committed by
GitHub
parent
4c2a373ae3
commit
8af3d02cbb
@@ -418,46 +418,18 @@ class OpenMeteoProvider {
|
||||
|
||||
// Add hourly data if available
|
||||
if (parsedData.hourly) {
|
||||
let h;
|
||||
const currentTime = parsedData.current_weather.time;
|
||||
|
||||
// Handle both data shapes: object with arrays or array of objects (after transpose)
|
||||
if (Array.isArray(parsedData.hourly)) {
|
||||
// Array of objects (after transpose)
|
||||
const hourlyIndex = parsedData.hourly.findIndex((hour) => hour.time.getTime() === currentTime.getTime());
|
||||
h = hourlyIndex !== -1 ? hourlyIndex : 0;
|
||||
|
||||
if (hourlyIndex === -1) {
|
||||
Log.debug("[openmeteo] Could not find current time in hourly data, using index 0");
|
||||
}
|
||||
|
||||
const hourData = parsedData.hourly[h];
|
||||
if (hourData) {
|
||||
current.humidity = hourData.relativehumidity_2m;
|
||||
current.feelsLikeTemp = hourData.apparent_temperature;
|
||||
current.rain = hourData.rain;
|
||||
current.snow = hourData.snowfall ? hourData.snowfall * 10 : undefined;
|
||||
current.precipitationAmount = hourData.precipitation;
|
||||
current.precipitationProbability = hourData.precipitation_probability;
|
||||
current.uvIndex = hourData.uv_index;
|
||||
}
|
||||
} else if (parsedData.hourly.time) {
|
||||
// Object with arrays (before transpose - shouldn't happen in normal flow)
|
||||
const hourlyIndex = parsedData.hourly.time.findIndex((time) => time === currentTime);
|
||||
h = hourlyIndex !== -1 ? hourlyIndex : 0;
|
||||
|
||||
if (hourlyIndex === -1) {
|
||||
Log.debug("[openmeteo] Could not find current time in hourly data, using index 0");
|
||||
}
|
||||
|
||||
current.humidity = parsedData.hourly.relativehumidity_2m?.[h];
|
||||
current.feelsLikeTemp = parsedData.hourly.apparent_temperature?.[h];
|
||||
current.rain = parsedData.hourly.rain?.[h];
|
||||
current.snow = parsedData.hourly.snowfall?.[h] ? parsedData.hourly.snowfall[h] * 10 : undefined;
|
||||
current.precipitationAmount = parsedData.hourly.precipitation?.[h];
|
||||
current.precipitationProbability = parsedData.hourly.precipitation_probability?.[h];
|
||||
current.uvIndex = parsedData.hourly.uv_index?.[h];
|
||||
}
|
||||
// Open-Meteo updates current_weather every 15 min, but hourly entries only
|
||||
// exist at full hours — find the last entry at or before the current time.
|
||||
const currentMs = parsedData.current_weather.time.getTime();
|
||||
const hourlyIndex = parsedData.hourly.findLastIndex((hour) => hour.time.getTime() <= currentMs);
|
||||
const hourData = parsedData.hourly[Math.max(0, hourlyIndex)];
|
||||
current.humidity = hourData.relativehumidity_2m;
|
||||
current.feelsLikeTemp = hourData.apparent_temperature;
|
||||
current.rain = hourData.rain;
|
||||
current.snow = hourData.snowfall != null ? hourData.snowfall * 10 : null;
|
||||
current.precipitationAmount = hourData.precipitation;
|
||||
current.precipitationProbability = hourData.precipitation_probability;
|
||||
current.uvIndex = hourData.uv_index;
|
||||
}
|
||||
|
||||
// Add daily data if available (after transpose, daily is array of objects)
|
||||
|
||||
@@ -144,12 +144,15 @@ describe("OpenMeteoProvider", () => {
|
||||
provider.start();
|
||||
|
||||
const result = await dataPromise;
|
||||
const currentHourUnix = Math.floor(currentData.current_weather.time / 3600) * 3600;
|
||||
const currentHourIndex = currentData.hourly.time.findIndex((time) => time === currentHourUnix);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.temperature).toBe(8.5);
|
||||
expect(result.windSpeed).toBeCloseTo(4.7, 1);
|
||||
expect(result.windFromDirection).toBe(9);
|
||||
expect(result.humidity).toBe(83);
|
||||
expect(result.humidity).toBe(currentData.hourly.relativehumidity_2m[currentHourIndex]);
|
||||
expect(result.humidity).not.toBe(currentData.hourly.relativehumidity_2m[0]);
|
||||
});
|
||||
|
||||
it("should include sunrise and sunset from daily data", async () => {
|
||||
|
||||
Reference in New Issue
Block a user