diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index 5dc11d9b580..a9f49586134 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -55,7 +55,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ): entities.append(DeconzBinarySensor(sensor, gateway)) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index 7cfb716b586..e4de5badb61 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -44,7 +44,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ): entities.append(DeconzThermostat(sensor, gateway)) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( diff --git a/homeassistant/components/deconz/cover.py b/homeassistant/components/deconz/cover.py index d1cd48c47cc..82f471305e9 100644 --- a/homeassistant/components/deconz/cover.py +++ b/homeassistant/components/deconz/cover.py @@ -37,7 +37,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ): entities.append(DeconzCover(light, gateway)) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( diff --git a/homeassistant/components/deconz/light.py b/homeassistant/components/deconz/light.py index cf7007109b3..78ddd83fe4f 100644 --- a/homeassistant/components/deconz/light.py +++ b/homeassistant/components/deconz/light.py @@ -52,7 +52,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ): entities.append(DeconzLight(light, gateway)) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( @@ -77,7 +78,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): if new_group.unique_id not in known_groups: entities.append(new_group) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( diff --git a/homeassistant/components/deconz/scene.py b/homeassistant/components/deconz/scene.py index 2ce3da6c234..9ca7f39f034 100644 --- a/homeassistant/components/deconz/scene.py +++ b/homeassistant/components/deconz/scene.py @@ -18,7 +18,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): """Add scene from deCONZ.""" entities = [DeconzScene(scene, gateway) for scene in scenes] - async_add_entities(entities) + if entities: + async_add_entities(entities) gateway.listeners.append( async_dispatcher_connect( diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index 32dc0ee7ea3..ebc62aee57f 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -108,7 +108,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ): entities.append(DeconzSensor(sensor, gateway)) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( diff --git a/homeassistant/components/deconz/switch.py b/homeassistant/components/deconz/switch.py index af543348a4d..02fa66fc35a 100644 --- a/homeassistant/components/deconz/switch.py +++ b/homeassistant/components/deconz/switch.py @@ -34,7 +34,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): ): entities.append(DeconzSiren(light, gateway)) - async_add_entities(entities, True) + if entities: + async_add_entities(entities, True) gateway.listeners.append( async_dispatcher_connect( diff --git a/tests/components/deconz/test_binary_sensor.py b/tests/components/deconz/test_binary_sensor.py index 8a93c8a5cdb..fdb0b62d5ea 100644 --- a/tests/components/deconz/test_binary_sensor.py +++ b/tests/components/deconz/test_binary_sensor.py @@ -66,8 +66,7 @@ async def test_platform_manually_configured(hass): async def test_no_binary_sensors(hass): """Test that no sensors in deconz results in no sensor entities.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -76,22 +75,13 @@ async def test_binary_sensors(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "binary_sensor.presence_sensor" in gateway.deconz_ids - assert "binary_sensor.temperature_sensor" not in gateway.deconz_ids - assert "binary_sensor.clip_presence_sensor" not in gateway.deconz_ids - assert "binary_sensor.vibration_sensor" in gateway.deconz_ids - assert len(hass.states.async_all()) == 3 + assert len(hass.states.async_all()) == 3 presence_sensor = hass.states.get("binary_sensor.presence_sensor") assert presence_sensor.state == "off" assert presence_sensor.attributes["device_class"] == DEVICE_CLASS_MOTION - - temperature_sensor = hass.states.get("binary_sensor.temperature_sensor") - assert temperature_sensor is None - - clip_presence_sensor = hass.states.get("binary_sensor.clip_presence_sensor") - assert clip_presence_sensor is None - + assert hass.states.get("binary_sensor.temperature_sensor") is None + assert hass.states.get("binary_sensor.clip_presence_sensor") is None vibration_sensor = hass.states.get("binary_sensor.vibration_sensor") assert vibration_sensor.state == "on" assert vibration_sensor.attributes["device_class"] == DEVICE_CLASS_VIBRATION @@ -106,8 +96,7 @@ async def test_binary_sensors(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - presence_sensor = hass.states.get("binary_sensor.presence_sensor") - assert presence_sensor.state == "on" + assert hass.states.get("binary_sensor.presence_sensor").state == "on" await gateway.async_reset() @@ -123,51 +112,38 @@ async def test_allow_clip_sensor(hass): options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True}, get_state_response=data, ) - assert "binary_sensor.presence_sensor" in gateway.deconz_ids - assert "binary_sensor.temperature_sensor" not in gateway.deconz_ids - assert "binary_sensor.clip_presence_sensor" in gateway.deconz_ids - assert "binary_sensor.vibration_sensor" in gateway.deconz_ids + assert len(hass.states.async_all()) == 4 + assert hass.states.get("binary_sensor.presence_sensor").state == "off" + assert hass.states.get("binary_sensor.temperature_sensor") is None + assert hass.states.get("binary_sensor.clip_presence_sensor").state == "off" + assert hass.states.get("binary_sensor.vibration_sensor").state == "on" - presence_sensor = hass.states.get("binary_sensor.presence_sensor") - assert presence_sensor.state == "off" - - temperature_sensor = hass.states.get("binary_sensor.temperature_sensor") - assert temperature_sensor is None - - clip_presence_sensor = hass.states.get("binary_sensor.clip_presence_sensor") - assert clip_presence_sensor.state == "off" - - vibration_sensor = hass.states.get("binary_sensor.vibration_sensor") - assert vibration_sensor.state == "on" + # Disallow clip sensors hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: False} ) await hass.async_block_till_done() - assert "binary_sensor.presence_sensor" in gateway.deconz_ids - assert "binary_sensor.temperature_sensor" not in gateway.deconz_ids - assert "binary_sensor.clip_presence_sensor" not in gateway.deconz_ids - assert "binary_sensor.vibration_sensor" in gateway.deconz_ids assert len(hass.states.async_all()) == 3 + assert hass.states.get("binary_sensor.clip_presence_sensor") is None + + # Allow clip sensors hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True} ) await hass.async_block_till_done() - assert "binary_sensor.presence_sensor" in gateway.deconz_ids - assert "binary_sensor.temperature_sensor" not in gateway.deconz_ids - assert "binary_sensor.clip_presence_sensor" in gateway.deconz_ids - assert "binary_sensor.vibration_sensor" in gateway.deconz_ids assert len(hass.states.async_all()) == 4 + assert hass.states.get("binary_sensor.clip_presence_sensor").state == "off" async def test_add_new_binary_sensor(hass): """Test that adding a new binary sensor works.""" gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + assert len(hass.states.async_all()) == 0 state_added_event = { "t": "event", @@ -179,10 +155,8 @@ async def test_add_new_binary_sensor(hass): gateway.api.event_handler(state_added_event) await hass.async_block_till_done() - assert "binary_sensor.presence_sensor" in gateway.deconz_ids - - presence_sensor = hass.states.get("binary_sensor.presence_sensor") - assert presence_sensor.state == "off" + assert len(hass.states.async_all()) == 1 + assert hass.states.get("binary_sensor.presence_sensor").state == "off" async def test_add_new_binary_sensor_ignored(hass): diff --git a/tests/components/deconz/test_climate.py b/tests/components/deconz/test_climate.py index ddc89295cba..bc6bc9415f3 100644 --- a/tests/components/deconz/test_climate.py +++ b/tests/components/deconz/test_climate.py @@ -25,14 +25,6 @@ SENSORS = { "uniqueid": "00:00:00:00:00:00:00:00-00", }, "2": { - "id": "Presence sensor id", - "name": "Presence sensor", - "type": "ZHAPresence", - "state": {"presence": False}, - "config": {"reachable": True}, - "uniqueid": "00:00:00:00:00:00:00:01-00", - }, - "3": { "id": "CLIP thermostat id", "name": "CLIP thermostat", "type": "CLIPThermostat", @@ -56,8 +48,7 @@ async def test_platform_manually_configured(hass): async def test_no_sensors(hass): """Test that no sensors in deconz results in no climate entities.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -66,27 +57,15 @@ async def test_climate_devices(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "climate.thermostat" in gateway.deconz_ids - assert "sensor.thermostat" not in gateway.deconz_ids - assert "sensor.thermostat_battery_level" in gateway.deconz_ids - assert "climate.presence_sensor" not in gateway.deconz_ids - assert "climate.clip_thermostat" not in gateway.deconz_ids - assert len(hass.states.async_all()) == 3 - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "auto" + assert len(hass.states.async_all()) == 2 + assert hass.states.get("climate.thermostat").state == "auto" + assert hass.states.get("sensor.thermostat") is None + assert hass.states.get("sensor.thermostat_battery_level").state == "100" + assert hass.states.get("climate.presence_sensor") is None + assert hass.states.get("climate.clip_thermostat") is None - thermostat = hass.states.get("sensor.thermostat") - assert thermostat is None - - thermostat_battery_level = hass.states.get("sensor.thermostat_battery_level") - assert thermostat_battery_level.state == "100" - - presence_sensor = hass.states.get("climate.presence_sensor") - assert presence_sensor is None - - clip_thermostat = hass.states.get("climate.clip_thermostat") - assert clip_thermostat is None + # Event signals thermostat configured off state_changed_event = { "t": "event", @@ -98,8 +77,9 @@ async def test_climate_devices(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "off" + assert hass.states.get("climate.thermostat").state == "off" + + # Event signals thermostat state on state_changed_event = { "t": "event", @@ -112,8 +92,9 @@ async def test_climate_devices(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "heat" + assert hass.states.get("climate.thermostat").state == "heat" + + # Event signals thermostat state off state_changed_event = { "t": "event", @@ -125,13 +106,14 @@ async def test_climate_devices(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "off" + assert hass.states.get("climate.thermostat").state == "off" # Verify service calls thermostat_device = gateway.api.sensors["1"] + # Service set HVAC mode to auto + with patch.object(thermostat_device, "_request", return_value=True) as set_callback: await hass.services.async_call( climate.DOMAIN, @@ -144,6 +126,8 @@ async def test_climate_devices(hass): "put", "/sensors/1/config", json={"mode": "auto"} ) + # Service set HVAC mode to heat + with patch.object(thermostat_device, "_request", return_value=True) as set_callback: await hass.services.async_call( climate.DOMAIN, @@ -156,6 +140,8 @@ async def test_climate_devices(hass): "put", "/sensors/1/config", json={"mode": "heat"} ) + # Service set HVAC mode to off + with patch.object(thermostat_device, "_request", return_value=True) as set_callback: await hass.services.async_call( climate.DOMAIN, @@ -167,6 +153,8 @@ async def test_climate_devices(hass): "put", "/sensors/1/config", json={"mode": "off"} ) + # Service set temperature to 20 + with patch.object(thermostat_device, "_request", return_value=True) as set_callback: await hass.services.async_call( climate.DOMAIN, @@ -192,51 +180,32 @@ async def test_clip_climate_device(hass): options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True}, get_state_response=data, ) - assert "climate.thermostat" in gateway.deconz_ids - assert "sensor.thermostat" not in gateway.deconz_ids - assert "sensor.thermostat_battery_level" in gateway.deconz_ids - assert "climate.presence_sensor" not in gateway.deconz_ids - assert "climate.clip_thermostat" in gateway.deconz_ids - assert len(hass.states.async_all()) == 4 - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "auto" + assert len(hass.states.async_all()) == 3 + assert hass.states.get("climate.thermostat").state == "auto" + assert hass.states.get("sensor.thermostat") is None + assert hass.states.get("sensor.thermostat_battery_level").state == "100" + assert hass.states.get("climate.clip_thermostat").state == "heat" - thermostat = hass.states.get("sensor.thermostat") - assert thermostat is None - - thermostat_battery_level = hass.states.get("sensor.thermostat_battery_level") - assert thermostat_battery_level.state == "100" - - presence_sensor = hass.states.get("climate.presence_sensor") - assert presence_sensor is None - - clip_thermostat = hass.states.get("climate.clip_thermostat") - assert clip_thermostat.state == "heat" + # Disallow clip sensors hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: False} ) await hass.async_block_till_done() - assert "climate.thermostat" in gateway.deconz_ids - assert "sensor.thermostat" not in gateway.deconz_ids - assert "sensor.thermostat_battery_level" in gateway.deconz_ids - assert "climate.presence_sensor" not in gateway.deconz_ids - assert "climate.clip_thermostat" not in gateway.deconz_ids - assert len(hass.states.async_all()) == 3 + assert len(hass.states.async_all()) == 2 + assert hass.states.get("climate.clip_thermostat") is None + + # Allow clip sensors hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True} ) await hass.async_block_till_done() - assert "climate.thermostat" in gateway.deconz_ids - assert "sensor.thermostat" not in gateway.deconz_ids - assert "sensor.thermostat_battery_level" in gateway.deconz_ids - assert "climate.presence_sensor" not in gateway.deconz_ids - assert "climate.clip_thermostat" in gateway.deconz_ids - assert len(hass.states.async_all()) == 4 + assert len(hass.states.async_all()) == 3 + assert hass.states.get("climate.clip_thermostat").state == "heat" async def test_verify_state_update(hass): @@ -244,10 +213,8 @@ async def test_verify_state_update(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "climate.thermostat" in gateway.deconz_ids - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "auto" + assert hass.states.get("climate.thermostat").state == "auto" state_changed_event = { "t": "event", @@ -259,15 +226,14 @@ async def test_verify_state_update(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "auto" + assert hass.states.get("climate.thermostat").state == "auto" assert gateway.api.sensors["1"].changed_keys == {"state", "r", "t", "on", "e", "id"} async def test_add_new_climate_device(hass): """Test that adding a new climate device works.""" gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + assert len(hass.states.async_all()) == 0 state_added_event = { "t": "event", @@ -279,7 +245,6 @@ async def test_add_new_climate_device(hass): gateway.api.event_handler(state_added_event) await hass.async_block_till_done() - assert "climate.thermostat" in gateway.deconz_ids - - thermostat = hass.states.get("climate.thermostat") - assert thermostat.state == "auto" + assert len(hass.states.async_all()) == 2 + assert hass.states.get("climate.thermostat").state == "auto" + assert hass.states.get("sensor.thermostat_battery_level").state == "100" diff --git a/tests/components/deconz/test_cover.py b/tests/components/deconz/test_cover.py index 095ae7e4bc5..9e294c09cf2 100644 --- a/tests/components/deconz/test_cover.py +++ b/tests/components/deconz/test_cover.py @@ -65,8 +65,7 @@ async def test_platform_manually_configured(hass): async def test_no_covers(hass): """Test that no cover entities are created.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -75,15 +74,15 @@ async def test_cover(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["lights"] = deepcopy(COVERS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "cover.level_controllable_cover" in gateway.deconz_ids - assert "cover.window_covering_device" in gateway.deconz_ids - assert "cover.unsupported_cover" not in gateway.deconz_ids - assert "cover.deconz_old_brightness_cover" in gateway.deconz_ids - assert "cover.window_covering_controller" in gateway.deconz_ids - assert len(hass.states.async_all()) == 5 - level_controllable_cover = hass.states.get("cover.level_controllable_cover") - assert level_controllable_cover.state == "open" + assert len(hass.states.async_all()) == 5 + assert hass.states.get("cover.level_controllable_cover").state == "open" + assert hass.states.get("cover.window_covering_device").state == "closed" + assert hass.states.get("cover.unsupported_cover") is None + assert hass.states.get("cover.deconz_old_brightness_cover").state == "open" + assert hass.states.get("cover.window_covering_controller").state == "closed" + + # Event signals cover is closed state_changed_event = { "t": "event", @@ -95,11 +94,14 @@ async def test_cover(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - level_controllable_cover = hass.states.get("cover.level_controllable_cover") - assert level_controllable_cover.state == "closed" + assert hass.states.get("cover.level_controllable_cover").state == "closed" + + # Verify service calls level_controllable_cover_device = gateway.api.lights["1"] + # Service open cover + with patch.object( level_controllable_cover_device, "_request", return_value=True ) as set_callback: @@ -112,6 +114,8 @@ async def test_cover(hass): await hass.async_block_till_done() set_callback.assert_called_with("put", "/lights/1/state", json={"on": False}) + # Service close cover + with patch.object( level_controllable_cover_device, "_request", return_value=True ) as set_callback: @@ -126,6 +130,8 @@ async def test_cover(hass): "put", "/lights/1/state", json={"on": True, "bri": 254} ) + # Service stop cover movement + with patch.object( level_controllable_cover_device, "_request", return_value=True ) as set_callback: @@ -139,8 +145,7 @@ async def test_cover(hass): set_callback.assert_called_with("put", "/lights/1/state", json={"bri_inc": 0}) # Test that a reported cover position of 255 (deconz-rest-api < 2.05.73) is interpreted correctly. - deconz_old_brightness_cover = hass.states.get("cover.deconz_old_brightness_cover") - assert deconz_old_brightness_cover.state == "open" + assert hass.states.get("cover.deconz_old_brightness_cover").state == "open" state_changed_event = { "t": "event", @@ -153,6 +158,7 @@ async def test_cover(hass): await hass.async_block_till_done() deconz_old_brightness_cover = hass.states.get("cover.deconz_old_brightness_cover") + assert deconz_old_brightness_cover.state == "closed" assert deconz_old_brightness_cover.attributes["current_position"] == 0 await gateway.async_reset() diff --git a/tests/components/deconz/test_deconz_event.py b/tests/components/deconz/test_deconz_event.py index 525821e389f..e7e584af679 100644 --- a/tests/components/deconz/test_deconz_event.py +++ b/tests/components/deconz/test_deconz_event.py @@ -56,24 +56,13 @@ async def test_deconz_events(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "sensor.switch_1" not in gateway.deconz_ids - assert "sensor.switch_1_battery_level" not in gateway.deconz_ids - assert "sensor.switch_2" not in gateway.deconz_ids - assert "sensor.switch_2_battery_level" in gateway.deconz_ids + assert len(hass.states.async_all()) == 3 assert len(gateway.events) == 5 - - switch_1 = hass.states.get("sensor.switch_1") - assert switch_1 is None - - switch_1_battery_level = hass.states.get("sensor.switch_1_battery_level") - assert switch_1_battery_level is None - - switch_2 = hass.states.get("sensor.switch_2") - assert switch_2 is None - - switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level") - assert switch_2_battery_level.state == "100" + assert hass.states.get("sensor.switch_1") is None + assert hass.states.get("sensor.switch_1_battery_level") is None + assert hass.states.get("sensor.switch_2") is None + assert hass.states.get("sensor.switch_2_battery_level").state == "100" events = async_capture_events(hass, CONF_DECONZ_EVENT) diff --git a/tests/components/deconz/test_light.py b/tests/components/deconz/test_light.py index 4e9f6b3d512..e2adf45d9f2 100644 --- a/tests/components/deconz/test_light.py +++ b/tests/components/deconz/test_light.py @@ -92,8 +92,7 @@ async def test_platform_manually_configured(hass): async def test_no_lights_or_groups(hass): """Test that no lights or groups entities are created.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -103,12 +102,6 @@ async def test_lights_and_groups(hass): data["groups"] = deepcopy(GROUPS) data["lights"] = deepcopy(LIGHTS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "light.rgb_light" in gateway.deconz_ids - assert "light.tunable_white_light" in gateway.deconz_ids - assert "light.light_group" in gateway.deconz_ids - assert "light.empty_group" not in gateway.deconz_ids - assert "light.on_off_switch" not in gateway.deconz_ids - assert "light.on_off_light" in gateway.deconz_ids assert len(hass.states.async_all()) == 6 @@ -159,8 +152,12 @@ async def test_lights_and_groups(hass): rgb_light = hass.states.get("light.rgb_light") assert rgb_light.state == "off" + # Verify service calls + rgb_light_device = gateway.api.lights["1"] + # Service turn on light with short color loop + with patch.object(rgb_light_device, "_request", return_value=True) as set_callback: await hass.services.async_call( light.DOMAIN, @@ -188,6 +185,8 @@ async def test_lights_and_groups(hass): }, ) + # Service turn on light disabling color loop with long flashing + with patch.object(rgb_light_device, "_request", return_value=True) as set_callback: await hass.services.async_call( light.DOMAIN, @@ -207,6 +206,8 @@ async def test_lights_and_groups(hass): json={"xy": (0.411, 0.351), "alert": "lselect", "effect": "none"}, ) + # Service turn on light with short flashing + with patch.object(rgb_light_device, "_request", return_value=True) as set_callback: await hass.services.async_call( light.DOMAIN, @@ -227,6 +228,8 @@ async def test_lights_and_groups(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() + # Service turn off light with short flashing + with patch.object(rgb_light_device, "_request", return_value=True) as set_callback: await hass.services.async_call( light.DOMAIN, @@ -241,6 +244,8 @@ async def test_lights_and_groups(hass): json={"bri": 0, "transitiontime": 50, "alert": "select"}, ) + # Service turn off light with long flashing + with patch.object(rgb_light_device, "_request", return_value=True) as set_callback: await hass.services.async_call( light.DOMAIN, @@ -259,7 +264,7 @@ async def test_lights_and_groups(hass): async def test_disable_light_groups(hass): - """Test successful creation of sensor entities.""" + """Test disallowing light groups work.""" data = deepcopy(DECONZ_WEB_REQUEST) data["groups"] = deepcopy(GROUPS) data["lights"] = deepcopy(LIGHTS) @@ -268,48 +273,25 @@ async def test_disable_light_groups(hass): options={deconz.gateway.CONF_ALLOW_DECONZ_GROUPS: False}, get_state_response=data, ) - assert "light.rgb_light" in gateway.deconz_ids - assert "light.tunable_white_light" in gateway.deconz_ids - assert "light.light_group" not in gateway.deconz_ids - assert "light.empty_group" not in gateway.deconz_ids - assert "light.on_off_switch" not in gateway.deconz_ids - # 3 entities + assert len(hass.states.async_all()) == 5 - - rgb_light = hass.states.get("light.rgb_light") - assert rgb_light is not None - - tunable_white_light = hass.states.get("light.tunable_white_light") - assert tunable_white_light is not None - - light_group = hass.states.get("light.light_group") - assert light_group is None - - empty_group = hass.states.get("light.empty_group") - assert empty_group is None + assert hass.states.get("light.rgb_light") + assert hass.states.get("light.tunable_white_light") + assert hass.states.get("light.light_group") is None + assert hass.states.get("light.empty_group") is None hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_DECONZ_GROUPS: True} ) await hass.async_block_till_done() - assert "light.rgb_light" in gateway.deconz_ids - assert "light.tunable_white_light" in gateway.deconz_ids - assert "light.light_group" in gateway.deconz_ids - assert "light.empty_group" not in gateway.deconz_ids - assert "light.on_off_switch" not in gateway.deconz_ids - # 3 entities assert len(hass.states.async_all()) == 6 + assert hass.states.get("light.light_group") hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_DECONZ_GROUPS: False} ) await hass.async_block_till_done() - assert "light.rgb_light" in gateway.deconz_ids - assert "light.tunable_white_light" in gateway.deconz_ids - assert "light.light_group" not in gateway.deconz_ids - assert "light.empty_group" not in gateway.deconz_ids - assert "light.on_off_switch" not in gateway.deconz_ids - # 3 entities assert len(hass.states.async_all()) == 5 + assert hass.states.get("light.light_group") is None diff --git a/tests/components/deconz/test_lock.py b/tests/components/deconz/test_lock.py index 554f825d42a..3452dcaa0ff 100644 --- a/tests/components/deconz/test_lock.py +++ b/tests/components/deconz/test_lock.py @@ -40,8 +40,7 @@ async def test_platform_manually_configured(hass): async def test_no_locks(hass): """Test that no lock entities are created.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -50,8 +49,9 @@ async def test_locks(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["lights"] = deepcopy(LOCKS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "lock.door_lock" in gateway.deconz_ids + assert len(hass.states.async_all()) == 1 + assert hass.states.get("lock.door_lock").state == STATE_UNLOCKED door_lock = hass.states.get("lock.door_lock") assert door_lock.state == STATE_UNLOCKED @@ -66,11 +66,14 @@ async def test_locks(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - door_lock = hass.states.get("lock.door_lock") - assert door_lock.state == STATE_LOCKED + assert hass.states.get("lock.door_lock").state == STATE_LOCKED + + # Verify service calls door_lock_device = gateway.api.lights["1"] + # Service lock door + with patch.object(door_lock_device, "_request", return_value=True) as set_callback: await hass.services.async_call( lock.DOMAIN, @@ -81,6 +84,8 @@ async def test_locks(hass): await hass.async_block_till_done() set_callback.assert_called_with("put", "/lights/1/state", json={"on": True}) + # Service unlock door + with patch.object(door_lock_device, "_request", return_value=True) as set_callback: await hass.services.async_call( lock.DOMAIN, diff --git a/tests/components/deconz/test_scene.py b/tests/components/deconz/test_scene.py index 538c849e831..fa1d02a4ce6 100644 --- a/tests/components/deconz/test_scene.py +++ b/tests/components/deconz/test_scene.py @@ -35,8 +35,7 @@ async def test_platform_manually_configured(hass): async def test_no_scenes(hass): """Test that scenes can be loaded without scenes being available.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -46,14 +45,15 @@ async def test_scenes(hass): data["groups"] = deepcopy(GROUPS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "scene.light_group_scene" in gateway.deconz_ids assert len(hass.states.async_all()) == 1 + assert hass.states.get("scene.light_group_scene") - light_group_scene = hass.states.get("scene.light_group_scene") - assert light_group_scene + # Verify service calls group_scene = gateway.api.groups["1"].scenes["1"] + # Service turn on scene + with patch.object(group_scene, "_request", return_value=True) as set_callback: await hass.services.async_call( "scene", "turn_on", {"entity_id": "scene.light_group_scene"}, blocking=True diff --git a/tests/components/deconz/test_sensor.py b/tests/components/deconz/test_sensor.py index 9d87c7b91cb..31799e2519a 100644 --- a/tests/components/deconz/test_sensor.py +++ b/tests/components/deconz/test_sensor.py @@ -93,8 +93,7 @@ async def test_platform_manually_configured(hass): async def test_no_sensors(hass): """Test that no sensors in deconz results in no sensor entities.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 @@ -103,40 +102,23 @@ async def test_sensors(hass): data = deepcopy(DECONZ_WEB_REQUEST) data["sensors"] = deepcopy(SENSORS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "sensor.light_level_sensor" in gateway.deconz_ids - assert "sensor.presence_sensor" not in gateway.deconz_ids - assert "sensor.switch_1" not in gateway.deconz_ids - assert "sensor.switch_1_battery_level" not in gateway.deconz_ids - assert "sensor.switch_2" not in gateway.deconz_ids - assert "sensor.switch_2_battery_level" in gateway.deconz_ids - assert "sensor.daylight_sensor" not in gateway.deconz_ids - assert "sensor.power_sensor" in gateway.deconz_ids - assert "sensor.consumption_sensor" in gateway.deconz_ids - assert "sensor.clip_light_level_sensor" not in gateway.deconz_ids + assert len(hass.states.async_all()) == 5 light_level_sensor = hass.states.get("sensor.light_level_sensor") assert light_level_sensor.state == "999.8" assert light_level_sensor.attributes["device_class"] == DEVICE_CLASS_ILLUMINANCE - presence_sensor = hass.states.get("sensor.presence_sensor") - assert presence_sensor is None - - switch_1 = hass.states.get("sensor.switch_1") - assert switch_1 is None - - switch_1_battery_level = hass.states.get("sensor.switch_1_battery_level") - assert switch_1_battery_level is None - - switch_2 = hass.states.get("sensor.switch_2") - assert switch_2 is None + assert hass.states.get("sensor.presence_sensor") is None + assert hass.states.get("sensor.switch_1") is None + assert hass.states.get("sensor.switch_1_battery_level") is None + assert hass.states.get("sensor.switch_2") is None switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level") assert switch_2_battery_level.state == "100" assert switch_2_battery_level.attributes["device_class"] == DEVICE_CLASS_BATTERY - daylight_sensor = hass.states.get("sensor.daylight_sensor") - assert daylight_sensor is None + assert hass.states.get("sensor.daylight_sensor") is None power_sensor = hass.states.get("sensor.power_sensor") assert power_sensor.state == "6" @@ -146,6 +128,10 @@ async def test_sensors(hass): assert consumption_sensor.state == "0.002" assert "device_class" not in consumption_sensor.attributes + assert hass.states.get("sensor.clip_light_level_sensor") is None + + # Event signals new light level + state_changed_event = { "t": "event", "e": "changed", @@ -155,6 +141,10 @@ async def test_sensors(hass): } gateway.api.event_handler(state_changed_event) + assert hass.states.get("sensor.light_level_sensor").state == "1.6" + + # Event signals new battery level + state_changed_event = { "t": "event", "e": "changed", @@ -165,11 +155,7 @@ async def test_sensors(hass): gateway.api.event_handler(state_changed_event) await hass.async_block_till_done() - light_level_sensor = hass.states.get("sensor.light_level_sensor") - assert light_level_sensor.state == "1.6" - - switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level") - assert switch_2_battery_level.state == "75" + assert hass.states.get("sensor.switch_2_battery_level").state == "75" await gateway.async_reset() @@ -185,87 +171,35 @@ async def test_allow_clip_sensors(hass): options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True}, get_state_response=data, ) - assert "sensor.light_level_sensor" in gateway.deconz_ids - assert "sensor.presence_sensor" not in gateway.deconz_ids - assert "sensor.switch_1" not in gateway.deconz_ids - assert "sensor.switch_1_battery_level" not in gateway.deconz_ids - assert "sensor.switch_2" not in gateway.deconz_ids - assert "sensor.switch_2_battery_level" in gateway.deconz_ids - assert "sensor.daylight_sensor" not in gateway.deconz_ids - assert "sensor.power_sensor" in gateway.deconz_ids - assert "sensor.consumption_sensor" in gateway.deconz_ids - assert "sensor.clip_light_level_sensor" in gateway.deconz_ids + assert len(hass.states.async_all()) == 6 + assert hass.states.get("sensor.clip_light_level_sensor").state == "999.8" - light_level_sensor = hass.states.get("sensor.light_level_sensor") - assert light_level_sensor.state == "999.8" - - presence_sensor = hass.states.get("sensor.presence_sensor") - assert presence_sensor is None - - switch_1 = hass.states.get("sensor.switch_1") - assert switch_1 is None - - switch_1_battery_level = hass.states.get("sensor.switch_1_battery_level") - assert switch_1_battery_level is None - - switch_2 = hass.states.get("sensor.switch_2") - assert switch_2 is None - - switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level") - assert switch_2_battery_level.state == "100" - - daylight_sensor = hass.states.get("sensor.daylight_sensor") - assert daylight_sensor is None - - power_sensor = hass.states.get("sensor.power_sensor") - assert power_sensor.state == "6" - - consumption_sensor = hass.states.get("sensor.consumption_sensor") - assert consumption_sensor.state == "0.002" - - clip_light_level_sensor = hass.states.get("sensor.clip_light_level_sensor") - assert clip_light_level_sensor.state == "999.8" + # Disallow clip sensors hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: False} ) await hass.async_block_till_done() - assert "sensor.light_level_sensor" in gateway.deconz_ids - assert "sensor.presence_sensor" not in gateway.deconz_ids - assert "sensor.switch_1" not in gateway.deconz_ids - assert "sensor.switch_1_battery_level" not in gateway.deconz_ids - assert "sensor.switch_2" not in gateway.deconz_ids - assert "sensor.switch_2_battery_level" in gateway.deconz_ids - assert "sensor.daylight_sensor" not in gateway.deconz_ids - assert "sensor.power_sensor" in gateway.deconz_ids - assert "sensor.consumption_sensor" in gateway.deconz_ids - assert "sensor.clip_light_level_sensor" not in gateway.deconz_ids assert len(hass.states.async_all()) == 5 + assert hass.states.get("sensor.clip_light_level_sensor") is None + + # Allow clip sensors hass.config_entries.async_update_entry( gateway.config_entry, options={deconz.gateway.CONF_ALLOW_CLIP_SENSOR: True} ) await hass.async_block_till_done() - assert "sensor.light_level_sensor" in gateway.deconz_ids - assert "sensor.presence_sensor" not in gateway.deconz_ids - assert "sensor.switch_1" not in gateway.deconz_ids - assert "sensor.switch_1_battery_level" not in gateway.deconz_ids - assert "sensor.switch_2" not in gateway.deconz_ids - assert "sensor.switch_2_battery_level" in gateway.deconz_ids - assert "sensor.daylight_sensor" not in gateway.deconz_ids - assert "sensor.power_sensor" in gateway.deconz_ids - assert "sensor.consumption_sensor" in gateway.deconz_ids - assert "sensor.clip_light_level_sensor" in gateway.deconz_ids assert len(hass.states.async_all()) == 6 + assert hass.states.get("sensor.clip_light_level_sensor") async def test_add_new_sensor(hass): """Test that adding a new sensor works.""" gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + assert len(hass.states.async_all()) == 0 state_added_event = { "t": "event", @@ -277,10 +211,8 @@ async def test_add_new_sensor(hass): gateway.api.event_handler(state_added_event) await hass.async_block_till_done() - assert "sensor.light_level_sensor" in gateway.deconz_ids - - light_level_sensor = hass.states.get("sensor.light_level_sensor") - assert light_level_sensor.state == "999.8" + assert len(hass.states.async_all()) == 1 + assert hass.states.get("sensor.light_level_sensor").state == "999.8" async def test_add_battery_later(hass): @@ -289,16 +221,16 @@ async def test_add_battery_later(hass): data["sensors"] = {"1": deepcopy(SENSORS["3"])} gateway = await setup_deconz_integration(hass, get_state_response=data) remote = gateway.api.sensors["1"] - assert len(gateway.deconz_ids) == 0 + + assert len(hass.states.async_all()) == 0 assert len(gateway.events) == 1 - assert len(remote._callbacks) == 2 + assert len(remote._callbacks) == 2 # Event and battery tracker remote.update({"config": {"battery": 50}}) await hass.async_block_till_done() - assert len(gateway.deconz_ids) == 1 + assert len(hass.states.async_all()) == 1 assert len(gateway.events) == 1 - assert len(remote._callbacks) == 2 + assert len(remote._callbacks) == 2 # Event and battery entity - battery_sensor = hass.states.get("sensor.switch_1_battery_level") - assert battery_sensor is not None + assert hass.states.get("sensor.switch_1_battery_level") diff --git a/tests/components/deconz/test_switch.py b/tests/components/deconz/test_switch.py index b441868859b..f83a3273a0c 100644 --- a/tests/components/deconz/test_switch.py +++ b/tests/components/deconz/test_switch.py @@ -9,7 +9,7 @@ from .test_gateway import DECONZ_WEB_REQUEST, setup_deconz_integration from tests.async_mock import patch -SWITCHES = { +POWER_PLUGS = { "1": { "id": "On off switch id", "name": "On off switch", @@ -25,20 +25,13 @@ SWITCHES = { "uniqueid": "00:00:00:00:00:00:00:01-00", }, "3": { - "id": "Warning device id", - "name": "Warning device", - "type": "Warning device", - "state": {"alert": "lselect", "reachable": True}, - "uniqueid": "00:00:00:00:00:00:00:02-00", - }, - "4": { "id": "Unsupported switch id", "name": "Unsupported switch", - "type": "Not a smart plug", + "type": "Not a switch", "state": {"reachable": True}, "uniqueid": "00:00:00:00:00:00:00:03-00", }, - "5": { + "4": { "id": "On off relay id", "name": "On off relay", "state": {"on": True, "reachable": True}, @@ -47,6 +40,23 @@ SWITCHES = { }, } +SIRENS = { + "1": { + "id": "Warning device id", + "name": "Warning device", + "type": "Warning device", + "state": {"alert": "lselect", "reachable": True}, + "uniqueid": "00:00:00:00:00:00:00:00-00", + }, + "2": { + "id": "Unsupported switch id", + "name": "Unsupported switch", + "type": "Not a switch", + "state": {"reachable": True}, + "uniqueid": "00:00:00:00:00:00:00:01-00", + }, +} + async def test_platform_manually_configured(hass): """Test that we do not discover anything or try to set up a gateway.""" @@ -61,34 +71,21 @@ async def test_platform_manually_configured(hass): async def test_no_switches(hass): """Test that no switch entities are created.""" - gateway = await setup_deconz_integration(hass) - assert len(gateway.deconz_ids) == 0 + await setup_deconz_integration(hass) assert len(hass.states.async_all()) == 0 -async def test_switches(hass): +async def test_power_plugs(hass): """Test that all supported switch entities are created.""" data = deepcopy(DECONZ_WEB_REQUEST) - data["lights"] = deepcopy(SWITCHES) + data["lights"] = deepcopy(POWER_PLUGS) gateway = await setup_deconz_integration(hass, get_state_response=data) - assert "switch.on_off_switch" in gateway.deconz_ids - assert "switch.smart_plug" in gateway.deconz_ids - assert "switch.warning_device" in gateway.deconz_ids - assert "switch.unsupported_switch" not in gateway.deconz_ids - assert "switch.on_off_relay" in gateway.deconz_ids - assert len(hass.states.async_all()) == 5 - on_off_switch = hass.states.get("switch.on_off_switch") - assert on_off_switch.state == "on" - - smart_plug = hass.states.get("switch.smart_plug") - assert smart_plug.state == "off" - - warning_device = hass.states.get("switch.warning_device") - assert warning_device.state == "on" - - on_off_relay = hass.states.get("switch.on_off_relay") - assert on_off_relay.state == "on" + assert len(hass.states.async_all()) == 4 + assert hass.states.get("switch.on_off_switch").state == "on" + assert hass.states.get("switch.smart_plug").state == "off" + assert hass.states.get("switch.on_off_relay").state == "on" + assert hass.states.get("switch.unsupported_switch") is None state_changed_event = { "t": "event", @@ -98,24 +95,15 @@ async def test_switches(hass): "state": {"on": False}, } gateway.api.event_handler(state_changed_event) - state_changed_event = { - "t": "event", - "e": "changed", - "r": "lights", - "id": "3", - "state": {"alert": None}, - } - gateway.api.event_handler(state_changed_event) - await hass.async_block_till_done() - on_off_switch = hass.states.get("switch.on_off_switch") - assert on_off_switch.state == "off" + assert hass.states.get("switch.on_off_switch").state == "off" - warning_device = hass.states.get("switch.warning_device") - assert warning_device.state == "off" + # Verify service calls on_off_switch_device = gateway.api.lights["1"] + # Service turn on power plug + with patch.object( on_off_switch_device, "_request", return_value=True ) as set_callback: @@ -128,6 +116,8 @@ async def test_switches(hass): await hass.async_block_till_done() set_callback.assert_called_with("put", "/lights/1/state", json={"on": True}) + # Service turn off power plug + with patch.object( on_off_switch_device, "_request", return_value=True ) as set_callback: @@ -140,7 +130,37 @@ async def test_switches(hass): await hass.async_block_till_done() set_callback.assert_called_with("put", "/lights/1/state", json={"on": False}) - warning_device_device = gateway.api.lights["3"] + await gateway.async_reset() + + assert len(hass.states.async_all()) == 0 + + +async def test_sirens(hass): + """Test that siren entities are created.""" + data = deepcopy(DECONZ_WEB_REQUEST) + data["lights"] = deepcopy(SIRENS) + gateway = await setup_deconz_integration(hass, get_state_response=data) + + assert len(hass.states.async_all()) == 2 + assert hass.states.get("switch.warning_device").state == "on" + assert hass.states.get("switch.unsupported_switch") is None + + state_changed_event = { + "t": "event", + "e": "changed", + "r": "lights", + "id": "1", + "state": {"alert": None}, + } + gateway.api.event_handler(state_changed_event) + + assert hass.states.get("switch.warning_device").state == "off" + + # Verify service calls + + warning_device_device = gateway.api.lights["1"] + + # Service turn on siren with patch.object( warning_device_device, "_request", return_value=True @@ -153,9 +173,11 @@ async def test_switches(hass): ) await hass.async_block_till_done() set_callback.assert_called_with( - "put", "/lights/3/state", json={"alert": "lselect"} + "put", "/lights/1/state", json={"alert": "lselect"} ) + # Service turn off siren + with patch.object( warning_device_device, "_request", return_value=True ) as set_callback: @@ -167,7 +189,7 @@ async def test_switches(hass): ) await hass.async_block_till_done() set_callback.assert_called_with( - "put", "/lights/3/state", json={"alert": "none"} + "put", "/lights/1/state", json={"alert": "none"} ) await gateway.async_reset()