From ec9544b9c318a88987892e512e5643431d13fa8c Mon Sep 17 00:00:00 2001 From: Johann Kellerman Date: Tue, 10 May 2016 07:48:03 +0200 Subject: [PATCH] Add a load_platform mechanism (#2012) * discovery.load_platform method * rm grep --- .gitignore | 2 ++ homeassistant/components/discovery.py | 28 +++++++++++++++++++++++ homeassistant/helpers/entity_component.py | 12 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/.gitignore b/.gitignore index 58b27eb7d49..f049564253f 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,5 @@ venv # vimmy stuff *.swp *.swo + +ctags.tmp diff --git a/homeassistant/components/discovery.py b/homeassistant/components/discovery.py index 0ba0c1ffb11..01211398f72 100644 --- a/homeassistant/components/discovery.py +++ b/homeassistant/components/discovery.py @@ -19,6 +19,8 @@ REQUIREMENTS = ['netdisco==0.6.6'] SCAN_INTERVAL = 300 # seconds +LOAD_PLATFORM = 'load_platform' + SERVICE_WEMO = 'belkin_wemo' SERVICE_HUE = 'philips_hue' SERVICE_CAST = 'google_cast' @@ -73,6 +75,32 @@ def discover(hass, service, discovered=None, component=None, hass_config=None): hass.bus.fire(EVENT_PLATFORM_DISCOVERED, data) +def load_platform(hass, component, platform, info=None, hass_config=None): + """Helper method for generic platform loading. + + This method allows a platform to be loaded dynamically without it being + known at runtime (in the DISCOVERY_PLATFORMS list of the component). + Advantages of using this method: + - Any component & platforms combination can be dynamically added + - A component (i.e. light) does not have to import every component + that can dynamically add a platform (e.g. wemo, wink, insteon_hub) + - Custom user components can take advantage of discovery/loading + + Target components will be loaded and an EVENT_PLATFORM_DISCOVERED will be + fired to load the platform. The event will contain: + { ATTR_SERVICE = LOAD_PLATFORM + '.' + <> + ATTR_DISCOVERED = {LOAD_PLATFORM: <>} } + + * dev note: This listener can be found in entity_component.py + """ + if info is None: + info = {LOAD_PLATFORM: platform} + else: + info[LOAD_PLATFORM] = platform + discover(hass, LOAD_PLATFORM + '.' + component, info, component, + hass_config) + + def setup(hass, config): """Start a discovery service.""" logger = logging.getLogger(__name__) diff --git a/homeassistant/helpers/entity_component.py b/homeassistant/helpers/entity_component.py index 3ce72e62835..2b94369bc69 100644 --- a/homeassistant/helpers/entity_component.py +++ b/homeassistant/helpers/entity_component.py @@ -55,12 +55,24 @@ class EntityComponent(object): self._setup_platform(p_type, p_config) if self.discovery_platforms: + # Discovery listener for all items in discovery_platforms array + # passed from a component's setup method (e.g. light/__init__.py) discovery.listen( self.hass, self.discovery_platforms.keys(), lambda service, info: self._setup_platform(self.discovery_platforms[service], {}, info)) + # Generic discovery listener for loading platform dynamically + # Refer to: homeassistant.components.discovery.load_platform() + def load_platform_callback(service, info): + """Callback to load a platform.""" + platform = info.pop(discovery.LOAD_PLATFORM) + self._setup_platform(platform, {}, info if info else None) + discovery.listen( + self.hass, discovery.LOAD_PLATFORM + '.' + self.domain, + load_platform_callback) + def extract_from_service(self, service): """Extract all known entities from a service call.