def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = get_test_home_assistant() loader.prepare(self.hass) self.known_dev_path = self.hass.config.path( device_tracker.KNOWN_DEVICES_FILE)
def from_config_dict(config, hass=None): """ Tries to configure Home Assistant from a config dict. Dynamically loads required components and its dependencies. """ if hass is None: hass = homeassistant.HomeAssistant() enable_logging(hass) loader.prepare(hass) # Make a copy because we are mutating it. # Convert it to defaultdict so components can always have config dict config = defaultdict(dict, config) # Filter out the repeating and common config section [homeassistant] components = (key for key in config.keys() if ' ' not in key and key != homeassistant.DOMAIN) if not core_components.setup(hass, config): _LOGGER.error("Home Assistant core failed to initialize. " "Further initialization aborted.") return hass _LOGGER.info("Home Assistant core initialized") # Setup the components for domain in loader.load_order_components(components): setup_component(hass, domain, config) return hass
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" loop = asyncio.new_event_loop() if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant(loop) if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) # FIXME should not be a daemon. Means hass.stop() not called in teardown stop_event = threading.Event() def run_loop(): loop.run_forever() loop.close() stop_event.set() threading.Thread(name="LoopThread", target=run_loop, daemon=True).start() orig_start = hass.start orig_stop = hass.stop @asyncio.coroutine def fake_stop(): yield None def start_hass(): """Helper to start hass.""" with patch.object(hass.loop, 'run_forever', return_value=None): with patch.object(hass, 'async_stop', return_value=fake_stop()): with patch.object(ha, 'async_create_timer', return_value=None): with patch.object(ha, 'async_monitor_worker_pool', return_value=None): orig_start() hass.block_till_done() def stop_hass(): orig_stop() stop_event.wait() hass.start = start_hass hass.stop = stop_hass return hass
def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = get_test_home_assistant() loader.prepare(self.hass) self.known_dev_path = self.hass.get_config_path( device_tracker.KNOWN_DEVICES_FILE)
def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = ha.HomeAssistant() loader.prepare(self.hass) self.assertTrue(comps.setup(self.hass, {})) self.hass.states.set('light.Bowl', comps.STATE_ON) self.hass.states.set('light.Ceiling', comps.STATE_OFF)
def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = ha.HomeAssistant() loader.prepare(self.hass) self.assertTrue(comps.setup(self.hass, {})) self.hass.states.set('light.Bowl', STATE_ON) self.hass.states.set('light.Ceiling', STATE_OFF)
def setUp(self): # pylint: disable=invalid-name self.hass = ha.HomeAssistant() loader.prepare(self.hass) self.calls = [] def record_call(service): self.calls.append(service) self.hass.services.register('test', 'automation', record_call)
def from_config_dict(config, hass=None): """ Tries to configure Home Assistant from a config dict. Dynamically loads required components and its dependencies. """ if hass is None: hass = homeassistant.HomeAssistant() logger = logging.getLogger(__name__) loader.prepare(hass) # Make a copy because we are mutating it. # Convert it to defaultdict so components can always have config dict config = defaultdict(dict, config) # Filter out the repeating and common config section [homeassistant] components = (key for key in config.keys() if ' ' not in key and key != homeassistant.DOMAIN) if not core_components.setup(hass, config): logger.error(("Home Assistant core failed to initialize. " "Further initialization aborted.")) return hass logger.info("Home Assistant core initialized") # Setup the components # We assume that all components that load before the group component loads # are components that poll devices. As their tasks are IO based, we will # add an extra worker for each of them. add_worker = True for domain in loader.load_order_components(components): component = loader.get_component(domain) try: if component.setup(hass, config): logger.info("component %s initialized", domain) add_worker = add_worker and domain != "group" if add_worker: hass.pool.add_worker() else: logger.error("component %s failed to initialize", domain) except Exception: # pylint: disable=broad-except logger.exception("Error during setup of component %s", domain) return hass
def setUp(self): # pylint: disable=invalid-name """ Init needed objects. """ self.hass = get_test_home_assistant() loader.prepare(self.hass) self.hass.states.set('light.Bowl', STATE_ON) self.hass.states.set('light.Ceiling', STATE_OFF) self.hass.states.set('light.Kitchen', STATE_OFF) loader.get_component('group').setup_group( self.hass, 'test', ['light.Ceiling', 'light.Kitchen'])
def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() loader.prepare(self.hass) platform = loader.get_component("switch.test") platform.init() self.assertTrue(switch.setup(self.hass, {switch.DOMAIN: {CONF_PLATFORM: "test"}})) # Switch 1 is ON, switch 2 is OFF self.switch_1, self.switch_2, self.switch_3 = platform.DEVICES
def setUp(self): # pylint: disable=invalid-name self.hass = ha.HomeAssistant() loader.prepare(self.hass) loader.set_component('switch.test', mock_toggledevice_platform) mock_toggledevice_platform.init() self.assertTrue(switch.setup( self.hass, {switch.DOMAIN: {ha.CONF_TYPE: 'test'}} )) # Switch 1 is ON, switch 2 is OFF self.switch_1, self.switch_2, self.switch_3 = \ mock_toggledevice_platform.get_switches(None, None)
def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() loader.prepare(self.hass) platform = loader.get_component('switch.test') platform.init() self.assertTrue(switch.setup( self.hass, {switch.DOMAIN: {CONF_PLATFORM: 'test'}} )) # Switch 1 is ON, switch 2 is OFF self.switch_1, self.switch_2, self.switch_3 = \ platform.get_switches(None, None)
def setUp(self): # pylint: disable=invalid-name self.hass = ha.HomeAssistant() loader.prepare(self.hass) loader.set_component('switch.test', mock_toggledevice_platform) mock_toggledevice_platform.init() self.assertTrue( switch.setup(self.hass, {switch.DOMAIN: { ha.CONF_TYPE: 'test' }})) # Switch 1 is ON, switch 2 is OFF self.switch_1, self.switch_2, self.switch_3 = \ mock_toggledevice_platform.get_switches(None, None)
def setUpModule(): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global KNOWN_DEV_PATH hass = get_test_home_assistant() loader.prepare(hass) KNOWN_DEV_PATH = hass.config.path(device_tracker.KNOWN_DEVICES_FILE) hass.stop() with open(KNOWN_DEV_PATH, 'w') as fil: fil.write('device,name,track,picture\n') fil.write('DEV1,device 1,1,http://example.com/dev1.jpg\n') fil.write('DEV2,device 2,1,http://example.com/dev2.jpg\n')
def setUpModule(): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global KNOWN_DEV_PATH hass = get_test_home_assistant() loader.prepare(hass) KNOWN_DEV_PATH = hass.config.path( device_tracker.KNOWN_DEVICES_FILE) hass.stop() with open(KNOWN_DEV_PATH, 'w') as fil: fil.write('device,name,track,picture\n') fil.write('DEV1,device 1,1,http://example.com/dev1.jpg\n') fil.write('DEV2,device 2,1,http://example.com/dev2.jpg\n')
def from_config_dict(config, hass=None): """ Tries to configure Home Assistant from a config dict. Dynamically loads required components and its dependencies. """ # Make a copy because we are mutating it. # Convert it to defaultdict so components can always have config dict config = defaultdict(dict, config) if hass is None: hass = homeassistant.HomeAssistant(config) logger = logging.getLogger(__name__) loader.prepare(hass) # Filter out the repeating and common config section [homeassistant] components = (key for key in config.keys() if ' ' not in key and key != homeassistant.DOMAIN) # Setup the components if core_components.setup(hass, config): logger.info("Home Assistant core initialized") for domain in loader.load_order_components(components): if domain is not "pushbullet": try: if loader.get_component(domain).setup(hass, config): logger.info("component %s initialized", domain) else: logger.error("component %s failed to initialize", domain) except Exception: # pylint: disable=broad-except logger.exception("Error during setup of component %s", domain) else: logger.error(("Home Assistant core failed to initialize. " "Further initialization aborted.")) return hass
def get_test_home_assistant(num_threads=None): """ Returns a Home Assistant object pointing at test config dir. """ if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant() if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) return hass
def get_test_home_assistant(num_threads=None): """ Returns a Home Assistant object pointing at test config dir. """ if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant() if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 if "custom_components.test" not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) return hass
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant() if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.temperature_unit = TEMP_CELSIUS if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) return hass
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant() if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.temperature_unit = TEMP_CELCIUS if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) return hass
def from_config_dict(config, hass=None): """ Tries to configure Home Assistant from a config dict. Dynamically loads required components and its dependencies. """ if hass is None: hass = homeassistant.HomeAssistant() logger = logging.getLogger(__name__) loader.prepare(hass) # Make a copy because we are mutating it. # Convert it to defaultdict so components can always have config dict config = defaultdict(dict, config) # Filter out the repeating and common config section [homeassistant] components = (key for key in config.keys() if ' ' not in key and key != homeassistant.DOMAIN) # Setup the components if core_components.setup(hass, config): logger.info("Home Assistant core initialized") for domain in loader.load_order_components(components): try: if loader.get_component(domain).setup(hass, config): logger.info("component %s initialized", domain) else: logger.error("component %s failed to initialize", domain) except Exception: # pylint: disable=broad-except logger.exception("Error during setup of component %s", domain) else: logger.error(("Home Assistant core failed to initialize. " "Further initialization aborted.")) return hass
def _ensure_loader_prepared(hass): """ Ensure Home Assistant loader is prepared. """ if not loader.PREPARED: loader.prepare(hass)
def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() loader.prepare(self.hass)
def check(config_dir, secrets=False): """Perform a check by mocking hass load functions.""" logging.getLogger('homeassistant.loader').setLevel(logging.CRITICAL) res = { 'yaml_files': OrderedDict(), # yaml_files loaded 'secrets': OrderedDict(), # secret cache and secrets loaded 'except': OrderedDict(), # exceptions raised (with config) 'components': None, # successful components 'secret_cache': None, } # pylint: disable=unused-variable def mock_load(filename): """Mock hass.util.load_yaml to save config file names.""" res['yaml_files'][filename] = True return MOCKS['load'][1](filename) # pylint: disable=unused-variable def mock_secrets(ldr, node): """Mock _get_secrets.""" try: val = MOCKS['secrets'][1](ldr, node) except HomeAssistantError: val = None res['secrets'][node.value] = val return val # Patches to skip functions for sil in SILENCE: PATCHES[sil] = patch(sil) # Patches with local mock functions for key, val in MOCKS.items(): if not secrets and key == 'secrets': continue # The * in the key is removed to find the mock_function (side_effect) # This allows us to use one side_effect to patch multiple locations mock_function = locals()['mock_' + key.replace('*', '')] PATCHES[key] = patch(val[0], side_effect=mock_function) # Start all patches for pat in PATCHES.values(): pat.start() if secrets: # Ensure !secrets point to the patched function yaml.yaml.SafeLoader.add_constructor('!secret', yaml._secret_yaml) try: class HassConfig(): """Hass object with config.""" def __init__(self, conf_dir): """Init the config_dir.""" self.config = core.Config() self.config.config_dir = conf_dir loader.prepare(HassConfig(config_dir)) res['components'] = check_ha_config_file(config_dir) res['secret_cache'] = OrderedDict(yaml.__SECRET_CACHE) for err in res['components'].errors: domain = err.domain or ERROR_STR res['except'].setdefault(domain, []).append(err.message) if err.config: res['except'].setdefault(domain, []).append(err.config) except Exception as err: # pylint: disable=broad-except print(color('red', 'Fatal error while loading config:'), str(err)) res['except'].setdefault(ERROR_STR, []).append(str(err)) finally: # Stop all patches for pat in PATCHES.values(): pat.stop() if secrets: # Ensure !secrets point to the original function yaml.yaml.SafeLoader.add_constructor('!secret', yaml._secret_yaml) bootstrap.clear_secret_cache() return res
def setUp(self): # pylint: disable=invalid-name self.hass = get_test_home_assistant() loader.prepare(self.hass) loader.set_component('light.test', mock_toggledevice_platform)
def from_config_dict(config, hass=None): """ Tries to configure Home Assistant from a config dict. Dynamically loads required components and its dependencies. """ if hass is None: hass = homeassistant.HomeAssistant() logger = logging.getLogger(__name__) # Make a copy because we are mutating it. # Convert it to defaultdict so components can always have config dict config = defaultdict(dict, config) # List of loaded components components = {} # List of components to validate to_validate = [] # List of validated components validated = [] # List of components we are going to load to_load = [key for key in config.keys() if key != homeassistant.DOMAIN] loader.prepare(hass) # Load required components while to_load: domain = to_load.pop() component = loader.get_component(domain) # if None it does not exist, error already thrown by get_component if component is not None: components[domain] = component # Special treatment for GROUP, we want to load it as late as # possible. We do this by loading it if all other to be loaded # modules depend on it. if component.DOMAIN == group.DOMAIN: pass # Components with no dependencies are valid elif not component.DEPENDENCIES: validated.append(domain) # If dependencies we'll validate it later else: to_validate.append(domain) # Make sure to load all dependencies that are not being loaded for dependency in component.DEPENDENCIES: if dependency not in chain(components.keys(), to_load): to_load.append(dependency) # Validate dependencies group_added = False while to_validate: newly_validated = [] for domain in to_validate: if all(domain in validated for domain in components[domain].DEPENDENCIES): newly_validated.append(domain) # We validated new domains this iteration, add them to validated if newly_validated: # Add newly validated domains to validated validated.extend(newly_validated) # remove domains from to_validate for domain in newly_validated: to_validate.remove(domain) newly_validated.clear() # Nothing validated this iteration. Add group dependency and try again. elif not group_added: group_added = True validated.append(group.DOMAIN) # Group has already been added and we still can't validate all. # Report missing deps as error and skip loading of these domains else: for domain in to_validate: missing_deps = [dep for dep in components[domain].DEPENDENCIES if dep not in validated] logger.error( "Could not validate all dependencies for %s: %s", domain, ", ".join(missing_deps)) break # Make sure we load groups if not in list yet. if not group_added: validated.append(group.DOMAIN) if group.DOMAIN not in components: components[group.DOMAIN] = \ loader.get_component(group.DOMAIN) # Setup the components if core_components.setup(hass, config): logger.info("Home Assistant core initialized") for domain in validated: component = components[domain] try: if component.setup(hass, config): logger.info("component %s initialized", domain) else: logger.error("component %s failed to initialize", domain) except Exception: # pylint: disable=broad-except logger.exception("Error during setup of component %s", domain) else: logger.error(("Home Assistant core failed to initialize. " "Further initialization aborted.")) return hass
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" loop = asyncio.new_event_loop() if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant(loop) if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) # FIXME should not be a daemon. Means hass.stop() not called in teardown stop_event = threading.Event() def run_loop(): loop.run_forever() loop.close() stop_event.set() threading.Thread(name="LoopThread", target=run_loop, daemon=True).start() orig_start = hass.start orig_stop = hass.stop @asyncio.coroutine def fake_stop(): yield None def start_hass(): """Helper to start hass.""" with patch.object(hass.loop, 'run_forever', return_value=None): with patch.object(hass, 'async_stop', return_value=fake_stop()): with patch.object(ha, 'async_create_timer', return_value=None): with patch.object(ha, 'async_monitor_worker_pool', return_value=None): with patch.object(hass.loop, 'add_signal_handler'): orig_start() hass.block_till_done() def stop_hass(): orig_stop() stop_event.wait() hass.start = start_hass hass.stop = stop_hass return hass