mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00: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:
parent
1e474bb5da
commit
a147a189ca
@ -45,14 +45,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
if config.get(CONF_STATION):
|
if config.get(CONF_STATION):
|
||||||
radar_object = ECRadar(station_id=config[CONF_STATION],
|
radar_object = ECRadar(station_id=config[CONF_STATION],
|
||||||
precip_type=config.get(CONF_PRECIP_TYPE))
|
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:
|
else:
|
||||||
radar_object = ECRadar(coordinates=(hass.config.latitude,
|
lat = config.get(CONF_LATITUDE, hass.config.latitude)
|
||||||
hass.config.longitude),
|
lon = config.get(CONF_LONGITUDE, hass.config.longitude)
|
||||||
precip_type=config.get(CONF_PRECIP_TYPE))
|
radar_object = ECRadar(coordinates=(lat, lon))
|
||||||
|
|
||||||
add_devices([ECCamera(radar_object, config.get(CONF_NAME))], True)
|
add_devices([ECCamera(radar_object, config.get(CONF_NAME))], True)
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Environment Canada",
|
"name": "Environment Canada",
|
||||||
"documentation": "https://www.home-assistant.io/components/environment_canada",
|
"documentation": "https://www.home-assistant.io/components/environment_canada",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"env_canada==0.0.10"
|
"env_canada==0.0.18"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -4,7 +4,7 @@ Support for the Environment Canada weather service.
|
|||||||
For more details about this platform, please refer to the documentation at
|
For more details about this platform, please refer to the documentation at
|
||||||
https://home-assistant.io/components/sensor.environment_canada/
|
https://home-assistant.io/components/sensor.environment_canada/
|
||||||
"""
|
"""
|
||||||
import datetime
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -12,11 +12,10 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_MONITORED_CONDITIONS, TEMP_CELSIUS, CONF_NAME, CONF_LATITUDE,
|
TEMP_CELSIUS, CONF_LATITUDE, CONF_LONGITUDE, ATTR_ATTRIBUTION,
|
||||||
CONF_LONGITUDE, ATTR_ATTRIBUTION, ATTR_LOCATION, ATTR_HIDDEN)
|
ATTR_LOCATION)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.util import Throttle
|
from homeassistant.util import Throttle
|
||||||
import homeassistant.util.dt as dt
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -28,43 +27,9 @@ ATTR_TIME = 'alert time'
|
|||||||
|
|
||||||
CONF_ATTRIBUTION = "Data provided by Environment Canada"
|
CONF_ATTRIBUTION = "Data provided by Environment Canada"
|
||||||
CONF_STATION = 'station'
|
CONF_STATION = 'station'
|
||||||
|
CONF_LANGUAGE = 'language'
|
||||||
|
|
||||||
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=10)
|
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
|
||||||
|
|
||||||
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'}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def validate_station(station):
|
def validate_station(station):
|
||||||
@ -77,52 +42,58 @@ def validate_station(station):
|
|||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)):
|
vol.Required(CONF_LANGUAGE, default='english'):
|
||||||
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
|
vol.In(['english', 'french']),
|
||||||
vol.Optional(CONF_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_STATION): validate_station,
|
vol.Optional(CONF_STATION): validate_station,
|
||||||
vol.Inclusive(CONF_LATITUDE, 'latlon'): cv.latitude,
|
vol.Inclusive(CONF_LATITUDE, 'latlon'): cv.latitude,
|
||||||
vol.Inclusive(CONF_LONGITUDE, 'latlon'): cv.longitude,
|
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."""
|
"""Set up the Environment Canada sensor."""
|
||||||
from env_canada import ECData
|
from env_canada import ECData
|
||||||
|
|
||||||
if config.get(CONF_STATION):
|
if config.get(CONF_STATION):
|
||||||
ec_data = ECData(station_id=config[CONF_STATION])
|
ec_data = ECData(station_id=config[CONF_STATION],
|
||||||
elif config.get(CONF_LATITUDE) and config.get(CONF_LONGITUDE):
|
language=config.get(CONF_LANGUAGE))
|
||||||
ec_data = ECData(coordinates=(config[CONF_LATITUDE],
|
|
||||||
config[CONF_LONGITUDE]))
|
|
||||||
else:
|
else:
|
||||||
ec_data = ECData(coordinates=(hass.config.latitude,
|
lat = config.get(CONF_LATITUDE, hass.config.latitude)
|
||||||
hass.config.longitude))
|
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))
|
sensor_list = list(ec_data.conditions.keys()) + list(ec_data.alerts.keys())
|
||||||
for sensor_type in config[CONF_MONITORED_CONDITIONS]],
|
sensor_list.remove('icon_code')
|
||||||
True)
|
add_entities([ECSensor(sensor_type,
|
||||||
|
ec_data)
|
||||||
|
for sensor_type in sensor_list],
|
||||||
|
True)
|
||||||
|
|
||||||
|
|
||||||
class ECSensor(Entity):
|
class ECSensor(Entity):
|
||||||
"""Implementation of an Environment Canada sensor."""
|
"""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."""
|
"""Initialize the sensor."""
|
||||||
self.sensor_type = sensor_type
|
self.sensor_type = sensor_type
|
||||||
self.ec_data = ec_data
|
self.ec_data = ec_data
|
||||||
self.platform_name = platform_name
|
|
||||||
|
self._unique_id = None
|
||||||
|
self._name = None
|
||||||
self._state = None
|
self._state = None
|
||||||
self._attr = 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
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Return the name of the sensor."""
|
"""Return the name of the sensor."""
|
||||||
if self.platform_name is None:
|
return self._name
|
||||||
return SENSOR_TYPES[self.sensor_type]['name']
|
|
||||||
|
|
||||||
return ' '.join([self.platform_name,
|
|
||||||
SENSOR_TYPES[self.sensor_type]['name']])
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self):
|
def state(self):
|
||||||
@ -137,7 +108,7 @@ class ECSensor(Entity):
|
|||||||
@property
|
@property
|
||||||
def unit_of_measurement(self):
|
def unit_of_measurement(self):
|
||||||
"""Return the units of measurement."""
|
"""Return the units of measurement."""
|
||||||
return SENSOR_TYPES[self.sensor_type].get('unit')
|
return self._unit
|
||||||
|
|
||||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||||
def update(self):
|
def update(self):
|
||||||
@ -145,34 +116,43 @@ class ECSensor(Entity):
|
|||||||
self.ec_data.update()
|
self.ec_data.update()
|
||||||
self.ec_data.conditions.update(self.ec_data.alerts)
|
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)
|
self._unique_id = '{}-{}'.format(metadata['location'],
|
||||||
if isinstance(sensor_data, list):
|
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'))
|
self._state = ' | '.join([str(s.get('title'))
|
||||||
for s in sensor_data])
|
for s in value])
|
||||||
self._attr.update({
|
self._attr.update({
|
||||||
ATTR_DETAIL: ' | '.join([str(s.get('detail'))
|
ATTR_DETAIL: ' | '.join([str(s.get('detail'))
|
||||||
for s in sensor_data]),
|
for s in value]),
|
||||||
ATTR_TIME: ' | '.join([str(s.get('date'))
|
ATTR_TIME: ' | '.join([str(s.get('date'))
|
||||||
for s in sensor_data])
|
for s in value])
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
self._state = sensor_data
|
self._state = value
|
||||||
|
|
||||||
timestamp = self.ec_data.conditions.get('timestamp')
|
if sensor_data.get('unit') == 'C':
|
||||||
if timestamp:
|
self._unit = TEMP_CELSIUS
|
||||||
updated_utc = datetime.datetime.strptime(timestamp, '%Y%m%d%H%M%S')
|
|
||||||
updated_local = dt.as_local(updated_utc).isoformat()
|
|
||||||
else:
|
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({
|
self._attr.update({
|
||||||
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
|
ATTR_ATTRIBUTION: CONF_ATTRIBUTION,
|
||||||
ATTR_UPDATED: updated_local,
|
ATTR_UPDATED: updated_utc,
|
||||||
ATTR_LOCATION: self.ec_data.conditions.get('location'),
|
ATTR_LOCATION: metadata.get('location'),
|
||||||
ATTR_STATION: self.ec_data.conditions.get('station'),
|
ATTR_STATION: metadata.get('station'),
|
||||||
ATTR_HIDDEN: hidden
|
|
||||||
})
|
})
|
||||||
|
@ -67,12 +67,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
"""Set up the Environment Canada weather."""
|
"""Set up the Environment Canada weather."""
|
||||||
if config.get(CONF_STATION):
|
if config.get(CONF_STATION):
|
||||||
ec_data = ECData(station_id=config[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:
|
else:
|
||||||
ec_data = ECData(coordinates=(hass.config.latitude,
|
lat = config.get(CONF_LATITUDE, hass.config.latitude)
|
||||||
hass.config.longitude))
|
lon = config.get(CONF_LONGITUDE, hass.config.longitude)
|
||||||
|
ec_data = ECData(coordinates=(lat, lon))
|
||||||
|
|
||||||
add_devices([ECWeather(ec_data, config)])
|
add_devices([ECWeather(ec_data, config)])
|
||||||
|
|
||||||
@ -96,13 +94,15 @@ class ECWeather(WeatherEntity):
|
|||||||
"""Return the name of the weather entity."""
|
"""Return the name of the weather entity."""
|
||||||
if self.platform_name:
|
if self.platform_name:
|
||||||
return self.platform_name
|
return self.platform_name
|
||||||
return self.ec_data.conditions['location']
|
return self.ec_data.metadata.get('location')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature(self):
|
def temperature(self):
|
||||||
"""Return the temperature."""
|
"""Return the temperature."""
|
||||||
if self.ec_data.conditions.get('temperature'):
|
if self.ec_data.conditions.get('temperature').get('value'):
|
||||||
return float(self.ec_data.conditions['temperature'])
|
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
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -113,48 +113,51 @@ class ECWeather(WeatherEntity):
|
|||||||
@property
|
@property
|
||||||
def humidity(self):
|
def humidity(self):
|
||||||
"""Return the humidity."""
|
"""Return the humidity."""
|
||||||
if self.ec_data.conditions.get('humidity'):
|
if self.ec_data.conditions.get('humidity').get('value'):
|
||||||
return float(self.ec_data.conditions['humidity'])
|
return float(self.ec_data.conditions['humidity']['value'])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wind_speed(self):
|
def wind_speed(self):
|
||||||
"""Return the wind speed."""
|
"""Return the wind speed."""
|
||||||
if self.ec_data.conditions.get('wind_speed'):
|
if self.ec_data.conditions.get('wind_speed').get('value'):
|
||||||
return float(self.ec_data.conditions['wind_speed'])
|
return float(self.ec_data.conditions['wind_speed']['value'])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wind_bearing(self):
|
def wind_bearing(self):
|
||||||
"""Return the wind bearing."""
|
"""Return the wind bearing."""
|
||||||
if self.ec_data.conditions.get('wind_bearing'):
|
if self.ec_data.conditions.get('wind_bearing').get('value'):
|
||||||
return float(self.ec_data.conditions['wind_bearing'])
|
return float(self.ec_data.conditions['wind_bearing']['value'])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pressure(self):
|
def pressure(self):
|
||||||
"""Return the pressure."""
|
"""Return the pressure."""
|
||||||
if self.ec_data.conditions.get('pressure'):
|
if self.ec_data.conditions.get('pressure').get('value'):
|
||||||
return 10 * float(self.ec_data.conditions['pressure'])
|
return 10 * float(self.ec_data.conditions['pressure']['value'])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def visibility(self):
|
def visibility(self):
|
||||||
"""Return the visibility."""
|
"""Return the visibility."""
|
||||||
if self.ec_data.conditions.get('visibility'):
|
if self.ec_data.conditions.get('visibility').get('value'):
|
||||||
return float(self.ec_data.conditions['visibility'])
|
return float(self.ec_data.conditions['visibility']['value'])
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def condition(self):
|
def condition(self):
|
||||||
"""Return the weather condition."""
|
"""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:
|
if icon_code:
|
||||||
return icon_code_to_condition(int(icon_code))
|
return icon_code_to_condition(int(icon_code))
|
||||||
condition = self.ec_data.conditions.get('condition')
|
return ''
|
||||||
if condition:
|
|
||||||
return condition
|
|
||||||
return 'Condition not observed'
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def forecast(self):
|
def forecast(self):
|
||||||
|
@ -430,7 +430,7 @@ enocean==0.50
|
|||||||
enturclient==0.2.0
|
enturclient==0.2.0
|
||||||
|
|
||||||
# homeassistant.components.environment_canada
|
# homeassistant.components.environment_canada
|
||||||
env_canada==0.0.10
|
env_canada==0.0.18
|
||||||
|
|
||||||
# homeassistant.components.envirophat
|
# homeassistant.components.envirophat
|
||||||
# envirophat==0.0.6
|
# envirophat==0.0.6
|
||||||
|
Loading…
x
Reference in New Issue
Block a user