async def test_if_fires_on_entity_change_with_for_attribute_change(hass, calls): """Test for firing on entity change with for and attribute change.""" assert await async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'numeric_state', 'entity_id': 'test.entity', 'above': 8, 'below': 12, 'for': { 'seconds': 5 }, }, 'action': { 'service': 'test.automation' } } }) utcnow = dt_util.utcnow() with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow: mock_utcnow.return_value = utcnow hass.states.async_set('test.entity', 9) await hass.async_block_till_done() mock_utcnow.return_value += timedelta(seconds=4) async_fire_time_changed(hass, mock_utcnow.return_value) hass.states.async_set('test.entity', 9, attributes={"mock_attr": "attr_change"}) await hass.async_block_till_done() assert 0 == len(calls) mock_utcnow.return_value += timedelta(seconds=4) async_fire_time_changed(hass, mock_utcnow.return_value) await hass.async_block_till_done() assert 1 == len(calls)
async def test_trigger_with_specific_trigger_time(hass): """Test disarm after trigger.""" assert await async_setup_component( hass, alarm_control_panel.DOMAIN, {'alarm_control_panel': { 'platform': 'manual', 'name': 'test', 'disarmed': { 'trigger_time': 5 }, 'pending_time': 0, 'disarm_after_trigger': True }}) entity_id = 'alarm_control_panel.test' assert STATE_ALARM_DISARMED == \ hass.states.get(entity_id).state common.async_alarm_trigger(hass, entity_id=entity_id) await hass.async_block_till_done() assert STATE_ALARM_TRIGGERED == \ hass.states.get(entity_id).state future = dt_util.utcnow() + timedelta(seconds=5) with patch(('homeassistant.components.manual.alarm_control_panel.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() assert STATE_ALARM_DISARMED == \ hass.states.get(entity_id).state
async def test_arm_home_with_pending(hass): """Test arm home method.""" assert await async_setup_component( 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' assert STATE_ALARM_DISARMED == \ hass.states.get(entity_id).state common.async_alarm_arm_home(hass, CODE, entity_id) await hass.async_block_till_done() assert STATE_ALARM_PENDING == \ hass.states.get(entity_id).state state = hass.states.get(entity_id) assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_HOME future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.manual.alarm_control_panel.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ALARM_ARMED_HOME
async def test_if_not_fires_on_entity_change_with_for(hass, calls): """Test for not firing on entity change with for.""" assert await async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'state', 'entity_id': 'test.entity', 'to': 'world', 'for': { 'seconds': 5 }, }, 'action': { 'service': 'test.automation' } } }) hass.states.async_set('test.entity', 'world') await hass.async_block_till_done() hass.states.async_set('test.entity', 'not_world') await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10)) await hass.async_block_till_done() assert 0 == len(calls)
async def test_if_fires_on_entity_change_with_for_multiple_force_update(hass, calls): """Test for firing on entity change with for and force update.""" assert await async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'state', 'entity_id': 'test.force_entity', 'to': 'world', 'for': { 'seconds': 5 }, }, 'action': { 'service': 'test.automation' } } }) utcnow = dt_util.utcnow() with patch('homeassistant.core.dt_util.utcnow') as mock_utcnow: mock_utcnow.return_value = utcnow hass.states.async_set('test.force_entity', 'world', None, True) await hass.async_block_till_done() for _ in range(0, 4): mock_utcnow.return_value += timedelta(seconds=1) async_fire_time_changed(hass, mock_utcnow.return_value) hass.states.async_set('test.force_entity', 'world', None, True) await hass.async_block_till_done() assert 0 == len(calls) mock_utcnow.return_value += timedelta(seconds=4) async_fire_time_changed(hass, mock_utcnow.return_value) await hass.async_block_till_done() assert 1 == len(calls)
async def test_trigger_no_pending(hass): """Test triggering when no pending submitted method.""" assert await async_setup_component( hass, alarm_control_panel.DOMAIN, {'alarm_control_panel': { 'platform': 'manual', 'name': 'test', 'trigger_time': 1, 'disarm_after_trigger': False }}) entity_id = 'alarm_control_panel.test' assert STATE_ALARM_DISARMED == \ hass.states.get(entity_id).state common.async_alarm_trigger(hass, entity_id=entity_id) await hass.async_block_till_done() assert STATE_ALARM_PENDING == \ hass.states.get(entity_id).state future = dt_util.utcnow() + timedelta(seconds=60) with patch(('homeassistant.components.manual.alarm_control_panel.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() assert STATE_ALARM_TRIGGERED == \ hass.states.get(entity_id).state
async def test_armed_night_with_specific_pending(hass): """Test arm home method.""" assert await async_setup_component( hass, alarm_control_panel.DOMAIN, {'alarm_control_panel': { 'platform': 'manual', 'name': 'test', 'pending_time': 10, 'armed_night': { 'pending_time': 2 } }}) entity_id = 'alarm_control_panel.test' common.async_alarm_arm_night(hass) await hass.async_block_till_done() assert STATE_ALARM_PENDING == \ hass.states.get(entity_id).state future = dt_util.utcnow() + timedelta(seconds=2) with patch(('homeassistant.components.manual.alarm_control_panel.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() assert STATE_ALARM_ARMED_NIGHT == \ hass.states.get(entity_id).state
async def test_if_fires_when_hour_matches(hass, calls): """Test for firing if hour is matching.""" assert await async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'time_pattern', 'hours': 0, 'minutes': '*', 'seconds': '*', }, 'action': { 'service': 'test.automation' } } }) async_fire_time_changed(hass, dt_util.utcnow().replace(hour=0)) await hass.async_block_till_done() assert 1 == len(calls) await common.async_turn_off(hass) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow().replace(hour=0)) await hass.async_block_till_done() assert 1 == len(calls)
async def test_stop_covers(hass, setup_comp): """Test stop cover function.""" await hass.services.async_call( DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: COVER_GROUP}, blocking=True) future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() await hass.services.async_call( DOMAIN, SERVICE_STOP_COVER, {ATTR_ENTITY_ID: COVER_GROUP}, blocking=True) future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(COVER_GROUP) assert state.state == STATE_OPEN assert state.attributes.get(ATTR_CURRENT_POSITION) == 100 assert hass.states.get(DEMO_COVER).state == STATE_OPEN assert hass.states.get(DEMO_COVER_POS) \ .attributes.get(ATTR_CURRENT_POSITION) == 20 assert hass.states.get(DEMO_COVER_TILT) \ .attributes.get(ATTR_CURRENT_POSITION) == 80
async def test_reset_switch(hass, hk_driver, entity_id, attrs, events): """Test if switch accessory is reset correctly.""" domain = split_entity_id(entity_id)[0] hass.states.async_set(entity_id, None, attrs) await hass.async_block_till_done() acc = Switch(hass, hk_driver, 'Switch', entity_id, 2, None) await hass.async_add_job(acc.run) await hass.async_block_till_done() assert acc.activate_only is True assert acc.char_on.value is False call_turn_on = async_mock_service(hass, domain, 'turn_on') call_turn_off = async_mock_service(hass, domain, 'turn_off') await hass.async_add_job(acc.char_on.client_update_value, True) await hass.async_block_till_done() assert acc.char_on.value is True assert call_turn_on assert call_turn_on[0].data[ATTR_ENTITY_ID] == entity_id assert len(events) == 1 assert events[-1].data[ATTR_VALUE] is None future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1 assert not call_turn_off await hass.async_add_job(acc.char_on.client_update_value, False) await hass.async_block_till_done() assert acc.char_on.value is False assert len(events) == 1
async def test_update_stale(hass): """Test stalled update.""" scanner = get_component(hass, 'device_tracker.test').SCANNER scanner.reset() scanner.come_home('DEV1') register_time = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) scan_time = datetime(2015, 9, 15, 23, 1, tzinfo=dt_util.UTC) with patch('homeassistant.components.device_tracker.dt_util.utcnow', return_value=register_time): with assert_setup_component(1, device_tracker.DOMAIN): assert await async_setup_component(hass, device_tracker.DOMAIN, { device_tracker.DOMAIN: { CONF_PLATFORM: 'test', device_tracker.CONF_CONSIDER_HOME: 59, }}) await hass.async_block_till_done() assert STATE_HOME == \ hass.states.get('device_tracker.dev1').state scanner.leave_home('DEV1') with patch('homeassistant.components.device_tracker.dt_util.utcnow', return_value=scan_time): async_fire_time_changed(hass, scan_time) await hass.async_block_till_done() assert STATE_NOT_HOME == \ hass.states.get('device_tracker.dev1').state
async def test_sunset_trigger_with_offset(hass, calls): """Test the sunset trigger with offset.""" now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) trigger_time = datetime(2015, 9, 16, 2, 30, tzinfo=dt_util.UTC) with patch('homeassistant.util.dt.utcnow', return_value=now): await async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'sun', 'event': SUN_EVENT_SUNSET, 'offset': '0:30:00' }, 'action': { 'service': 'test.automation', 'data_template': { 'some': '{{ trigger.%s }}' % '}} - {{ trigger.'.join(( 'platform', 'event', 'offset')) }, } } }) async_fire_time_changed(hass, trigger_time) await hass.async_block_till_done() assert 1 == len(calls) assert 'sun - sunset - 0:30:00' == calls[0].data['some']
async def test_sunset_trigger(hass, calls): """Test the sunset trigger.""" now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC) trigger_time = datetime(2015, 9, 16, 2, tzinfo=dt_util.UTC) with patch('homeassistant.util.dt.utcnow', return_value=now): await async_setup_component(hass, automation.DOMAIN, { automation.DOMAIN: { 'trigger': { 'platform': 'sun', 'event': SUN_EVENT_SUNSET, }, 'action': { 'service': 'test.automation', } } }) await common.async_turn_off(hass) await hass.async_block_till_done() async_fire_time_changed(hass, trigger_time) await hass.async_block_till_done() assert 0 == len(calls) with patch('homeassistant.util.dt.utcnow', return_value=now): await common.async_turn_on(hass) await hass.async_block_till_done() async_fire_time_changed(hass, trigger_time) await hass.async_block_till_done() assert 1 == len(calls)
async def test_saving_and_loading(hass): """Test that we're saving and loading correctly.""" loader.set_component( hass, 'test', MockModule('test', async_setup_entry=lambda *args: mock_coro(True))) class TestFlow(config_entries.ConfigFlow): VERSION = 5 CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL @asyncio.coroutine def async_step_user(self, user_input=None): return self.async_create_entry( title='Test Title', data={ 'token': 'abcd' } ) with patch.dict(config_entries.HANDLERS, {'test': TestFlow}): await hass.config_entries.flow.async_init( 'test', context={'source': config_entries.SOURCE_USER}) class Test2Flow(config_entries.ConfigFlow): VERSION = 3 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_PUSH @asyncio.coroutine def async_step_user(self, user_input=None): return self.async_create_entry( title='Test 2 Title', data={ 'username': '******' } ) with patch('homeassistant.config_entries.HANDLERS.get', return_value=Test2Flow): await hass.config_entries.flow.async_init( 'test', context={'source': config_entries.SOURCE_USER}) # To trigger the call_later async_fire_time_changed(hass, dt.utcnow() + timedelta(seconds=1)) # To execute the save await hass.async_block_till_done() # Now load written data in new config manager manager = config_entries.ConfigEntries(hass, {}) await manager.async_initialize() # Ensure same order for orig, loaded in zip(hass.config_entries.async_entries(), manager.async_entries()): assert orig.version == loaded.version assert orig.domain == loaded.domain assert orig.title == loaded.title assert orig.data == loaded.data assert orig.source == loaded.source assert orig.connection_class == loaded.connection_class
def test_template_delay_off(hass): """Test binary sensor template delay off.""" config = { 'binary_sensor': { 'platform': 'template', 'sensors': { 'test': { 'friendly_name': 'virtual thingy', 'value_template': "{{ states.sensor.test_state.state == 'on' }}", 'device_class': 'motion', 'delay_off': 5 }, }, }, } hass.states.async_set('sensor.test_state', 'on') yield from setup.async_setup_component(hass, 'binary_sensor', config) yield from hass.async_start() hass.states.async_set('sensor.test_state', 'off') yield from hass.async_block_till_done() state = hass.states.get('binary_sensor.test') assert state.state == 'on' future = dt_util.utcnow() + timedelta(seconds=5) async_fire_time_changed(hass, future) yield from hass.async_block_till_done() state = hass.states.get('binary_sensor.test') assert state.state == 'off' # check with time changes hass.states.async_set('sensor.test_state', 'on') yield from hass.async_block_till_done() state = hass.states.get('binary_sensor.test') assert state.state == 'on' hass.states.async_set('sensor.test_state', 'off') yield from hass.async_block_till_done() state = hass.states.get('binary_sensor.test') assert state.state == 'on' hass.states.async_set('sensor.test_state', 'on') yield from hass.async_block_till_done() state = hass.states.get('binary_sensor.test') assert state.state == 'on' future = dt_util.utcnow() + timedelta(seconds=5) async_fire_time_changed(hass, future) yield from hass.async_block_till_done() state = hass.states.get('binary_sensor.test') assert state.state == 'on'
async def poll_and_get_state(self): """Trigger a time based poll and return the current entity state.""" next_update = dt_util.utcnow() + timedelta(seconds=60) async_fire_time_changed(self.hass, next_update) await self.hass.async_block_till_done() state = self.hass.states.get(self.entity_id) assert state is not None return state
async def test_trigger_with_pending_and_specific_delay(hass): """Test trigger method and switch from pending to triggered.""" assert await async_setup_component( hass, alarm_control_panel.DOMAIN, {'alarm_control_panel': { 'platform': 'manual', 'name': 'test', 'code': CODE, 'delay_time': 10, 'pending_time': 0, 'armed_away': { 'delay_time': 1 }, 'triggered': { 'pending_time': 1 }, 'disarm_after_trigger': False }}) entity_id = 'alarm_control_panel.test' assert STATE_ALARM_DISARMED == \ hass.states.get(entity_id).state common.async_alarm_arm_away(hass, CODE) await hass.async_block_till_done() assert STATE_ALARM_ARMED_AWAY == \ hass.states.get(entity_id).state common.async_alarm_trigger(hass, entity_id=entity_id) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ALARM_PENDING assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.manual.alarm_control_panel.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ALARM_PENDING assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED future += timedelta(seconds=1) with patch(('homeassistant.components.manual.alarm_control_panel.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ALARM_TRIGGERED
async def test_saving_with_delay(hass, store, hass_storage): """Test saving data after a delay.""" store.async_delay_save(lambda: MOCK_DATA, 1) assert store.key not in hass_storage async_fire_time_changed(hass, dt.utcnow() + timedelta(seconds=1)) await hass.async_block_till_done() assert hass_storage[store.key] == { 'version': MOCK_VERSION, 'key': MOCK_KEY, 'data': MOCK_DATA, }
async def test_action_delay(hass, calls): """Test action delay.""" assert await async_setup_component(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 }}' } }, {'delay': {'minutes': '10'}}, { '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): hass.bus.async_fire('test_event') await hass.async_block_till_done() assert len(calls) == 1 assert calls[0].data['some'] == 'event - test_event' future = dt_util.utcnow() + timedelta(minutes=10) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert len(calls) == 2 assert calls[1].data['some'] == 'event - test_event' state = hass.states.get('automation.hello') assert state is not None assert state.attributes.get('last_triggered') == time state = hass.states.get('group.all_automations') assert state is not None assert state.attributes.get('entity_id') == ('automation.hello',)
def test_auto_heal_disabled(hass, mock_openzwave): """Test network auto-heal disabled.""" assert (yield from async_setup_component(hass, 'zwave', { 'zwave': { 'autoheal': False, }})) network = hass.data[zwave.DATA_NETWORK] assert not network.heal.called time = datetime(2017, 5, 6, 0, 0, 0) async_fire_time_changed(hass, time) yield from hass.async_block_till_done() assert not network.heal.called
async def simulate_time(hass, mock_lj, delta): """Test to simulate time.""" _LOGGER.info( '*** simulate time change by %s: %s', delta, mock_lj.start_time + delta) mock_lj.last_delta = delta with mock.patch('homeassistant.helpers.condition.dt_util.utcnow', return_value=mock_lj.start_time + delta): _LOGGER.info('now=%s', dt_util.utcnow()) async_fire_time_changed(hass, mock_lj.start_time + delta) await hass.async_block_till_done() _LOGGER.info('done with now=%s', dt_util.utcnow())
async def test_available(hass, platforms, main_dtv, mock_now): """Test available status.""" next_update = mock_now + timedelta(minutes=5) with patch('homeassistant.util.dt.utcnow', return_value=next_update): async_fire_time_changed(hass, next_update) await hass.async_block_till_done() # Confirm service is currently set to available. state = hass.states.get(MAIN_ENTITY_ID) assert state.state != STATE_UNAVAILABLE # Make update fail 1st time next_update = next_update + timedelta(minutes=5) with patch.object( main_dtv, 'get_standby', side_effect=requests.RequestException), \ patch('homeassistant.util.dt.utcnow', return_value=next_update): async_fire_time_changed(hass, next_update) await hass.async_block_till_done() state = hass.states.get(MAIN_ENTITY_ID) assert state.state != STATE_UNAVAILABLE # Make update fail 2nd time within 1 minute next_update = next_update + timedelta(seconds=30) with patch.object( main_dtv, 'get_standby', side_effect=requests.RequestException), \ patch('homeassistant.util.dt.utcnow', return_value=next_update): async_fire_time_changed(hass, next_update) await hass.async_block_till_done() state = hass.states.get(MAIN_ENTITY_ID) assert state.state != STATE_UNAVAILABLE # Make update fail 3rd time more then a minute after 1st failure next_update = next_update + timedelta(minutes=1) with patch.object( main_dtv, 'get_standby', side_effect=requests.RequestException), \ patch('homeassistant.util.dt.utcnow', return_value=next_update): async_fire_time_changed(hass, next_update) await hass.async_block_till_done() state = hass.states.get(MAIN_ENTITY_ID) assert state.state == STATE_UNAVAILABLE # Recheck state, update should work again. next_update = next_update + timedelta(minutes=5) with patch('homeassistant.util.dt.utcnow', return_value=next_update): async_fire_time_changed(hass, next_update) await hass.async_block_till_done() state = hass.states.get(MAIN_ENTITY_ID) assert state.state != STATE_UNAVAILABLE
async def test_set_cover_position(hass, setup_comp): """Test moving the cover to a specific position.""" state = hass.states.get(ENTITY_COVER) assert 70 == state.attributes.get('current_position') await hass.services.async_call( DOMAIN, SERVICE_SET_COVER_POSITION, {ATTR_ENTITY_ID: ENTITY_COVER, ATTR_POSITION: 10}, blocking=True) for _ in range(6): future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(ENTITY_COVER) assert 10 == state.attributes.get('current_position')
async def test_open_cover_tilt(hass, setup_comp): """Test opening the cover tilt.""" state = hass.states.get(ENTITY_COVER) assert 50 == state.attributes.get('current_tilt_position') await hass.services.async_call( DOMAIN, SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True) for _ in range(7): future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(ENTITY_COVER) assert 100 == state.attributes.get('current_tilt_position')
async def test_check_attributes(hass, platforms, mock_now): """Test attributes.""" next_update = mock_now + timedelta(minutes=5) with patch('homeassistant.util.dt.utcnow', return_value=next_update): async_fire_time_changed(hass, next_update) await hass.async_block_till_done() # Start playing TV with patch('homeassistant.util.dt.utcnow', return_value=next_update): await async_media_play(hass, CLIENT_ENTITY_ID) await hass.async_block_till_done() state = hass.states.get(CLIENT_ENTITY_ID) assert state.state == STATE_PLAYING assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_ID) == \ RECORDING['programId'] assert state.attributes.get(mp.ATTR_MEDIA_CONTENT_TYPE) == \ mp.MEDIA_TYPE_TVSHOW assert state.attributes.get(mp.ATTR_MEDIA_DURATION) == \ RECORDING['duration'] assert state.attributes.get(mp.ATTR_MEDIA_POSITION) == 2 assert state.attributes.get( mp.ATTR_MEDIA_POSITION_UPDATED_AT) == next_update assert state.attributes.get(mp.ATTR_MEDIA_TITLE) == RECORDING['title'] assert state.attributes.get(mp.ATTR_MEDIA_SERIES_TITLE) == \ RECORDING['episodeTitle'] assert state.attributes.get(mp.ATTR_MEDIA_CHANNEL) == \ "{} ({})".format(RECORDING['callsign'], RECORDING['major']) assert state.attributes.get(mp.ATTR_INPUT_SOURCE) == RECORDING['major'] assert state.attributes.get(ATTR_MEDIA_CURRENTLY_RECORDING) == \ RECORDING['isRecording'] assert state.attributes.get(ATTR_MEDIA_RATING) == RECORDING['rating'] assert state.attributes.get(ATTR_MEDIA_RECORDED) assert state.attributes.get(ATTR_MEDIA_START_TIME) == \ datetime(2018, 11, 10, 19, 0, tzinfo=dt_util.UTC) # Test to make sure that ATTR_MEDIA_POSITION_UPDATED_AT is not # updated if TV is paused. with patch('homeassistant.util.dt.utcnow', return_value=next_update + timedelta(minutes=5)): await async_media_pause(hass, CLIENT_ENTITY_ID) await hass.async_block_till_done() state = hass.states.get(CLIENT_ENTITY_ID) assert state.state == STATE_PAUSED assert state.attributes.get( mp.ATTR_MEDIA_POSITION_UPDATED_AT) == next_update
async def test_set_position_cover(hass_hue, hue_client): """Test setting postion cover .""" COVER_ID = "cover.living_room_window" # Turn the office light off first await hass_hue.services.async_call( cover.DOMAIN, const.SERVICE_CLOSE_COVER, {const.ATTR_ENTITY_ID: COVER_ID}, blocking=True) cover_test = hass_hue.states.get(COVER_ID) assert cover_test.state == 'closing' for _ in range(7): future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass_hue, future) await hass_hue.async_block_till_done() cover_test = hass_hue.states.get(COVER_ID) assert cover_test.state == 'closed' level = 20 brightness = round(level/100*255) # Go through the API to open cover_result = await perform_put_light_state( hass_hue, hue_client, COVER_ID, False, brightness) assert cover_result.status == 200 assert 'application/json' in cover_result.headers['content-type'] cover_result_json = await cover_result.json() assert len(cover_result_json) == 2 assert True, cover_result_json[0]['success'][ '/lights/cover.living_room_window/state/on'] assert cover_result_json[1]['success'][ '/lights/cover.living_room_window/state/bri'] == level for _ in range(100): future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass_hue, future) await hass_hue.async_block_till_done() # Check to make sure the state changed cover_test_2 = hass_hue.states.get(COVER_ID) assert cover_test_2.state == 'open' assert cover_test_2.attributes.get('current_position') == level
def test_same_version_not_show_entity(hass, mock_get_uuid, mock_get_newest_version): """Test if new entity is created if new version is available.""" mock_get_uuid.return_value = MOCK_HUUID mock_get_newest_version.return_value = mock_coro((MOCK_VERSION, '')) res = yield from async_setup_component( hass, updater.DOMAIN, {updater.DOMAIN: {}}) assert res, 'Updater failed to setup' with patch('homeassistant.components.updater.CURRENT_VERSION', MOCK_VERSION): async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=1)) yield from hass.async_block_till_done() assert hass.states.get(updater.ENTITY_ID) is None
async def test_set_tilt_positions(hass, setup_comp): """Test set tilt position function.""" await hass.services.async_call( DOMAIN, SERVICE_SET_COVER_TILT_POSITION, {ATTR_ENTITY_ID: COVER_GROUP, ATTR_TILT_POSITION: 80}, blocking=True) for _ in range(3): future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(COVER_GROUP) assert state.state == STATE_OPEN assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 80 assert hass.states.get(DEMO_COVER_TILT) \ .attributes.get(ATTR_CURRENT_TILT_POSITION) == 80
def test_wait_till_timer_expires(hass): """Test for a timer to end.""" hass.state = CoreState.starting yield from async_setup_component(hass, DOMAIN, { DOMAIN: { 'test1': { CONF_DURATION: 10, } }}) state = hass.states.get('timer.test1') assert state assert state.state == STATUS_IDLE results = [] def fake_event_listener(event): """Fake event listener for trigger.""" results.append(event) hass.bus.async_listen(EVENT_TIMER_STARTED, fake_event_listener) hass.bus.async_listen(EVENT_TIMER_PAUSED, fake_event_listener) hass.bus.async_listen(EVENT_TIMER_FINISHED, fake_event_listener) hass.bus.async_listen(EVENT_TIMER_CANCELLED, fake_event_listener) yield from hass.services.async_call(DOMAIN, SERVICE_START, {CONF_ENTITY_ID: 'timer.test1'}) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_ACTIVE assert results[-1].event_type == EVENT_TIMER_STARTED assert len(results) == 1 async_fire_time_changed(hass, utcnow() + timedelta(seconds=10)) yield from hass.async_block_till_done() state = hass.states.get('timer.test1') assert state assert state.state == STATUS_IDLE assert results[-1].event_type == EVENT_TIMER_FINISHED assert len(results) == 2
async def test_stop_cover(hass, setup_comp): """Test stopping the cover.""" state = hass.states.get(ENTITY_COVER) assert 70 == state.attributes.get('current_position') await hass.services.async_call( DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True) future = dt_util.utcnow() + timedelta(seconds=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() await hass.services.async_call( DOMAIN, SERVICE_STOP_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True) async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(ENTITY_COVER) assert 80 == state.attributes.get('current_position')
async def test_arm_away_after_disabled_disarmed(hass): """Test pending state with and without zero trigger time.""" assert await async_setup_component( hass, alarm_control_panel.DOMAIN, { "alarm_control_panel": { "platform": "manual", "name": "test", "code": CODE, "pending_time": 0, "delay_time": 1, "armed_away": {"pending_time": 1}, "disarmed": {"trigger_time": 0}, "disarm_after_trigger": False, } }, ) entity_id = "alarm_control_panel.test" assert STATE_ALARM_DISARMED == hass.states.get(entity_id).state await common.async_alarm_arm_away(hass, CODE) state = hass.states.get(entity_id) assert STATE_ALARM_PENDING == state.state assert STATE_ALARM_DISARMED == state.attributes["pre_pending_state"] assert STATE_ALARM_ARMED_AWAY == state.attributes["post_pending_state"] await common.async_alarm_trigger(hass, entity_id=entity_id) state = hass.states.get(entity_id) assert STATE_ALARM_PENDING == state.state assert STATE_ALARM_DISARMED == state.attributes["pre_pending_state"] assert STATE_ALARM_ARMED_AWAY == state.attributes["post_pending_state"] future = dt_util.utcnow() + timedelta(seconds=1) with patch( ("homeassistant.components.manual.alarm_control_panel.dt_util.utcnow"), return_value=future, ): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(entity_id) assert STATE_ALARM_ARMED_AWAY == state.state await common.async_alarm_trigger(hass, entity_id=entity_id) state = hass.states.get(entity_id) assert STATE_ALARM_PENDING == state.state assert STATE_ALARM_ARMED_AWAY == state.attributes["pre_pending_state"] assert STATE_ALARM_TRIGGERED == state.attributes["post_pending_state"] future += timedelta(seconds=1) with patch( ("homeassistant.components.manual.alarm_control_panel.dt_util.utcnow"), return_value=future, ): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get(entity_id) assert STATE_ALARM_TRIGGERED == state.state
async def test_if_fires_on_state_change(opp, calls): """Test for turn_on and turn_off triggers firing.""" opp.states.async_set( "humidifier.entity", STATE_ON, { const.ATTR_HUMIDITY: 23, ATTR_MODE: "home", const.ATTR_AVAILABLE_MODES: ["home", "away"], ATTR_SUPPORTED_FEATURES: 1, }, ) assert await async_setup_component( opp, automation.DOMAIN, { automation.DOMAIN: [ { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": "", "entity_id": "humidifier.entity", "type": "target_humidity_changed", "below": 20, }, "action": { "service": "test.automation", "data_template": { "some": "target_humidity_changed_below" }, }, }, { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": "", "entity_id": "humidifier.entity", "type": "target_humidity_changed", "above": 30, }, "action": { "service": "test.automation", "data_template": { "some": "target_humidity_changed_above" }, }, }, { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": "", "entity_id": "humidifier.entity", "type": "target_humidity_changed", "above": 30, "for": { "seconds": 5 }, }, "action": { "service": "test.automation", "data_template": { "some": "target_humidity_changed_above_for" }, }, }, { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": "", "entity_id": "humidifier.entity", "type": "turned_on", }, "action": { "service": "test.automation", "data_template": { "some": "turn_on {{ trigger.%s }}" % "}} - {{ trigger.".join(( "platform", "entity_id", "from_state.state", "to_state.state", "for", )) }, }, }, { "trigger": { "platform": "device", "domain": DOMAIN, "device_id": "", "entity_id": "humidifier.entity", "type": "turned_off", }, "action": { "service": "test.automation", "data_template": { "some": "turn_off {{ trigger.%s }}" % "}} - {{ trigger.".join(( "platform", "entity_id", "from_state.state", "to_state.state", "for", )) }, }, }, ] }, ) # Fake that the humidity is changing opp.states.async_set("humidifier.entity", STATE_ON, {const.ATTR_HUMIDITY: 7}) await opp.async_block_till_done() assert len(calls) == 1 assert calls[0].data["some"] == "target_humidity_changed_below" # Fake that the humidity is changing opp.states.async_set("humidifier.entity", STATE_ON, {const.ATTR_HUMIDITY: 37}) await opp.async_block_till_done() assert len(calls) == 2 assert calls[1].data["some"] == "target_humidity_changed_above" # Wait 6 minutes async_fire_time_changed(opp, dt_util.utcnow() + datetime.timedelta(minutes=6)) await opp.async_block_till_done() assert len(calls) == 3 assert calls[2].data["some"] == "target_humidity_changed_above_for" # Fake turn off opp.states.async_set("humidifier.entity", STATE_OFF, {const.ATTR_HUMIDITY: 37}) await opp.async_block_till_done() assert len(calls) == 4 assert (calls[3].data["some"] == "turn_off device - humidifier.entity - on - off - None") # Fake turn on opp.states.async_set("humidifier.entity", STATE_ON, {const.ATTR_HUMIDITY: 37}) await opp.async_block_till_done() assert len(calls) == 5 assert (calls[4].data["some"] == "turn_on device - humidifier.entity - off - on - None")
async def test_not_available_at_startup(hass: HomeAssistant): """Test when configured devices are not available.""" config = { tplink.DOMAIN: { CONF_DISCOVERY: False, CONF_SWITCH: [{ CONF_HOST: "321.321.321.321" }], } } with patch( "homeassistant.components.tplink.common.Discover.discover" ), patch( "homeassistant.components.tplink.get_static_devices" ) as get_static_devices, patch( "homeassistant.components.tplink.common.SmartDevice._query_helper" ), patch( "homeassistant.components.tplink.light.async_setup_entry", return_value=mock_coro(True), ), patch("homeassistant.components.tplink.common.SmartPlug.is_dimmable", False): switch = SmartPlug("321.321.321.321") switch.get_sysinfo = MagicMock(side_effect=SmartDeviceException()) get_static_devices.return_value = SmartDevices([], [switch]) # run setup while device unreachable await async_setup_component(hass, tplink.DOMAIN, config) await hass.async_block_till_done() entries = hass.config_entries.async_entries(tplink.DOMAIN) assert len(entries) == 1 assert entries[0].state is config_entries.ConfigEntryState.LOADED entities = hass.states.async_entity_ids(SWITCH_DOMAIN) assert len(entities) == 0 # retrying with still unreachable device async_fire_time_changed(hass, dt.utcnow() + UNAVAILABLE_RETRY_DELAY) await hass.async_block_till_done() entries = hass.config_entries.async_entries(tplink.DOMAIN) assert len(entries) == 1 assert entries[0].state is config_entries.ConfigEntryState.LOADED entities = hass.states.async_entity_ids(SWITCH_DOMAIN) assert len(entities) == 0 # retrying with now reachable device switch.get_sysinfo = MagicMock( return_value=SMARTPLUG_HS100_DATA["sysinfo"]) async_fire_time_changed(hass, dt.utcnow() + UNAVAILABLE_RETRY_DELAY) await hass.async_block_till_done() entries = hass.config_entries.async_entries(tplink.DOMAIN) assert len(entries) == 1 assert entries[0].state is config_entries.ConfigEntryState.LOADED entities = hass.states.async_entity_ids(SWITCH_DOMAIN) assert len(entities) == 1
async def test_location_change_with_overlapping_udn_st_combinations( hass, aioclient_mock): """Test handling when a UDN and ST broadcast multiple locations.""" mock_get_ssdp = { "test_integration": [{ "manufacturer": "test_manufacturer", "modelName": "test_model" }] } hue_response = """ <root xmlns="urn:schemas-upnp-org:device-1-0"> <device> <manufacturer>test_manufacturer</manufacturer> <modelName>test_model</modelName> </device> </root> """ aioclient_mock.get( "http://192.168.72.1:49154/wps_device.xml", text=hue_response.format(ip_address="192.168.72.1"), ) aioclient_mock.get( "http://192.168.72.1:49152/wps_device.xml", text=hue_response.format(ip_address="192.168.72.1"), ) ssdp_response_without_location = { "ST": "upnp:rootdevice", "_udn": "uuid:a793d3cc-e802-44fb-84f4-5a30f33115b6", "USN": "uuid:a793d3cc-e802-44fb-84f4-5a30f33115b6::upnp:rootdevice", "EXT": "", } port_49154_response = CaseInsensitiveDict( **ssdp_response_without_location, **{"LOCATION": "http://192.168.72.1:49154/wps_device.xml"}, ) port_49152_response = CaseInsensitiveDict( **ssdp_response_without_location, **{"LOCATION": "http://192.168.72.1:49152/wps_device.xml"}, ) mock_ssdp_response = port_49154_response def _generate_fake_ssdp_listener(*args, **kwargs): listener = SSDPListener(*args, **kwargs) async def _async_callback(*_): pass @callback def _callback(*_): hass.async_create_task(listener.async_callback(mock_ssdp_response)) listener.async_start = _async_callback listener.async_search = _callback return listener with patch( "homeassistant.components.ssdp.async_get_ssdp", return_value=mock_get_ssdp, ), patch( "homeassistant.components.ssdp.SSDPListener", new=_generate_fake_ssdp_listener, ), patch.object(hass.config_entries.flow, "async_init") as mock_init: assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}}) await hass.async_block_till_done() hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() assert len(mock_init.mock_calls) == 1 assert mock_init.mock_calls[0][1][0] == "test_integration" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert (mock_init.mock_calls[0][2]["data"][ssdp.ATTR_SSDP_LOCATION] == port_49154_response["location"]) mock_init.reset_mock() mock_ssdp_response = port_49152_response async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=400)) await hass.async_block_till_done() assert mock_init.mock_calls[0][1][0] == "test_integration" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert (mock_init.mock_calls[0][2]["data"][ssdp.ATTR_SSDP_LOCATION] == port_49152_response["location"]) mock_init.reset_mock() mock_ssdp_response = port_49154_response async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=600)) await hass.async_block_till_done() assert mock_init.mock_calls[0][1][0] == "test_integration" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert (mock_init.mock_calls[0][2]["data"][ssdp.ATTR_SSDP_LOCATION] == port_49154_response["location"])
def increment_time(time): mock_utc.return_value += time mock_utc_weather.return_value += time async_fire_time_changed(hass, mock_utc.return_value)
async def test_see_passive_zone_state( hass, mock_device_tracker_conf, enable_custom_integrations ): """Test that the device tracker sets gps for passive trackers.""" now = dt_util.utcnow() register_time = datetime(now.year + 1, 9, 15, 23, tzinfo=dt_util.UTC) scan_time = datetime(now.year + 1, 9, 15, 23, 1, tzinfo=dt_util.UTC) with assert_setup_component(1, zone.DOMAIN): zone_info = { "name": "Home", "latitude": 1, "longitude": 2, "radius": 250, "passive": False, } await async_setup_component(hass, zone.DOMAIN, {"zone": zone_info}) scanner = getattr(hass.components, "test.device_tracker").SCANNER scanner.reset() scanner.come_home("dev1") with patch( "homeassistant.components.device_tracker.legacy.dt_util.utcnow", return_value=register_time, ), assert_setup_component(1, device_tracker.DOMAIN): assert await async_setup_component( hass, device_tracker.DOMAIN, { device_tracker.DOMAIN: { CONF_PLATFORM: "test", device_tracker.CONF_CONSIDER_HOME: 59, } }, ) await hass.async_block_till_done() state = hass.states.get("device_tracker.dev1") attrs = state.attributes assert state.state == STATE_HOME assert state.object_id == "dev1" assert state.name == "dev1" assert attrs.get("friendly_name") == "dev1" assert attrs.get("latitude") == 1 assert attrs.get("longitude") == 2 assert attrs.get("gps_accuracy") == 0 assert attrs.get("source_type") == device_tracker.SOURCE_TYPE_ROUTER scanner.leave_home("dev1") with patch( "homeassistant.components.device_tracker.legacy.dt_util.utcnow", return_value=scan_time, ): async_fire_time_changed(hass, scan_time) await hass.async_block_till_done() state = hass.states.get("device_tracker.dev1") attrs = state.attributes assert state.state == STATE_NOT_HOME assert state.object_id == "dev1" assert state.name == "dev1" assert attrs.get("friendly_name") == "dev1" assert attrs.get("latitude") is None assert attrs.get("longitude") is None assert attrs.get("gps_accuracy") is None assert attrs.get("source_type") == device_tracker.SOURCE_TYPE_ROUTER
async def test_location_change_evicts_prior_location_from_cache( hass, aioclient_mock): """Test that a location change for a UDN will evict the prior location from the cache.""" mock_get_ssdp = { "hue": [{ "manufacturer": "Signify", "modelName": "Philips hue bridge 2015" }] } hue_response = """ <root xmlns="urn:schemas-upnp-org:device-1-0"> <specVersion> <major>1</major> <minor>0</minor> </specVersion> <URLBase>http://{ip_address}:80/</URLBase> <device> <deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType> <friendlyName>Philips hue ({ip_address})</friendlyName> <manufacturer>Signify</manufacturer> <manufacturerURL>http://www.philips-hue.com</manufacturerURL> <modelDescription>Philips hue Personal Wireless Lighting</modelDescription> <modelName>Philips hue bridge 2015</modelName> <modelNumber>BSB002</modelNumber> <modelURL>http://www.philips-hue.com</modelURL> <serialNumber>001788a36abf</serialNumber> <UDN>uuid:2f402f80-da50-11e1-9b23-001788a36abf</UDN> </device> </root> """ aioclient_mock.get( "http://192.168.212.23/description.xml", text=hue_response.format(ip_address="192.168.212.23"), ) aioclient_mock.get( "http://169.254.8.155/description.xml", text=hue_response.format(ip_address="169.254.8.155"), ) ssdp_response_without_location = { "ST": "uuid:2f402f80-da50-11e1-9b23-001788a36abf", "_udn": "uuid:2f402f80-da50-11e1-9b23-001788a36abf", "USN": "uuid:2f402f80-da50-11e1-9b23-001788a36abf", "SERVER": "Hue/1.0 UPnP/1.0 IpBridge/1.44.0", "hue-bridgeid": "001788FFFEA36ABF", "EXT": "", } mock_good_ip_ssdp_response = CaseInsensitiveDict( **ssdp_response_without_location, **{"LOCATION": "http://192.168.212.23/description.xml"}, ) mock_link_local_ip_ssdp_response = CaseInsensitiveDict( **ssdp_response_without_location, **{"LOCATION": "http://169.254.8.155/description.xml"}, ) mock_ssdp_response = mock_good_ip_ssdp_response def _generate_fake_ssdp_listener(*args, **kwargs): listener = SSDPListener(*args, **kwargs) async def _async_callback(*_): pass @callback def _callback(*_): hass.async_create_task(listener.async_callback(mock_ssdp_response)) listener.async_start = _async_callback listener.async_search = _callback return listener with patch( "homeassistant.components.ssdp.async_get_ssdp", return_value=mock_get_ssdp, ), patch( "homeassistant.components.ssdp.SSDPListener", new=_generate_fake_ssdp_listener, ), patch.object(hass.config_entries.flow, "async_init") as mock_init: assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}}) await hass.async_block_till_done() hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() assert len(mock_init.mock_calls) == 1 assert mock_init.mock_calls[0][1][0] == "hue" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert (mock_init.mock_calls[0][2]["data"][ssdp.ATTR_SSDP_LOCATION] == mock_good_ip_ssdp_response["location"]) mock_init.reset_mock() mock_ssdp_response = mock_link_local_ip_ssdp_response async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=400)) await hass.async_block_till_done() assert mock_init.mock_calls[0][1][0] == "hue" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert (mock_init.mock_calls[0][2]["data"][ssdp.ATTR_SSDP_LOCATION] == mock_link_local_ip_ssdp_response["location"]) mock_init.reset_mock() mock_ssdp_response = mock_good_ip_ssdp_response async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=600)) await hass.async_block_till_done() assert mock_init.mock_calls[0][1][0] == "hue" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert (mock_init.mock_calls[0][2]["data"][ssdp.ATTR_SSDP_LOCATION] == mock_good_ip_ssdp_response["location"])
async def test_binary_sensor_get_state(hass, init_integration, entity_id: str, uid: str, name: str, model: str): """Test states of the binary_sensor.""" init_integration registry = er.async_get(hass) registry_device = dr.async_get(hass) device = registry_device.async_get_device({("freedompro", uid)}) assert device is not None assert device.identifiers == {("freedompro", uid)} assert device.manufacturer == "Freedompro" assert device.name == name assert device.model == model state = hass.states.get(entity_id) assert state assert state.attributes.get("friendly_name") == name entry = registry.async_get(entity_id) assert entry assert entry.unique_id == uid assert state.state == STATE_OFF with patch( "homeassistant.components.freedompro.get_states", return_value=[], ): async_fire_time_changed(hass, utcnow() + timedelta(hours=2)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state assert state.attributes.get("friendly_name") == name entry = registry.async_get(entity_id) assert entry assert entry.unique_id == uid assert state.state == STATE_OFF get_states_response = list(DEVICES_STATE) for state_response in get_states_response: if state_response["uid"] == uid: if state_response["type"] == "smokeSensor": state_response["state"]["smokeDetected"] = True if state_response["type"] == "occupancySensor": state_response["state"]["occupancyDetected"] = True if state_response["type"] == "motionSensor": state_response["state"]["motionDetected"] = True if state_response["type"] == "contactSensor": state_response["state"]["contactSensorState"] = True with patch( "homeassistant.components.freedompro.get_states", return_value=get_states_response, ): async_fire_time_changed(hass, utcnow() + timedelta(hours=2)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state assert state.attributes.get("friendly_name") == name entry = registry.async_get(entity_id) assert entry assert entry.unique_id == uid assert state.state == STATE_ON
async def test_expiration_on_discovery_and_discovery_update_of_binary_sensor( hass, mqtt_mock_entry_no_yaml_config, caplog): """Test that binary_sensor with expire_after set behaves correctly on discovery and discovery update.""" await mqtt_mock_entry_no_yaml_config() config = { "name": "Test", "state_topic": "test-topic", "expire_after": 4, "force_update": True, } config_msg = json.dumps(config) # Set time and publish config message to create binary_sensor via discovery with 4 s expiry realnow = dt_util.utcnow() now = datetime(realnow.year + 1, 1, 1, 1, tzinfo=dt_util.UTC) with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): async_fire_time_changed(hass, now) async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", config_msg) await hass.async_block_till_done() # Test that binary_sensor is not available state = hass.states.get("binary_sensor.test") assert state.state == STATE_UNAVAILABLE # Publish state message with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): async_fire_mqtt_message(hass, "test-topic", "ON") await hass.async_block_till_done() # Test that binary_sensor has correct state state = hass.states.get("binary_sensor.test") assert state.state == STATE_ON # Advance +3 seconds now = now + timedelta(seconds=3) with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): async_fire_time_changed(hass, now) await hass.async_block_till_done() # binary_sensor is not yet expired state = hass.states.get("binary_sensor.test") assert state.state == STATE_ON # Resend config message to update discovery with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): async_fire_time_changed(hass, now) async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", config_msg) await hass.async_block_till_done() # Test that binary_sensor has not expired state = hass.states.get("binary_sensor.test") assert state.state == STATE_ON # Add +2 seconds now = now + timedelta(seconds=2) with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): async_fire_time_changed(hass, now) await hass.async_block_till_done() # Test that binary_sensor has expired state = hass.states.get("binary_sensor.test") assert state.state == STATE_UNAVAILABLE # Resend config message to update discovery with patch(("homeassistant.helpers.event.dt_util.utcnow"), return_value=now): async_fire_mqtt_message(hass, "homeassistant/binary_sensor/bla/config", config_msg) await hass.async_block_till_done() # Test that binary_sensor is still expired state = hass.states.get("binary_sensor.test") assert state.state == STATE_UNAVAILABLE
async def test_sensors_sensors( hass: HomeAssistant, mock_fully_kiosk: MagicMock, init_integration: MockConfigEntry, ) -> None: """Test standard Fully Kiosk sensors.""" entity_registry = er.async_get(hass) device_registry = dr.async_get(hass) state = hass.states.get("sensor.amazon_fire_battery") assert state assert state.state == "100" assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.BATTERY assert state.attributes.get(ATTR_FRIENDLY_NAME) == "Amazon Fire Battery" assert state.attributes.get( ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT entry = entity_registry.async_get("sensor.amazon_fire_battery") assert entry assert entry.unique_id == "abcdef-123456-batteryLevel" state = hass.states.get("sensor.amazon_fire_screen_orientation") assert state assert state.state == "90" assert state.attributes.get( ATTR_FRIENDLY_NAME) == "Amazon Fire Screen orientation" entry = entity_registry.async_get("sensor.amazon_fire_screen_orientation") assert entry assert entry.unique_id == "abcdef-123456-screenOrientation" state = hass.states.get("sensor.amazon_fire_foreground_app") assert state assert state.state == "de.ozerov.fully" assert state.attributes.get( ATTR_FRIENDLY_NAME) == "Amazon Fire Foreground app" entry = entity_registry.async_get("sensor.amazon_fire_foreground_app") assert entry assert entry.unique_id == "abcdef-123456-foregroundApp" state = hass.states.get("sensor.amazon_fire_current_page") assert state assert state.state == "https://homeassistant.local" assert state.attributes.get(ATTR_DEVICE_CLASS) is None assert state.attributes.get( ATTR_FRIENDLY_NAME) == "Amazon Fire Current page" entry = entity_registry.async_get("sensor.amazon_fire_current_page") assert entry assert entry.unique_id == "abcdef-123456-currentPage" state = hass.states.get("sensor.amazon_fire_internal_storage_free_space") assert state assert state.state == "11675.5" assert state.attributes.get(ATTR_DEVICE_CLASS) is None assert (state.attributes.get(ATTR_FRIENDLY_NAME) == "Amazon Fire Internal storage free space") assert state.attributes.get( ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT entry = entity_registry.async_get( "sensor.amazon_fire_internal_storage_free_space") assert entry assert entry.unique_id == "abcdef-123456-internalStorageFreeSpace" assert entry.entity_category == EntityCategory.DIAGNOSTIC state = hass.states.get("sensor.amazon_fire_internal_storage_total_space") assert state assert state.state == "12938.5" assert state.attributes.get(ATTR_DEVICE_CLASS) is None assert (state.attributes.get(ATTR_FRIENDLY_NAME) == "Amazon Fire Internal storage total space") assert state.attributes.get( ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT entry = entity_registry.async_get( "sensor.amazon_fire_internal_storage_total_space") assert entry assert entry.unique_id == "abcdef-123456-internalStorageTotalSpace" assert entry.entity_category == EntityCategory.DIAGNOSTIC state = hass.states.get("sensor.amazon_fire_free_memory") assert state assert state.state == "362.4" assert state.attributes.get(ATTR_DEVICE_CLASS) is None assert state.attributes.get( ATTR_FRIENDLY_NAME) == "Amazon Fire Free memory" assert state.attributes.get( ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT entry = entity_registry.async_get("sensor.amazon_fire_free_memory") assert entry assert entry.unique_id == "abcdef-123456-ramFreeMemory" assert entry.entity_category == EntityCategory.DIAGNOSTIC state = hass.states.get("sensor.amazon_fire_total_memory") assert state assert state.state == "1440.1" assert state.attributes.get(ATTR_DEVICE_CLASS) is None assert state.attributes.get( ATTR_FRIENDLY_NAME) == "Amazon Fire Total memory" assert state.attributes.get( ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT entry = entity_registry.async_get("sensor.amazon_fire_total_memory") assert entry assert entry.unique_id == "abcdef-123456-ramTotalMemory" assert entry.entity_category == EntityCategory.DIAGNOSTIC assert entry.device_id device_entry = device_registry.async_get(entry.device_id) assert device_entry assert device_entry.configuration_url == "http://192.168.1.234:2323" assert device_entry.entry_type is None assert device_entry.hw_version is None assert device_entry.identifiers == {(DOMAIN, "abcdef-123456")} assert device_entry.manufacturer == "amzn" assert device_entry.model == "KFDOWI" assert device_entry.name == "Amazon Fire" assert device_entry.sw_version == "1.42.5" # Test unknown/missing data mock_fully_kiosk.getDeviceInfo.return_value = {} async_fire_time_changed(hass, dt.utcnow() + UPDATE_INTERVAL) await hass.async_block_till_done() state = hass.states.get("sensor.amazon_fire_internal_storage_free_space") assert state assert state.state == STATE_UNKNOWN # Test failed update mock_fully_kiosk.getDeviceInfo.side_effect = FullyKioskError( "error", "status") async_fire_time_changed(hass, dt.utcnow() + UPDATE_INTERVAL) await hass.async_block_till_done() state = hass.states.get("sensor.amazon_fire_internal_storage_free_space") assert state assert state.state == STATE_UNAVAILABLE
async def time_changed(hass: HomeAssistant, seconds: int) -> None: """Trigger time changed.""" next_update = dt_util.utcnow() + timedelta(seconds) async_fire_time_changed(hass, next_update) await hass.async_block_till_done()
async def test_setup(hass): """Test the general setup of the integration.""" # Set up some mock feed entries for this test. mock_entry_1 = _generate_mock_feed_entry( "1234", "Description 1", 15.5, (38.0, -3.0), event_name="Name 1", event_type_short="DR", event_type="Drought", alert_level="Alert Level 1", country="Country 1", attribution="Attribution 1", from_date=datetime.datetime(2020, 1, 10, 8, 0, tzinfo=datetime.timezone.utc), to_date=datetime.datetime(2020, 1, 20, 8, 0, tzinfo=datetime.timezone.utc), duration_in_week=1, population="Population 1", severity="Severity 1", vulnerability="Vulnerability 1", ) mock_entry_2 = _generate_mock_feed_entry( "2345", "Description 2", 20.5, (38.1, -3.1), event_name="Name 2", event_type_short="TC", event_type="Tropical Cyclone", ) mock_entry_3 = _generate_mock_feed_entry( "3456", "Description 3", 25.5, (38.2, -3.2), event_name="Name 3", event_type_short="TC", event_type="Tropical Cyclone", country="Country 2", ) mock_entry_4 = _generate_mock_feed_entry("4567", "Description 4", 12.5, (38.3, -3.3)) # Patching 'utcnow' to gain more control over the timed update. utcnow = dt_util.utcnow() with patch("homeassistant.util.dt.utcnow", return_value=utcnow), patch( "aio_georss_client.feed.GeoRssFeed.update") as mock_feed_update: mock_feed_update.return_value = "OK", [ mock_entry_1, mock_entry_2, mock_entry_3 ] assert await async_setup_component(hass, gdacs.DOMAIN, CONFIG) # Artificially trigger update and collect events. hass.bus.async_fire(EVENT_HOMEASSISTANT_START) await hass.async_block_till_done() all_states = hass.states.async_all() # 3 geolocation and 1 sensor entities assert len(all_states) == 4 entity_registry = await async_get_registry(hass) assert len(entity_registry.entities) == 4 state = hass.states.get("geo_location.drought_name_1") assert state is not None assert state.name == "Drought: Name 1" assert state.attributes == { ATTR_EXTERNAL_ID: "1234", ATTR_LATITUDE: 38.0, ATTR_LONGITUDE: -3.0, ATTR_FRIENDLY_NAME: "Drought: Name 1", ATTR_DESCRIPTION: "Description 1", ATTR_COUNTRY: "Country 1", ATTR_ATTRIBUTION: "Attribution 1", ATTR_FROM_DATE: datetime.datetime(2020, 1, 10, 8, 0, tzinfo=datetime.timezone.utc), ATTR_TO_DATE: datetime.datetime(2020, 1, 20, 8, 0, tzinfo=datetime.timezone.utc), ATTR_DURATION_IN_WEEK: 1, ATTR_ALERT_LEVEL: "Alert Level 1", ATTR_POPULATION: "Population 1", ATTR_EVENT_TYPE: "Drought", ATTR_SEVERITY: "Severity 1", ATTR_VULNERABILITY: "Vulnerability 1", ATTR_UNIT_OF_MEASUREMENT: "km", ATTR_SOURCE: "gdacs", ATTR_ICON: "mdi:water-off", } assert float(state.state) == 15.5 state = hass.states.get("geo_location.tropical_cyclone_name_2") assert state is not None assert state.name == "Tropical Cyclone: Name 2" assert state.attributes == { ATTR_EXTERNAL_ID: "2345", ATTR_LATITUDE: 38.1, ATTR_LONGITUDE: -3.1, ATTR_FRIENDLY_NAME: "Tropical Cyclone: Name 2", ATTR_DESCRIPTION: "Description 2", ATTR_EVENT_TYPE: "Tropical Cyclone", ATTR_UNIT_OF_MEASUREMENT: "km", ATTR_SOURCE: "gdacs", ATTR_ICON: "mdi:weather-hurricane", } assert float(state.state) == 20.5 state = hass.states.get("geo_location.tropical_cyclone_name_3") assert state is not None assert state.name == "Tropical Cyclone: Name 3" assert state.attributes == { ATTR_EXTERNAL_ID: "3456", ATTR_LATITUDE: 38.2, ATTR_LONGITUDE: -3.2, ATTR_FRIENDLY_NAME: "Tropical Cyclone: Name 3", ATTR_DESCRIPTION: "Description 3", ATTR_EVENT_TYPE: "Tropical Cyclone", ATTR_COUNTRY: "Country 2", ATTR_UNIT_OF_MEASUREMENT: "km", ATTR_SOURCE: "gdacs", ATTR_ICON: "mdi:weather-hurricane", } assert float(state.state) == 25.5 # Simulate an update - two existing, one new entry, one outdated entry mock_feed_update.return_value = "OK", [ mock_entry_1, mock_entry_4, mock_entry_3 ] async_fire_time_changed(hass, utcnow + DEFAULT_SCAN_INTERVAL) await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 4 # Simulate an update - empty data, but successful update, # so no changes to entities. mock_feed_update.return_value = "OK_NO_DATA", None async_fire_time_changed(hass, utcnow + 2 * DEFAULT_SCAN_INTERVAL) await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 4 # Simulate an update - empty data, removes all entities mock_feed_update.return_value = "ERROR", None async_fire_time_changed(hass, utcnow + 3 * DEFAULT_SCAN_INTERVAL) await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 1 assert len(entity_registry.entities) == 1
async def test_action_delay(hass, calls): """Test action delay.""" assert await async_setup_component( 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 }}" }, }, { "delay": { "minutes": "10" } }, { "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): hass.bus.async_fire("test_event") await hass.async_block_till_done() assert len(calls) == 1 assert calls[0].data["some"] == "event - test_event" future = dt_util.utcnow() + timedelta(minutes=10) async_fire_time_changed(hass, future) await hass.async_block_till_done() assert len(calls) == 2 assert calls[1].data["some"] == "event - test_event" state = hass.states.get("automation.hello") assert state is not None assert state.attributes.get("last_triggered") == time state = hass.states.get("group.all_automations") assert state is not None assert state.attributes.get("entity_id") == ("automation.hello", )
async def test_report_state(hass, caplog, legacy_patchable_time): """Test report state works.""" hass.states.async_set("light.ceiling", "off") hass.states.async_set("switch.ac", "on") with patch.object(BASIC_CONFIG, "async_report_state_all", AsyncMock()) as mock_report, patch.object( report_state, "INITIAL_REPORT_DELAY", 0): unsub = report_state.async_enable_report_state(hass, BASIC_CONFIG) async_fire_time_changed(hass, utcnow()) await hass.async_block_till_done() # Test that enabling report state does a report on all entities assert len(mock_report.mock_calls) == 1 assert mock_report.mock_calls[0][1][0] == { "devices": { "states": { "light.ceiling": { "on": False, "online": True }, "switch.ac": { "on": True, "online": True }, } } } with patch.object(BASIC_CONFIG, "async_report_state_all", AsyncMock()) as mock_report: hass.states.async_set("light.kitchen", "on") await hass.async_block_till_done() assert len(mock_report.mock_calls) == 1 assert mock_report.mock_calls[0][1][0] == { "devices": { "states": { "light.kitchen": { "on": True, "online": True } } } } # Test that state changes that change something that Google doesn't care about # do not trigger a state report. with patch.object(BASIC_CONFIG, "async_report_state_all", AsyncMock()) as mock_report: hass.states.async_set("light.kitchen", "on", {"irrelevant": "should_be_ignored"}) await hass.async_block_till_done() assert len(mock_report.mock_calls) == 0 # Test that entities that we can't query don't report a state with patch.object(BASIC_CONFIG, "async_report_state_all", AsyncMock( )) as mock_report, patch( "homeassistant.components.google_assistant.report_state.GoogleEntity.query_serialize", side_effect=error.SmartHomeError("mock-error", "mock-msg"), ): hass.states.async_set("light.kitchen", "off") await hass.async_block_till_done() assert "Not reporting state for light.kitchen: mock-error" assert len(mock_report.mock_calls) == 0 unsub() with patch.object(BASIC_CONFIG, "async_report_state_all", AsyncMock()) as mock_report: hass.states.async_set("light.kitchen", "on") await hass.async_block_till_done() assert len(mock_report.mock_calls) == 0
async def test_bind_failure_skips_adapter(hass, caplog): """Test that an adapter with a bind failure is skipped.""" mock_get_ssdp = { "mock-domain": [{ ssdp.ATTR_UPNP_DEVICE_TYPE: "ABC", }] } create_args = [] search_args = [] @callback def _callback(*args): nonlocal search_args search_args.append(args) pass def _generate_failing_ssdp_listener(*args, **kwargs): create_args.append([args, kwargs]) listener = SSDPListener(*args, **kwargs) async def _async_callback(*_): if kwargs["source_ip"] == IPv6Address("2001:db8::"): raise OSError pass listener.async_start = _async_callback listener.async_search = _callback return listener with patch( "homeassistant.components.ssdp.async_get_ssdp", return_value=mock_get_ssdp, ), patch( "homeassistant.components.ssdp.SSDPListener", new=_generate_failing_ssdp_listener, ), patch( "homeassistant.components.ssdp.network.async_get_adapters", return_value=_ADAPTERS_WITH_MANUAL_CONFIG, ): assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}}) await hass.async_block_till_done() hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) await hass.async_block_till_done() argset = set() for argmap in create_args: argset.add((argmap[1].get("source_ip"), argmap[1].get("target_ip"))) assert argset == { (IPv6Address("2001:db8::"), None), (IPv4Address("192.168.1.5"), None), } assert "Failed to setup listener for" in caplog.text async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() assert set(search_args) == { (), (( "255.255.255.255", 1900, ), ), }
async def base_test( hass, config_device, device_name, entity_domain, array_name_discovery, array_name_old_config, register_words, expected, method_discovery=False, check_config_only=False, config_modbus=None, scan_interval=None, expect_init_to_fail=False, expect_setup_to_fail=False, ): """Run test on device for given config.""" if config_modbus is None: config_modbus = { DOMAIN: { CONF_NAME: DEFAULT_HUB, CONF_TYPE: "tcp", CONF_HOST: "modbusTest", CONF_PORT: 5001, }, } mock_sync = mock.MagicMock() with mock.patch( "homeassistant.components.modbus.modbus.ModbusTcpClient", return_value=mock_sync ), mock.patch( "homeassistant.components.modbus.modbus.ModbusSerialClient", return_value=mock_sync, ), mock.patch( "homeassistant.components.modbus.modbus.ModbusUdpClient", return_value=mock_sync ): # Setup inputs for the sensor if register_words is None: mock_sync.read_coils.side_effect = ModbusException("fail read_coils") mock_sync.read_discrete_inputs.side_effect = ModbusException( "fail read_coils" ) mock_sync.read_input_registers.side_effect = ModbusException( "fail read_coils" ) mock_sync.read_holding_registers.side_effect = ModbusException( "fail read_coils" ) else: read_result = ReadResult(register_words) mock_sync.read_coils.return_value = read_result mock_sync.read_discrete_inputs.return_value = read_result mock_sync.read_input_registers.return_value = read_result mock_sync.read_holding_registers.return_value = read_result # mock timer and add old/new config now = dt_util.utcnow() with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): if method_discovery and config_device is not None: # setup modbus which in turn does setup for the devices config_modbus[DOMAIN].update( {array_name_discovery: [{**config_device}]} ) config_device = None assert ( await async_setup_component(hass, DOMAIN, config_modbus) is not expect_setup_to_fail ) await hass.async_block_till_done() # setup platform old style if config_device is not None: config_device = { entity_domain: { CONF_PLATFORM: DOMAIN, array_name_old_config: [ { **config_device, } ], } } if scan_interval is not None: config_device[entity_domain][CONF_SCAN_INTERVAL] = scan_interval assert await async_setup_component(hass, entity_domain, config_device) await hass.async_block_till_done() assert (DOMAIN in hass.config.components) is not expect_setup_to_fail if config_device is not None: entity_id = f"{entity_domain}.{device_name}" device = hass.states.get(entity_id) if expect_init_to_fail: assert device is None elif device is None: pytest.fail("CONFIG failed, see output") if check_config_only: return # Trigger update call with time_changed event now = now + timedelta(seconds=scan_interval + 60) with mock.patch("homeassistant.helpers.event.dt_util.utcnow", return_value=now): async_fire_time_changed(hass, now) await hass.async_block_till_done() # Check state entity_id = f"{entity_domain}.{device_name}" return hass.states.get(entity_id).state
async def test_scan_second_hit(hass, aioclient_mock, caplog): """Test matching on second scan.""" aioclient_mock.get( "http://1.1.1.1", text=""" <root> <device> <deviceType>Paulus</deviceType> </device> </root> """, ) mock_ssdp_response = CaseInsensitiveDict( **{ "ST": "mock-st", "LOCATION": "http://1.1.1.1", "USN": "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3", "SERVER": "mock-server", "EXT": "", }) mock_get_ssdp = {"mock-domain": [{"st": "mock-st"}]} integration_callbacks = [] @callback def _async_integration_callbacks(info): integration_callbacks.append(info) def _generate_fake_ssdp_listener(*args, **kwargs): listener = SSDPListener(*args, **kwargs) async def _async_callback(*_): pass @callback def _callback(*_): hass.async_create_task(listener.async_callback(mock_ssdp_response)) listener.async_start = _async_callback listener.async_search = _callback return listener with patch( "homeassistant.components.ssdp.async_get_ssdp", return_value=mock_get_ssdp, ), patch( "homeassistant.components.ssdp.SSDPListener", new=_generate_fake_ssdp_listener, ), patch.object(hass.config_entries.flow, "async_init", return_value=mock_coro()) as mock_init: assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}}) await hass.async_block_till_done() remove = ssdp.async_register_callback( hass, _async_integration_callbacks, {"st": "mock-st"}, ) hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() remove() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() assert len(integration_callbacks) == 4 assert integration_callbacks[0] == { ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus", ssdp.ATTR_SSDP_EXT: "", ssdp.ATTR_SSDP_LOCATION: "http://1.1.1.1", ssdp.ATTR_SSDP_SERVER: "mock-server", ssdp.ATTR_SSDP_ST: "mock-st", ssdp.ATTR_SSDP_USN: "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3", ssdp.ATTR_UPNP_UDN: "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL", } assert len(mock_init.mock_calls) == 1 assert mock_init.mock_calls[0][1][0] == "mock-domain" assert mock_init.mock_calls[0][2]["context"] == { "source": config_entries.SOURCE_SSDP } assert mock_init.mock_calls[0][2]["data"] == { ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus", ssdp.ATTR_SSDP_ST: "mock-st", ssdp.ATTR_SSDP_LOCATION: "http://1.1.1.1", ssdp.ATTR_SSDP_SERVER: "mock-server", ssdp.ATTR_SSDP_EXT: "", ssdp.ATTR_SSDP_USN: "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3", ssdp.ATTR_UPNP_UDN: "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL", } assert "Failed to fetch ssdp data" not in caplog.text udn_discovery_info = ssdp.async_get_discovery_info_by_st(hass, "mock-st") discovery_info = udn_discovery_info[0] assert discovery_info[ssdp.ATTR_SSDP_LOCATION] == "http://1.1.1.1" assert discovery_info[ssdp.ATTR_SSDP_ST] == "mock-st" assert (discovery_info[ssdp.ATTR_UPNP_UDN] == "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL") assert ( discovery_info[ssdp.ATTR_SSDP_USN] == "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3" ) st_discovery_info = ssdp.async_get_discovery_info_by_udn( hass, "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL") discovery_info = st_discovery_info[0] assert discovery_info[ssdp.ATTR_SSDP_LOCATION] == "http://1.1.1.1" assert discovery_info[ssdp.ATTR_SSDP_ST] == "mock-st" assert (discovery_info[ssdp.ATTR_UPNP_UDN] == "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL") assert ( discovery_info[ssdp.ATTR_SSDP_USN] == "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3" ) discovery_info = ssdp.async_get_discovery_info_by_udn_st( hass, "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL", "mock-st") assert discovery_info[ssdp.ATTR_SSDP_LOCATION] == "http://1.1.1.1" assert discovery_info[ssdp.ATTR_SSDP_ST] == "mock-st" assert (discovery_info[ssdp.ATTR_UPNP_UDN] == "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL") assert ( discovery_info[ssdp.ATTR_SSDP_USN] == "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3" ) assert ssdp.async_get_discovery_info_by_udn_st(hass, "wrong", "mock-st") is None
async def test_periodic_task_clock_rollback(hass): """Test periodic tasks with the time rolling backwards.""" specific_runs = [] unsub = async_track_utc_time_change(hass, lambda x: specific_runs.append(1), hour="/2", minute=0, second=0) async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) await hass.async_block_till_done() assert len(specific_runs) == 1 async_fire_time_changed(hass, datetime(2014, 5, 24, 23, 0, 0)) await hass.async_block_till_done() assert len(specific_runs) == 1 async_fire_time_changed(hass, datetime(2014, 5, 24, 22, 0, 0)) await hass.async_block_till_done() assert len(specific_runs) == 2 async_fire_time_changed(hass, datetime(2014, 5, 24, 0, 0, 0)) await hass.async_block_till_done() assert len(specific_runs) == 3 async_fire_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0)) await hass.async_block_till_done() assert len(specific_runs) == 4 unsub() async_fire_time_changed(hass, datetime(2014, 5, 25, 2, 0, 0)) await hass.async_block_till_done() assert len(specific_runs) == 4
async def test_unsolicited_ssdp_registered_callback(hass, aioclient_mock, caplog): """Test matching based on callback can handle unsolicited ssdp traffic without st.""" aioclient_mock.get( "http://10.6.9.12:1400/xml/device_description.xml", text=""" <root> <device> <deviceType>Paulus</deviceType> </device> </root> """, ) mock_ssdp_response = { "location": "http://10.6.9.12:1400/xml/device_description.xml", "nt": "uuid:RINCON_1111BB963FD801400", "nts": "ssdp:alive", "server": "Linux UPnP/1.0 Sonos/63.2-88230 (ZPS12)", "usn": "uuid:RINCON_1111BB963FD801400", "x-rincon-household": "Sonos_dfjfkdghjhkjfhkdjfhkd", "x-rincon-bootseq": "250", "bootid.upnp.org": "250", "x-rincon-wifimode": "0", "x-rincon-variant": "1", "household.smartspeaker.audio": "Sonos_v3294823948542543534", } integration_callbacks = [] @callback def _async_integration_callbacks(info): integration_callbacks.append(info) def _generate_fake_ssdp_listener(*args, **kwargs): listener = SSDPListener(*args, **kwargs) async def _async_callback(*_): await listener.async_callback(mock_ssdp_response) @callback def _callback(*_): hass.async_create_task(listener.async_callback(mock_ssdp_response)) listener.async_start = _async_callback listener.async_search = _callback return listener with patch( "homeassistant.components.ssdp.SSDPListener", new=_generate_fake_ssdp_listener, ): hass.state = CoreState.stopped assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}}) await hass.async_block_till_done() ssdp.async_register_callback( hass, _async_integration_callbacks, { "nts": "ssdp:alive", "x-rincon-bootseq": MATCH_ALL }, ) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) hass.state = CoreState.running await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() assert hass.state == CoreState.running assert (len(integration_callbacks) == 4 ) # unsolicited callbacks without st are not cached assert integration_callbacks[0] == { "UDN": "uuid:RINCON_1111BB963FD801400", "bootid.upnp.org": "250", "deviceType": "Paulus", "household.smartspeaker.audio": "Sonos_v3294823948542543534", "nt": "uuid:RINCON_1111BB963FD801400", "nts": "ssdp:alive", "ssdp_location": "http://10.6.9.12:1400/xml/device_description.xml", "ssdp_server": "Linux UPnP/1.0 Sonos/63.2-88230 (ZPS12)", "ssdp_usn": "uuid:RINCON_1111BB963FD801400", "x-rincon-bootseq": "250", "x-rincon-household": "Sonos_dfjfkdghjhkjfhkdjfhkd", "x-rincon-variant": "1", "x-rincon-wifimode": "0", } assert "Failed to callback info" not in caplog.text
async def test_periodic_task_leaving_dst(hass): """Test periodic task behavior when leaving dst.""" timezone = dt_util.get_time_zone("Europe/Vienna") dt_util.set_default_time_zone(timezone) specific_runs = [] now = dt_util.utcnow() time_that_will_not_match_right_away = timezone.localize(datetime( now.year + 1, 10, 28, 2, 28, 0), is_dst=True) with patch("homeassistant.util.dt.utcnow", return_value=time_that_will_not_match_right_away): unsub = async_track_time_change( hass, callback(lambda x: specific_runs.append(x)), hour=2, minute=30, second=0, ) async_fire_time_changed( hass, timezone.localize(datetime(now.year + 1, 10, 28, 2, 5, 0, 999999), is_dst=False), ) await hass.async_block_till_done() assert len(specific_runs) == 0 async_fire_time_changed( hass, timezone.localize(datetime(now.year + 1, 10, 28, 2, 55, 0, 999999), is_dst=False), ) await hass.async_block_till_done() assert len(specific_runs) == 1 async_fire_time_changed( hass, timezone.localize(datetime(now.year + 2, 10, 28, 2, 45, 0, 999999), is_dst=True), ) await hass.async_block_till_done() assert len(specific_runs) == 2 async_fire_time_changed( hass, timezone.localize(datetime(now.year + 2, 10, 28, 2, 55, 0, 999999), is_dst=True), ) await hass.async_block_till_done() assert len(specific_runs) == 2 async_fire_time_changed( hass, timezone.localize(datetime(now.year + 2, 10, 28, 2, 55, 0, 999999), is_dst=True), ) await hass.async_block_till_done() assert len(specific_runs) == 2 unsub()
async def test_scan_with_registered_callback(hass, aioclient_mock, caplog): """Test matching based on callback.""" aioclient_mock.get( "http://1.1.1.1", text=""" <root> <device> <deviceType>Paulus</deviceType> </device> </root> """, ) mock_ssdp_response = { "st": "mock-st", "location": "http://1.1.1.1", "usn": "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3", "server": "mock-server", "x-rincon-bootseq": "55", "ext": "", } not_matching_integration_callbacks = [] integration_match_all_callbacks = [] integration_match_all_not_present_callbacks = [] integration_callbacks = [] integration_callbacks_from_cache = [] match_any_callbacks = [] @callback def _async_exception_callbacks(info): raise ValueError @callback def _async_integration_callbacks(info): integration_callbacks.append(info) @callback def _async_integration_match_all_callbacks(info): integration_match_all_callbacks.append(info) @callback def _async_integration_match_all_not_present_callbacks(info): integration_match_all_not_present_callbacks.append(info) @callback def _async_integration_callbacks_from_cache(info): integration_callbacks_from_cache.append(info) @callback def _async_not_matching_integration_callbacks(info): not_matching_integration_callbacks.append(info) @callback def _async_match_any_callbacks(info): match_any_callbacks.append(info) def _generate_fake_ssdp_listener(*args, **kwargs): listener = SSDPListener(*args, **kwargs) async def _async_callback(*_): await listener.async_callback(mock_ssdp_response) @callback def _callback(*_): hass.async_create_task(listener.async_callback(mock_ssdp_response)) listener.async_start = _async_callback listener.async_search = _callback return listener with patch( "homeassistant.components.ssdp.SSDPListener", new=_generate_fake_ssdp_listener, ): hass.state = CoreState.stopped assert await async_setup_component(hass, ssdp.DOMAIN, {ssdp.DOMAIN: {}}) await hass.async_block_till_done() ssdp.async_register_callback(hass, _async_exception_callbacks, {}) ssdp.async_register_callback( hass, _async_integration_callbacks, {"st": "mock-st"}, ) ssdp.async_register_callback( hass, _async_integration_match_all_callbacks, {"x-rincon-bootseq": MATCH_ALL}, ) ssdp.async_register_callback( hass, _async_integration_match_all_not_present_callbacks, {"x-not-there": MATCH_ALL}, ) ssdp.async_register_callback( hass, _async_not_matching_integration_callbacks, {"st": "not-match-mock-st"}, ) ssdp.async_register_callback( hass, _async_match_any_callbacks, ) await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) ssdp.async_register_callback( hass, _async_integration_callbacks_from_cache, {"st": "mock-st"}, ) await hass.async_block_till_done() hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) hass.state = CoreState.running await hass.async_block_till_done() async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200)) await hass.async_block_till_done() assert hass.state == CoreState.running assert len(integration_callbacks) == 5 assert len(integration_callbacks_from_cache) == 5 assert len(integration_match_all_callbacks) == 5 assert len(integration_match_all_not_present_callbacks) == 0 assert len(match_any_callbacks) == 5 assert len(not_matching_integration_callbacks) == 0 assert integration_callbacks[0] == { ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus", ssdp.ATTR_SSDP_EXT: "", ssdp.ATTR_SSDP_LOCATION: "http://1.1.1.1", ssdp.ATTR_SSDP_SERVER: "mock-server", ssdp.ATTR_SSDP_ST: "mock-st", ssdp.ATTR_SSDP_USN: "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL::urn:mdx-netflix-com:service:target:3", ssdp.ATTR_UPNP_UDN: "uuid:TIVRTLSR7ANF-D6E-1557809135086-RETAIL", "x-rincon-bootseq": "55", } assert "Failed to callback info" in caplog.text
async def test_track_sunset(hass, legacy_patchable_time): """Test track the sunset.""" latitude = 32.87336 longitude = 117.22743 # Setup sun component hass.config.latitude = latitude hass.config.longitude = longitude assert await async_setup_component(hass, sun.DOMAIN, {sun.DOMAIN: { sun.CONF_ELEVATION: 0 }}) # Get next sunrise/sunset astral = Astral() utc_now = datetime(2014, 5, 24, 12, 0, 0, tzinfo=dt_util.UTC) utc_today = utc_now.date() mod = -1 while True: next_setting = astral.sunset_utc(utc_today + timedelta(days=mod), latitude, longitude) if next_setting > utc_now: break mod += 1 # Track sunset runs = [] with patch("homeassistant.util.dt.utcnow", return_value=utc_now): unsub = async_track_sunset(hass, callback(lambda: runs.append(1))) offset_runs = [] offset = timedelta(minutes=30) with patch("homeassistant.util.dt.utcnow", return_value=utc_now): unsub2 = async_track_sunset(hass, callback(lambda: offset_runs.append(1)), offset) # Run tests async_fire_time_changed(hass, next_setting - offset) await hass.async_block_till_done() assert len(runs) == 0 assert len(offset_runs) == 0 async_fire_time_changed(hass, next_setting) await hass.async_block_till_done() assert len(runs) == 1 assert len(offset_runs) == 0 async_fire_time_changed(hass, next_setting + offset) await hass.async_block_till_done() assert len(runs) == 1 assert len(offset_runs) == 1 unsub() unsub2() async_fire_time_changed(hass, next_setting + offset) await hass.async_block_till_done() assert len(runs) == 1 assert len(offset_runs) == 1
async def test_light_update(hass, mock_light): """Test KulerSkyLight update.""" utcnow = dt_util.utcnow() state = hass.states.get("light.bedroom") assert state.state == STATE_OFF assert dict(state.attributes) == { ATTR_FRIENDLY_NAME: "Bedroom", ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGBW], ATTR_SUPPORTED_FEATURES: 0, } # Test an exception during discovery mock_light.get_color.side_effect = pykulersky.PykulerskyException("TEST") utcnow = utcnow + SCAN_INTERVAL async_fire_time_changed(hass, utcnow) await hass.async_block_till_done() state = hass.states.get("light.bedroom") assert state.state == STATE_UNAVAILABLE assert dict(state.attributes) == { ATTR_FRIENDLY_NAME: "Bedroom", ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGBW], ATTR_SUPPORTED_FEATURES: 0, } mock_light.get_color.side_effect = None mock_light.get_color.return_value = (80, 160, 255, 0) utcnow = utcnow + SCAN_INTERVAL async_fire_time_changed(hass, utcnow) await hass.async_block_till_done() state = hass.states.get("light.bedroom") assert state.state == STATE_ON assert dict(state.attributes) == { ATTR_FRIENDLY_NAME: "Bedroom", ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGBW], ATTR_SUPPORTED_FEATURES: 0, ATTR_COLOR_MODE: COLOR_MODE_RGBW, ATTR_BRIGHTNESS: 255, ATTR_HS_COLOR: (approx(212.571), approx(68.627)), ATTR_RGB_COLOR: (80, 160, 255), ATTR_RGBW_COLOR: (80, 160, 255, 0), ATTR_XY_COLOR: (approx(0.17), approx(0.193)), } mock_light.get_color.side_effect = None mock_light.get_color.return_value = (80, 160, 200, 255) utcnow = utcnow + SCAN_INTERVAL async_fire_time_changed(hass, utcnow) await hass.async_block_till_done() state = hass.states.get("light.bedroom") assert state.state == STATE_ON assert dict(state.attributes) == { ATTR_FRIENDLY_NAME: "Bedroom", ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGBW], ATTR_SUPPORTED_FEATURES: 0, ATTR_COLOR_MODE: COLOR_MODE_RGBW, ATTR_BRIGHTNESS: 255, ATTR_HS_COLOR: (approx(199.701), approx(26.275)), ATTR_RGB_COLOR: (188, 233, 255), ATTR_RGBW_COLOR: (80, 160, 200, 255), ATTR_XY_COLOR: (approx(0.259), approx(0.306)), } mock_light.get_color.side_effect = None mock_light.get_color.return_value = (80, 160, 200, 240) utcnow = utcnow + SCAN_INTERVAL async_fire_time_changed(hass, utcnow) await hass.async_block_till_done() state = hass.states.get("light.bedroom") assert state.state == STATE_ON assert dict(state.attributes) == { ATTR_FRIENDLY_NAME: "Bedroom", ATTR_SUPPORTED_COLOR_MODES: [COLOR_MODE_RGBW], ATTR_SUPPORTED_FEATURES: 0, ATTR_COLOR_MODE: COLOR_MODE_RGBW, ATTR_BRIGHTNESS: 240, ATTR_HS_COLOR: (approx(200.0), approx(27.059)), ATTR_RGB_COLOR: (186, 232, 255), ATTR_RGBW_COLOR: (85, 170, 212, 255), ATTR_XY_COLOR: (approx(0.257), approx(0.305)), }
async def test_smart_strip_custom_random_effect(hass: HomeAssistant) -> None: """Test smart strip custom random effects.""" already_migrated_config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=MAC_ADDRESS) already_migrated_config_entry.add_to_hass(hass) strip = _mocked_smart_light_strip() with _patch_discovery(device=strip), _patch_single_discovery(device=strip): await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}}) await hass.async_block_till_done() entity_id = "light.my_bulb" state = hass.states.get(entity_id) assert state.state == STATE_ON await hass.services.async_call( DOMAIN, "random_effect", { ATTR_ENTITY_ID: entity_id, "init_states": [340, 20, 50], "backgrounds": [[340, 20, 50], [20, 50, 50], [0, 100, 50]], }, blocking=True, ) strip.set_custom_effect.assert_called_once_with({ "custom": 1, "id": "yMwcNpLxijmoKamskHCvvravpbnIqAIN", "brightness": 100, "name": "Custom", "segments": [0], "expansion_strategy": 1, "enable": 1, "duration": 0, "transition": 0, "type": "random", "init_states": [[340, 20, 50]], "random_seed": 100, "backgrounds": [(340, 20, 50), (20, 50, 50), (0, 100, 50)], }) strip.set_custom_effect.reset_mock() strip.effect = { "custom": 1, "id": "yMwcNpLxijmoKamskHCvvravpbnIqAIN", "brightness": 100, "name": "Custom", "enable": 1, } async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON strip.is_off = True strip.is_on = False strip.effect = { "custom": 1, "id": "yMwcNpLxijmoKamskHCvvravpbnIqAIN", "brightness": 100, "name": "Custom", "enable": 0, } async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=20)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF assert ATTR_EFFECT not in state.attributes await hass.services.async_call( LIGHT_DOMAIN, "turn_on", {ATTR_ENTITY_ID: entity_id}, blocking=True, ) strip.set_custom_effect.assert_called_once_with({ "custom": 1, "id": "yMwcNpLxijmoKamskHCvvravpbnIqAIN", "brightness": 100, "name": "Custom", "segments": [0], "expansion_strategy": 1, "enable": 1, "duration": 0, "transition": 0, "type": "random", "init_states": [[340, 20, 50]], "random_seed": 100, "backgrounds": [(340, 20, 50), (20, 50, 50), (0, 100, 50)], }) strip.set_custom_effect.reset_mock() await hass.services.async_call( DOMAIN, "random_effect", { ATTR_ENTITY_ID: entity_id, "init_states": [340, 20, 50], "backgrounds": [[340, 20, 50], [20, 50, 50], [0, 100, 50]], "random_seed": 50, "brightness": 80, "duration": 5000, "transition": 2000, "fadeoff": 3000, "hue_range": [0, 360], "saturation_range": [0, 100], "brightness_range": [0, 100], "transition_range": [2000, 3000], }, ) await hass.async_block_till_done() strip.set_custom_effect.assert_called_once_with({ "custom": 1, "id": "yMwcNpLxijmoKamskHCvvravpbnIqAIN", "brightness": 80, "name": "Custom", "segments": [0], "expansion_strategy": 1, "enable": 1, "duration": 5000, "transition": 0, "type": "random", "init_states": [[340, 20, 50]], "random_seed": 50, "backgrounds": [(340, 20, 50), (20, 50, 50), (0, 100, 50)], "fadeoff": 3000, "hue_range": [0, 360], "saturation_range": [0, 100], "brightness_range": [0, 100], "transition_range": [2000, 3000], }) strip.set_custom_effect.reset_mock()
async def test_setup(hass): """Test the general setup of the platform.""" # Set up some mock feed entries for this test. mock_entry_1 = _generate_mock_feed_entry( "1234", "Title 1", 15.5, (-31.0, 150.0), category="Category 1", location="Location 1", attribution="Attribution 1", publication_date=datetime.datetime(2018, 9, 22, 8, 0, tzinfo=datetime.timezone.utc), council_area="Council Area 1", status="Status 1", entry_type="Type 1", size="Size 1", responsible_agency="Agency 1", ) mock_entry_2 = _generate_mock_feed_entry("2345", "Title 2", 20.5, (-31.1, 150.1), fire=False) mock_entry_3 = _generate_mock_feed_entry("3456", "Title 3", 25.5, (-31.2, 150.2)) mock_entry_4 = _generate_mock_feed_entry("4567", "Title 4", 12.5, (-31.3, 150.3)) # Patching 'utcnow' to gain more control over the timed update. utcnow = dt_util.utcnow() with patch("homeassistant.util.dt.utcnow", return_value=utcnow), patch( "aio_geojson_client.feed.GeoJsonFeed.update") as mock_feed_update: mock_feed_update.return_value = ( "OK", [mock_entry_1, mock_entry_2, mock_entry_3], ) with assert_setup_component(1, geo_location.DOMAIN): assert await async_setup_component(hass, geo_location.DOMAIN, CONFIG) await hass.async_block_till_done() # Artificially trigger update. hass.bus.async_fire(EVENT_HOMEASSISTANT_START) # Collect events. await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 3 state = hass.states.get("geo_location.title_1") assert state is not None assert state.name == "Title 1" assert state.attributes == { ATTR_EXTERNAL_ID: "1234", ATTR_LATITUDE: -31.0, ATTR_LONGITUDE: 150.0, ATTR_FRIENDLY_NAME: "Title 1", ATTR_CATEGORY: "Category 1", ATTR_LOCATION: "Location 1", ATTR_ATTRIBUTION: "Attribution 1", ATTR_PUBLICATION_DATE: datetime.datetime(2018, 9, 22, 8, 0, tzinfo=datetime.timezone.utc), ATTR_FIRE: True, ATTR_COUNCIL_AREA: "Council Area 1", ATTR_STATUS: "Status 1", ATTR_TYPE: "Type 1", ATTR_SIZE: "Size 1", ATTR_RESPONSIBLE_AGENCY: "Agency 1", ATTR_UNIT_OF_MEASUREMENT: LENGTH_KILOMETERS, ATTR_SOURCE: "nsw_rural_fire_service_feed", ATTR_ICON: "mdi:fire", } assert round(abs(float(state.state) - 15.5), 7) == 0 state = hass.states.get("geo_location.title_2") assert state is not None assert state.name == "Title 2" assert state.attributes == { ATTR_EXTERNAL_ID: "2345", ATTR_LATITUDE: -31.1, ATTR_LONGITUDE: 150.1, ATTR_FRIENDLY_NAME: "Title 2", ATTR_FIRE: False, ATTR_UNIT_OF_MEASUREMENT: LENGTH_KILOMETERS, ATTR_SOURCE: "nsw_rural_fire_service_feed", ATTR_ICON: "mdi:alarm-light", } assert round(abs(float(state.state) - 20.5), 7) == 0 state = hass.states.get("geo_location.title_3") assert state is not None assert state.name == "Title 3" assert state.attributes == { ATTR_EXTERNAL_ID: "3456", ATTR_LATITUDE: -31.2, ATTR_LONGITUDE: 150.2, ATTR_FRIENDLY_NAME: "Title 3", ATTR_FIRE: True, ATTR_UNIT_OF_MEASUREMENT: LENGTH_KILOMETERS, ATTR_SOURCE: "nsw_rural_fire_service_feed", ATTR_ICON: "mdi:fire", } assert round(abs(float(state.state) - 25.5), 7) == 0 # Simulate an update - one existing, one new entry, # one outdated entry mock_feed_update.return_value = ( "OK", [mock_entry_1, mock_entry_4, mock_entry_3], ) async_fire_time_changed(hass, utcnow + SCAN_INTERVAL) await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 3 # Simulate an update - empty data, but successful update, # so no changes to entities. mock_feed_update.return_value = "OK_NO_DATA", None async_fire_time_changed(hass, utcnow + 2 * SCAN_INTERVAL) await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 3 # Simulate an update - empty data, removes all entities mock_feed_update.return_value = "ERROR", None async_fire_time_changed(hass, utcnow + 3 * SCAN_INTERVAL) await hass.async_block_till_done() all_states = hass.states.async_all() assert len(all_states) == 0 # Artificially trigger update. hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) # Collect events. await hass.async_block_till_done()
async def test_smart_strip_effects(hass: HomeAssistant) -> None: """Test smart strip effects.""" already_migrated_config_entry = MockConfigEntry(domain=DOMAIN, data={}, unique_id=MAC_ADDRESS) already_migrated_config_entry.add_to_hass(hass) strip = _mocked_smart_light_strip() with _patch_discovery(device=strip), _patch_single_discovery(device=strip): await async_setup_component(hass, tplink.DOMAIN, {tplink.DOMAIN: {}}) await hass.async_block_till_done() entity_id = "light.my_bulb" state = hass.states.get(entity_id) assert state.state == STATE_ON assert state.attributes[ATTR_EFFECT] == "Effect1" assert state.attributes[ATTR_EFFECT_LIST] == ["Effect1", "Effect2"] await hass.services.async_call( LIGHT_DOMAIN, "turn_on", { ATTR_ENTITY_ID: entity_id, ATTR_EFFECT: "Effect2" }, blocking=True, ) strip.set_effect.assert_called_once_with("Effect2") strip.set_effect.reset_mock() strip.effect = {"name": "Effect1", "enable": 0, "custom": 0} async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=10)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON assert ATTR_EFFECT not in state.attributes strip.is_off = True strip.is_on = False async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=20)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF assert ATTR_EFFECT not in state.attributes await hass.services.async_call( LIGHT_DOMAIN, "turn_on", {ATTR_ENTITY_ID: entity_id}, blocking=True, ) strip.set_effect.assert_called_once_with("Effect1") strip.set_effect.reset_mock() strip.is_off = False strip.is_on = True strip.effect_list = None async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=30)) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON assert state.attributes[ATTR_EFFECT_LIST] is None
async def test_lock_update_via_pubnub(hass): """Test creation of a lock with doorsense and bridge.""" lock_one = await _mock_doorsense_enabled_august_lock_detail(hass) assert lock_one.pubsub_channel == "pubsub" pubnub = AugustPubNub() activities = await _mock_activities_from_fixture(hass, "get_activity.lock.json") config_entry = await _create_august_with_devices(hass, [lock_one], activities=activities, pubnub=pubnub) pubnub.connected = True lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_LOCKED pubnub.message( pubnub, Mock( channel=lock_one.pubsub_channel, timetoken=dt_util.utcnow().timestamp() * 10000000, message={ "status": "kAugLockState_Unlocking", }, ), ) await hass.async_block_till_done() await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_UNLOCKING pubnub.message( pubnub, Mock( channel=lock_one.pubsub_channel, timetoken=(dt_util.utcnow().timestamp() + 1) * 10000000, message={ "status": "kAugLockState_Locking", }, ), ) await hass.async_block_till_done() await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_LOCKING async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(seconds=30)) await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_LOCKING pubnub.connected = True async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(seconds=30)) await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_LOCKING # Ensure pubnub status is always preserved async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(hours=2)) await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_LOCKING pubnub.message( pubnub, Mock( channel=lock_one.pubsub_channel, timetoken=(dt_util.utcnow().timestamp() + 2) * 10000000, message={ "status": "kAugLockState_Unlocking", }, ), ) await hass.async_block_till_done() await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_UNLOCKING async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(hours=4)) await hass.async_block_till_done() lock_online_with_doorsense_name = hass.states.get( "lock.online_with_doorsense_name") assert lock_online_with_doorsense_name.state == STATE_UNLOCKING await hass.config_entries.async_unload(config_entry.entry_id) await hass.async_block_till_done()
async def test_off_delay(hass, monkeypatch): """Test off_delay option.""" # setup mocking rflink module event_callback, create, _, _ = await mock_rflink(hass, CONFIG, DOMAIN, monkeypatch) # make sure arguments are passed assert create.call_args_list[0][1]['ignore'] events = [] on_event = { 'id': 'test2', 'command': 'on', } @ha.callback def callback(event): """Verify event got called.""" events.append(event) hass.bus.async_listen(EVENT_STATE_CHANGED, callback) now = dt_util.utcnow() # fake time and turn on sensor future = now + timedelta(seconds=0) with patch(('homeassistant.helpers.event.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) event_callback(on_event) await hass.async_block_till_done() state = hass.states.get('binary_sensor.test2') assert state.state == STATE_ON assert len(events) == 1 # fake time and turn on sensor again future = now + timedelta(seconds=15) with patch(('homeassistant.helpers.event.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) event_callback(on_event) await hass.async_block_till_done() state = hass.states.get('binary_sensor.test2') assert state.state == STATE_ON assert len(events) == 2 # fake time and verify sensor still on (de-bounce) future = now + timedelta(seconds=35) with patch(('homeassistant.helpers.event.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get('binary_sensor.test2') assert state.state == STATE_ON assert len(events) == 2 # fake time and verify sensor is off future = now + timedelta(seconds=45) with patch(('homeassistant.helpers.event.' 'dt_util.utcnow'), return_value=future): async_fire_time_changed(hass, future) await hass.async_block_till_done() state = hass.states.get('binary_sensor.test2') assert state.state == STATE_OFF assert len(events) == 3
async def fire_alarm(hass, point_in_time): """Fire an alarm and wait for callbacks to run.""" with patch("homeassistant.util.dt.utcnow", return_value=point_in_time): async_fire_time_changed(hass, point_in_time) await hass.async_block_till_done()
async def _ffwd_next_update_interval(hass): now = dt_util.utcnow() async_fire_time_changed(hass, now + UPDATE_INTERVAL) await hass.async_block_till_done()