diff --git a/CODEOWNERS b/CODEOWNERS index 6555e58c88a..3945feb927c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -159,7 +159,7 @@ homeassistant/components/mcp23017/* @jardiamj homeassistant/components/mediaroom/* @dgomes homeassistant/components/melissa/* @kennedyshead homeassistant/components/met/* @danielhiversen -homeassistant/components/meteo_france/* @victorcerutti +homeassistant/components/meteo_france/* @victorcerutti @oncleben31 homeassistant/components/meteoalarm/* @rolfberkenbosch homeassistant/components/miflora/* @danielhiversen @ChristianKuehnel homeassistant/components/mill/* @danielhiversen diff --git a/homeassistant/components/meteo_france/__init__.py b/homeassistant/components/meteo_france/__init__.py index df0292ec407..3e9f0cf75f3 100644 --- a/homeassistant/components/meteo_france/__init__.py +++ b/homeassistant/components/meteo_france/__init__.py @@ -31,6 +31,7 @@ SENSOR_TYPES = { 'next_rain': ['Next rain', 'min'], 'temperature': ['Temperature', TEMP_CELSIUS], 'uv': ['UV', None], + 'weather_alert': ['Weather Alert', None], } CONDITION_CLASSES = { @@ -77,6 +78,28 @@ def setup(hass, config): """Set up the Meteo-France component.""" hass.data[DATA_METEO_FRANCE] = {} + # Check if at least weather alert have to be monitored for one location. + need_weather_alert_watcher = False + for location in config[DOMAIN]: + if CONF_MONITORED_CONDITIONS in location \ + and 'weather_alert' in location[CONF_MONITORED_CONDITIONS]: + need_weather_alert_watcher = True + + # If weather alert monitoring is expected initiate a client to be used by + # all weather_alert entities. + if need_weather_alert_watcher: + from vigilancemeteo import VigilanceMeteoFranceProxy, \ + VigilanceMeteoError + + weather_alert_client = VigilanceMeteoFranceProxy() + try: + weather_alert_client.update_data() + except VigilanceMeteoError as exp: + _LOGGER.error(exp) + else: + weather_alert_client = None + hass.data[DATA_METEO_FRANCE]['weather_alert_client'] = weather_alert_client + for location in config[DOMAIN]: city = location[CONF_CITY] @@ -98,6 +121,7 @@ def setup(hass, config): if CONF_MONITORED_CONDITIONS in location: monitored_conditions = location[CONF_MONITORED_CONDITIONS] + _LOGGER.debug("meteo_france sensor platfrom loaded for %s", city) load_platform( hass, 'sensor', DOMAIN, { CONF_CITY: city, diff --git a/homeassistant/components/meteo_france/manifest.json b/homeassistant/components/meteo_france/manifest.json index 301d9538c20..b485458be40 100644 --- a/homeassistant/components/meteo_france/manifest.json +++ b/homeassistant/components/meteo_france/manifest.json @@ -3,10 +3,12 @@ "name": "Meteo france", "documentation": "https://www.home-assistant.io/components/meteo_france", "requirements": [ - "meteofrance==0.3.7" + "meteofrance==0.3.7", + "vigilancemeteo==3.0.0" ], "dependencies": [], "codeowners": [ - "@victorcerutti" + "@victorcerutti", + "@oncleben31" ] -} +} \ No newline at end of file diff --git a/homeassistant/components/meteo_france/sensor.py b/homeassistant/components/meteo_france/sensor.py index 122b91cae44..d30b58bdd5a 100644 --- a/homeassistant/components/meteo_france/sensor.py +++ b/homeassistant/components/meteo_france/sensor.py @@ -9,6 +9,7 @@ from . import ATTRIBUTION, CONF_CITY, DATA_METEO_FRANCE, SENSOR_TYPES _LOGGER = logging.getLogger(__name__) STATE_ATTR_FORECAST = '1h rain forecast' +STATE_ATTR_BULLETIN_TIME = 'Bulletin date' def setup_platform(hass, config, add_entities, discovery_info=None): @@ -19,18 +20,44 @@ def setup_platform(hass, config, add_entities, discovery_info=None): city = discovery_info[CONF_CITY] monitored_conditions = discovery_info[CONF_MONITORED_CONDITIONS] client = hass.data[DATA_METEO_FRANCE][city] + weather_alert_client = hass.data[DATA_METEO_FRANCE]['weather_alert_client'] - add_entities([MeteoFranceSensor(variable, client) + from vigilancemeteo import DepartmentWeatherAlert + + alert_watcher = None + if 'weather_alert' in monitored_conditions: + datas = hass.data[DATA_METEO_FRANCE][city].get_data() + # Check if a department code is available for this city. + if "dept" in datas: + try: + # If yes create the watcher DepartmentWeatherAlert object. + alert_watcher = DepartmentWeatherAlert(datas["dept"], + weather_alert_client) + except ValueError as exp: + _LOGGER.error(exp) + alert_watcher = None + else: + _LOGGER.info("weather alert watcher added for %s" + "in department %s", + city, datas["dept"]) + else: + _LOGGER.warning("No dept key found for '%s'. So weather alert " + "information won't be available", city) + # Exit and don't create the sensor if no department code available. + return + + add_entities([MeteoFranceSensor(variable, client, alert_watcher) for variable in monitored_conditions], True) class MeteoFranceSensor(Entity): """Representation of a Meteo-France sensor.""" - def __init__(self, condition, client): + def __init__(self, condition, client, alert_watcher): """Initialize the Meteo-France sensor.""" self._condition = condition self._client = client + self._alert_watcher = alert_watcher self._state = None self._data = {} @@ -48,12 +75,25 @@ class MeteoFranceSensor(Entity): @property def device_state_attributes(self): """Return the state attributes of the sensor.""" + # Attributes for next_rain sensor. if self._condition == 'next_rain' and 'rain_forecast' in self._data: return { **{STATE_ATTR_FORECAST: self._data['rain_forecast']}, ** self._data['next_rain_intervals'], **{ATTR_ATTRIBUTION: ATTRIBUTION} } + + # Attributes for weather_alert sensor. + if self._condition == 'weather_alert' \ + and self._alert_watcher is not None: + return { + **{STATE_ATTR_BULLETIN_TIME: + self._alert_watcher.bulletin_date}, + ** self._alert_watcher.alerts_list, + ATTR_ATTRIBUTION: ATTRIBUTION + } + + # Attributes for all other sensors. return {ATTR_ATTRIBUTION: ATTRIBUTION} @property @@ -66,7 +106,19 @@ class MeteoFranceSensor(Entity): try: self._client.update() self._data = self._client.get_data() - self._state = self._data[self._condition] + + if self._condition == 'weather_alert': + if self._alert_watcher is not None: + self._alert_watcher.update_department_status() + self._state = self._alert_watcher.department_color + _LOGGER.debug("weather alert watcher for %s updated. Proxy" + " have the status: %s", self._data['name'], + self._alert_watcher.proxy.status) + else: + _LOGGER.warning("No weather alert data for location %s", + self._data['name']) + else: + self._state = self._data[self._condition] except KeyError: _LOGGER.error("No condition %s for location %s", self._condition, self._data['name']) diff --git a/homeassistant/components/meteo_france/weather.py b/homeassistant/components/meteo_france/weather.py index b2b94c7622e..05b760e49f1 100644 --- a/homeassistant/components/meteo_france/weather.py +++ b/homeassistant/components/meteo_france/weather.py @@ -102,3 +102,11 @@ class MeteoFranceWeather(WeatherEntity): if condition in value: return key return condition + + @property + def device_state_attributes(self): + """Return the state attributes.""" + data = dict() + if self._data and "next_rain" in self._data: + data["next_rain"] = self._data["next_rain"] + return data diff --git a/requirements_all.txt b/requirements_all.txt index efe78e0b93f..c8d6911e712 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1820,6 +1820,9 @@ uvcclient==0.11.0 # homeassistant.components.venstar venstarcolortouch==0.7 +# homeassistant.components.meteo_france +vigilancemeteo==3.0.0 + # homeassistant.components.volkszaehler volkszaehler==0.1.2