Skip to content

Commit 075dd6d

Browse files
fix(weather): handle missing sunrise/sunset data gracefully
Add defensive checks in WeatherObject methods and template: - nextSunAction() returns null if sunrise/sunset unavailable - isDayTime() defaults to true if sunrise/sunset unavailable - current.njk template checks nextSunAction() before displaying sun times - Prevents 'Invalid date' display when provider doesn't supply sun data
1 parent 5d0704d commit 075dd6d

3 files changed

Lines changed: 57 additions & 27 deletions

File tree

defaultmodules/weather/current.njk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
{% if config.showHumidity === "wind" %}
2626
{{ humidity() }}
2727
{% endif %}
28-
{% if config.showSun %}
28+
{% if config.showSun and current.nextSunAction() %}
2929
<span class="wi dimmed wi-{{ current.nextSunAction() }}"></span>
3030
<span>
3131
{% if current.nextSunAction() === "sunset" %}

defaultmodules/weather/providers/openmeteo.js

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -413,36 +413,58 @@ class OpenMeteoProvider {
413413
}
414414

415415
#generateWeatherDayFromCurrentWeather (parsedData) {
416-
// Find the correct hourly index by matching current_weather.time
417-
const currentTime = parsedData.current_weather.time;
418-
const hourlyIndex = parsedData.hourly.time.findIndex((time) => time === currentTime);
419-
const h = hourlyIndex !== -1 ? hourlyIndex : 0;
420-
421-
if (hourlyIndex === -1) {
422-
Log.warn("Could not find current time in hourly data, using index 0");
423-
}
424-
425-
return {
416+
// Basic current weather data
417+
const current = {
426418
date: parsedData.current_weather.time,
427419
windSpeed: parsedData.current_weather.windspeed,
428420
windFromDirection: parsedData.current_weather.winddirection,
429-
sunrise: parsedData.daily[0].sunrise,
430-
sunset: parsedData.daily[0].sunset,
431-
temperature: parseFloat(parsedData.current_weather.temperature),
432-
minTemperature: parseFloat(parsedData.daily[0].temperature_2m_min),
433-
maxTemperature: parseFloat(parsedData.daily[0].temperature_2m_max),
434-
weatherType: this.#convertWeatherType(
435-
parsedData.current_weather.weathercode,
436-
this.#isDayTime(parsedData.current_weather.time, parsedData.daily[0].sunrise, parsedData.daily[0].sunset)
437-
),
438-
humidity: parseFloat(parsedData.hourly[h].relativehumidity_2m),
439-
feelsLikeTemp: parseFloat(parsedData.hourly[h].apparent_temperature),
440-
rain: parseFloat(parsedData.hourly[h].rain),
441-
snow: parseFloat(parsedData.hourly[h].snowfall * 10),
442-
precipitationAmount: parseFloat(parsedData.hourly[h].precipitation),
443-
precipitationProbability: parseFloat(parsedData.hourly[h].precipitation_probability),
444-
uvIndex: parseFloat(parsedData.hourly[h].uv_index)
421+
temperature: parsedData.current_weather.temperature,
422+
weatherType: this.#convertWeatherType(parsedData.current_weather.weathercode, true)
445423
};
424+
425+
// Add hourly data if available
426+
if (parsedData.hourly && parsedData.hourly.time) {
427+
const currentTime = parsedData.current_weather.time;
428+
const hourlyIndex = parsedData.hourly.time.findIndex((time) => time === currentTime);
429+
const h = hourlyIndex !== -1 ? hourlyIndex : 0;
430+
431+
if (hourlyIndex === -1) {
432+
Log.warn("[weatherprovider.openmeteo] Could not find current time in hourly data, using index 0");
433+
}
434+
435+
current.humidity = parsedData.hourly.relativehumidity_2m?.[h];
436+
current.feelsLikeTemp = parsedData.hourly.apparent_temperature?.[h];
437+
current.rain = parsedData.hourly.rain?.[h];
438+
current.snow = parsedData.hourly.snowfall?.[h] ? parsedData.hourly.snowfall[h] * 10 : undefined;
439+
current.precipitationAmount = parsedData.hourly.precipitation?.[h];
440+
current.precipitationProbability = parsedData.hourly.precipitation_probability?.[h];
441+
current.uvIndex = parsedData.hourly.uv_index?.[h];
442+
}
443+
444+
// Add daily data if available
445+
if (parsedData.daily) {
446+
if (parsedData.daily.sunrise?.[0]) {
447+
current.sunrise = parsedData.daily.sunrise[0];
448+
}
449+
if (parsedData.daily.sunset?.[0]) {
450+
current.sunset = parsedData.daily.sunset[0];
451+
// Update weatherType with correct day/night status
452+
if (current.sunrise && current.sunset) {
453+
current.weatherType = this.#convertWeatherType(
454+
parsedData.current_weather.weathercode,
455+
this.#isDayTime(parsedData.current_weather.time, current.sunrise, current.sunset)
456+
);
457+
}
458+
}
459+
if (parsedData.daily.temperature_2m_min?.[0]) {
460+
current.minTemperature = parsedData.daily.temperature_2m_min[0];
461+
}
462+
if (parsedData.daily.temperature_2m_max?.[0]) {
463+
current.maxTemperature = parsedData.daily.temperature_2m_max[0];
464+
}
465+
}
466+
467+
return current;
446468
}
447469

448470
#generateWeatherObjectsFromForecast (parsedData) {

defaultmodules/weather/weatherobject.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ class WeatherObject {
6969
* @returns {string} "sunset" or "sunrise"
7070
*/
7171
nextSunAction (date = moment()) {
72+
// Return null if sunrise/sunset data is unavailable
73+
if (!this.sunrise || !this.sunset) {
74+
return null;
75+
}
7276
return date.isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise";
7377
}
7478

@@ -84,6 +88,10 @@ class WeatherObject {
8488
* @returns {boolean} true if it is at dayTime
8589
*/
8690
isDayTime () {
91+
// Default to daytime if sunrise/sunset data unavailable
92+
if (!this.sunrise || !this.sunset) {
93+
return true;
94+
}
8795
const now = !this.date ? moment() : this.date;
8896
return now.isBetween(this.sunrise, this.sunset, undefined, "[]");
8997
}

0 commit comments

Comments
 (0)