def async_load_config(path: str, hass: HomeAssistantType, consider_home: timedelta): """Load devices from YAML configuration file. This method is a coroutine. """ dev_schema = vol.Schema({ vol.Required('name'): cv.string, vol.Optional('track', default=False): cv.boolean, vol.Optional('mac', default=None): vol.Any(None, vol.All(cv.string, vol.Upper)), vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE): cv.boolean, vol.Optional('gravatar', default=None): vol.Any(None, cv.string), vol.Optional('picture', default=None): vol.Any(None, cv.string), vol.Optional(CONF_CONSIDER_HOME, default=consider_home): vol.All(cv.time_period, cv.positive_timedelta), vol.Optional('vendor', default=None): vol.Any(None, cv.string), }) try: result = [] try: devices = yield from hass.loop.run_in_executor( None, load_yaml_config_file, path) except HomeAssistantError as err: _LOGGER.error('Unable to load %s: %s', path, str(err)) return [] for dev_id, device in devices.items(): try: device = dev_schema(device) device['dev_id'] = cv.slugify(dev_id) except vol.Invalid as exp: async_log_exception(exp, dev_id, devices, hass) else: result.append(Device(hass, **device)) return result except (HomeAssistantError, FileNotFoundError): # When YAML file could not be loaded/did not contain a dict return []
def async_load_config(path: str, hass: HomeAssistantType, consider_home: timedelta): """Load devices from YAML configuration file. This method is a coroutine. """ dev_schema = vol.Schema({ vol.Required('name'): cv.string, vol.Optional('track', default=False): cv.boolean, vol.Optional('mac', default=None): vol.Any(None, vol.All(cv.string, vol.Upper)), vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE): cv.boolean, vol.Optional('gravatar', default=None): vol.Any(None, cv.string), vol.Optional('picture', default=None): vol.Any(None, cv.string), vol.Optional(CONF_CONSIDER_HOME, default=consider_home): vol.All( cv.time_period, cv.positive_timedelta), vol.Optional('vendor', default=None): vol.Any(None, cv.string), }) try: result = [] try: devices = yield from hass.loop.run_in_executor( None, load_yaml_config_file, path) except HomeAssistantError as err: _LOGGER.error('Unable to load %s: %s', path, str(err)) return [] for dev_id, device in devices.items(): try: device = dev_schema(device) device['dev_id'] = cv.slugify(dev_id) except vol.Invalid as exp: async_log_exception(exp, dev_id, devices, hass) else: result.append(Device(hass, **device)) return result except (HomeAssistantError, FileNotFoundError): # When YAML file could not be loaded/did not contain a dict return []
def async_setup(hass: HomeAssistantType, config: ConfigType): """Setup device tracker.""" yaml_path = hass.config.path(YAML_DEVICES) try: conf = config.get(DOMAIN, []) except vol.Invalid as ex: async_log_exception(ex, DOMAIN, config, hass) return False else: conf = conf[0] if len(conf) > 0 else {} consider_home = conf.get(CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME) track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) devices = yield from async_load_config(yaml_path, hass, consider_home) tracker = DeviceTracker(hass, consider_home, track_new, devices) # update tracked devices update_tasks = [device.async_update_ha_state() for device in devices if device.track] if update_tasks: yield from asyncio.wait(update_tasks, loop=hass.loop) @asyncio.coroutine def async_setup_platform(p_type, p_config, disc_info=None): """Setup a device tracker platform.""" platform = yield from async_prepare_setup_platform( hass, config, DOMAIN, p_type) if platform is None: return _LOGGER.info("Setting up %s.%s", DOMAIN, p_type) try: scanner = None setup = None if hasattr(platform, 'async_get_scanner'): scanner = yield from platform.async_get_scanner( hass, {DOMAIN: p_config}) elif hasattr(platform, 'get_scanner'): scanner = yield from hass.loop.run_in_executor( None, platform.get_scanner, hass, {DOMAIN: p_config}) elif hasattr(platform, 'async_setup_scanner'): setup = yield from platform.async_setup_scanner( hass, p_config, tracker.async_see, disc_info) elif hasattr(platform, 'setup_scanner'): setup = yield from hass.loop.run_in_executor( None, platform.setup_scanner, hass, p_config, tracker.see, disc_info) else: raise HomeAssistantError("Invalid device_tracker platform.") if scanner: yield from async_setup_scanner_platform( hass, p_config, scanner, tracker.async_see) return if not setup: _LOGGER.error('Error setting up platform %s', p_type) return except Exception: # pylint: disable=broad-except _LOGGER.exception('Error setting up platform %s', p_type) setup_tasks = [async_setup_platform(p_type, p_config) for p_type, p_config in config_per_platform(config, DOMAIN)] if setup_tasks: yield from asyncio.wait(setup_tasks, loop=hass.loop) yield from tracker.async_setup_group() @callback def async_device_tracker_discovered(service, info): """Called when a device tracker platform is discovered.""" hass.async_add_job( async_setup_platform(DISCOVERY_PLATFORMS[service], {}, info)) discovery.async_listen( hass, DISCOVERY_PLATFORMS.keys(), async_device_tracker_discovered) @asyncio.coroutine def async_platform_discovered(platform, info): """Callback to load a platform.""" yield from async_setup_platform(platform, {}, disc_info=info) discovery.async_listen_platform(hass, DOMAIN, async_platform_discovered) # Clean up stale devices async_track_utc_time_change( hass, tracker.async_update_stale, second=range(0, 60, 5)) @asyncio.coroutine def async_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, ATTR_ATTRIBUTES)} yield from tracker.async_see(**args) descriptions = yield from hass.loop.run_in_executor( None, load_yaml_config_file, os.path.join(os.path.dirname(__file__), 'services.yaml') ) hass.services.async_register( DOMAIN, SERVICE_SEE, async_see_service, descriptions.get(SERVICE_SEE)) return True
def async_setup(hass: HomeAssistantType, config: ConfigType): """Setup device tracker.""" yaml_path = hass.config.path(YAML_DEVICES) try: conf = config.get(DOMAIN, []) except vol.Invalid as ex: async_log_exception(ex, DOMAIN, config, hass) return False else: conf = conf[0] if len(conf) > 0 else {} consider_home = conf.get(CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME) track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) devices = yield from async_load_config(yaml_path, hass, consider_home) tracker = DeviceTracker(hass, consider_home, track_new, devices) # update tracked devices update_tasks = [ device.async_update_ha_state() for device in devices if device.track ] if update_tasks: yield from asyncio.wait(update_tasks, loop=hass.loop) @asyncio.coroutine def async_setup_platform(p_type, p_config, disc_info=None): """Setup a device tracker platform.""" platform = yield from async_prepare_setup_platform( hass, config, DOMAIN, p_type) if platform is None: return _LOGGER.info("Setting up %s.%s", DOMAIN, p_type) try: scanner = None setup = None if hasattr(platform, 'async_get_scanner'): scanner = yield from platform.async_get_scanner( hass, {DOMAIN: p_config}) elif hasattr(platform, 'get_scanner'): scanner = yield from hass.loop.run_in_executor( None, platform.get_scanner, hass, {DOMAIN: p_config}) elif hasattr(platform, 'async_setup_scanner'): setup = yield from platform.async_setup_scanner( hass, p_config, tracker.see) elif hasattr(platform, 'setup_scanner'): setup = yield from hass.loop.run_in_executor( None, platform.setup_scanner, hass, p_config, tracker.see) else: raise HomeAssistantError("Invalid device_tracker platform.") if scanner: yield from async_setup_scanner_platform( hass, p_config, scanner, tracker.async_see) return if not setup: _LOGGER.error('Error setting up platform %s', p_type) return except Exception: # pylint: disable=broad-except _LOGGER.exception('Error setting up platform %s', p_type) setup_tasks = [ async_setup_platform(p_type, p_config) for p_type, p_config in config_per_platform(config, DOMAIN) ] if setup_tasks: yield from asyncio.wait(setup_tasks, loop=hass.loop) yield from tracker.async_setup_group() @callback def async_device_tracker_discovered(service, info): """Called when a device tracker platform is discovered.""" hass.async_add_job( async_setup_platform(DISCOVERY_PLATFORMS[service], {}, info)) discovery.async_listen(hass, DISCOVERY_PLATFORMS.keys(), async_device_tracker_discovered) # Clean up stale devices async_track_utc_time_change(hass, tracker.async_update_stale, second=range(0, 60, 5)) @asyncio.coroutine def async_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, ATTR_ATTRIBUTES) } yield from tracker.async_see(**args) descriptions = yield from hass.loop.run_in_executor( None, load_yaml_config_file, os.path.join(os.path.dirname(__file__), 'services.yaml')) hass.services.async_register(DOMAIN, SERVICE_SEE, async_see_service, descriptions.get(SERVICE_SEE)) return True