1
mirror of https://github.com/home-assistant/core synced 2024-09-25 00:41:32 +02:00

Update Environment Canada platforms (#24884)

* Add support for French

* Move labels to env_canada

* Bump env_canada to 0.0.17, change update frequency to 1 minute

* Update requirements_all.txt

* Set entity IDs separate from labels

* Flake error

* Remove monitored conditions

* Use next hourly forecast for missing conditions

* Switch sensors to unique_id

* Flake error

* Requested changes

* Simplify setting location parameters
This commit is contained in:
michaeldavie 2019-07-13 12:14:29 -04:00 committed by Pascal Vizeli
parent 1e474bb5da
commit a147a189ca
5 changed files with 89 additions and 110 deletions

View File

@ -45,14 +45,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if config.get(CONF_STATION):
radar_object = ECRadar(station_id=config[CONF_STATION],
precip_type=config.get(CONF_PRECIP_TYPE))
elif config.get(CONF_LATITUDE) and config.get(CONF_LONGITUDE):
radar_object = ECRadar(coordinates=(config[CONF_LATITUDE],
config[CONF_LONGITUDE]),
precip_type=config.get(CONF_PRECIP_TYPE))
else:
radar_object = ECRadar(coordinates=(hass.config.latitude,
hass.config.longitude),
precip_type=config.get(CONF_PRECIP_TYPE))
lat = config.get(CONF_LATITUDE, hass.config.latitude)
lon = config.get(CONF_LONGITUDE, hass.config.longitude)
radar_object = ECRadar(coordinates=(lat, lon))
add_devices([ECCamera(radar_object, config.get(CONF_NAME))], True)

View File

@ -3,7 +3,7 @@
"name": "Environment Canada",
"documentation": "https://www.home-assistant.io/components/environment_canada",
"requirements": [
"env_canada==0.0.10"
"env_canada==0.0.18"
],
"dependencies": [],
"codeowners": [

View File

@ -4,7 +4,7 @@ Support for the Environment Canada weather service.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.environment_canada/
"""
import datetime
from datetime import datetime, timedelta
import logging
import re
@ -12,11 +12,10 @@ import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import (
CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, CONF_NAME, CONF_LATITUDE,
CONF_LONGITUDE, ATTR_ATTRIBUTION, ATTR_LOCATION, ATTR_HIDDEN)
TEMP_CELSIUS, CONF_LATITUDE, CONF_LONGITUDE, ATTR_ATTRIBUTION,
ATTR_LOCATION)
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
import homeassistant.util.dt as dt
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
@ -28,43 +27,9 @@ ATTR_TIME = 'alert time'
CONF_ATTRIBUTION = "Data provided by Environment Canada"
CONF_STATION = 'station'
CONF_LANGUAGE = 'language'
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=10)
SENSOR_TYPES = {
'temperature': {'name': 'Temperature',
'unit': TEMP_CELSIUS},
'dewpoint': {'name': 'Dew Point',
'unit': TEMP_CELSIUS},
'wind_chill': {'name': 'Wind Chill',
'unit': TEMP_CELSIUS},
'humidex': {'name': 'Humidex',
'unit': TEMP_CELSIUS},
'pressure': {'name': 'Pressure',
'unit': 'kPa'},
'tendency': {'name': 'Tendency'},
'humidity': {'name': 'Humidity',
'unit': '%'},
'visibility': {'name': 'Visibility',
'unit': 'km'},
'condition': {'name': 'Condition'},
'wind_speed': {'name': 'Wind Speed',
'unit': 'km/h'},
'wind_gust': {'name': 'Wind Gust',
'unit': 'km/h'},
'wind_dir': {'name': 'Wind Direction'},
'high_temp': {'name': 'High Temperature',
'unit': TEMP_CELSIUS},
'low_temp': {'name': 'Low Temperature',
'unit': TEMP_CELSIUS},
'pop': {'name': 'Chance of Precip.',
'unit': '%'},
'warnings': {'name': 'Warnings'},
'watches': {'name': 'Watches'},
'advisories': {'name': 'Advisories'},
'statements': {'name': 'Statements'},
'endings': {'name': 'Ended'}
}
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
def validate_station(station):
@ -77,52 +42,58 @@ def validate_station(station):
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)):
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_LANGUAGE, default='english'):
vol.In(['english', 'french']),
vol.Optional(CONF_STATION): validate_station,
vol.Inclusive(CONF_LATITUDE, 'latlon'): cv.latitude,
vol.Inclusive(CONF_LONGITUDE, 'latlon'): cv.longitude,
})
def setup_platform(hass, config, add_devices, discovery_info=None):
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Environment Canada sensor."""
from env_canada import ECData
if config.get(CONF_STATION):
ec_data = ECData(station_id=config[CONF_STATION])
elif config.get(CONF_LATITUDE) and config.get(CONF_LONGITUDE):
ec_data = ECData(coordinates=(config[CONF_LATITUDE],
config[CONF_LONGITUDE]))
ec_data = ECData(station_id=config[CONF_STATION],
language=config.get(CONF_LANGUAGE))
else:
ec_data = ECData(coordinates=(hass.config.latitude,
hass.config.longitude))
lat = config.get(CONF_LATITUDE, hass.config.latitude)
lon = config.get(CONF_LONGITUDE, hass.config.longitude)
ec_data = ECData(coordinates=(lat, lon),
language=config.get(CONF_LANGUAGE))
add_devices([ECSensor(sensor_type, ec_data, config.get(CONF_NAME))
for sensor_type in config[CONF_MONITORED_CONDITIONS]],
True)
sensor_list = list(ec_data.conditions.keys()) + list(ec_data.alerts.keys())
sensor_list.remove('icon_code')
add_entities([ECSensor(sensor_type,
ec_data)
for sensor_type in sensor_list],
True)
class ECSensor(Entity):
"""Implementation of an Environment Canada sensor."""
def __init__(self, sensor_type, ec_data, platform_name):
def __init__(self, sensor_type, ec_data):
"""Initialize the sensor."""
self.sensor_type = sensor_type
self.ec_data = ec_data
self.platform_name = platform_name
self._unique_id = None
self._name = None
self._state = None
self._attr = None
self._unit = None
@property
def unique_id(self) -> str:
"""Return the unique ID of the sensor."""
return self._unique_id
@property
def name(self):
"""Return the name of the sensor."""
if self.platform_name is None:
return SENSOR_TYPES[self.sensor_type]['name']
return ' '.join([self.platform_name,
SENSOR_TYPES[self.sensor_type]['name']])
return self._name
@property
def state(self):
@ -137,7 +108,7 @@ class ECSensor(Entity):
@property
def unit_of_measurement(self):
"""Return the units of measurement."""
return SENSOR_TYPES[self.sensor_type].get('unit')
return self._unit
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
@ -145,34 +116,43 @@ class ECSensor(Entity):
self.ec_data.update()
self.ec_data.conditions.update(self.ec_data.alerts)
self._attr = {}
conditions = self.ec_data.conditions
metadata = self.ec_data.metadata
sensor_data = conditions.get(self.sensor_type)
sensor_data = self.ec_data.conditions.get(self.sensor_type)
if isinstance(sensor_data, list):
self._unique_id = '{}-{}'.format(metadata['location'],
self.sensor_type)
self._attr = {}
self._name = sensor_data.get('label')
value = sensor_data.get('value')
if isinstance(value, list):
self._state = ' | '.join([str(s.get('title'))
for s in sensor_data])
for s in value])
self._attr.update({
ATTR_DETAIL: ' | '.join([str(s.get('detail'))
for s in sensor_data]),
for s in value]),
ATTR_TIME: ' | '.join([str(s.get('date'))
for s in sensor_data])
for s in value])
})
else:
self._state = sensor_data
self._state = value
timestamp = self.ec_data.conditions.get('timestamp')
if timestamp:
updated_utc = datetime.datetime.strptime(timestamp, '%Y%m%d%H%M%S')
updated_local = dt.as_local(updated_utc).isoformat()
if sensor_data.get('unit') == 'C':
self._unit = TEMP_CELSIUS
else:
updated_local = None
self._unit = sensor_data.get('unit')
hidden = bool(self._state is None or self._state == '')
timestamp = metadata.get('timestamp')
if timestamp:
updated_utc = datetime.strptime(timestamp,
'%Y%m%d%H%M%S').isoformat()
else:
updated_utc = None
self._attr.update({
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
ATTR_UPDATED: updated_local,
ATTR_LOCATION: self.ec_data.conditions.get('location'),
ATTR_STATION: self.ec_data.conditions.get('station'),
ATTR_HIDDEN: hidden
ATTR_UPDATED: updated_utc,
ATTR_LOCATION: metadata.get('location'),
ATTR_STATION: metadata.get('station'),
})

View File

@ -67,12 +67,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Environment Canada weather."""
if config.get(CONF_STATION):
ec_data = ECData(station_id=config[CONF_STATION])
elif config.get(CONF_LATITUDE) and config.get(CONF_LONGITUDE):
ec_data = ECData(coordinates=(config[CONF_LATITUDE],
config[CONF_LONGITUDE]))
else:
ec_data = ECData(coordinates=(hass.config.latitude,
hass.config.longitude))
lat = config.get(CONF_LATITUDE, hass.config.latitude)
lon = config.get(CONF_LONGITUDE, hass.config.longitude)
ec_data = ECData(coordinates=(lat, lon))
add_devices([ECWeather(ec_data, config)])
@ -96,13 +94,15 @@ class ECWeather(WeatherEntity):
"""Return the name of the weather entity."""
if self.platform_name:
return self.platform_name
return self.ec_data.conditions['location']
return self.ec_data.metadata.get('location')
@property
def temperature(self):
"""Return the temperature."""
if self.ec_data.conditions.get('temperature'):
return float(self.ec_data.conditions['temperature'])
if self.ec_data.conditions.get('temperature').get('value'):
return float(self.ec_data.conditions['temperature']['value'])
if self.ec_data.hourly_forecasts[0].get('temperature'):
return float(self.ec_data.hourly_forecasts[0]['temperature'])
return None
@property
@ -113,48 +113,51 @@ class ECWeather(WeatherEntity):
@property
def humidity(self):
"""Return the humidity."""
if self.ec_data.conditions.get('humidity'):
return float(self.ec_data.conditions['humidity'])
if self.ec_data.conditions.get('humidity').get('value'):
return float(self.ec_data.conditions['humidity']['value'])
return None
@property
def wind_speed(self):
"""Return the wind speed."""
if self.ec_data.conditions.get('wind_speed'):
return float(self.ec_data.conditions['wind_speed'])
if self.ec_data.conditions.get('wind_speed').get('value'):
return float(self.ec_data.conditions['wind_speed']['value'])
return None
@property
def wind_bearing(self):
"""Return the wind bearing."""
if self.ec_data.conditions.get('wind_bearing'):
return float(self.ec_data.conditions['wind_bearing'])
if self.ec_data.conditions.get('wind_bearing').get('value'):
return float(self.ec_data.conditions['wind_bearing']['value'])
return None
@property
def pressure(self):
"""Return the pressure."""
if self.ec_data.conditions.get('pressure'):
return 10 * float(self.ec_data.conditions['pressure'])
if self.ec_data.conditions.get('pressure').get('value'):
return 10 * float(self.ec_data.conditions['pressure']['value'])
return None
@property
def visibility(self):
"""Return the visibility."""
if self.ec_data.conditions.get('visibility'):
return float(self.ec_data.conditions['visibility'])
if self.ec_data.conditions.get('visibility').get('value'):
return float(self.ec_data.conditions['visibility']['value'])
return None
@property
def condition(self):
"""Return the weather condition."""
icon_code = self.ec_data.conditions.get('icon_code')
icon_code = None
if self.ec_data.conditions.get('icon_code').get('value'):
icon_code = self.ec_data.conditions['icon_code']['value']
elif self.ec_data.hourly_forecasts[0].get('icon_code'):
icon_code = self.ec_data.hourly_forecasts[0]['icon_code']
if icon_code:
return icon_code_to_condition(int(icon_code))
condition = self.ec_data.conditions.get('condition')
if condition:
return condition
return 'Condition not observed'
return ''
@property
def forecast(self):

View File

@ -430,7 +430,7 @@ enocean==0.50
enturclient==0.2.0
# homeassistant.components.environment_canada
env_canada==0.0.10
env_canada==0.0.18
# homeassistant.components.envirophat
# envirophat==0.0.6