def setUpModule(): # pylint: disable=invalid-name """ Initalizes a Home Assistant server and Slave instance. """ global hass, slave, master_api, broken_api hass = ha.HomeAssistant() hass.bus.listen('test_event', lambda _: _) hass.states.set('test.test', 'a_state') bootstrap.setup_component( hass, http.DOMAIN, {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, http.CONF_SERVER_PORT: 8122}}) bootstrap.setup_component(hass, 'api') hass.start() master_api = remote.API("127.0.0.1", API_PASSWORD, 8122) # Start slave slave = remote.HomeAssistant(master_api) slave.start() # Setup API pointing at nothing broken_api = remote.API("127.0.0.1", "", 8125)
def setup_ecobee(hass, network, config): """Setup Ecobee thermostat.""" # If ecobee has a PIN then it needs to be configured. if network.pin is not None: request_configuration(network, hass, config) return if 'ecobee' in _CONFIGURING: configurator = get_component('configurator') configurator.request_done(_CONFIGURING.pop('ecobee')) # Ensure component is loaded bootstrap.setup_component(hass, 'thermostat', config) bootstrap.setup_component(hass, 'sensor', config) hold_temp = config[DOMAIN].get(HOLD_TEMP, False) # Fire thermostat discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: DISCOVER_THERMOSTAT, ATTR_DISCOVERED: {'hold_temp': hold_temp} }) # Fire sensor discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: DISCOVER_SENSORS, ATTR_DISCOVERED: {} })
def test_service_say_russian_config(self, aioclient_mock): """Test service call say.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) url_param = { 'text': 'HomeAssistant', 'lang': 'ru-RU', 'key': '1234567xx', 'speaker': 'zahar', 'format': 'mp3', 'emotion': 'neutral', 'speed': 1 } aioclient_mock.get( self._base_url, status=200, content=b'test', params=url_param) config = { tts.DOMAIN: { 'platform': 'yandextts', 'api_key': '1234567xx', 'language': 'ru-RU', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'yandextts_say', { tts.ATTR_MESSAGE: "HomeAssistant", }) self.hass.block_till_done() assert len(aioclient_mock.mock_calls) == 1 assert len(calls) == 1
def test_platform_specific_config_validation(self): """Test platform that specifies config.""" platform_schema = PLATFORM_SCHEMA.extend({ 'valid': True, }, extra=vol.PREVENT_EXTRA) loader.set_component( 'switch.platform_a', MockPlatform('comp_b', platform_schema=platform_schema)) assert not bootstrap.setup_component(self.hass, 'switch', { 'switch': { 'platform': 'platform_a', 'invalid': True } }) assert not bootstrap.setup_component(self.hass, 'switch', { 'switch': { 'platform': 'platform_a', 'valid': True, 'invalid_extra': True, } }) assert bootstrap.setup_component(self.hass, 'switch', { 'switch': { 'platform': 'platform_a', 'valid': True } })
def setUpModule(): # pylint: disable=invalid-name """Initialize a Home Assistant server for testing this module.""" global hass hass = get_test_home_assistant() bootstrap.setup_component( hass, http.DOMAIN, {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, http.CONF_SERVER_PORT: SERVER_PORT}}) hass.services.register('test', 'alexa', lambda call: calls.append(call)) bootstrap.setup_component(hass, alexa.DOMAIN, { 'alexa': { 'intents': { 'WhereAreWeIntent': { 'speech': { 'type': 'plaintext', 'text': """ {%- if is_state('device_tracker.paulus', 'home') and is_state('device_tracker.anne_therese', 'home') -%} You are both home, you silly {%- else -%} Anne Therese is at {{ states("device_tracker.anne_therese") }} and Paulus is at {{ states("device_tracker.paulus") }} {% endif %} """, } }, 'GetZodiacHoroscopeIntent': { 'speech': { 'type': 'plaintext', 'text': 'You told us your sign is {{ ZodiacSign }}.', } }, 'CallServiceIntent': { 'speech': { 'type': 'plaintext', 'text': 'Service called', }, 'action': { 'service': 'test.alexa', 'data_template': { 'hello': '{{ ZodiacSign }}' }, 'entity_id': 'switch.test', } } } } }) hass.start() time.sleep(0.05)
def setup(hass, config): """ Sets up the Wink component. """ logger = logging.getLogger(__name__) if not validate_config(config, {DOMAIN: [CONF_ACCESS_TOKEN]}, logger): return False import pywink pywink.set_bearer_token(config[DOMAIN][CONF_ACCESS_TOKEN]) # Load components for the devices in the Wink that we support for component_name, func_exists, discovery_type in ( ('light', pywink.get_bulbs, DISCOVER_LIGHTS), ('switch', pywink.get_switches, DISCOVER_SWITCHES), ('sensor', pywink.get_sensors, DISCOVER_SENSORS)): if func_exists(): component = get_component(component_name) # Ensure component is loaded bootstrap.setup_component(hass, component.DOMAIN, config) # Fire discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: discovery_type, ATTR_DISCOVERED: {} }) return True
def test_setup_component_and_test_service_with_config_language(self): """Setup the demo platform and call service.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) config = { tts.DOMAIN: { 'platform': 'demo', 'language': 'de' } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'demo_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MEDIA_TYPE_MUSIC assert calls[0].data[ATTR_MEDIA_CONTENT_ID].find( "/api/tts_proxy/265944c108cbb00b2a621be5930513e03a0bb2cd" "_de_-_demo.mp3") \ != -1 assert os.path.isfile(os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_de_-_demo.mp3"))
def value_added(node, value): """ Called when a value is added to a node on the network. """ for (component, discovery_service, command_ids, value_type, value_genre) in DISCOVERY_COMPONENTS: if value.command_class not in command_ids: continue if value_type is not None and value_type != value.type: continue if value_genre is not None and value_genre != value.genre: continue # Ensure component is loaded bootstrap.setup_component(hass, component, config) # Fire discovery event hass.bus.fire(EVENT_PLATFORM_DISCOVERED, { ATTR_SERVICE: discovery_service, ATTR_DISCOVERED: { ATTR_NODE_ID: node.node_id, ATTR_VALUE_ID: value.value_id, } })
def test_webcomponent_custom_path(self, mock_register, _mock_setup): """Test if a web component is found in config panels dir.""" with NamedTemporaryFile() as fp: config = { 'panel_custom': { 'name': 'todomvc', 'webcomponent_path': fp.name, 'sidebar_title': 'Sidebar Title', 'sidebar_icon': 'mdi:iconicon', 'url_path': 'nice_url', 'config': 5, } } with patch('os.path.isfile', return_value=False): assert not bootstrap.setup_component(self.hass, 'panel_custom', config) assert not mock_register.called assert bootstrap.setup_component(self.hass, 'panel_custom', config) assert mock_register.called args = mock_register.mock_calls[0][1] kwargs = mock_register.mock_calls[0][2] assert args == (self.hass, 'todomvc', fp.name) assert kwargs == { 'config': 5, 'url_path': 'nice_url', 'sidebar_icon': 'mdi:iconicon', 'sidebar_title': 'Sidebar Title' }
def test_service_say(self, aioclient_mock): """Test service call say.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) aioclient_mock.post( self.url, data=self.form_data, status=200, content=b'test') config = { tts.DOMAIN: { 'platform': 'voicerss', 'api_key': '1234567xx', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'voicerss_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 assert len(aioclient_mock.mock_calls) == 1 assert aioclient_mock.mock_calls[0][2] == self.form_data assert calls[0].data[ATTR_MEDIA_CONTENT_ID].find(".mp3") != -1
def test_service_say_german_config(self, aioclient_mock): """Test service call say with german code in the config.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) self.form_data['hl'] = 'de-de' aioclient_mock.post( self.url, data=self.form_data, status=200, content=b'test') config = { tts.DOMAIN: { 'platform': 'voicerss', 'api_key': '1234567xx', 'language': 'de-de', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'voicerss_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 assert len(aioclient_mock.mock_calls) == 1 assert aioclient_mock.mock_calls[0][2] == self.form_data
def test_service_say_timeout(self, aioclient_mock): """Test service call say with http timeout.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) aioclient_mock.post( self.url, data=self.form_data, exc=asyncio.TimeoutError()) config = { tts.DOMAIN: { 'platform': 'voicerss', 'api_key': '1234567xx', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'voicerss_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 0 assert len(aioclient_mock.mock_calls) == 1 assert aioclient_mock.mock_calls[0][2] == self.form_data
def test_setup_component_load_cache_retrieve_without_mem_cache(self): """Setup component and load cache and get without mem cache.""" _, demo_data = self.demo_provider.get_tts_audio("bla", 'en') cache_file = os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_en_-_demo.mp3") os.mkdir(self.default_tts_cache) with open(cache_file, "wb") as voice_file: voice_file.write(demo_data) config = { tts.DOMAIN: { 'platform': 'demo', 'cache': True, } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.start() url = ("{}/api/tts_proxy/265944c108cbb00b2a621be5930513e03a0bb2cd" "_en_-_demo.mp3").format(self.hass.config.api.base_url) req = requests.get(url) assert req.status_code == 200 assert req.content == demo_data
def test_active_zone_skips_passive_zones(self): """Test active and passive zones.""" assert bootstrap.setup_component(self.hass, zone.DOMAIN, { 'zone': [ { 'name': 'Passive Zone', 'latitude': 32.880600, 'longitude': -117.237561, 'radius': 250, 'passive': True }, ] }) active = zone.active_zone(self.hass, 32.880600, -117.237561) assert active is None self.hass.config.components.remove('zone') assert bootstrap.setup_component(self.hass, zone.DOMAIN, { 'zone': [ { 'name': 'Active Zone', 'latitude': 32.880800, 'longitude': -117.237561, 'radius': 500, }, ] }) active = zone.active_zone(self.hass, 32.880700, -117.237561) assert 'zone.active_zone' == active.entity_id
def test_setup_component_test_with_cache_dir(self): """Setup demo platform with cache and call service without cache.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) _, demo_data = self.demo_provider.get_tts_audio("bla", 'en') cache_file = os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_en_-_demo.mp3") os.mkdir(self.default_tts_cache) with open(cache_file, "wb") as voice_file: voice_file.write(demo_data) config = { tts.DOMAIN: { 'platform': 'demo', 'cache': True, } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) with patch('homeassistant.components.tts.demo.DemoProvider.' 'get_tts_audio', return_value=(None, None)): self.hass.services.call(tts.DOMAIN, 'demo_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 assert calls[0].data[ATTR_MEDIA_CONTENT_ID].find( "/api/tts_proxy/265944c108cbb00b2a621be5930513e03a0bb2cd" "_en_-_demo.mp3") \ != -1
def setUp(self): # pylint: disable=invalid-name """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() self.events = [] self.service1 = MagicMock() self.service2 = MagicMock() def mock_get_service(hass, config): if config['name'] == 'demo1': return self.service1 else: return self.service2 with assert_setup_component(2), \ patch.object(demo, 'get_service', mock_get_service): setup_component(self.hass, notify.DOMAIN, { 'notify': [{ 'name': 'demo1', 'platform': 'demo' }, { 'name': 'demo2', 'platform': 'demo' }] }) self.service = group.get_service(self.hass, {'services': [ {'service': 'demo1'}, {'service': 'demo2', 'data': {'target': 'unnamed device', 'data': {'test': 'message'}}}]}) assert self.service is not None
def test_setup_component_and_test_service_clear_cache(self): """Setup the demo platform and call service clear cache.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) config = { tts.DOMAIN: { 'platform': 'demo', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'demo_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 assert os.path.isfile(os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_en_-_demo.mp3")) self.hass.services.call(tts.DOMAIN, tts.SERVICE_CLEAR_CACHE, {}) self.hass.block_till_done() assert not os.path.isfile(os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_en_-_demo.mp3"))
def test_setup_component_and_test_service_with_receive_voice_german(self): """Setup the demo platform and call service and receive voice.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) config = { tts.DOMAIN: { 'platform': 'demo', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.start() self.hass.services.call(tts.DOMAIN, 'demo_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 req = requests.get(calls[0].data[ATTR_MEDIA_CONTENT_ID]) _, demo_data = self.demo_provider.get_tts_audio("bla", "de") assert req.status_code == 200 assert req.content == demo_data
def test_setup_component_and_test_with_service_options_def(self, def_mock): """Setup the demo platform and call service with default options.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) config = { tts.DOMAIN: { 'platform': 'demo', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'demo_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", tts.ATTR_LANGUAGE: "de", }) self.hass.block_till_done() opt_hash = ctypes.c_size_t(hash(frozenset({'voice': 'alex'}))).value assert len(calls) == 1 assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MEDIA_TYPE_MUSIC assert calls[0].data[ATTR_MEDIA_CONTENT_ID].find( "/api/tts_proxy/265944c108cbb00b2a621be5930513e03a0bb2cd" "_de_{0}_demo.mp3".format(opt_hash)) \ != -1 assert os.path.isfile(os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_de_{0}_demo.mp3".format( opt_hash)))
def test_setup_component_and_test_service_with_service_options_wrong(self): """Setup the demo platform and call service with wrong options.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) config = { tts.DOMAIN: { 'platform': 'demo', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'demo_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", tts.ATTR_LANGUAGE: "de", tts.ATTR_OPTIONS: { 'speed': 1 } }) self.hass.block_till_done() opt_hash = ctypes.c_size_t(hash(frozenset({'speed': 1}))).value assert len(calls) == 0 assert not os.path.isfile(os.path.join( self.default_tts_cache, "265944c108cbb00b2a621be5930513e03a0bb2cd_de_{0}_demo.mp3".format( opt_hash)))
def test_service_groups(self, mock_update, aioclient_mock): """Setup component, test groups services.""" aioclient_mock.put( mf.FACE_API_URL.format("persongroups/service_group"), status=200, text="{}" ) aioclient_mock.delete( mf.FACE_API_URL.format("persongroups/service_group"), status=200, text="{}" ) with assert_setup_component(2, mf.DOMAIN): setup_component(self.hass, mf.DOMAIN, self.config) mf.create_group(self.hass, 'Service Group') self.hass.block_till_done() entity = self.hass.states.get('microsoft_face.service_group') assert entity is not None assert len(aioclient_mock.mock_calls) == 1 mf.delete_group(self.hass, 'Service Group') self.hass.block_till_done() entity = self.hass.states.get('microsoft_face.service_group') assert entity is None assert len(aioclient_mock.mock_calls) == 2
def test_setup_component_test_entities(self, aioclient_mock): """Setup component.""" aioclient_mock.get( mf.FACE_API_URL.format("persongroups"), text=load_fixture('microsoft_face_persongroups.json') ) aioclient_mock.get( mf.FACE_API_URL.format("persongroups/test_group1/persons"), text=load_fixture('microsoft_face_persons.json') ) aioclient_mock.get( mf.FACE_API_URL.format("persongroups/test_group2/persons"), text=load_fixture('microsoft_face_persons.json') ) with assert_setup_component(2, mf.DOMAIN): setup_component(self.hass, mf.DOMAIN, self.config) assert len(aioclient_mock.mock_calls) == 3 entity_group1 = self.hass.states.get('microsoft_face.test_group1') entity_group2 = self.hass.states.get('microsoft_face.test_group2') assert entity_group1 is not None assert entity_group2 is not None assert entity_group1.attributes['Ryan'] == \ '25985303-c537-4467-b41d-bdb45cd95ca1' assert entity_group1.attributes['David'] == \ '2ae4935b-9659-44c3-977f-61fac20d0538' assert entity_group2.attributes['Ryan'] == \ '25985303-c537-4467-b41d-bdb45cd95ca1' assert entity_group2.attributes['David'] == \ '2ae4935b-9659-44c3-977f-61fac20d0538'
def test_service_face(self, camera_mock, aioclient_mock): """Setup component, test person face services.""" aioclient_mock.get( mf.FACE_API_URL.format("persongroups"), text=load_fixture('microsoft_face_persongroups.json') ) aioclient_mock.get( mf.FACE_API_URL.format("persongroups/test_group1/persons"), text=load_fixture('microsoft_face_persons.json') ) aioclient_mock.get( mf.FACE_API_URL.format("persongroups/test_group2/persons"), text=load_fixture('microsoft_face_persons.json') ) self.config['camera'] = {'platform': 'demo'} with assert_setup_component(2, mf.DOMAIN): setup_component(self.hass, mf.DOMAIN, self.config) assert len(aioclient_mock.mock_calls) == 3 aioclient_mock.post( mf.FACE_API_URL.format( "persongroups/test_group2/persons/" "2ae4935b-9659-44c3-977f-61fac20d0538/persistedFaces"), status=200, text="{}" ) mf.face_person( self.hass, 'test_group2', 'David', 'camera.demo_camera') self.hass.block_till_done() assert len(aioclient_mock.mock_calls) == 4 assert aioclient_mock.mock_calls[3][2] == b'Test'
def test_service_say_german_config(self, mock_calculate, aioclient_mock): """Test service call say with german code in the config.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) self.url_param['tl'] = 'de' aioclient_mock.get( self.url, params=self.url_param, status=200, content=b'test') config = { tts.DOMAIN: { 'platform': 'google', 'language': 'de', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'google_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 1 assert len(aioclient_mock.mock_calls) == 1
def setup(hass, config): """ Setup Insteon Hub component. This will automatically import associated lights. """ if not validate_config( config, {DOMAIN: [CONF_USERNAME, CONF_PASSWORD, CONF_API_KEY]}, _LOGGER): return False import insteon username = config[DOMAIN][CONF_USERNAME] password = config[DOMAIN][CONF_PASSWORD] api_key = config[DOMAIN][CONF_API_KEY] global INSTEON INSTEON = insteon.Insteon(username, password, api_key) if INSTEON is None: _LOGGER.error("Could not connect to Insteon service.") return comp_name = 'light' discovery = DISCOVER_LIGHTS component = get_component(comp_name) bootstrap.setup_component(hass, component.DOMAIN, config) hass.bus.fire( EVENT_PLATFORM_DISCOVERED, {ATTR_SERVICE: discovery, ATTR_DISCOVERED: {}}) return True
def setup_method(self): """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() setup_component( self.hass, http.DOMAIN, {http.DOMAIN: {http.CONF_SERVER_PORT: get_test_instance_port()}}) config = { ip.DOMAIN: { 'platform': 'demo' }, 'camera': { 'platform': 'demo' }, } with patch('homeassistant.components.image_processing.demo.' 'DemoImageProcessing.should_poll', new_callable=PropertyMock(return_value=False)): setup_component(self.hass, ip.DOMAIN, config) state = self.hass.states.get('camera.demo_camera') self.url = "{0}{1}".format( self.hass.config.api.base_url, state.attributes.get(ATTR_ENTITY_PICTURE))
def test_service_say_error_msg(self, aioclient_mock): """Test service call say with http error api message.""" calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) aioclient_mock.post( self.url, data=self.form_data, status=200, content=b'The subscription does not support SSML!' ) config = { tts.DOMAIN: { 'platform': 'voicerss', 'api_key': '1234567xx', } } with assert_setup_component(1, tts.DOMAIN): setup_component(self.hass, tts.DOMAIN, config) self.hass.services.call(tts.DOMAIN, 'voicerss_say', { tts.ATTR_MESSAGE: "I person is on front of your door.", }) self.hass.block_till_done() assert len(calls) == 0 assert len(aioclient_mock.mock_calls) == 1 assert aioclient_mock.mock_calls[0][2] == self.form_data
def test_webcomponent_custom_path(self, mock_register, _mock_setup): """Test if a web component is found in config panels dir.""" filename = "mock.file" config = { "panel_custom": { "name": "todomvc", "webcomponent_path": filename, "sidebar_title": "Sidebar Title", "sidebar_icon": "mdi:iconicon", "url_path": "nice_url", "config": 5, } } with patch("os.path.isfile", Mock(return_value=False)): assert not bootstrap.setup_component(self.hass, "panel_custom", config) assert not mock_register.called with patch("os.path.isfile", Mock(return_value=True)): with patch("os.access", Mock(return_value=True)): assert bootstrap.setup_component(self.hass, "panel_custom", config) assert mock_register.called args = mock_register.mock_calls[0][1] assert args == (self.hass, "todomvc", filename) kwargs = mock_register.mock_calls[0][2] assert kwargs == { "config": 5, "url_path": "nice_url", "sidebar_icon": "mdi:iconicon", "sidebar_title": "Sidebar Title", }
def setup_method(self): """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() config = { ip.DOMAIN: { 'platform': 'demo' }, 'camera': { 'platform': 'demo' }, } with patch('homeassistant.components.image_processing.demo.' 'DemoImageProcessingFaceIdentify.should_poll', new_callable=PropertyMock(return_value=False)): setup_component(self.hass, ip.DOMAIN, config) state = self.hass.states.get('camera.demo_camera') self.url = "{0}{1}".format( self.hass.config.api.base_url, state.attributes.get(ATTR_ENTITY_PICTURE)) self.face_events = [] @callback def mock_face_event(event): """Mock event.""" self.face_events.append(event) self.hass.bus.listen('identify_face', mock_face_event)
def test_disable_component_if_invalid_return(self): """Test disabling component if invalid return.""" loader.set_component( 'disabled_component', MockModule('disabled_component', setup=lambda hass, config: None)) assert not bootstrap.setup_component(self.hass, 'disabled_component') assert loader.get_component('disabled_component') is None assert 'disabled_component' not in self.hass.config.components loader.set_component( 'disabled_component', MockModule('disabled_component', setup=lambda hass, config: False)) assert not bootstrap.setup_component(self.hass, 'disabled_component') assert loader.get_component('disabled_component') is not None assert 'disabled_component' not in self.hass.config.components loader.set_component( 'disabled_component', MockModule('disabled_component', setup=lambda hass, config: True)) assert bootstrap.setup_component(self.hass, 'disabled_component') assert loader.get_component('disabled_component') is not None assert 'disabled_component' in self.hass.config.components
def test_service_specify_data(self): """Test service data.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { 'platform': 'event', 'event_type': 'test_event', }, 'action': { 'service': 'test.automation', 'data_template': { 'some': '{{ trigger.platform }} - ' '{{ trigger.event.event_type }}' }, } } }) time = dt_util.utcnow() with patch('homeassistant.components.automation.utcnow', return_value=time): self.hass.bus.fire('test_event') self.hass.block_till_done() assert len(self.calls) == 1 assert self.calls[0].data['some'] == 'event - test_event' state = self.hass.states.get('automation.hello') assert state is not None assert state.attributes.get('last_triggered') == time state = self.hass.states.get('group.all_automations') assert state is not None assert state.attributes.get('entity_id') == ('automation.hello', )
def test_discover_cover_noautoadd(self): """Test with discovery of cover when auto add is False.""" self.assertTrue(setup_component(self.hass, 'cover', { 'cover': {'platform': 'rfxtrx', 'automatic_add': False, 'devices': {}}})) event = rfxtrx_core.get_rfx_object('0a1400adf394ab010d0060') event.data = bytearray([0x0A, 0x14, 0x00, 0xAD, 0xF3, 0x94, 0xAB, 0x01, 0x0D, 0x00, 0x60]) for evt_sub in rfxtrx_core.RECEIVED_EVT_SUBSCRIBERS: evt_sub(event) self.assertEqual(0, len(rfxtrx_core.RFX_DEVICES)) event = rfxtrx_core.get_rfx_object('0a1400adf394ab020e0060') event.data = bytearray([0x0A, 0x14, 0x00, 0xAD, 0xF3, 0x94, 0xAB, 0x02, 0x0E, 0x00, 0x60]) for evt_sub in rfxtrx_core.RECEIVED_EVT_SUBSCRIBERS: evt_sub(event) self.assertEqual(0, len(rfxtrx_core.RFX_DEVICES)) # Trying to add a sensor event = rfxtrx_core.get_rfx_object('0a52085e070100b31b0279') event.data = bytearray(b'\nR\x08^\x07\x01\x00\xb3\x1b\x02y') for evt_sub in rfxtrx_core.RECEIVED_EVT_SUBSCRIBERS: evt_sub(event) self.assertEqual(0, len(rfxtrx_core.RFX_DEVICES)) # Trying to add a light event = rfxtrx_core.get_rfx_object('0b1100100118cdea02010f70') event.data = bytearray([0x0b, 0x11, 0x11, 0x10, 0x01, 0x18, 0xcd, 0xea, 0x01, 0x02, 0x0f, 0x70]) for evt_sub in rfxtrx_core.RECEIVED_EVT_SUBSCRIBERS: evt_sub(event) self.assertEqual(0, len(rfxtrx_core.RFX_DEVICES))
def test_sending_mqtt_commands_and_optimistic(self): """Test the sending MQTT commands in optimistic mode.""" with assert_setup_component(1): assert setup_component( self.hass, garage_door.DOMAIN, { garage_door.DOMAIN: { 'platform': 'mqtt', 'name': 'test', 'command_topic': 'command-topic', 'state_open': 'beer state open', 'state_closed': 'beer state closed', 'service_open': 'beer open', 'service_close': 'beer close', 'qos': '2' } }) state = self.hass.states.get('garage_door.test') self.assertEqual(STATE_CLOSED, state.state) self.assertTrue(state.attributes.get(ATTR_ASSUMED_STATE)) garage_door.open_door(self.hass, 'garage_door.test') self.hass.block_till_done() self.assertEqual(('command-topic', 'beer open', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('garage_door.test') self.assertEqual(STATE_OPEN, state.state) garage_door.close_door(self.hass, 'garage_door.test') self.hass.block_till_done() self.assertEqual(('command-topic', 'beer close', 2, False), self.mock_publish.mock_calls[-1][1]) state = self.hass.states.get('garage_door.test') self.assertEqual(STATE_CLOSED, state.state)
def test_if_fires_on_entity_change_with_for(self): """Test for firing on entity change with for.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'state', 'entity_id': 'test.entity', 'to': 'world', 'for': { 'seconds': 5 }, }, 'action': { 'service': 'test.automation' } } }) self.hass.states.set('test.entity', 'world') self.hass.block_till_done() fire_time_changed(self.hass, dt_util.utcnow() + timedelta(seconds=10)) self.hass.block_till_done() self.assertEqual(1, len(self.calls))
def test_entity_attributes(self): """Test the entity attributes.""" dev_id = 'test_entity' entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) friendly_name = 'Paulus' picture = 'http://placehold.it/200x200' device = device_tracker.Device(self.hass, timedelta(seconds=180), True, dev_id, None, friendly_name, picture, hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) self.assertTrue( setup_component(self.hass, device_tracker.DOMAIN, TEST_PLATFORM)) attrs = self.hass.states.get(entity_id).attributes self.assertEqual(friendly_name, attrs.get(ATTR_FRIENDLY_NAME)) self.assertEqual(picture, attrs.get(ATTR_ENTITY_PICTURE))
def test_missing_off_does_not_create(self): """Test missing off.""" with assert_setup_component(0): assert bootstrap.setup_component( self.hass, 'switch', { 'switch': { 'platform': 'template', 'switches': { 'test_template_switch': { 'value_template': "{{ states.switch.test_state.state }}", 'turn_on': { 'service': 'switch.turn_on', 'entity_id': 'switch.test_state' }, 'not_off': { 'service': 'switch.turn_off', 'entity_id': 'switch.test_state' }, } } } }) assert self.hass.states.all() == []
def test_toggle_service(self): """Test the toggling of a service.""" event = 'test_event' events = [] @callback def record_event(event): """Add recorded event to set.""" events.append(event) self.hass.bus.listen(event, record_event) assert setup_component( self.hass, 'script', { 'script': { 'test': { 'sequence': [{ 'delay': { 'seconds': 5 } }, { 'event': event, }] } } }) script.toggle(self.hass, ENTITY_ID) self.hass.block_till_done() self.assertTrue(script.is_on(self.hass, ENTITY_ID)) self.assertEqual(0, len(events)) script.toggle(self.hass, ENTITY_ID) self.hass.block_till_done() self.assertFalse(script.is_on(self.hass, ENTITY_ID)) self.assertEqual(0, len(events))
def test_arm_home_no_pending(self): """Test arm home method.""" self.assertTrue( setup_component( self.hass, alarm_control_panel.DOMAIN, { 'alarm_control_panel': { 'platform': 'manual', 'name': 'test', 'code': CODE, 'pending_time': 0, 'disarm_after_trigger': False } })) entity_id = 'alarm_control_panel.test' self.assertEqual(STATE_ALARM_DISARMED, self.hass.states.get(entity_id).state) alarm_control_panel.alarm_arm_home(self.hass, CODE) self.hass.block_till_done() self.assertEqual(STATE_ALARM_ARMED_HOME, self.hass.states.get(entity_id).state)
def test_scan_devices(self): """Test creating device info (MAC, name) from response. The created known_devices.yaml device info is compared to the DD-WRT Lan Status request response fixture. This effectively checks the data parsing functions. """ with requests_mock.Mocker() as mock_request: mock_request.register_uri( 'GET', r'http://%s/Status_Wireless.live.asp' % TEST_HOST, text=load_fixture('Ddwrt_Status_Wireless.txt')) mock_request.register_uri( 'GET', r'http://%s/Status_Lan.live.asp' % TEST_HOST, text=load_fixture('Ddwrt_Status_Lan.txt')) with assert_setup_component(1): assert setup_component( self.hass, DOMAIN, { DOMAIN: { CONF_PLATFORM: 'ddwrt', CONF_HOST: TEST_HOST, CONF_USERNAME: '******', CONF_PASSWORD: '******' } }) self.hass.block_till_done() path = self.hass.config.path(device_tracker.YAML_DEVICES) devices = config.load_yaml_config_file(path) for device in devices: self.assertIn(devices[device]['mac'], load_fixture('Ddwrt_Status_Lan.txt')) self.assertIn(slugify(devices[device]['name']), load_fixture('Ddwrt_Status_Lan.txt'))
def test_arm_home_with_invalid_code(self): """Attempt to arm home without a valid code.""" self.assertTrue( setup_component( self.hass, alarm_control_panel.DOMAIN, { 'alarm_control_panel': { 'platform': 'manual', 'name': 'test', 'code': CODE, 'pending_time': 1, 'disarm_after_trigger': False } })) entity_id = 'alarm_control_panel.test' self.assertEqual(STATE_ALARM_DISARMED, self.hass.states.get(entity_id).state) alarm_control_panel.alarm_arm_home(self.hass, CODE + '2') self.hass.block_till_done() self.assertEqual(STATE_ALARM_DISARMED, self.hass.states.get(entity_id).state)
def test_setup_get(self, mock_req): """Test setup with valid configuration.""" mock_req.get('http://localhost', status_code=200) self.assertTrue( setup_component( self.hass, 'sensor', { 'sensor': { 'platform': 'rest', 'resource': 'http://localhost', 'method': 'GET', 'value_template': '{{ value_json.key }}', 'name': 'foo', 'unit_of_measurement': 'MB', 'verify_ssl': 'true', 'authentication': 'basic', 'username': '******', 'password': '******', 'headers': { 'Accept': 'application/json' } } })) self.assertEqual(2, mock_req.call_count) assert_setup_component(1, 'sensor')
def test_if_fires_on_change_bool(self): """Test for firing on boolean change.""" assert setup_component(self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'template', 'value_template': '{{ true }}', }, 'action': { 'service': 'test.automation' } } }) self.hass.states.set('test.entity', 'world') self.hass.block_till_done() self.assertEqual(1, len(self.calls)) automation.turn_off(self.hass) self.hass.block_till_done() self.hass.states.set('test.entity', 'planet') self.hass.block_till_done() self.assertEqual(1, len(self.calls))
def test_if_fires_on_two_change(self): """Test for firing on two changes.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'template', 'value_template': '{{ true }}', }, 'action': { 'service': 'test.automation' } } }) # Trigger once self.hass.states.set('test.entity', 'world') self.hass.block_till_done() self.assertEqual(1, len(self.calls)) # Trigger again self.hass.states.set('test.entity', 'world') self.hass.block_till_done() self.assertEqual(1, len(self.calls))
def test_see_service(self, mock_see): """Test the see service with a unicode dev_id and NO MAC.""" self.assertTrue( setup_component(self.hass, device_tracker.DOMAIN, TEST_PLATFORM)) params = { 'dev_id': 'some_device', 'host_name': 'example.com', 'location_name': 'Work', 'gps': [.3, .8] } device_tracker.see(self.hass, **params) self.hass.block_till_done() assert mock_see.call_count == 1 self.assertEqual(mock_see.call_count, 1) self.assertEqual(mock_see.call_args, call(**params)) mock_see.reset_mock() params['dev_id'] += chr(233) # e' acute accent from icloud device_tracker.see(self.hass, **params) self.hass.block_till_done() assert mock_see.call_count == 1 self.assertEqual(mock_see.call_count, 1) self.assertEqual(mock_see.call_args, call(**params))
def test_if_fires_on_event_with_data(self): """Test the firing of events with data.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'event', 'event_type': 'test_event', 'event_data': { 'some_attr': 'some_value' } }, 'action': { 'service': 'test.automation', } } }) self.hass.bus.fire('test_event', { 'some_attr': 'some_value', 'another': 'value' }) self.hass.block_till_done() self.assertEqual(1, len(self.calls))
def test_proximity(self): """Test the proximity.""" config = { 'proximity': { 'home': { 'ignored_zones': ['work'], 'devices': ['device_tracker.test1', 'device_tracker.test2'], 'tolerance': '1' } } } self.assertTrue(setup_component(self.hass, DOMAIN, config)) state = self.hass.states.get('proximity.home') assert state.state == 'not set' assert state.attributes.get('nearest') == 'not set' assert state.attributes.get('dir_of_travel') == 'not set' self.hass.states.set('proximity.home', '0') self.hass.block_till_done() state = self.hass.states.get('proximity.home') assert state.state == '0'
def test_template_state_boolean_off(self): """Test the setting of the state with off.""" assert bootstrap.setup_component( self.hass, 'switch', { 'switch': { 'platform': 'template', 'switches': { 'test_template_switch': { 'value_template': "{{ 1 == 2 }}", 'turn_on': { 'service': 'switch.turn_on', 'entity_id': 'switch.test_state' }, 'turn_off': { 'service': 'switch.turn_off', 'entity_id': 'switch.test_state' }, } } } }) state = self.hass.states.get('switch.test_template_switch') assert state.state == STATE_OFF
def test_notify_file(self, mock_utcnow, mock_stat): """Test the notify file output.""" mock_utcnow.return_value = dt_util.as_utc(dt_util.now()) mock_stat.return_value.st_size = 0 m_open = mock_open() with patch('homeassistant.components.notify.file.open', m_open, create=True): filename = 'mock_file' message = 'one, two, testing, testing' self.assertTrue( setup_component( self.hass, notify.DOMAIN, { 'notify': { 'name': 'test', 'platform': 'file', 'filename': filename, 'timestamp': False, } })) title = '{} notifications (Log started: {})\n{}\n'.format( ATTR_TITLE_DEFAULT, dt_util.utcnow().isoformat(), '-' * 80) self.hass.services.call('notify', 'test', {'message': message}, blocking=True) full_filename = os.path.join(self.hass.config.path(), filename) self.assertEqual(m_open.call_count, 1) self.assertEqual(m_open.call_args, call(full_filename, 'a')) self.assertEqual(m_open.return_value.write.call_count, 2) self.assertEqual(m_open.return_value.write.call_args_list, [call(title), call(message + '\n')])
def test_if_action_one_weekday(self): """Test for if action with one weekday.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'event', 'event_type': 'test_event' }, 'condition': { 'condition': 'time', 'weekday': 'mon', }, 'action': { 'service': 'test.automation' } } }) days_past_monday = dt_util.now().weekday() monday = dt_util.now() - timedelta(days=days_past_monday) tuesday = monday + timedelta(days=1) with patch('homeassistant.helpers.condition.dt_util.now', return_value=monday): self.hass.bus.fire('test_event') self.hass.block_till_done() self.assertEqual(1, len(self.calls)) with patch('homeassistant.helpers.condition.dt_util.now', return_value=tuesday): self.hass.bus.fire('test_event') self.hass.block_till_done() self.assertEqual(1, len(self.calls))
def test_setup_platform_timeout_loginpage(self, mock_error, aioclient_mock): """Setup a platform with timeout on loginpage.""" aioclient_mock.get( "http://{}/common_page/login.html".format(self.host), exc=asyncio.TimeoutError() ) aioclient_mock.post( "http://{}/xml/getter.xml".format(self.host), content=b'successful', ) with assert_setup_component(1): assert setup_component( self.hass, DOMAIN, {DOMAIN: { CONF_PLATFORM: 'upc_connect', CONF_HOST: self.host, CONF_PASSWORD: '******' }}) assert len(aioclient_mock.mock_calls) == 1 assert 'Error setting up platform' in \ str(mock_error.call_args_list[-1])
def test_sensor_lower(self): """Test if source is below threshold.""" config = { 'binary_sensor': { 'platform': 'threshold', 'threshold': '15', 'name': 'Test_threshold', 'type': 'lower', 'entity_id': 'sensor.test_monitored', } } assert setup_component(self.hass, 'binary_sensor', config) self.hass.states.set('sensor.test_monitored', 16) self.hass.block_till_done() state = self.hass.states.get('binary_sensor.test_threshold') self.assertEqual('lower', state.attributes.get('type')) assert state.state == 'off' self.hass.states.set('sensor.test_monitored', 14) self.hass.block_till_done() state = self.hass.states.get('binary_sensor.test_threshold') assert state.state == 'on' self.hass.states.set('sensor.test_monitored', 15) self.hass.block_till_done() state = self.hass.states.get('binary_sensor.test_threshold') assert state.state == 'off'
def test_reload_config_handles_load_fails(self): """Test the reload config service.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'alias': 'hello', 'trigger': { 'platform': 'event', 'event_type': 'test_event', }, 'action': { 'service': 'test.automation', 'data_template': { 'event': '{{ trigger.event.event_type }}' } } } }) assert self.hass.states.get('automation.hello') is not None self.hass.bus.fire('test_event') self.hass.block_till_done() assert len(self.calls) == 1 assert self.calls[0].data.get('event') == 'test_event' with patch('homeassistant.config.load_yaml_config_file', side_effect=HomeAssistantError('bla')): automation.reload(self.hass) self.hass.block_till_done() assert self.hass.states.get('automation.hello') is not None self.hass.bus.fire('test_event') self.hass.block_till_done() assert len(self.calls) == 2
def test_device_tracker_test1_in_zone(self): """Test for tracker in zone.""" config = { 'proximity': { 'home': { 'ignored_zones': ['work'], 'devices': ['device_tracker.test1'], 'tolerance': '1' } } } self.assertTrue(setup_component(self.hass, DOMAIN, config)) self.hass.states.set('device_tracker.test1', 'home', { 'friendly_name': 'test1', 'latitude': 2.1, 'longitude': 1.1 }) self.hass.block_till_done() state = self.hass.states.get('proximity.home') assert state.state == '0' assert state.attributes.get('nearest') == 'test1' assert state.attributes.get('dir_of_travel') == 'arrived'
def test_not_fires_on_attr_change_with_attr_not_below_multiple_attr(self): """"Test if not fired changed attributes.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'numeric_state', 'entity_id': 'test.entity', 'value_template': '{{ state.attributes.test_attribute }}', 'below': 10, }, 'action': { 'service': 'test.automation' } } }) # 11 is not below 10 self.hass.states.set('test.entity', 'entity', { 'test_attribute': 11, 'not_test_attribute': 9 }) self.hass.block_till_done() self.assertEqual(0, len(self.calls))
def test_if_not_fires_on_entity_change_above_to_above(self): """"Test the firing with changed entity.""" # set initial state self.hass.states.set('test.entity', 11) self.hass.block_till_done() assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'numeric_state', 'entity_id': 'test.entity', 'above': 10, }, 'action': { 'service': 'test.automation' } } }) # 11 is above 10 so this should fire again self.hass.states.set('test.entity', 12) self.hass.block_till_done() self.assertEqual(0, len(self.calls))
def test_two_triggers(self): """Test triggers.""" assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': [{ 'platform': 'event', 'event_type': 'test_event', }, { 'platform': 'state', 'entity_id': 'test.entity', }], 'action': { 'service': 'test.automation', } } }) self.hass.bus.fire('test_event') self.hass.block_till_done() self.assertEqual(1, len(self.calls)) self.hass.states.set('test.entity', 'hello') self.hass.block_till_done() self.assertEqual(2, len(self.calls))
def test_reading_yaml_config(self): """Test the rendering of the YAML configuration.""" dev_id = 'test' device = device_tracker.Device(self.hass, timedelta(seconds=180), True, dev_id, 'AB:CD:EF:GH:IJ', 'Test name', picture='http://test.picture', hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) with assert_setup_component(1, device_tracker.DOMAIN): assert setup_component(self.hass, device_tracker.DOMAIN, TEST_PLATFORM) config = device_tracker.load_config(self.yaml_devices, self.hass, device.consider_home)[0] self.assertEqual(device.dev_id, config.dev_id) self.assertEqual(device.track, config.track) self.assertEqual(device.mac, config.mac) self.assertEqual(device.config_picture, config.config_picture) self.assertEqual(device.away_hide, config.away_hide) self.assertEqual(device.consider_home, config.consider_home) self.assertEqual(device.vendor, config.vendor)
def test_if_fires_on_entity_change_over_to_below_above_range(self): """"Test the firing with changed entity.""" self.hass.states.set('test.entity', 11) self.hass.block_till_done() assert setup_component( self.hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'numeric_state', 'entity_id': 'test.entity', 'below': 10, 'above': 5, }, 'action': { 'service': 'test.automation' } } }) # 4 is below 5 so it should not fire self.hass.states.set('test.entity', 4) self.hass.block_till_done() self.assertEqual(0, len(self.calls))
def test_group_all_devices(self): """Test grouping of devices.""" dev_id = 'test_entity' entity_id = device_tracker.ENTITY_ID_FORMAT.format(dev_id) device = device_tracker.Device(self.hass, timedelta(seconds=180), True, dev_id, None, hide_if_away=True) device_tracker.update_config(self.yaml_devices, dev_id, device) scanner = get_component('device_tracker.test').SCANNER scanner.reset() with assert_setup_component(1, device_tracker.DOMAIN): assert setup_component(self.hass, device_tracker.DOMAIN, TEST_PLATFORM) state = self.hass.states.get(device_tracker.ENTITY_ID_ALL_DEVICES) self.assertIsNotNone(state) self.assertEqual(STATE_NOT_HOME, state.state) self.assertSequenceEqual((entity_id, ), state.attributes.get(ATTR_ENTITY_ID))
def test_not_enough_sensor_value(self): """Test that there is nothing done if not enough values available.""" config = { 'sensor': { 'platform': 'min_max', 'name': 'test', 'type': 'max', 'entity_ids': [ 'sensor.test_1', 'sensor.test_2', 'sensor.test_3', ] } } assert setup_component(self.hass, 'sensor', config) entity_ids = config['sensor']['entity_ids'] self.hass.states.set(entity_ids[0], self.values[0]) self.hass.block_till_done() state = self.hass.states.get('sensor.test_max') self.assertEqual(STATE_UNKNOWN, state.state) self.hass.states.set(entity_ids[1], self.values[1]) self.hass.block_till_done() state = self.hass.states.get('sensor.test_max') self.assertEqual(STATE_UNKNOWN, state.state) self.hass.states.set(entity_ids[2], self.values[2]) self.hass.block_till_done() state = self.hass.states.get('sensor.test_max') self.assertNotEqual(STATE_UNKNOWN, state.state)