mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Fix ecobee weather platform (#27369)
* Fix ecobee weather platform * Remove custom forecast attributes * Tidy up process forecast method * Fix lint complaints * Add missed weather symbol
This commit is contained in:
parent
baa750a3c7
commit
829cffd5de
@ -24,3 +24,31 @@ ECOBEE_MODEL_TO_NAME = {
|
|||||||
ECOBEE_PLATFORMS = ["binary_sensor", "climate", "sensor", "weather"]
|
ECOBEE_PLATFORMS = ["binary_sensor", "climate", "sensor", "weather"]
|
||||||
|
|
||||||
MANUFACTURER = "ecobee"
|
MANUFACTURER = "ecobee"
|
||||||
|
|
||||||
|
# Translates ecobee API weatherSymbol to HASS usable names
|
||||||
|
# https://www.ecobee.com/home/developer/api/documentation/v1/objects/WeatherForecast.shtml
|
||||||
|
ECOBEE_WEATHER_SYMBOL_TO_HASS = {
|
||||||
|
0: "sunny",
|
||||||
|
1: "partlycloudy",
|
||||||
|
2: "partlycloudy",
|
||||||
|
3: "cloudy",
|
||||||
|
4: "cloudy",
|
||||||
|
5: "cloudy",
|
||||||
|
6: "rainy",
|
||||||
|
7: "snowy-rainy",
|
||||||
|
8: "pouring",
|
||||||
|
9: "hail",
|
||||||
|
10: "snowy",
|
||||||
|
11: "snowy",
|
||||||
|
12: "snowy-rainy",
|
||||||
|
13: "snowy-heavy",
|
||||||
|
14: "hail",
|
||||||
|
15: "lightning-rainy",
|
||||||
|
16: "windy",
|
||||||
|
17: "tornado",
|
||||||
|
18: "fog",
|
||||||
|
19: "hazy",
|
||||||
|
20: "hazy",
|
||||||
|
21: "hazy",
|
||||||
|
-2: None,
|
||||||
|
}
|
||||||
|
@ -8,17 +8,19 @@ from homeassistant.components.weather import (
|
|||||||
ATTR_FORECAST_TEMP,
|
ATTR_FORECAST_TEMP,
|
||||||
ATTR_FORECAST_TEMP_LOW,
|
ATTR_FORECAST_TEMP_LOW,
|
||||||
ATTR_FORECAST_TIME,
|
ATTR_FORECAST_TIME,
|
||||||
|
ATTR_FORECAST_WIND_BEARING,
|
||||||
ATTR_FORECAST_WIND_SPEED,
|
ATTR_FORECAST_WIND_SPEED,
|
||||||
WeatherEntity,
|
WeatherEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.const import TEMP_FAHRENHEIT
|
from homeassistant.const import TEMP_FAHRENHEIT
|
||||||
|
|
||||||
from .const import DOMAIN, ECOBEE_MODEL_TO_NAME, MANUFACTURER, _LOGGER
|
from .const import (
|
||||||
|
DOMAIN,
|
||||||
ATTR_FORECAST_TEMP_HIGH = "temphigh"
|
ECOBEE_MODEL_TO_NAME,
|
||||||
ATTR_FORECAST_PRESSURE = "pressure"
|
ECOBEE_WEATHER_SYMBOL_TO_HASS,
|
||||||
ATTR_FORECAST_VISIBILITY = "visibility"
|
MANUFACTURER,
|
||||||
ATTR_FORECAST_HUMIDITY = "humidity"
|
_LOGGER,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||||
@ -94,7 +96,7 @@ class EcobeeWeather(WeatherEntity):
|
|||||||
def condition(self):
|
def condition(self):
|
||||||
"""Return the current condition."""
|
"""Return the current condition."""
|
||||||
try:
|
try:
|
||||||
return self.get_forecast(0, "condition")
|
return ECOBEE_WEATHER_SYMBOL_TO_HASS[self.get_forecast(0, "weatherSymbol")]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -131,7 +133,7 @@ class EcobeeWeather(WeatherEntity):
|
|||||||
def visibility(self):
|
def visibility(self):
|
||||||
"""Return the visibility."""
|
"""Return the visibility."""
|
||||||
try:
|
try:
|
||||||
return int(self.get_forecast(0, "visibility"))
|
return int(self.get_forecast(0, "visibility")) / 1000
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -154,45 +156,59 @@ class EcobeeWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def attribution(self):
|
def attribution(self):
|
||||||
"""Return the attribution."""
|
"""Return the attribution."""
|
||||||
if self.weather:
|
if not self.weather:
|
||||||
station = self.weather.get("weatherStation", "UNKNOWN")
|
return None
|
||||||
time = self.weather.get("timestamp", "UNKNOWN")
|
|
||||||
return f"Ecobee weather provided by {station} at {time}"
|
station = self.weather.get("weatherStation", "UNKNOWN")
|
||||||
return None
|
time = self.weather.get("timestamp", "UNKNOWN")
|
||||||
|
return f"Ecobee weather provided by {station} at {time} UTC"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def forecast(self):
|
def forecast(self):
|
||||||
"""Return the forecast array."""
|
"""Return the forecast array."""
|
||||||
try:
|
if "forecasts" not in self.weather:
|
||||||
forecasts = []
|
|
||||||
for day in self.weather["forecasts"]:
|
|
||||||
date_time = datetime.strptime(
|
|
||||||
day["dateTime"], "%Y-%m-%d %H:%M:%S"
|
|
||||||
).isoformat()
|
|
||||||
forecast = {
|
|
||||||
ATTR_FORECAST_TIME: date_time,
|
|
||||||
ATTR_FORECAST_CONDITION: day["condition"],
|
|
||||||
ATTR_FORECAST_TEMP: float(day["tempHigh"]) / 10,
|
|
||||||
}
|
|
||||||
if day["tempHigh"] == ECOBEE_STATE_UNKNOWN:
|
|
||||||
break
|
|
||||||
if day["tempLow"] != ECOBEE_STATE_UNKNOWN:
|
|
||||||
forecast[ATTR_FORECAST_TEMP_LOW] = float(day["tempLow"]) / 10
|
|
||||||
if day["pressure"] != ECOBEE_STATE_UNKNOWN:
|
|
||||||
forecast[ATTR_FORECAST_PRESSURE] = int(day["pressure"])
|
|
||||||
if day["windSpeed"] != ECOBEE_STATE_UNKNOWN:
|
|
||||||
forecast[ATTR_FORECAST_WIND_SPEED] = int(day["windSpeed"])
|
|
||||||
if day["visibility"] != ECOBEE_STATE_UNKNOWN:
|
|
||||||
forecast[ATTR_FORECAST_WIND_SPEED] = int(day["visibility"])
|
|
||||||
if day["relativeHumidity"] != ECOBEE_STATE_UNKNOWN:
|
|
||||||
forecast[ATTR_FORECAST_HUMIDITY] = int(day["relativeHumidity"])
|
|
||||||
forecasts.append(forecast)
|
|
||||||
return forecasts
|
|
||||||
except (ValueError, IndexError, KeyError):
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
forecasts = list()
|
||||||
|
for day in range(1, 5):
|
||||||
|
forecast = _process_forecast(self.weather["forecasts"][day])
|
||||||
|
if forecast is None:
|
||||||
|
continue
|
||||||
|
forecasts.append(forecast)
|
||||||
|
|
||||||
|
if forecasts:
|
||||||
|
return forecasts
|
||||||
|
return None
|
||||||
|
|
||||||
async def async_update(self):
|
async def async_update(self):
|
||||||
"""Get the latest weather data."""
|
"""Get the latest weather data."""
|
||||||
await self.data.update()
|
await self.data.update()
|
||||||
thermostat = self.data.ecobee.get_thermostat(self._index)
|
thermostat = self.data.ecobee.get_thermostat(self._index)
|
||||||
self.weather = thermostat.get("weather", None)
|
self.weather = thermostat.get("weather", None)
|
||||||
|
|
||||||
|
|
||||||
|
def _process_forecast(json):
|
||||||
|
"""Process a single ecobee API forecast to return expected values."""
|
||||||
|
forecast = dict()
|
||||||
|
try:
|
||||||
|
forecast[ATTR_FORECAST_TIME] = datetime.strptime(
|
||||||
|
json["dateTime"], "%Y-%m-%d %H:%M:%S"
|
||||||
|
).isoformat()
|
||||||
|
forecast[ATTR_FORECAST_CONDITION] = ECOBEE_WEATHER_SYMBOL_TO_HASS[
|
||||||
|
json["weatherSymbol"]
|
||||||
|
]
|
||||||
|
if json["tempHigh"] != ECOBEE_STATE_UNKNOWN:
|
||||||
|
forecast[ATTR_FORECAST_TEMP] = float(json["tempHigh"]) / 10
|
||||||
|
if json["tempLow"] != ECOBEE_STATE_UNKNOWN:
|
||||||
|
forecast[ATTR_FORECAST_TEMP_LOW] = float(json["tempLow"]) / 10
|
||||||
|
if json["windBearing"] != ECOBEE_STATE_UNKNOWN:
|
||||||
|
forecast[ATTR_FORECAST_WIND_BEARING] = int(json["windBearing"])
|
||||||
|
if json["windSpeed"] != ECOBEE_STATE_UNKNOWN:
|
||||||
|
forecast[ATTR_FORECAST_WIND_SPEED] = int(json["windSpeed"])
|
||||||
|
|
||||||
|
except (ValueError, IndexError, KeyError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if forecast:
|
||||||
|
return forecast
|
||||||
|
return None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user