From 5cf7b2fbf6e395df789199715409cb5ed1d21c9f Mon Sep 17 00:00:00 2001 From: xunguangzlj-cloud <293371022+xunguangzlj-cloud@users.noreply.github.com> Date: Sun, 8 Nov 2026 19:21:09 +0800 Subject: [PATCH 1/2] fix(weather): preserve zero feels-like temperatures --- defaultmodules/weather/weatherobject.js | 2 +- .../default/weather/weather_object_spec.js | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/defaultmodules/weather/weatherobject.js b/defaultmodules/weather/weatherobject.js index e0fadab4d3..d5f1d256a6 100644 --- a/defaultmodules/weather/weatherobject.js +++ b/defaultmodules/weather/weatherobject.js @@ -77,7 +77,7 @@ class WeatherObject { } feelsLike () { - if (this.feelsLikeTemp) { + if (this.feelsLikeTemp || this.feelsLikeTemp === 0) { return this.feelsLikeTemp; } return WeatherUtils.calculateFeelsLike(this.temperature, this.windSpeed, this.humidity); diff --git a/tests/unit/modules/default/weather/weather_object_spec.js b/tests/unit/modules/default/weather/weather_object_spec.js index 9fe0a9bb6f..9eff77d9e3 100644 --- a/tests/unit/modules/default/weather/weather_object_spec.js +++ b/tests/unit/modules/default/weather/weather_object_spec.js @@ -5,6 +5,8 @@ const WeatherObject = require(`../../../../../${defaults.defaultModulesDir}/weat global.moment = require("moment-timezone"); global.SunCalc = require("suncalc"); +global.WeatherUtils = require(`../../../../../${defaults.defaultModulesDir}/weather/weatherutils`); + describe("WeatherObject", () => { let originalTimeZone; let weatherobject; @@ -44,6 +46,26 @@ describe("WeatherObject", () => { expect(weatherobject.feelsLike()).toBe("feelsLikeTempValue"); }); + it("should preserve a provider's zero feels-like temperature", () => { + const current = Object.assign(new WeatherObject(), { + temperature: 12, + windSpeed: 0, + humidity: 50, + feelsLikeTemp: 0 + }); + expect(current.feelsLike()).toBe(0); + }); + + it.each([null, undefined, NaN])("should calculate a fallback for %s", (feelsLikeTemp) => { + const current = Object.assign(new WeatherObject(), { + temperature: 12, + windSpeed: 0, + humidity: 50, + feelsLikeTemp + }); + expect(current.feelsLike()).toBeCloseTo(11.741); + }); + afterAll(() => { moment.tz.setDefault(originalTimeZone); }); From eb705773a1a49e90e45c523dab4d4930383e2a82 Mon Sep 17 00:00:00 2001 From: xunguangzlj-cloud Date: Mon, 9 Nov 2026 10:24:16 +0800 Subject: [PATCH 2/2] fix(weather): keep zero in Met Office feels-like readings --- .../weather/providers/ukmetofficedatahub.js | 8 ++++---- .../providers/ukmetofficedatahub_spec.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/defaultmodules/weather/providers/ukmetofficedatahub.js b/defaultmodules/weather/providers/ukmetofficedatahub.js index 89091c66de..40c483ad2e 100644 --- a/defaultmodules/weather/providers/ukmetofficedatahub.js +++ b/defaultmodules/weather/providers/ukmetofficedatahub.js @@ -140,7 +140,7 @@ class UkMetOfficeDataHubProvider extends WeatherProvider { snow: hour.totalSnowAmount || 0, precipitationAmount: (hour.totalPrecipAmount || 0) + (hour.totalSnowAmount || 0), precipitationProbability: hour.probOfPrecipitation || null, - feelsLikeTemp: hour.feelsLikeTemperature || null, + feelsLikeTemp: hour.feelsLikeTemperature ?? null, sunrise: null, sunset: null }; @@ -167,7 +167,7 @@ class UkMetOfficeDataHubProvider extends WeatherProvider { snow: firstHour.totalSnowAmount || 0, precipitationAmount: (firstHour.totalPrecipAmount || 0) + (firstHour.totalSnowAmount || 0), precipitationProbability: firstHour.probOfPrecipitation || null, - feelsLikeTemp: firstHour.feelsLikeTemperature || null, + feelsLikeTemp: firstHour.feelsLikeTemperature ?? null, sunrise: null, sunset: null }; @@ -204,7 +204,7 @@ class UkMetOfficeDataHubProvider extends WeatherProvider { snow: day.dayProbabilityOfSnow || 0, precipitationAmount: 0, precipitationProbability: day.dayProbabilityOfPrecipitation || null, - feelsLikeTemp: day.dayMaxFeelsLikeTemp || null + feelsLikeTemp: day.dayMaxFeelsLikeTemp ?? null }); } } @@ -235,7 +235,7 @@ class UkMetOfficeDataHubProvider extends WeatherProvider { snow: hour.totalSnowAmount || 0, precipitationAmount: (hour.totalPrecipAmount || 0) + (hour.totalSnowAmount || 0), precipitationProbability: hour.probOfPrecipitation || null, - feelsLikeTemp: hour.feelsLikeTemp || null + feelsLikeTemp: hour.feelsLikeTemp ?? null }); } diff --git a/tests/unit/modules/default/weather/providers/ukmetofficedatahub_spec.js b/tests/unit/modules/default/weather/providers/ukmetofficedatahub_spec.js index 397345980d..4d599b8d10 100644 --- a/tests/unit/modules/default/weather/providers/ukmetofficedatahub_spec.js +++ b/tests/unit/modules/default/weather/providers/ukmetofficedatahub_spec.js @@ -60,6 +60,25 @@ describe("UKMetOfficeDataHubProvider", () => { UKMetOfficeDataHubProvider = module.default || module; }); + it.each([ + ["current observation", "current", -1, "feelsLikeTemperature"], + ["current fallback", "current", -120, "feelsLikeTemperature"], + ["daily forecast", "forecast", 1440, "dayMaxFeelsLikeTemp"], + ["hourly forecast", "hourly", 60, "feelsLikeTemp"] + ])("should preserve zero feels-like temperature in the %s", (label, type, offsetMinutes, field) => { + const provider = new UKMetOfficeDataHubProvider({ apiKey: "test-key", type }); + const onData = vi.fn(); + provider.setCallbacks(onData, vi.fn()); + const time = new Date(Date.now() + offsetMinutes * 60_000).toISOString(); + const data = { features: [{ properties: { timeSeries: [{ time, [field]: 0 }] } }] }; + vi.spyOn(provider, "_createJSONFetcher").mockImplementation((options, onResponse) => onResponse(data)); + + provider.initialize(); + + const [weather] = onData.mock.calls[0]; + expect((Array.isArray(weather) ? weather[0] : weather).feelsLikeTemp).toBe(0); + }); + describe("Constructor & Configuration", () => { it("should set config values from params", () => { const provider = new UKMetOfficeDataHubProvider({