Skip to content

Commit 4a851d7

Browse files
fix(envcanada): handle empty currentConditions element
Environment Canada's XML feed now returns <currentConditions/> as an empty element. Adapt by extracting current weather from the first forecast period instead. Additional fixes: - Add missing return when city page URL not found - Restore sunrise/sunset data (from riseSet element) - Accept both "high" and "low" temperature classes
1 parent e417f32 commit 4a851d7

1 file changed

Lines changed: 28 additions & 24 deletions

File tree

defaultmodules/weather/providers/envcanada.js

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ class EnvCanadaProvider {
8484
const cityPageURL = this.#extractCityPageURL(html);
8585

8686
if (!cityPageURL) {
87-
// This can happen during hour transitions when old responses arrive
87+
// This can happen during hour transitions when old responses arrive
8888
Log.debug("[envcanada] Could not find city page URL (may be stale response from previous hour)");
89+
return;
8990
}
9091

9192
if (cityPageURL === this.lastCityPageURL) {
@@ -154,8 +155,17 @@ class EnvCanadaProvider {
154155
#generateCurrentWeather (xml) {
155156
const current = { date: new Date() };
156157

157-
// Temperature (with caching for missing values)
158-
const temp = this.#extract(xml, /<currentConditions>.*?<temperature[^>]*>(.*?)<\/temperature>/s);
158+
// Since <currentConditions/> is often empty, extract from first forecast period
159+
const firstForecast = xml.match(/<forecast>(.*?)<\/forecast>/s);
160+
if (!firstForecast) {
161+
Log.warn("[envcanada] No forecast data available");
162+
return current;
163+
}
164+
165+
const forecastXml = firstForecast[1];
166+
167+
// Temperature from first forecast (class can be "high" or "low" depending on time of day)
168+
const temp = this.#extract(forecastXml, /<temperature[^>]*>(.*?)<\/temperature>/);
159169
if (temp && temp !== "") {
160170
current.temperature = parseFloat(temp);
161171
this.cacheCurrentTemp = current.temperature;
@@ -165,32 +175,26 @@ class EnvCanadaProvider {
165175
current.temperature = null;
166176
}
167177

168-
// Wind
169-
const windSpeed = this.#extract(xml, /<wind>.*?<speed[^>]*>(.*?)<\/speed>/s);
170-
current.windSpeed = (windSpeed === "calm") ? 0 : convertKmhToMs(parseFloat(windSpeed));
178+
// Wind speed
179+
const windSpeed = this.#extract(forecastXml, /<speed[^>]*>(.*?)<\/speed>/);
180+
if (windSpeed) {
181+
current.windSpeed = (windSpeed === "calm") ? 0 : convertKmhToMs(parseFloat(windSpeed));
182+
}
171183

172-
const windBearing = this.#extract(xml, /<wind>.*?<bearing[^>]*>(.*?)<\/bearing>/s);
184+
const windBearing = this.#extract(forecastXml, /<bearing[^>]*>(.*?)<\/bearing>/);
173185
if (windBearing) current.windFromDirection = parseFloat(windBearing);
174186

175-
// Humidity
176-
const humidity = this.#extract(xml, /<relativeHumidity[^>]*>(.*?)<\/relativeHumidity>/);
177-
if (humidity) current.humidity = parseFloat(humidity);
178-
179-
// Feels like
180-
current.feelsLikeTemp = current.temperature;
181-
const windChill = this.#extract(xml, /<windChill[^>]*>(.*?)<\/windChill>/);
182-
const humidex = this.#extract(xml, /<humidex[^>]*>(.*?)<\/humidex>/);
183-
if (windChill) {
184-
current.feelsLikeTemp = parseFloat(windChill);
185-
} else if (humidex) {
186-
current.feelsLikeTemp = parseFloat(humidex);
187-
}
188-
189-
// Weather type
190-
const iconCode = this.#extract(xml, /<currentConditions>.*?<iconCode[^>]*>(.*?)<\/iconCode>/s);
187+
// Weather type from icon code
188+
const iconCode = this.#extract(forecastXml, /<iconCode[^>]*>(.*?)<\/iconCode>/);
191189
if (iconCode) current.weatherType = this.#convertWeatherType(iconCode);
192190

193-
// Sunrise/sunset
191+
// Precipitation probability
192+
const pop = this.#extract(forecastXml, /<pop[^>]*>(.*?)<\/pop>/);
193+
if (pop && pop !== "") {
194+
current.precipitationProbability = parseFloat(pop);
195+
}
196+
197+
// Sunrise/sunset (from riseSet, independent of currentConditions)
194198
const sunriseTime = this.#extract(xml, /<dateTime[^>]*name="sunrise"[^>]*>.*?<timeStamp>(.*?)<\/timeStamp>/s);
195199
const sunsetTime = this.#extract(xml, /<dateTime[^>]*name="sunset"[^>]*>.*?<timeStamp>(.*?)<\/timeStamp>/s);
196200
if (sunriseTime) current.sunrise = this.#parseECTime(sunriseTime);

0 commit comments

Comments
 (0)