mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
WUnderground unique ids (#13311)
* WUnderground unique_id * Remove async_generate_entity_id * Lint * Address comment
This commit is contained in:
parent
ce98dfe395
commit
14c7fa8882
@ -15,13 +15,13 @@ import voluptuous as vol
|
||||
|
||||
from homeassistant.helpers.typing import HomeAssistantType, ConfigType
|
||||
from homeassistant.components import sensor
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, ENTITY_ID_FORMAT
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
CONF_MONITORED_CONDITIONS, CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE,
|
||||
TEMP_FAHRENHEIT, TEMP_CELSIUS, LENGTH_INCHES, LENGTH_KILOMETERS,
|
||||
LENGTH_MILES, LENGTH_FEET, ATTR_ATTRIBUTION, CONF_ENTITY_NAMESPACE)
|
||||
LENGTH_MILES, LENGTH_FEET, ATTR_ATTRIBUTION)
|
||||
from homeassistant.exceptions import PlatformNotReady
|
||||
from homeassistant.helpers.entity import Entity, async_generate_entity_id
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.util import Throttle
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
@ -618,8 +618,6 @@ LANG_CODES = [
|
||||
'CY', 'SN', 'JI', 'YI',
|
||||
]
|
||||
|
||||
DEFAULT_ENTITY_NAMESPACE = 'pws'
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_API_KEY): cv.string,
|
||||
vol.Optional(CONF_PWS_ID): cv.string,
|
||||
@ -629,31 +627,30 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Inclusive(CONF_LONGITUDE, 'coordinates',
|
||||
'Latitude and longitude must exist together'): cv.longitude,
|
||||
vol.Required(CONF_MONITORED_CONDITIONS):
|
||||
vol.All(cv.ensure_list, vol.Length(min=1), [vol.In(SENSOR_TYPES)]),
|
||||
vol.Optional(CONF_ENTITY_NAMESPACE,
|
||||
default=DEFAULT_ENTITY_NAMESPACE): cv.string,
|
||||
vol.All(cv.ensure_list, vol.Length(min=1), [vol.In(SENSOR_TYPES)])
|
||||
})
|
||||
|
||||
# Stores a list of entity ids we added in order to support multiple stations
|
||||
# at once.
|
||||
ADDED_ENTITY_IDS_KEY = 'wunderground_added_entity_ids'
|
||||
|
||||
|
||||
async def async_setup_platform(hass: HomeAssistantType, config: ConfigType,
|
||||
async_add_devices, discovery_info=None):
|
||||
"""Set up the WUnderground sensor."""
|
||||
hass.data.setdefault(ADDED_ENTITY_IDS_KEY, set())
|
||||
|
||||
latitude = config.get(CONF_LATITUDE, hass.config.latitude)
|
||||
longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
|
||||
namespace = config.get(CONF_ENTITY_NAMESPACE)
|
||||
pws_id = config.get(CONF_PWS_ID)
|
||||
|
||||
rest = WUndergroundData(
|
||||
hass, config.get(CONF_API_KEY), config.get(CONF_PWS_ID),
|
||||
hass, config.get(CONF_API_KEY), pws_id,
|
||||
config.get(CONF_LANG), latitude, longitude)
|
||||
|
||||
if pws_id is None:
|
||||
unique_id_base = "@{:06f},{:06f}".format(longitude, latitude)
|
||||
else:
|
||||
# Manually specified weather station, use that for unique_id
|
||||
unique_id_base = pws_id
|
||||
sensors = []
|
||||
for variable in config[CONF_MONITORED_CONDITIONS]:
|
||||
sensors.append(WUndergroundSensor(hass, rest, variable, namespace))
|
||||
sensors.append(WUndergroundSensor(hass, rest, variable,
|
||||
unique_id_base))
|
||||
|
||||
await rest.async_update()
|
||||
if not rest.data:
|
||||
@ -666,7 +663,7 @@ class WUndergroundSensor(Entity):
|
||||
"""Implementing the WUnderground sensor."""
|
||||
|
||||
def __init__(self, hass: HomeAssistantType, rest, condition,
|
||||
namespace: str):
|
||||
unique_id_base: str):
|
||||
"""Initialize the sensor."""
|
||||
self.rest = rest
|
||||
self._condition = condition
|
||||
@ -678,12 +675,10 @@ class WUndergroundSensor(Entity):
|
||||
self._entity_picture = None
|
||||
self._unit_of_measurement = self._cfg_expand("unit_of_measurement")
|
||||
self.rest.request_feature(SENSOR_TYPES[condition].feature)
|
||||
current_ids = set(hass.states.async_entity_ids(sensor.DOMAIN))
|
||||
current_ids |= hass.data[ADDED_ENTITY_IDS_KEY]
|
||||
self.entity_id = async_generate_entity_id(
|
||||
ENTITY_ID_FORMAT, "{} {}".format(namespace, condition),
|
||||
current_ids=current_ids)
|
||||
hass.data[ADDED_ENTITY_IDS_KEY].add(self.entity_id)
|
||||
# This is only the suggested entity id, it might get changed by
|
||||
# the entity registry later.
|
||||
self.entity_id = sensor.ENTITY_ID_FORMAT.format('pws_' + condition)
|
||||
self._unique_id = "{},{}".format(unique_id_base, condition)
|
||||
|
||||
def _cfg_expand(self, what, default=None):
|
||||
"""Parse and return sensor data."""
|
||||
@ -763,6 +758,11 @@ class WUndergroundSensor(Entity):
|
||||
self._entity_picture = re.sub(r'^http://', 'https://',
|
||||
url, flags=re.IGNORECASE)
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Return a unique ID."""
|
||||
return self._unique_id
|
||||
|
||||
|
||||
class WUndergroundData(object):
|
||||
"""Get data from WUnderground."""
|
||||
|
@ -148,10 +148,11 @@ def test_invalid_data(hass, aioclient_mock):
|
||||
async def test_entity_id_with_multiple_stations(hass, aioclient_mock):
|
||||
"""Test not generating duplicate entity ids with multiple stations."""
|
||||
aioclient_mock.get(URL, text=load_fixture('wunderground-valid.json'))
|
||||
aioclient_mock.get(PWS_URL, text=load_fixture('wunderground-valid.json'))
|
||||
|
||||
config = [
|
||||
VALID_CONFIG,
|
||||
{**VALID_CONFIG, 'entity_namespace': 'hi'}
|
||||
{**VALID_CONFIG_PWS, 'entity_namespace': 'hi'}
|
||||
]
|
||||
await async_setup_component(hass, 'sensor', {'sensor': config})
|
||||
await hass.async_block_till_done()
|
||||
@ -160,6 +161,25 @@ async def test_entity_id_with_multiple_stations(hass, aioclient_mock):
|
||||
assert state is not None
|
||||
assert state.state == 'Clear'
|
||||
|
||||
state = hass.states.get('sensor.hi_weather')
|
||||
state = hass.states.get('sensor.hi_pws_weather')
|
||||
assert state is not None
|
||||
assert state.state == 'Clear'
|
||||
|
||||
|
||||
async def test_fails_because_of_unique_id(hass, aioclient_mock):
|
||||
"""Test same config twice fails because of unique_id."""
|
||||
aioclient_mock.get(URL, text=load_fixture('wunderground-valid.json'))
|
||||
aioclient_mock.get(PWS_URL, text=load_fixture('wunderground-valid.json'))
|
||||
|
||||
config = [
|
||||
VALID_CONFIG,
|
||||
{**VALID_CONFIG, 'entity_namespace': 'hi'},
|
||||
VALID_CONFIG_PWS
|
||||
]
|
||||
await async_setup_component(hass, 'sensor', {'sensor': config})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
states = hass.states.async_all()
|
||||
expected = len(VALID_CONFIG['monitored_conditions']) + \
|
||||
len(VALID_CONFIG_PWS['monitored_conditions'])
|
||||
assert len(states) == expected
|
||||
|
Loading…
x
Reference in New Issue
Block a user