Compare commits

..

10 Commits

Author SHA1 Message Date
Paulus Schoutsen
e049b35413 Merge pull request #20354 from home-assistant/rc
0.86.0
2019-01-23 12:49:23 -08:00
Paulus Schoutsen
cdcc535ae1 Version bump to 0.86.0 2019-01-23 10:48:55 -08:00
Paulus Schoutsen
4662ab215c Fix invalid entity ID in entity registry (#20328) 2019-01-23 10:48:15 -08:00
rolfberkenbosch
80aa2075c6 Update locationsharinglib to version 3.0.11 (#20322)
* Update google_maps.py

There are known bug in locationsharinglib version 3.0.9, the developer has fixed this in 3.0.11. (https://github.com/costastf/locationsharinglib/issues/42)

* Update requirements_all.txt
2019-01-23 10:48:14 -08:00
Sebastian Muszynski
4b7d944a74 Fix xiaomi speed attribute name clash (#20312) 2019-01-23 10:48:14 -08:00
Richard Mitchell
b7218e6a1d Should require the 'GATTOOL' setup extras which includes pexpect. (#20263)
* Should require the 'GATTOOL' setup extras which includes pexpect.

* Also fix skybeacon's requirement and requirements_all.
2019-01-23 10:48:13 -08:00
Paulus Schoutsen
6d0ac30687 Bumped version to 0.86.0b3 2019-01-21 21:23:00 -08:00
Fabien Piuzzi
0ceace96e7 Bugfix: prevent error notification when octoprint server auto detected but no configuration present. (#20303) 2019-01-21 21:22:20 -08:00
Johann Kellerman
ec7f2657cd Config Validator: schema_with_slug_keys (#20298)
* schema_with_slug_keys

* Update config_validation.py

* Update config_validation.py
2019-01-21 21:21:00 -08:00
Paulus Schoutsen
5945929e7e Updated frontend to 20190121.1 2019-01-21 21:20:23 -08:00
49 changed files with 124 additions and 79 deletions

View File

@@ -46,9 +46,7 @@ ALERT_SCHEMA = vol.Schema({
vol.Required(CONF_NOTIFIERS): cv.ensure_list})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: ALERT_SCHEMA,
}),
DOMAIN: cv.schema_with_slug_keys(ALERT_SCHEMA),
}, extra=vol.ALLOW_EXTRA)

View File

@@ -50,9 +50,7 @@ DEVICE_SCHEMA = vol.Schema({
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: DEVICE_SCHEMA,
}),
DOMAIN: cv.schema_with_slug_keys(DEVICE_SCHEMA),
}, extra=vol.ALLOW_EXTRA)
SERVICE_VAPIX_CALL = 'vapix_call'

View File

@@ -41,7 +41,7 @@ SENSOR_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SENSORS): vol.Schema({cv.slug: SENSOR_SCHEMA}),
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(SENSOR_SCHEMA),
})

View File

@@ -51,7 +51,7 @@ SENSOR_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SENSORS): vol.Schema({cv.slug: SENSOR_SCHEMA}),
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(SENSOR_SCHEMA),
})

View File

@@ -37,8 +37,8 @@ SERVICE_SCHEMA = vol.Schema({
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.Any({
DOMAIN: cv.schema_with_slug_keys(
vol.Any({
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_INITIAL, default=DEFAULT_INITIAL):
cv.positive_int,
@@ -46,7 +46,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_RESTORE, default=True): cv.boolean,
vol.Optional(CONF_STEP, default=DEFAULT_STEP): cv.positive_int,
}, None)
})
)
}, extra=vol.ALLOW_EXTRA)

View File

@@ -27,7 +27,7 @@ COVER_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COVERS): vol.Schema({cv.slug: COVER_SCHEMA}),
vol.Required(CONF_COVERS): cv.schema_with_slug_keys(COVER_SCHEMA),
})

View File

@@ -47,7 +47,7 @@ COVER_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COVERS): vol.Schema({cv.slug: COVER_SCHEMA}),
vol.Required(CONF_COVERS): cv.schema_with_slug_keys(COVER_SCHEMA),
})

View File

@@ -46,7 +46,7 @@ COVER_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COVERS): vol.Schema({cv.slug: COVER_SCHEMA}),
vol.Required(CONF_COVERS): cv.schema_with_slug_keys(COVER_SCHEMA),
})

View File

@@ -18,7 +18,8 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['scsgate']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_DEVICES): vol.Schema({cv.slug: scsgate.SCSGATE_SCHEMA}),
vol.Required(CONF_DEVICES):
cv.schema_with_slug_keys(scsgate.SCSGATE_SCHEMA),
})

View File

@@ -67,7 +67,7 @@ COVER_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COVERS): vol.Schema({cv.slug: COVER_SCHEMA}),
vol.Required(CONF_COVERS): cv.schema_with_slug_keys(COVER_SCHEMA),
})

View File

@@ -26,7 +26,7 @@ COVER_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_COVERS): vol.Schema({cv.slug: COVER_SCHEMA}),
vol.Required(CONF_COVERS): cv.schema_with_slug_keys(COVER_SCHEMA),
})
DEPENDENCIES = ['velbus']

View File

@@ -15,7 +15,7 @@ import homeassistant.util.dt as dt_util
_LOGGER = logging.getLogger(__name__)
REQUIREMENTS = ['pygatt==3.2.0']
REQUIREMENTS = ['pygatt[GATTTOOL]==3.2.0']
BLE_PREFIX = 'BLE_'
MIN_SEEN_NEW = 5

View File

@@ -19,7 +19,7 @@ from homeassistant.helpers.event import track_time_interval
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import slugify, dt as dt_util
REQUIREMENTS = ['locationsharinglib==3.0.9']
REQUIREMENTS = ['locationsharinglib==3.0.11']
_LOGGER = logging.getLogger(__name__)

View File

@@ -62,7 +62,7 @@ FAN_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend({
vol.Required(CONF_FANS): vol.Schema({cv.slug: FAN_SCHEMA}),
vol.Required(CONF_FANS): cv.schema_with_slug_keys(FAN_SCHEMA),
})

View File

@@ -111,7 +111,7 @@ ATTR_TRANS_LEVEL = 'trans_level'
ATTR_HARDWARE_VERSION = 'hardware_version'
# Air Humidifier CA
ATTR_SPEED = 'speed'
ATTR_MOTOR_SPEED = 'motor_speed'
ATTR_DEPTH = 'depth'
ATTR_DRY = 'dry'
@@ -223,7 +223,7 @@ AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER = {
AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_CA = {
**AVAILABLE_ATTRIBUTES_AIRHUMIDIFIER_COMMON,
ATTR_SPEED: 'speed',
ATTR_MOTOR_SPEED: 'speed',
ATTR_DEPTH: 'depth',
ATTR_DRY: 'dry',
}

View File

@@ -24,7 +24,7 @@ from homeassistant.core import callback
from homeassistant.helpers.translation import async_get_translations
from homeassistant.loader import bind_hass
REQUIREMENTS = ['home-assistant-frontend==20190121.0']
REQUIREMENTS = ['home-assistant-frontend==20190121.1']
DOMAIN = 'frontend'
DEPENDENCIES = ['api', 'websocket_api', 'http', 'system_log',

View File

@@ -34,7 +34,7 @@ GRAPH_SCHEMA = vol.Schema({
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({cv.slug: GRAPH_SCHEMA})
DOMAIN: cv.schema_with_slug_keys(GRAPH_SCHEMA)
}, extra=vol.ALLOW_EXTRA)

View File

@@ -30,13 +30,13 @@ SERVICE_SCHEMA = vol.Schema({
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.Any({
DOMAIN: cv.schema_with_slug_keys(
vol.Any({
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_INITIAL): cv.boolean,
vol.Optional(CONF_ICON): cv.icon,
}, None)
})
)
}, extra=vol.ALLOW_EXTRA)

View File

@@ -46,14 +46,15 @@ def has_date_or_time(conf):
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.All({
DOMAIN: cv.schema_with_slug_keys(
vol.All({
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_HAS_DATE, default=False): cv.boolean,
vol.Optional(CONF_HAS_TIME, default=False): cv.boolean,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_INITIAL): cv.string,
}, has_date_or_time)})
}, has_date_or_time)
)
}, extra=vol.ALLOW_EXTRA)

View File

@@ -63,8 +63,8 @@ def _cv_input_number(cfg):
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.All({
DOMAIN: cv.schema_with_slug_keys(
vol.All({
vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_MIN): vol.Coerce(float),
vol.Required(CONF_MAX): vol.Coerce(float),
@@ -76,7 +76,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_MODE, default=MODE_SLIDER):
vol.In([MODE_BOX, MODE_SLIDER]),
}, _cv_input_number)
})
)
}, required=True, extra=vol.ALLOW_EXTRA)

View File

@@ -64,14 +64,15 @@ def _cv_input_select(cfg):
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.All({
DOMAIN: cv.schema_with_slug_keys(
vol.All({
vol.Optional(CONF_NAME): cv.string,
vol.Required(CONF_OPTIONS):
vol.All(cv.ensure_list, vol.Length(min=1), [cv.string]),
vol.Optional(CONF_INITIAL): cv.string,
vol.Optional(CONF_ICON): cv.icon,
}, _cv_input_select)})
}, _cv_input_select)
)
}, required=True, extra=vol.ALLOW_EXTRA)

View File

@@ -55,8 +55,8 @@ def _cv_input_text(cfg):
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.All({
DOMAIN: cv.schema_with_slug_keys(
vol.All({
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_MIN, default=0): vol.Coerce(int),
vol.Optional(CONF_MAX, default=100): vol.Coerce(int),
@@ -67,7 +67,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_MODE, default=MODE_TEXT):
vol.In([MODE_TEXT, MODE_PASSWORD]),
}, _cv_input_text)
})
)
}, required=True, extra=vol.ALLOW_EXTRA)

View File

@@ -19,7 +19,8 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['scsgate']
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_DEVICES): vol.Schema({cv.slug: scsgate.SCSGATE_SCHEMA}),
vol.Required(CONF_DEVICES):
cv.schema_with_slug_keys(scsgate.SCSGATE_SCHEMA),
})

View File

@@ -44,7 +44,7 @@ LIGHT_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_LIGHTS): vol.Schema({cv.slug: LIGHT_SCHEMA}),
vol.Required(CONF_LIGHTS): cv.schema_with_slug_keys(LIGHT_SCHEMA),
})

View File

@@ -47,8 +47,8 @@ CONF_SERVICE_DATA = 'service_data'
OFF_STATES = [STATE_IDLE, STATE_OFF, STATE_UNAVAILABLE]
ATTRS_SCHEMA = vol.Schema({cv.slug: cv.string})
CMD_SCHEMA = vol.Schema({cv.slug: cv.SERVICE_SCHEMA})
ATTRS_SCHEMA = cv.schema_with_slug_keys(cv.string)
CMD_SCHEMA = cv.schema_with_slug_keys(cv.SERVICE_SCHEMA)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_NAME): cv.string,

View File

@@ -92,6 +92,10 @@ def setup(hass, config):
discovery.listen(hass, SERVICE_OCTOPRINT, device_discovered)
if DOMAIN not in config:
# Skip the setup if there is no configuration present
return True
for printer in config[DOMAIN]:
name = printer[CONF_NAME]
ssl = 's' if printer[CONF_SSL] else ''

View File

@@ -19,8 +19,8 @@ CONF_RELATIVE_URL_ERROR_MSG = "Invalid relative URL. Absolute path required."
CONF_RELATIVE_URL_REGEX = r'\A/'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: {
DOMAIN: cv.schema_with_slug_keys(
vol.Schema({
# pylint: disable=no-value-for-parameter
vol.Optional(CONF_TITLE): cv.string,
vol.Optional(CONF_ICON): cv.icon,
@@ -29,7 +29,9 @@ CONFIG_SCHEMA = vol.Schema({
CONF_RELATIVE_URL_REGEX,
msg=CONF_RELATIVE_URL_ERROR_MSG),
vol.Url()),
}})}, extra=vol.ALLOW_EXTRA)
})
)
}, extra=vol.ALLOW_EXTRA)
async def async_setup(hass, config):

View File

@@ -49,9 +49,7 @@ ZONE_SCHEMA = vol.Schema({
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: ZONE_SCHEMA,
}),
DOMAIN: cv.schema_with_slug_keys(ZONE_SCHEMA),
}, extra=vol.ALLOW_EXTRA)

View File

@@ -57,7 +57,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(ATTR_HIDDEN, default=True): cv.boolean,
vol.Required(CONF_TOKEN): vol.All(str, vol.Length(min=32, max=32)),
vol.Optional(CONF_COMMANDS, default={}):
vol.Schema({cv.slug: COMMAND_SCHEMA}),
cv.schema_with_slug_keys(COMMAND_SCHEMA),
}, extra=vol.ALLOW_EXTRA)

View File

@@ -47,9 +47,7 @@ COMMAND_SCHEMA = vol.Schema({
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: COMMAND_SCHEMA,
}),
DOMAIN: cv.schema_with_slug_keys(COMMAND_SCHEMA),
}, extra=vol.ALLOW_EXTRA)

View File

@@ -45,7 +45,7 @@ SENSOR_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SENSORS): vol.Schema({cv.slug: SENSOR_SCHEMA}),
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(SENSOR_SCHEMA),
vol.Optional(CONF_BAUD, default=DEFAULT_BAUD): cv.string,
vol.Optional(CONF_DATARATE): cv.positive_int,
vol.Optional(CONF_DEVICE, default=DEFAULT_DEVICE): cv.string,

View File

@@ -16,7 +16,7 @@ from homeassistant.const import (
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
REQUIREMENTS = ['pygatt==3.2.0']
REQUIREMENTS = ['pygatt[GATTTOOL]==3.2.0']
_LOGGER = logging.getLogger(__name__)

View File

@@ -68,9 +68,9 @@ PLATFORM_SCHEMA = vol.All(PLATFORM_SCHEMA.extend({
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_GROUP, default=GROUPS[0]): vol.In(GROUPS),
vol.Optional(CONF_SENSORS, default={}):
vol.Schema({cv.slug: cv.ensure_list}),
cv.schema_with_slug_keys(cv.ensure_list),
vol.Optional(CONF_CUSTOM, default={}):
vol.Schema({cv.slug: CUSTOM_SCHEMA}),
cv.schema_with_slug_keys(CUSTOM_SCHEMA),
}, extra=vol.PREVENT_EXTRA), _check_sensor_schema)

View File

@@ -36,7 +36,7 @@ SENSOR_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SENSORS): vol.Schema({cv.slug: SENSOR_SCHEMA}),
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(SENSOR_SCHEMA),
})

View File

@@ -21,9 +21,7 @@ DOMAIN = 'shell_command'
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: cv.string,
}),
DOMAIN: cv.schema_with_slug_keys(cv.string),
}, extra=vol.ALLOW_EXTRA)

View File

@@ -59,7 +59,7 @@ MP1_SWITCH_SLOT_SCHEMA = vol.Schema({
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_SWITCHES, default={}):
vol.Schema({cv.slug: SWITCH_SCHEMA}),
cv.schema_with_slug_keys(SWITCH_SCHEMA),
vol.Optional(CONF_SLOTS, default={}): MP1_SWITCH_SLOT_SCHEMA,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_MAC): cv.string,

View File

@@ -28,7 +28,7 @@ SWITCH_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SWITCHES): vol.Schema({cv.slug: SWITCH_SCHEMA}),
vol.Required(CONF_SWITCHES): cv.schema_with_slug_keys(SWITCH_SCHEMA),
})

View File

@@ -30,7 +30,7 @@ SWITCH_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SWITCHES): vol.Schema({cv.slug: SWITCH_SCHEMA}),
vol.Required(CONF_SWITCHES): cv.schema_with_slug_keys(SWITCH_SCHEMA),
})

View File

@@ -24,7 +24,8 @@ CONF_SCENARIO = 'scenario'
CONF_SCS_ID = 'scs_id'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_DEVICES): vol.Schema({cv.slug: scsgate.SCSGATE_SCHEMA}),
vol.Required(CONF_DEVICES):
cv.schema_with_slug_keys(scsgate.SCSGATE_SCHEMA),
})

View File

@@ -32,7 +32,7 @@ SWITCH_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SWITCHES): vol.Schema({cv.slug: SWITCH_SCHEMA}),
vol.Required(CONF_SWITCHES): cv.schema_with_slug_keys(SWITCH_SCHEMA),
})
SCAN_INTERVAL = timedelta(seconds=10)

View File

@@ -38,7 +38,7 @@ SWITCH_SCHEMA = vol.Schema({
})
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_SWITCHES): vol.Schema({cv.slug: SWITCH_SCHEMA}),
vol.Required(CONF_SWITCHES): cv.schema_with_slug_keys(SWITCH_SCHEMA),
})

View File

@@ -53,14 +53,14 @@ SERVICE_SCHEMA_DURATION = vol.Schema({
})
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
cv.slug: vol.Any({
DOMAIN: cv.schema_with_slug_keys(
vol.Any({
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_ICON): cv.icon,
vol.Optional(CONF_DURATION, timedelta(DEFAULT_DURATION)):
cv.time_period,
}, None)
})
)
}, extra=vol.ALLOW_EXTRA)

View File

@@ -93,8 +93,8 @@ CONFIG_SCHEMA = vol.Schema({
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_UPDATE_INTERVAL, default=DEFAULT_UPDATE_INTERVAL): (
vol.All(cv.time_period, vol.Clamp(min=MIN_UPDATE_INTERVAL))),
vol.Optional(CONF_NAME, default={}): vol.Schema(
{cv.slug: cv.string}),
vol.Optional(CONF_NAME, default={}):
cv.schema_with_slug_keys(cv.string),
vol.Optional(CONF_RESOURCES): vol.All(
cv.ensure_list, [vol.In(RESOURCES)]),
vol.Optional(CONF_REGION): cv.string,

View File

@@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 86
PATCH_VERSION = '0b2'
PATCH_VERSION = '0'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 5, 3)

View File

@@ -329,6 +329,9 @@ def schema_with_slug_keys(value_schema: Union[T, Callable]) -> Callable:
def verify(value: Dict) -> Dict:
"""Validate all keys are slugs and then the value_schema."""
if not isinstance(value, dict):
raise vol.Invalid('expected dictionary')
for key in value.keys():
slug(key)
return schema(value)

View File

@@ -122,8 +122,15 @@ class EntityRegistry:
entity_id = self.async_get_entity_id(domain, platform, unique_id)
if entity_id:
return self._async_update_entity(
entity_id, config_entry_id=config_entry_id,
device_id=device_id)
entity_id,
config_entry_id=config_entry_id,
device_id=device_id,
# When we changed our slugify algorithm, we invalidated some
# stored entity IDs with either a __ or ending in _.
# Fix introduced in 0.86 (Jan 23, 2018). Next line can be
# removed when we release 1.0 or in 2019.
new_entity_id='.'.join(slugify(part) for part
in entity_id.split('.', 1)))
entity_id = self.async_generate_entity_id(
domain, suggested_object_id or '{}_{}'.format(platform, unique_id),

View File

@@ -514,7 +514,7 @@ hole==0.3.0
holidays==0.9.9
# homeassistant.components.frontend
home-assistant-frontend==20190121.0
home-assistant-frontend==20190121.1
# homeassistant.components.zwave
homeassistant-pyozw==0.1.2
@@ -625,7 +625,7 @@ liveboxplaytv==2.0.2
lmnotify==0.0.4
# homeassistant.components.device_tracker.google_maps
locationsharinglib==3.0.9
locationsharinglib==3.0.11
# homeassistant.components.logi_circle
logi_circle==0.1.7
@@ -1003,7 +1003,7 @@ pyfttt==0.3
# homeassistant.components.device_tracker.bluetooth_le_tracker
# homeassistant.components.sensor.skybeacon
pygatt==3.2.0
pygatt[GATTTOOL]==3.2.0
# homeassistant.components.cover.gogogate2
pygogogate2==0.1.1

View File

@@ -107,7 +107,7 @@ hdate==0.8.7
holidays==0.9.9
# homeassistant.components.frontend
home-assistant-frontend==20190121.0
home-assistant-frontend==20190121.1
# homeassistant.components.homematicip_cloud
homematicip==0.10.3

View File

@@ -4,6 +4,7 @@ from unittest.mock import patch
import pytest
from homeassistant.core import valid_entity_id
from homeassistant.helpers import entity_registry
from tests.common import mock_registry, flush_store
@@ -222,3 +223,36 @@ async def test_migration(hass):
assert entry.name == 'Test Name'
assert entry.disabled_by == 'hass'
assert entry.config_entry_id == 'test-config-id'
async def test_loading_invalid_entity_id(hass, hass_storage):
"""Test we autofix invalid entity IDs."""
hass_storage[entity_registry.STORAGE_KEY] = {
'version': entity_registry.STORAGE_VERSION,
'data': {
'entities': [
{
'entity_id': 'test.invalid__middle',
'platform': 'super_platform',
'unique_id': 'id-invalid-middle',
'name': 'registry override',
}, {
'entity_id': 'test.invalid_end_',
'platform': 'super_platform',
'unique_id': 'id-invalid-end',
}
]
}
}
registry = await entity_registry.async_get_registry(hass)
entity_invalid_middle = registry.async_get_or_create(
'test', 'super_platform', 'id-invalid-middle')
assert valid_entity_id(entity_invalid_middle.entity_id)
entity_invalid_end = registry.async_get_or_create(
'test', 'super_platform', 'id-invalid-end')
assert valid_entity_id(entity_invalid_end.entity_id)