diff --git a/homeassistant/const.py b/homeassistant/const.py index 77e540cd76f..bcf81cbcde6 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -33,6 +33,7 @@ CONF_ACCESS_TOKEN = "access_token" CONF_FILENAME = "filename" CONF_MONITORED_CONDITIONS = 'monitored_conditions' CONF_OPTIMISTIC = 'optimistic' +CONF_ENTITY_NAMESPACE = "entity_namespace" CONF_SCAN_INTERVAL = "scan_interval" CONF_VALUE_TEMPLATE = "value_template" diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 6434c23f807..423a276f11a 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -27,7 +27,7 @@ def generate_entity_id(entity_id_format, name, current_ids=None, hass=None): current_ids = hass.states.entity_ids() return ensure_unique_string( - entity_id_format.format(slugify(name.lower())), current_ids) + entity_id_format.format(slugify(name)), current_ids) def split_entity_id(entity_id): diff --git a/homeassistant/helpers/entity_component.py b/homeassistant/helpers/entity_component.py index 43d6e435509..3ce72e62835 100644 --- a/homeassistant/helpers/entity_component.py +++ b/homeassistant/helpers/entity_component.py @@ -3,7 +3,9 @@ from threading import Lock from homeassistant.bootstrap import prepare_setup_platform from homeassistant.components import discovery, group -from homeassistant.const import ATTR_ENTITY_ID, CONF_SCAN_INTERVAL +from homeassistant.const import ( + ATTR_ENTITY_ID, CONF_SCAN_INTERVAL, CONF_ENTITY_NAMESPACE, + DEVICE_DEFAULT_NAME) from homeassistant.helpers import config_per_platform from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.event import track_utc_time_change @@ -37,8 +39,8 @@ class EntityComponent(object): self.config = None self.lock = Lock() - self.add_entities = EntityPlatform(self, - self.scan_interval).add_entities + self.add_entities = EntityPlatform(self, self.scan_interval, + None).add_entities def setup(self, config): """Set up a full entity component. @@ -86,11 +88,13 @@ class EntityComponent(object): scan_interval = platform_config.get( CONF_SCAN_INTERVAL, getattr(platform, 'SCAN_INTERVAL', self.scan_interval)) + entity_namespace = platform_config.get(CONF_ENTITY_NAMESPACE) try: platform.setup_platform( self.hass, platform_config, - EntityPlatform(self, scan_interval).add_entities, + EntityPlatform(self, scan_interval, + entity_namespace).add_entities, discovery_info) self.hass.config.components.append( @@ -99,7 +103,7 @@ class EntityComponent(object): self.logger.exception( 'Error while setting up platform %s', platform_type) - def add_entity(self, entity): + def add_entity(self, entity, platform=None): """Add entity to component.""" if entity is None or entity in self.entities.values(): return False @@ -107,8 +111,14 @@ class EntityComponent(object): entity.hass = self.hass if getattr(entity, 'entity_id', None) is None: + object_id = entity.name or DEVICE_DEFAULT_NAME + + if platform is not None and platform.entity_namespace is not None: + object_id = '{} {}'.format(platform.entity_namespace, + object_id) + entity.entity_id = generate_entity_id( - self.entity_id_format, entity.name, + self.entity_id_format, object_id, self.entities.keys()) self.entities[entity.entity_id] = entity @@ -130,10 +140,11 @@ class EntityPlatform(object): """Keep track of entities for a single platform.""" # pylint: disable=too-few-public-methods - def __init__(self, component, scan_interval): + def __init__(self, component, scan_interval, entity_namespace): """Initalize the entity platform.""" self.component = component self.scan_interval = scan_interval + self.entity_namespace = entity_namespace self.platform_entities = [] self.is_polling = False @@ -141,7 +152,7 @@ class EntityPlatform(object): """Add entities for a single platform.""" with self.component.lock: for entity in new_entities: - if self.component.add_entity(entity): + if self.component.add_entity(entity, self): self.platform_entities.append(entity) self.component.update_group() diff --git a/tests/helpers/test_entity_component.py b/tests/helpers/test_entity_component.py index 702d05f9a9d..0b4b852d397 100644 --- a/tests/helpers/test_entity_component.py +++ b/tests/helpers/test_entity_component.py @@ -290,3 +290,28 @@ class TestHelpersEntityComponent(unittest.TestCase): assert mock_track.called assert [0, 30] == list(mock_track.call_args[1]['second']) + + def test_set_entity_namespace_via_config(self): + """Test setting an entity namespace.""" + def platform_setup(hass, config, add_devices, discovery_info=None): + """Test the platform setup.""" + add_devices([ + EntityTest(name='beer'), + EntityTest(name=None), + ]) + + platform = MockPlatform(platform_setup) + + loader.set_component('test_domain.platform', platform) + + component = EntityComponent(_LOGGER, DOMAIN, self.hass) + + component.setup({ + DOMAIN: { + 'platform': 'platform', + 'entity_namespace': 'yummy' + } + }) + + assert sorted(self.hass.states.entity_ids()) == \ + ['test_domain.yummy_beer', 'test_domain.yummy_unnamed_device']