diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index 8216681496b..82530708838 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -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), diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index a8c9086b2d2..ef7b4a60ee2 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -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)