async def test_unavailable_state_doesnt_sync(hass): """Test that an unavailable entity does not sync over.""" light = DemoLight( None, 'Demo Light', state=False, ) light.hass = hass light.entity_id = 'light.demo_light' light._available = False # pylint: disable=protected-access await light.async_update_ha_state() result = await sh.async_handle_message( hass, BASIC_CONFIG, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'agentUserId': 'test-agent', 'devices': [] } }
async def test_empty_name_doesnt_sync(hass): """Test that an entity with empty name does not sync over.""" light = DemoLight( None, ' ', state=False, ) light.hass = hass light.entity_id = 'light.demo_light' await light.async_update_ha_state() result = await sh.async_handle_message( hass, BASIC_CONFIG, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'agentUserId': 'test-agent', 'devices': [] } }
async def test_unavailable_state_doesnt_sync(hass): """Test that an unavailable entity does not sync over.""" light = DemoLight(None, "Demo Light", state=False) light.hass = hass light.entity_id = "light.demo_light" light._available = False # pylint: disable=protected-access await light.async_update_ha_state() result = await sh.async_handle_message( hass, BASIC_CONFIG, "test-agent", { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [] }, }
async def test_unavailable_state_does_sync(hass): """Test that an unavailable entity does sync over.""" light = DemoLight(None, "Demo Light", state=False, hs_color=(180, 75)) light.hass = hass light.entity_id = "light.demo_light" light._available = False # pylint: disable=protected-access await light.async_update_ha_state() events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, BASIC_CONFIG, "test-agent", { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }, const.SOURCE_CLOUD, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [{ "id": "light.demo_light", "name": { "name": "Demo Light" }, "traits": [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, ], "type": const.TYPE_LIGHT, "willReportState": False, "attributes": { "colorModel": "hsv", "colorTemperatureRange": { "temperatureMinK": 2000, "temperatureMaxK": 6535, }, }, }], }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == {"request_id": REQ_ID, "source": "cloud"}
async def test_sync_message_recovery(hass, caplog): """Test a sync message recovers from bad entities.""" light = DemoLight( None, "Demo Light", state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = "light.demo_light" await light.async_update_ha_state() hass.states.async_set( "light.bad_light", "on", { "min_mireds": "badvalue", "supported_color_modes": ["color_temp"], }, ) result = await sh.async_handle_message( hass, BASIC_CONFIG, "test-agent", {"requestId": REQ_ID, "inputs": [{"intent": "action.devices.SYNC"}]}, const.SOURCE_CLOUD, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [ { "id": "light.demo_light", "name": {"name": "Demo Light"}, "attributes": { "colorModel": "hsv", "colorTemperatureRange": { "temperatureMaxK": 6535, "temperatureMinK": 2000, }, }, "traits": [ "action.devices.traits.Brightness", "action.devices.traits.OnOff", "action.devices.traits.ColorSetting", ], "willReportState": False, "type": "action.devices.types.LIGHT", }, ], }, } assert "Error serializing light.bad_light" in caplog.text
async def test_light(hass, hass_client): """Test prometheus metrics for lights.""" client = await setup_prometheus_client(hass, hass_client, "") light1 = DemoSensor(None, "Desk", 1, None, None, None, None) light1.hass = hass light1.entity_id = "light.desk" await light1.async_update_ha_state() light2 = DemoSensor(None, "Wall", 0, None, None, None, None) light2.hass = hass light2.entity_id = "light.wall" await light2.async_update_ha_state() light3 = DemoLight(None, "TV", True, True, 255, None, None) light3.hass = hass light3.entity_id = "light.tv" await light3.async_update_ha_state() light4 = DemoLight(None, "PC", True, True, 180, None, None) light4.hass = hass light4.entity_id = "light.pc" await light4.async_update_ha_state() await hass.async_block_till_done() body = await generate_latest_metrics(client) assert ('light_brightness_percent{domain="light",' 'entity="light.desk",' 'friendly_name="Desk"} 100.0' in body) assert ('light_brightness_percent{domain="light",' 'entity="light.wall",' 'friendly_name="Wall"} 0.0' in body) assert ('light_brightness_percent{domain="light",' 'entity="light.tv",' 'friendly_name="TV"} 100.0' in body) assert ('light_brightness_percent{domain="light",' 'entity="light.pc",' 'friendly_name="PC"} 70.58823529411765' in body)
async def test_yandex_entity_capabilities(hass): light = DemoLight( unique_id='test_light', name='Light', available=True, state=True, ) light.hass = hass light.entity_id = 'light.test' await light.async_update_ha_state() state = hass.states.get('light.test') state_sensor = State('sensor.test', '33') config = MockConfig( entity_config={ light.entity_id: { const.CONF_ENTITY_MODE_MAP: { const.MODE_INSTANCE_DISHWASHING: { const.MODE_INSTANCE_MODE_ECO: [''] } }, const.CONF_ENTITY_CUSTOM_RANGES: { const.RANGE_INSTANCE_HUMIDITY: { const.CONF_ENTITY_CUSTOM_CAPABILITY_STATE_ENTITY_ID: state_sensor.entity_id, const.CONF_ENTITY_CUSTOM_RANGE_SET_VALUE: {}, } }, const.CONF_ENTITY_CUSTOM_TOGGLES: { const.TOGGLE_INSTANCE_PAUSE: { const.CONF_ENTITY_CUSTOM_CAPABILITY_STATE_ENTITY_ID: state_sensor.entity_id, const.CONF_ENTITY_CUSTOM_TOGGLE_TURN_ON: {}, const.CONF_ENTITY_CUSTOM_TOGGLE_TURN_OFF: {}, } }, const.CONF_ENTITY_CUSTOM_MODES: { const.MODE_INSTANCE_DISHWASHING: { const.CONF_ENTITY_CUSTOM_CAPABILITY_STATE_ENTITY_ID: state_sensor.entity_id, const.CONF_ENTITY_CUSTOM_MODE_SET_MODE: {}, } } } } ) entity = YandexEntity(hass, config, state) assert [type(c) for c in entity.capabilities()] == [ CustomModeCapability, CustomToggleCapability, CustomRangeCapability, RgbCapability, TemperatureKCapability, BrightnessCapability, OnOffCapabilityBasic ]
def hass_platform_cloud_connection(loop, hass, config_entry_cloud_connection): demo_sensor = DemoSensor( unique_id='outside_temp', name='Outside Temperature', state=15.6, device_class=DEVICE_CLASS_TEMPERATURE, state_class=STATE_CLASS_MEASUREMENT, unit_of_measurement=TEMP_CELSIUS, battery=None ) demo_sensor.hass = hass demo_sensor.entity_id = 'sensor.outside_temp' demo_light = DemoLight( unique_id='light_kitchen', name='Kitchen Light', available=True, state=True, ) demo_light.hass = hass demo_light.entity_id = 'light.kitchen' loop.run_until_complete( demo_sensor.async_update_ha_state() ) loop.run_until_complete( demo_light.async_update_ha_state() ) loop.run_until_complete( async_setup_component(hass, http.DOMAIN, {http.DOMAIN: {}}) ) loop.run_until_complete( hass.async_block_till_done() ) with patch.object(hass.config_entries.flow, 'async_init', return_value=None), patch_yaml_files({ YAML_CONFIG_FILE: 'yandex_smart_home:' }): config_entry_cloud_connection.add_to_hass(hass) loop.run_until_complete(async_setup(hass, {DOMAIN: {}})) with patch('custom_components.yandex_smart_home.cloud.CloudManager.connect', return_value=None): loop.run_until_complete(async_setup_entry(hass, config_entry_cloud_connection)) return hass
async def test_sync_message(hass): """Test a sync message.""" light = DemoLight( None, "Demo Light", state=False, hs_color=(180, 75), effect_list=LIGHT_EFFECT_LIST, effect=LIGHT_EFFECT_LIST[0], ) light.hass = hass light.entity_id = "light.demo_light" await light.async_update_ha_state() # This should not show up in the sync request hass.states.async_set("sensor.no_match", "something") # Excluded via config hass.states.async_set("light.not_expose", "on") config = MockConfig( should_expose=lambda state: state.entity_id != "light.not_expose", entity_config={ "light.demo_light": { const.CONF_ROOM_HINT: "Living Room", const.CONF_ALIASES: ["Hello", "World"], } }, ) events = async_capture_events(hass, EVENT_SYNC_RECEIVED) result = await sh.async_handle_message( hass, config, "test-agent", {"requestId": REQ_ID, "inputs": [{"intent": "action.devices.SYNC"}]}, const.SOURCE_CLOUD, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [ { "id": "light.demo_light", "name": { "name": "Demo Light", "nicknames": ["Demo Light", "Hello", "World"], }, "traits": [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, trait.TRAIT_MODES, ], "type": const.TYPE_LIGHT, "willReportState": False, "attributes": { "availableModes": [ { "name": "effect", "name_values": [ {"lang": "en", "name_synonym": ["effect"]} ], "ordered": False, "settings": [ { "setting_name": "rainbow", "setting_values": [ { "lang": "en", "setting_synonym": ["rainbow"], } ], }, { "setting_name": "none", "setting_values": [ {"lang": "en", "setting_synonym": ["none"]} ], }, ], } ], "colorModel": "hsv", "colorTemperatureRange": { "temperatureMinK": 2000, "temperatureMaxK": 6535, }, }, "roomHint": "Living Room", } ], }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == {"request_id": REQ_ID, "source": "cloud"}
async def test_sync_message(hass): """Test a sync message.""" light = DemoLight( None, 'Demo Light', state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = 'light.demo_light' await light.async_update_ha_state() # This should not show up in the sync request hass.states.async_set('sensor.no_match', 'something') # Excluded via config hass.states.async_set('light.not_expose', 'on') config = helpers.Config( should_expose=lambda state: state.entity_id != 'light.not_expose', allow_unlock=False, entity_config={ 'light.demo_light': { const.CONF_ROOM_HINT: 'Living Room', const.CONF_ALIASES: ['Hello', 'World'] } } ) events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, config, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'agentUserId': 'test-agent', 'devices': [{ 'id': 'light.demo_light', 'name': { 'name': 'Demo Light', 'nicknames': [ 'Hello', 'World', ] }, 'traits': [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SPECTRUM, trait.TRAIT_COLOR_TEMP, ], 'type': sh.TYPE_LIGHT, 'willReportState': False, 'attributes': { 'colorModel': 'rgb', 'temperatureMinK': 2000, 'temperatureMaxK': 6535, }, 'roomHint': 'Living Room' }] } } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == { 'request_id': REQ_ID, }
async def test_sync_message(hass): """Test a sync message.""" light = DemoLight( None, 'Demo Light', state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = 'light.demo_light' await light.async_update_ha_state() # This should not show up in the sync request hass.states.async_set('sensor.no_match', 'something') # Excluded via config hass.states.async_set('light.not_expose', 'on') config = helpers.Config( should_expose=lambda state: state.entity_id != 'light.not_expose', entity_config={ 'light.demo_light': { const.CONF_ROOM_HINT: 'Living Room', const.CONF_ALIASES: ['Hello', 'World'] } }) events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, config, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'agentUserId': 'test-agent', 'devices': [{ 'id': 'light.demo_light', 'name': { 'name': 'Demo Light', 'nicknames': [ 'Hello', 'World', ] }, 'traits': [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, ], 'type': const.TYPE_LIGHT, 'willReportState': False, 'attributes': { 'colorModel': 'hsv', 'colorTemperatureRange': { 'temperatureMinK': 2000, 'temperatureMaxK': 6535, } }, 'roomHint': 'Living Room' }] } } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == { 'request_id': REQ_ID, }
async def test_query_message(hass): """Test a sync message.""" light = DemoLight( None, 'Demo Light', state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = 'light.demo_light' await light.async_update_ha_state() light2 = DemoLight( None, 'Another Light', state=True, hs_color=(180, 75), ct=400, brightness=78, ) light2.hass = hass light2.entity_id = 'light.another_light' await light2.async_update_ha_state() events = [] hass.bus.async_listen(EVENT_QUERY_RECEIVED, events.append) result = await sh.async_handle_message( hass, BASIC_CONFIG, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.QUERY", "payload": { "devices": [{ "id": "light.demo_light", }, { "id": "light.another_light", }, { "id": "light.non_existing", }] } }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'devices': { 'light.non_existing': { 'online': False, }, 'light.demo_light': { 'on': False, 'online': True, }, 'light.another_light': { 'on': True, 'online': True, 'brightness': 30, 'color': { 'spectrumRGB': 4194303, 'temperature': 2500, } }, } } } assert len(events) == 3 assert events[0].event_type == EVENT_QUERY_RECEIVED assert events[0].data == { 'request_id': REQ_ID, 'entity_id': 'light.demo_light' } assert events[1].event_type == EVENT_QUERY_RECEIVED assert events[1].data == { 'request_id': REQ_ID, 'entity_id': 'light.another_light' } assert events[2].event_type == EVENT_QUERY_RECEIVED assert events[2].data == { 'request_id': REQ_ID, 'entity_id': 'light.non_existing' }
async def test_query_message(hass): """Test a sync message.""" light = DemoLight(None, "Demo Light", state=False, hs_color=(180, 75)) light.hass = hass light.entity_id = "light.demo_light" await light.async_update_ha_state() light2 = DemoLight( None, "Another Light", state=True, hs_color=(180, 75), ct=400, brightness=78 ) light2.hass = hass light2.entity_id = "light.another_light" await light2.async_update_ha_state() events = [] hass.bus.async_listen(EVENT_QUERY_RECEIVED, events.append) result = await sh.async_handle_message( hass, BASIC_CONFIG, "test-agent", { "requestId": REQ_ID, "inputs": [ { "intent": "action.devices.QUERY", "payload": { "devices": [ {"id": "light.demo_light"}, {"id": "light.another_light"}, {"id": "light.non_existing"}, ] }, } ], }, ) assert result == { "requestId": REQ_ID, "payload": { "devices": { "light.non_existing": {"online": False}, "light.demo_light": {"on": False, "online": True, "brightness": 0}, "light.another_light": { "on": True, "online": True, "brightness": 30, "color": { "spectrumHsv": { "hue": 180, "saturation": 0.75, "value": 0.3058823529411765, }, "temperatureK": 2500, }, }, } }, } assert len(events) == 3 assert events[0].event_type == EVENT_QUERY_RECEIVED assert events[0].data == {"request_id": REQ_ID, "entity_id": "light.demo_light"} assert events[1].event_type == EVENT_QUERY_RECEIVED assert events[1].data == {"request_id": REQ_ID, "entity_id": "light.another_light"} assert events[2].event_type == EVENT_QUERY_RECEIVED assert events[2].data == {"request_id": REQ_ID, "entity_id": "light.non_existing"}
async def test_unavailable_state_does_sync(hass): """Test that an unavailable entity does sync over.""" light = DemoLight( None, "Demo Light", state=False, hs_color=(180, 75), effect_list=LIGHT_EFFECT_LIST, effect=LIGHT_EFFECT_LIST[0], ) light.hass = hass light.entity_id = "light.demo_light" light._available = False # pylint: disable=protected-access await light.async_update_ha_state() events = async_capture_events(hass, EVENT_SYNC_RECEIVED) result = await sh.async_handle_message( hass, BASIC_CONFIG, "test-agent", {"requestId": REQ_ID, "inputs": [{"intent": "action.devices.SYNC"}]}, const.SOURCE_CLOUD, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [ { "id": "light.demo_light", "name": {"name": "Demo Light"}, "traits": [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, trait.TRAIT_MODES, ], "type": const.TYPE_LIGHT, "willReportState": False, "attributes": { "availableModes": [ { "name": "effect", "name_values": [ {"lang": "en", "name_synonym": ["effect"]} ], "ordered": False, "settings": [ { "setting_name": "rainbow", "setting_values": [ { "lang": "en", "setting_synonym": ["rainbow"], } ], }, { "setting_name": "none", "setting_values": [ {"lang": "en", "setting_synonym": ["none"]} ], }, ], } ], "colorModel": "hsv", "colorTemperatureRange": { "temperatureMinK": 2000, "temperatureMaxK": 6535, }, }, } ], }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == {"request_id": REQ_ID, "source": "cloud"}
async def test_sync_in_area(area_on_device, hass, registries): """Test a sync message where room hint comes from area.""" area = registries.area.async_create("Living Room") device = registries.device.async_get_or_create( config_entry_id="1234", manufacturer="Someone", model="Some model", sw_version="Some Version", connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) registries.device.async_update_device( device.id, area_id=area.id if area_on_device else None ) entity = registries.entity.async_get_or_create( "light", "test", "1235", suggested_object_id="demo_light", device_id=device.id, area_id=area.id if not area_on_device else None, ) light = DemoLight( None, "Demo Light", state=False, hs_color=(180, 75), effect_list=LIGHT_EFFECT_LIST, effect=LIGHT_EFFECT_LIST[0], ) light.hass = hass light.entity_id = entity.entity_id await light.async_update_ha_state() config = MockConfig(should_expose=lambda _: True, entity_config={}) events = async_capture_events(hass, EVENT_SYNC_RECEIVED) result = await sh.async_handle_message( hass, config, "test-agent", {"requestId": REQ_ID, "inputs": [{"intent": "action.devices.SYNC"}]}, const.SOURCE_CLOUD, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [ { "id": "light.demo_light", "name": {"name": "Demo Light"}, "traits": [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, trait.TRAIT_MODES, ], "type": const.TYPE_LIGHT, "willReportState": False, "attributes": { "availableModes": [ { "name": "effect", "name_values": [ {"lang": "en", "name_synonym": ["effect"]} ], "ordered": False, "settings": [ { "setting_name": "rainbow", "setting_values": [ { "lang": "en", "setting_synonym": ["rainbow"], } ], }, { "setting_name": "none", "setting_values": [ {"lang": "en", "setting_synonym": ["none"]} ], }, ], } ], "colorModel": "hsv", "colorTemperatureRange": { "temperatureMinK": 2000, "temperatureMaxK": 6535, }, }, "deviceInfo": { "manufacturer": "Someone", "model": "Some model", "swVersion": "Some Version", }, "roomHint": "Living Room", } ], }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == {"request_id": REQ_ID, "source": "cloud"}
async def test_query_message(hass): """Test a sync message.""" light = DemoLight( None, "Demo Light", state=False, hs_color=(180, 75), effect_list=LIGHT_EFFECT_LIST, effect=LIGHT_EFFECT_LIST[0], ) light.hass = hass light.entity_id = "light.demo_light" await light.async_update_ha_state() light2 = DemoLight( None, "Another Light", state=True, hs_color=(180, 75), ct=400, brightness=78 ) light2.hass = hass light2.entity_id = "light.another_light" await light2.async_update_ha_state() light3 = DemoLight(None, "Color temp Light", state=True, ct=400, brightness=200) light3.hass = hass light3.entity_id = "light.color_temp_light" await light3.async_update_ha_state() events = async_capture_events(hass, EVENT_QUERY_RECEIVED) result = await sh.async_handle_message( hass, BASIC_CONFIG, "test-agent", { "requestId": REQ_ID, "inputs": [ { "intent": "action.devices.QUERY", "payload": { "devices": [ {"id": "light.demo_light"}, {"id": "light.another_light"}, {"id": "light.color_temp_light"}, {"id": "light.non_existing"}, ] }, } ], }, const.SOURCE_CLOUD, ) assert result == { "requestId": REQ_ID, "payload": { "devices": { "light.non_existing": {"online": False}, "light.demo_light": {"on": False, "online": True, "brightness": 0}, "light.another_light": { "on": True, "online": True, "brightness": 30, "color": { "spectrumHsv": { "hue": 180, "saturation": 0.75, "value": 0.3058823529411765, }, }, }, "light.color_temp_light": { "on": True, "online": True, "brightness": 78, "color": {"temperatureK": 2500}, }, } }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_QUERY_RECEIVED assert events[0].data == { "request_id": REQ_ID, "entity_id": [ "light.demo_light", "light.another_light", "light.color_temp_light", "light.non_existing", ], "source": "cloud", }
async def test_sync_in_area(hass, registries): """Test a sync message where room hint comes from area.""" area = registries.area.async_create("Living Room") device = registries.device.async_get_or_create( config_entry_id='1234', connections={(device_registry.CONNECTION_NETWORK_MAC, '12:34:56:AB:CD:EF')}) registries.device.async_update_device(device.id, area_id=area.id) entity = registries.entity.async_get_or_create( 'light', 'test', '1235', suggested_object_id='demo_light', device_id=device.id) light = DemoLight( None, 'Demo Light', state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = entity.entity_id await light.async_update_ha_state() config = helpers.Config(should_expose=lambda _: True, entity_config={}) events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, config, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'agentUserId': 'test-agent', 'devices': [{ 'id': 'light.demo_light', 'name': { 'name': 'Demo Light' }, 'traits': [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, ], 'type': const.TYPE_LIGHT, 'willReportState': False, 'attributes': { 'colorModel': 'hsv', 'colorTemperatureRange': { 'temperatureMinK': 2000, 'temperatureMaxK': 6535, } }, 'roomHint': 'Living Room' }] } } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == { 'request_id': REQ_ID, }
async def test_sync_in_area(hass, registries): """Test a sync message where room hint comes from area.""" area = registries.area.async_create("Living Room") device = registries.device.async_get_or_create( config_entry_id="1234", connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) registries.device.async_update_device(device.id, area_id=area.id) entity = registries.entity.async_get_or_create( "light", "test", "1235", suggested_object_id="demo_light", device_id=device.id ) light = DemoLight(None, "Demo Light", state=False, hs_color=(180, 75)) light.hass = hass light.entity_id = entity.entity_id await light.async_update_ha_state() config = MockConfig(should_expose=lambda _: True, entity_config={}) events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, config, "test-agent", {"requestId": REQ_ID, "inputs": [{"intent": "action.devices.SYNC"}]}, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [ { "id": "light.demo_light", "name": {"name": "Demo Light"}, "traits": [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, ], "type": const.TYPE_LIGHT, "willReportState": False, "attributes": { "colorModel": "hsv", "colorTemperatureRange": { "temperatureMinK": 2000, "temperatureMaxK": 6535, }, }, "roomHint": "Living Room", } ], }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == {"request_id": REQ_ID}
async def test_query_message(hass): """Test a sync message.""" light = DemoLight( None, 'Demo Light', state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = 'light.demo_light' await light.async_update_ha_state() light2 = DemoLight( None, 'Another Light', state=True, hs_color=(180, 75), ct=400, brightness=78, ) light2.hass = hass light2.entity_id = 'light.another_light' await light2.async_update_ha_state() events = [] hass.bus.async_listen(EVENT_QUERY_RECEIVED, events.append) result = await sh.async_handle_message( hass, BASIC_CONFIG, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.QUERY", "payload": { "devices": [{ "id": "light.demo_light", }, { "id": "light.another_light", }, { "id": "light.non_existing", }] } }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'devices': { 'light.non_existing': { 'online': False, }, 'light.demo_light': { 'on': False, 'online': True, }, 'light.another_light': { 'on': True, 'online': True, 'brightness': 30, 'color': { 'spectrumHsv': { 'hue': 180, 'saturation': 0.75, 'value': 0.3058823529411765, }, 'temperatureK': 2500, } }, } } } assert len(events) == 3 assert events[0].event_type == EVENT_QUERY_RECEIVED assert events[0].data == { 'request_id': REQ_ID, 'entity_id': 'light.demo_light' } assert events[1].event_type == EVENT_QUERY_RECEIVED assert events[1].data == { 'request_id': REQ_ID, 'entity_id': 'light.another_light' } assert events[2].event_type == EVENT_QUERY_RECEIVED assert events[2].data == { 'request_id': REQ_ID, 'entity_id': 'light.non_existing' }
async def test_sync_message(hass): """Test a sync message.""" light = DemoLight(None, "Demo Light", state=False, hs_color=(180, 75)) light.hass = hass light.entity_id = "light.demo_light" await light.async_update_ha_state() # This should not show up in the sync request hass.states.async_set("sensor.no_match", "something") # Excluded via config hass.states.async_set("light.not_expose", "on") config = MockConfig( should_expose=lambda state: state.entity_id != "light.not_expose", entity_config={ "light.demo_light": { const.CONF_ROOM_HINT: "Living Room", const.CONF_ALIASES: ["Hello", "World"], } }, ) events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, config, "test-agent", {"requestId": REQ_ID, "inputs": [{"intent": "action.devices.SYNC"}]}, ) assert result == { "requestId": REQ_ID, "payload": { "agentUserId": "test-agent", "devices": [ { "id": "light.demo_light", "name": {"name": "Demo Light", "nicknames": ["Hello", "World"]}, "traits": [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SETTING, ], "type": const.TYPE_LIGHT, "willReportState": False, "attributes": { "colorModel": "hsv", "colorTemperatureRange": { "temperatureMinK": 2000, "temperatureMaxK": 6535, }, }, "roomHint": "Living Room", } ], }, } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == {"request_id": REQ_ID}
async def test_sync_in_area(hass, registries): """Test a sync message where room hint comes from area.""" area = registries.area.async_create("Living Room") device = registries.device.async_get_or_create( config_entry_id='1234', connections={ (device_registry.CONNECTION_NETWORK_MAC, '12:34:56:AB:CD:EF') }) registries.device.async_update_device(device.id, area_id=area.id) entity = registries.entity.async_get_or_create( 'light', 'test', '1235', suggested_object_id='demo_light', device_id=device.id) light = DemoLight( None, 'Demo Light', state=False, hs_color=(180, 75), ) light.hass = hass light.entity_id = entity.entity_id await light.async_update_ha_state() config = helpers.Config( should_expose=lambda _: True, allow_unlock=False, entity_config={} ) events = [] hass.bus.async_listen(EVENT_SYNC_RECEIVED, events.append) result = await sh.async_handle_message( hass, config, 'test-agent', { "requestId": REQ_ID, "inputs": [{ "intent": "action.devices.SYNC" }] }) assert result == { 'requestId': REQ_ID, 'payload': { 'agentUserId': 'test-agent', 'devices': [{ 'id': 'light.demo_light', 'name': { 'name': 'Demo Light' }, 'traits': [ trait.TRAIT_BRIGHTNESS, trait.TRAIT_ONOFF, trait.TRAIT_COLOR_SPECTRUM, trait.TRAIT_COLOR_TEMP, ], 'type': sh.TYPE_LIGHT, 'willReportState': False, 'attributes': { 'colorModel': 'rgb', 'temperatureMinK': 2000, 'temperatureMaxK': 6535, }, 'roomHint': 'Living Room' }] } } await hass.async_block_till_done() assert len(events) == 1 assert events[0].event_type == EVENT_SYNC_RECEIVED assert events[0].data == { 'request_id': REQ_ID, }