Skip to content

Commit 25efe42

Browse files
authored
Update feels_like temperature formula (#3869)
The current logic never showed any different temperature than the current one, so I looked into a more "explained" formula and found one in the HomeAssistant forums.
1 parent f8679b6 commit 25efe42

File tree

3 files changed

+60
-18
lines changed

3 files changed

+60
-18
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Thanks to: @dathbe.
3939
### Updated
4040

4141
- [core] Update dependencies including electron to v37 as well as github actions (#3831, #3849, #3857, #3858)
42+
- [weather] Update feels_like temperature calculation formula (#3869)
4243

4344
### Fixed
4445

modules/default/weather/weatherutils.js

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ const WeatherUtils = {
6161
return unit === "imperial" ? tempInC * 1.8 + 32 : tempInC;
6262
},
6363

64+
/**
65+
* Convert temp (from degrees C) into metric unit
66+
* @param {number} tempInF the temperature in Fahrenheit you want to convert
67+
* @returns {number} the converted temperature
68+
*/
69+
convertTempToMetric (tempInF) {
70+
return ((tempInF - 32) * 5) / 9;
71+
},
72+
6473
/**
6574
* Convert wind speed into another unit.
6675
* @param {number} windInMS the windspeed in meter/sec you want to convert
@@ -118,27 +127,51 @@ const WeatherUtils = {
118127
return kmh * 0.27777777777778;
119128
},
120129

130+
/**
131+
* Taken from https://community.home-assistant.io/t/calculating-apparent-feels-like-temperature/370834/18
132+
* @param {number} temperature temperature in degrees Celsius
133+
* @param {number} windSpeed wind speed in meter/second
134+
* @param {number} humidity relative humidity in percent
135+
* @returns {number} the feels like temperature in degrees Celsius
136+
*/
121137
calculateFeelsLike (temperature, windSpeed, humidity) {
122138
const windInMph = this.convertWind(windSpeed, "imperial");
123139
const tempInF = this.convertTemp(temperature, "imperial");
124-
let feelsLike = tempInF;
125-
126-
if (windInMph > 3 && tempInF < 50) {
127-
feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16));
128-
} else if (tempInF > 80 && humidity > 40) {
129-
feelsLike
130-
= -42.379
131-
+ 2.04901523 * tempInF
132-
+ 10.14333127 * humidity
133-
- 0.22475541 * tempInF * humidity
134-
- 6.83783 * Math.pow(10, -3) * tempInF * tempInF
135-
- 5.481717 * Math.pow(10, -2) * humidity * humidity
136-
+ 1.22874 * Math.pow(10, -3) * tempInF * tempInF * humidity
137-
+ 8.5282 * Math.pow(10, -4) * tempInF * humidity * humidity
138-
- 1.99 * Math.pow(10, -6) * tempInF * tempInF * humidity * humidity;
140+
141+
let HI;
142+
let WC = tempInF;
143+
144+
// Calculate wind chill for certain conditions
145+
if (tempInF <= 70 && windInMph >= 3) {
146+
WC = 35.74 + (0.6215 * tempInF) - 35.75 * Math.pow(windInMph, 0.16) + ((0.4275 * tempInF) * Math.pow(windInMph, 0.16));
139147
}
140148

141-
return ((feelsLike - 32) * 5) / 9;
149+
// Steadman Heat Index Vorberechnung
150+
const STEADMAN_HI = 0.5 * (tempInF + 61.0 + ((tempInF - 68.0) * 1.2) + (humidity * 0.094));
151+
152+
if (STEADMAN_HI >= 80) {
153+
// Rothfusz-Komplex
154+
const ROTHFUSZ_HI = -42.379 + 2.04901523 * tempInF + 10.14333127 * humidity - 0.22475541 * tempInF * humidity - 0.00683783 * tempInF * tempInF - 0.05481717 * humidity * humidity + 0.00122874 * tempInF * tempInF * humidity + 0.00085282 * tempInF * humidity * humidity - 0.00000199 * tempInF * tempInF * humidity * humidity;
155+
156+
HI = ROTHFUSZ_HI;
157+
158+
if (humidity < 13 && tempInF > 80 && tempInF < 112) {
159+
const ADJUSTMENT = ((13 - humidity) / 4) * Math.pow(Math.abs(17 - (tempInF - 95)), 0.5) / 17; // sqrt Teil
160+
HI = HI - ADJUSTMENT;
161+
} else if (humidity > 85 && tempInF > 80 && tempInF < 87) {
162+
const ADJUSTMENT = ((humidity - 85) / 10) * ((87 - tempInF) / 5);
163+
HI = HI + ADJUSTMENT;
164+
}
165+
166+
} else { HI = STEADMAN_HI; }
167+
168+
// Feuchte Lastberechnung FL
169+
let FL;
170+
if (tempInF < 50) { FL = WC; }
171+
else if (tempInF >= 50 && tempInF < 70) { FL = ((70 - tempInF) / 20) * WC + ((tempInF - 50) / 20) * HI; }
172+
else if (tempInF >= 70) { FL = HI; }
173+
174+
return this.convertTempToMetric(FL);
142175
},
143176

144177
/**

tests/unit/modules/default/weather/weather_utils_spec.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@ const WeatherUtils = require("../../../../../modules/default/weather/weatherutil
33

44
describe("Weather utils tests", () => {
55
describe("temperature conversion to imperial", () => {
6+
it("should convert temp correctly from Celsius to Celsius", () => {
7+
expect(Math.round(WeatherUtils.convertTemp(10, "metric"))).toBe(10);
8+
});
9+
610
it("should convert temp correctly from Celsius to Fahrenheit", () => {
711
expect(Math.round(WeatherUtils.convertTemp(10, "imperial"))).toBe(50);
812
});
13+
14+
it("should convert temp correctly from Fahrenheit to Celsius", () => {
15+
expect(Math.round(WeatherUtils.convertTempToMetric(10))).toBe(-12);
16+
});
917
});
1018

1119
describe("windspeed conversion to beaufort", () => {
@@ -44,11 +52,11 @@ describe("Weather utils tests", () => {
4452

4553
describe("feelsLike calculation", () => {
4654
it("should return a calculated feelsLike info (negative value)", () => {
47-
expect(WeatherUtils.calculateFeelsLike(0, 20, 40)).toBe(-9.444444444444445);
55+
expect(WeatherUtils.calculateFeelsLike(0, 20, 40)).toBe(-9.397005931555448);
4856
});
4957

5058
it("should return a calculated feelsLike info (positive value)", () => {
51-
expect(WeatherUtils.calculateFeelsLike(30, 0, 60)).toBe(32.8320322777777);
59+
expect(WeatherUtils.calculateFeelsLike(30, 0, 60)).toBe(32.832032277777756);
5260
});
5361
});
5462

0 commit comments

Comments
 (0)