def setup(self, config): """Set up a full entity component. Loads the platforms from the config and will listen for supported discovered platforms. """ self.config = config # Look in config for Domain, Domain 2, Domain 3 etc and load them for p_type, p_config in config_per_platform(config, self.domain): 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 setup(self, config): """Set up a full entity component. Loads the platforms from the config and will listen for supported discovered platforms. """ self.config = config # Look in config for Domain, Domain 2, Domain 3 etc and load them for p_type, p_config in config_per_platform(config, self.domain): 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 setup(hass, config): """Common setup for WeMo devices.""" import pywemo global SUBSCRIPTION_REGISTRY SUBSCRIPTION_REGISTRY = pywemo.SubscriptionRegistry() SUBSCRIPTION_REGISTRY.start() def stop_wemo(event): """Shutdown Wemo subscriptions and subscription thread on exit.""" _LOGGER.info("Shutting down subscriptions.") SUBSCRIPTION_REGISTRY.stop() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_wemo) def discovery_dispatch(service, discovery_info): """Dispatcher for WeMo discovery events.""" # name, model, location, mac _, model_name, _, _, serial = discovery_info # Only register a device once if serial in KNOWN_DEVICES: return _LOGGER.debug('Discovered unique device %s', serial) KNOWN_DEVICES.append(serial) service = WEMO_MODEL_DISPATCH.get(model_name) or DISCOVER_SWITCHES component = WEMO_SERVICE_DISPATCH.get(service) discovery.discover(hass, service, discovery_info, component, config) discovery.listen(hass, discovery.SERVICE_WEMO, discovery_dispatch) _LOGGER.info("Scanning for WeMo devices.") devices = [(device.host, device) for device in pywemo.discover_devices()] # Add static devices from the config file. devices.extend((address, None) for address in config.get(DOMAIN, {}).get('static', [])) for address, device in devices: port = pywemo.ouimeaux_device.probe_wemo(address) if not port: _LOGGER.warning('Unable to probe wemo at %s', address) continue _LOGGER.info('Adding wemo at %s:%i', address, port) url = 'http://%s:%i/setup.xml' % (address, port) if device is None: device = pywemo.discovery.device_from_description(url, None) discovery_info = (device.name, device.model_name, url, device.mac, device.serialnumber) discovery.discover(hass, discovery.SERVICE_WEMO, discovery_info) return True
def setup(self, config): """ Sets up a full entity component: - Loads the platforms from the config - Will listen for supported discovered platforms """ # Look in config for Domain, Domain 2, Domain 3 etc and load them for p_type, p_config in \ config_per_platform(config, self.domain, self.logger): self._setup_platform(p_type, p_config) if self.discovery_platforms: discovery.listen(self.hass, self.discovery_platforms.keys(), self._entity_discovered)
def setup(hass, config): """ Track states and offer events for sensors. """ logger = logging.getLogger(__name__) sensors = platform_devices_from_config( config, DOMAIN, hass, ENTITY_ID_FORMAT, logger) @util.Throttle(MIN_TIME_BETWEEN_SCANS) def update_sensor_states(now): """ Update states of all sensors. """ if sensors: logger.info("Updating sensor states") for sensor in sensors.values(): sensor.update_ha_state(hass, True) update_sensor_states(None) # Track all sensors in a group sensor_group = group.Group( hass, GROUP_NAME_ALL_SENSORS, sensors.keys(), False) def sensor_discovered(service, info): """ Called when a sensor is discovered. """ platform = get_component("{}.{}".format( DOMAIN, DISCOVERY_PLATFORMS[service])) discovered = platform.devices_discovered(hass, config, info) for sensor in discovered: if sensor is not None and sensor not in sensors.values(): sensor.entity_id = util.ensure_unique_string( ENTITY_ID_FORMAT.format(util.slugify(sensor.name)), sensors.keys()) sensors[sensor.entity_id] = sensor sensor.update_ha_state(hass) sensor_group.update_tracked_entity_ids(sensors.keys()) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), sensor_discovered) # Fire every 3 seconds hass.track_time_change(update_sensor_states, seconds=range(0, 60, 3)) return True
def setup(hass, config): """ Track states and offer events for sensors. """ logger = logging.getLogger(__name__) sensors = platform_devices_from_config(config, DOMAIN, hass, ENTITY_ID_FORMAT, logger) @util.Throttle(MIN_TIME_BETWEEN_SCANS) def update_sensor_states(now): """ Update states of all sensors. """ if sensors: logger.info("Updating sensor states") for sensor in sensors.values(): sensor.update_ha_state(hass, True) update_sensor_states(None) # Track all sensors in a group sensor_group = group.Group(hass, GROUP_NAME_ALL_SENSORS, sensors.keys(), False) def sensor_discovered(service, info): """ Called when a sensor is discovered. """ platform = get_component("{}.{}".format(DOMAIN, DISCOVERY_PLATFORMS[service])) discovered = platform.devices_discovered(hass, config, info) for sensor in discovered: if sensor is not None and sensor not in sensors.values(): sensor.entity_id = util.ensure_unique_string( ENTITY_ID_FORMAT.format(util.slugify(sensor.name)), sensors.keys()) sensors[sensor.entity_id] = sensor sensor.update_ha_state(hass) sensor_group.update_tracked_entity_ids(sensors.keys()) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), sensor_discovered) # Fire every 3 seconds hass.track_time_change(update_sensor_states, seconds=range(0, 60, 3)) return True
def setup(self, config): """Set up a full entity component. Loads the platforms from the config and will listen for supported discovered platforms. """ self.config = config # Look in config for Domain, Domain 2, Domain 3 etc and load them for p_type, p_config in config_per_platform(config, self.domain): self._setup_platform(p_type, p_config) if self.discovery_platforms: discovery.listen( self.hass, self.discovery_platforms.keys(), lambda service, info: self._setup_platform( self.discovery_platforms[service], {}, info))
def setup(self, config): """Set up a full entity component. Loads the platforms from the config and will listen for supported discovered platforms. """ self.config = config # Look in config for Domain, Domain 2, Domain 3 etc and load them for p_type, p_config in config_per_platform(config, self.domain): self._setup_platform(p_type, p_config) if self.discovery_platforms: discovery.listen( self.hass, self.discovery_platforms.keys(), lambda service, info: self._setup_platform(self.discovery_platforms[service], {}, info))
def setup(self, config): """ Sets up a full device component: - Loads the platforms from the config - Will update devices on an interval - Will listen for supported discovered platforms """ # only setup group if name is given if self.group_name is None: self.group = None else: self.group = group.Group(self.hass, self.group_name, user_defined=False) # Look in config for Domain, Domain 2, Domain 3 etc and load them for p_type, p_config in \ config_per_platform(config, self.domain, self.logger): self._setup_platform(p_type, p_config) if self.discovery_platforms: discovery.listen(self.hass, self.discovery_platforms.keys(), self._device_discovered)
def setup(hass, config): """Setup device tracker.""" yaml_path = hass.config.path(YAML_DEVICES) conf = config.get(DOMAIN, {}) if isinstance(conf, list): conf = conf[0] consider_home = timedelta( seconds=util.convert(conf.get(CONF_CONSIDER_HOME), int, DEFAULT_CONSIDER_HOME)) track_new = util.convert(conf.get(CONF_TRACK_NEW), bool, DEFAULT_CONF_TRACK_NEW) home_range = util.convert(conf.get(CONF_HOME_RANGE), int, DEFAULT_HOME_RANGE) devices = load_config(yaml_path, hass, consider_home, home_range) tracker = DeviceTracker(hass, consider_home, track_new, home_range, devices) def setup_platform(p_type, p_config, disc_info=None): """Setup a device tracker platform.""" platform = prepare_setup_platform(hass, config, DOMAIN, p_type) if platform is None: return try: if hasattr(platform, 'get_scanner'): scanner = platform.get_scanner(hass, {DOMAIN: p_config}) if scanner is None: _LOGGER.error('Error setting up platform %s', p_type) return setup_scanner_platform(hass, p_config, scanner, tracker.see) return if not platform.setup_scanner(hass, p_config, tracker.see): _LOGGER.error('Error setting up platform %s', p_type) except Exception: # pylint: disable=broad-except _LOGGER.exception('Error setting up platform %s', p_type) for p_type, p_config in config_per_platform(config, DOMAIN): setup_platform(p_type, p_config) def device_tracker_discovered(service, info): """Called when a device tracker platform is discovered.""" setup_platform(DISCOVERY_PLATFORMS[service], {}, info) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), device_tracker_discovered) def update_stale(now): """Clean up stale devices.""" tracker.update_stale(now) track_utc_time_change(hass, update_stale, second=range(0, 60, 5)) tracker.setup_group() def see_service(call): """Service to see a device.""" args = {key: value for key, value in call.data.items() if key in (ATTR_MAC, ATTR_DEV_ID, ATTR_HOST_NAME, ATTR_LOCATION_NAME, ATTR_GPS, ATTR_GPS_ACCURACY, ATTR_BATTERY)} tracker.see(**args) descriptions = load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) hass.services.register(DOMAIN, SERVICE_SEE, see_service, descriptions.get(SERVICE_SEE)) return True
def setup(hass, config): """ Exposes light control via statemachine and services. """ # Load built-in profiles and custom profiles profile_paths = [os.path.join(os.path.dirname(__file__), LIGHT_PROFILES_FILE), hass.get_config_path(LIGHT_PROFILES_FILE)] profiles = {} for profile_path in profile_paths: if os.path.isfile(profile_path): with open(profile_path) as inp: reader = csv.reader(inp) # Skip the header next(reader, None) try: for profile_id, color_x, color_y, brightness in reader: profiles[profile_id] = (float(color_x), float(color_y), int(brightness)) except ValueError: # ValueError if not 4 values per row # ValueError if convert to float/int failed _LOGGER.error( "Error parsing light profiles from %s", profile_path) return False # Dict to track entity_id -> lights lights = {} # Track all lights in a group light_group = group.Group(hass, GROUP_NAME_ALL_LIGHTS, user_defined=False) def add_lights(new_lights): """ Add lights to the component to track. """ for light in new_lights: if light is not None and light not in lights.values(): light.entity_id = generate_entity_id( ENTITY_ID_FORMAT, light.name, lights.keys()) lights[light.entity_id] = light light.update_ha_state(hass) light_group.update_tracked_entity_ids(lights.keys()) for p_type, p_config in config_per_platform(config, DOMAIN, _LOGGER): platform = get_component(ENTITY_ID_FORMAT.format(p_type)) if platform is None: _LOGGER.error("Unknown type specified: %s", p_type) platform.setup_platform(hass, p_config, add_lights) def update_lights_state(now): """ Update the states of all the lights. """ if lights: _LOGGER.info("Updating light states") for light in lights.values(): light.update_ha_state(hass, True) update_lights_state(None) def light_discovered(service, info): """ Called when a light is discovered. """ platform = get_component( ENTITY_ID_FORMAT.format(DISCOVERY_PLATFORMS[service])) platform.setup_platform(hass, {}, add_lights, info) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), light_discovered) def handle_light_service(service): """ Hande a turn light on or off service call. """ # Get and validate data dat = service.data # Convert the entity ids to valid light ids target_lights = [lights[entity_id] for entity_id in extract_entity_ids(hass, service) if entity_id in lights] if not target_lights: target_lights = lights.values() params = {} transition = util.convert(dat.get(ATTR_TRANSITION), int) if transition is not None: params[ATTR_TRANSITION] = transition if service.service == SERVICE_TURN_OFF: for light in target_lights: # pylint: disable=star-args light.turn_off(**params) else: # Processing extra data for turn light on request # We process the profile first so that we get the desired # behavior that extra service data attributes overwrite # profile values profile = profiles.get(dat.get(ATTR_PROFILE)) if profile: *params[ATTR_XY_COLOR], params[ATTR_BRIGHTNESS] = profile if ATTR_BRIGHTNESS in dat: # We pass in the old value as the default parameter if parsing # of the new one goes wrong. params[ATTR_BRIGHTNESS] = util.convert( dat.get(ATTR_BRIGHTNESS), int, params.get(ATTR_BRIGHTNESS)) if ATTR_XY_COLOR in dat: try: # xy_color should be a list containing 2 floats xycolor = dat.get(ATTR_XY_COLOR) # Without this check, a xycolor with value '99' would work if not isinstance(xycolor, str): params[ATTR_XY_COLOR] = [float(val) for val in xycolor] except (TypeError, ValueError): # TypeError if xy_color is not iterable # ValueError if value could not be converted to float pass if ATTR_RGB_COLOR in dat: try: # rgb_color should be a list containing 3 ints rgb_color = dat.get(ATTR_RGB_COLOR) if len(rgb_color) == 3: params[ATTR_XY_COLOR] = \ util.color_RGB_to_xy(int(rgb_color[0]), int(rgb_color[1]), int(rgb_color[2])) except (TypeError, ValueError): # TypeError if rgb_color is not iterable # ValueError if not all values can be converted to int pass if ATTR_FLASH in dat: if dat[ATTR_FLASH] == FLASH_SHORT: params[ATTR_FLASH] = FLASH_SHORT elif dat[ATTR_FLASH] == FLASH_LONG: params[ATTR_FLASH] = FLASH_LONG for light in target_lights: # pylint: disable=star-args light.turn_on(**params) for light in target_lights: light.update_ha_state(hass, True) # Update light state every 30 seconds hass.track_time_change(update_lights_state, second=[0, 30]) # Listen for light on and light off service calls hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_light_service) hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_light_service) return True
def setup(hass, config): """ Setup device tracker """ yaml_path = hass.config.path(YAML_DEVICES) csv_path = hass.config.path(CSV_DEVICES) if os.path.isfile(csv_path) and not os.path.isfile(yaml_path) and \ convert_csv_config(csv_path, yaml_path): os.remove(csv_path) conf = config.get(DOMAIN, {}) if isinstance(conf, list): conf = conf[0] consider_home = timedelta(seconds=util.convert( conf.get(CONF_CONSIDER_HOME), int, DEFAULT_CONSIDER_HOME)) track_new = util.convert(conf.get(CONF_TRACK_NEW), bool, DEFAULT_CONF_TRACK_NEW) home_range = util.convert(conf.get(CONF_HOME_RANGE), int, DEFAULT_HOME_RANGE) devices = load_config(yaml_path, hass, consider_home, home_range) tracker = DeviceTracker(hass, consider_home, track_new, home_range, devices) def setup_platform(p_type, p_config, disc_info=None): """ Setup a device tracker platform. """ platform = prepare_setup_platform(hass, config, DOMAIN, p_type) if platform is None: return try: if hasattr(platform, 'get_scanner'): scanner = platform.get_scanner(hass, {DOMAIN: p_config}) if scanner is None: _LOGGER.error('Error setting up platform %s', p_type) return setup_scanner_platform(hass, p_config, scanner, tracker.see) return if not platform.setup_scanner(hass, p_config, tracker.see): _LOGGER.error('Error setting up platform %s', p_type) except Exception: # pylint: disable=broad-except _LOGGER.exception('Error setting up platform %s', p_type) for p_type, p_config in \ config_per_platform(config, DOMAIN, _LOGGER): setup_platform(p_type, p_config) def device_tracker_discovered(service, info): """ Called when a device tracker platform is discovered. """ setup_platform(DISCOVERY_PLATFORMS[service], {}, info) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), device_tracker_discovered) def update_stale(now): """ Clean up stale devices. """ tracker.update_stale(now) track_utc_time_change(hass, update_stale, second=range(0, 60, 5)) tracker.setup_group() def see_service(call): """ Service to see a device. """ args = { key: value for key, value in call.data.items() if key in (ATTR_MAC, ATTR_DEV_ID, ATTR_HOST_NAME, ATTR_LOCATION_NAME, ATTR_GPS, ATTR_GPS_ACCURACY, ATTR_BATTERY) } tracker.see(**args) descriptions = load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) hass.services.register(DOMAIN, SERVICE_SEE, see_service, descriptions.get(SERVICE_SEE)) return True
def setup(hass, config): """ Exposes light control via statemachine and services. """ # Load built-in profiles and custom profiles profile_paths = [ os.path.join(os.path.dirname(__file__), LIGHT_PROFILES_FILE), hass.get_config_path(LIGHT_PROFILES_FILE) ] profiles = {} for profile_path in profile_paths: if os.path.isfile(profile_path): with open(profile_path) as inp: reader = csv.reader(inp) # Skip the header next(reader, None) try: for profile_id, color_x, color_y, brightness in reader: profiles[profile_id] = (float(color_x), float(color_y), int(brightness)) except ValueError: # ValueError if not 4 values per row # ValueError if convert to float/int failed _LOGGER.error("Error parsing light profiles from %s", profile_path) return False # Dict to track entity_id -> lights lights = {} # Track all lights in a group light_group = group.Group(hass, GROUP_NAME_ALL_LIGHTS, user_defined=False) def add_lights(new_lights): """ Add lights to the component to track. """ for light in new_lights: if light is not None and light not in lights.values(): light.entity_id = generate_entity_id(ENTITY_ID_FORMAT, light.name, lights.keys()) lights[light.entity_id] = light light.update_ha_state(hass) light_group.update_tracked_entity_ids(lights.keys()) for p_type, p_config in config_per_platform(config, DOMAIN, _LOGGER): platform = get_component(ENTITY_ID_FORMAT.format(p_type)) if platform is None: _LOGGER.error("Unknown type specified: %s", p_type) platform.setup_platform(hass, p_config, add_lights) def update_lights_state(now): """ Update the states of all the lights. """ if lights: _LOGGER.info("Updating light states") for light in lights.values(): light.update_ha_state(hass, True) update_lights_state(None) def light_discovered(service, info): """ Called when a light is discovered. """ platform = get_component( ENTITY_ID_FORMAT.format(DISCOVERY_PLATFORMS[service])) platform.setup_platform(hass, {}, add_lights, info) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), light_discovered) def handle_light_service(service): """ Hande a turn light on or off service call. """ # Get and validate data dat = service.data # Convert the entity ids to valid light ids target_lights = [ lights[entity_id] for entity_id in extract_entity_ids(hass, service) if entity_id in lights ] if not target_lights: target_lights = lights.values() params = {} transition = util.convert(dat.get(ATTR_TRANSITION), int) if transition is not None: params[ATTR_TRANSITION] = transition if service.service == SERVICE_TURN_OFF: for light in target_lights: # pylint: disable=star-args light.turn_off(**params) else: # Processing extra data for turn light on request # We process the profile first so that we get the desired # behavior that extra service data attributes overwrite # profile values profile = profiles.get(dat.get(ATTR_PROFILE)) if profile: *params[ATTR_XY_COLOR], params[ATTR_BRIGHTNESS] = profile if ATTR_BRIGHTNESS in dat: # We pass in the old value as the default parameter if parsing # of the new one goes wrong. params[ATTR_BRIGHTNESS] = util.convert( dat.get(ATTR_BRIGHTNESS), int, params.get(ATTR_BRIGHTNESS)) if ATTR_XY_COLOR in dat: try: # xy_color should be a list containing 2 floats xycolor = dat.get(ATTR_XY_COLOR) # Without this check, a xycolor with value '99' would work if not isinstance(xycolor, str): params[ATTR_XY_COLOR] = [float(val) for val in xycolor] except (TypeError, ValueError): # TypeError if xy_color is not iterable # ValueError if value could not be converted to float pass if ATTR_RGB_COLOR in dat: try: # rgb_color should be a list containing 3 ints rgb_color = dat.get(ATTR_RGB_COLOR) if len(rgb_color) == 3: params[ATTR_XY_COLOR] = \ util.color_RGB_to_xy(int(rgb_color[0]), int(rgb_color[1]), int(rgb_color[2])) except (TypeError, ValueError): # TypeError if rgb_color is not iterable # ValueError if not all values can be converted to int pass if ATTR_FLASH in dat: if dat[ATTR_FLASH] == FLASH_SHORT: params[ATTR_FLASH] = FLASH_SHORT elif dat[ATTR_FLASH] == FLASH_LONG: params[ATTR_FLASH] = FLASH_LONG for light in target_lights: # pylint: disable=star-args light.turn_on(**params) for light in target_lights: light.update_ha_state(hass, True) # Update light state every 30 seconds hass.track_time_change(update_lights_state, second=[0, 30]) # Listen for light on and light off service calls hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_light_service) hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_light_service) return True
def setup(hass, config): """ Track states and offer events for switches. """ logger = logging.getLogger(__name__) switches = platform_devices_from_config( config, DOMAIN, hass, ENTITY_ID_FORMAT, logger) @util.Throttle(MIN_TIME_BETWEEN_SCANS) def update_states(now): """ Update states of all switches. """ if switches: logger.info("Updating switch states") for switch in switches.values(): switch.update_ha_state(hass, True) update_states(None) # Track all switches in a group switch_group = group.Group( hass, GROUP_NAME_ALL_SWITCHES, switches.keys(), False) def switch_discovered(service, info): """ Called when a switch is discovered. """ platform = get_component("{}.{}".format( DOMAIN, DISCOVERY_PLATFORMS[service])) discovered = platform.devices_discovered(hass, config, info) for switch in discovered: if switch is not None and switch not in switches.values(): switch.entity_id = generate_entity_id( ENTITY_ID_FORMAT, switch.name, switches.keys()) switches[switch.entity_id] = switch switch.update_ha_state(hass) switch_group.update_tracked_entity_ids(switches.keys()) discovery.listen(hass, DISCOVERY_PLATFORMS.keys(), switch_discovered) def handle_switch_service(service): """ Handles calls to the switch services. """ target_switches = [switches[entity_id] for entity_id in extract_entity_ids(hass, service) if entity_id in switches] if not target_switches: target_switches = switches.values() for switch in target_switches: if service.service == SERVICE_TURN_ON: switch.turn_on() else: switch.turn_off() switch.update_ha_state(hass) # Update state every 30 seconds hass.track_time_change(update_states, second=[0, 30]) hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_switch_service) hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_switch_service) return True