예제 #1
0
async def test_activated_event(opp, mock_litejet):
    """Test handling an event from LiteJet."""

    await async_init_integration(opp)

    # Light 1
    mock_litejet.get_load_level.return_value = 99
    mock_litejet.get_load_level.reset_mock()
    mock_litejet.load_activated_callbacks[ENTITY_LIGHT_NUMBER]()
    await opp.async_block_till_done()

    mock_litejet.get_load_level.assert_called_once_with(ENTITY_LIGHT_NUMBER)

    assert light.is_on(opp, ENTITY_LIGHT)
    assert not light.is_on(opp, ENTITY_OTHER_LIGHT)
    assert opp.states.get(ENTITY_LIGHT).state == "on"
    assert opp.states.get(ENTITY_OTHER_LIGHT).state == "off"
    assert opp.states.get(ENTITY_LIGHT).attributes.get(ATTR_BRIGHTNESS) == 255

    # Light 2

    mock_litejet.get_load_level.return_value = 40
    mock_litejet.get_load_level.reset_mock()
    mock_litejet.load_activated_callbacks[ENTITY_OTHER_LIGHT_NUMBER]()
    await opp.async_block_till_done()

    mock_litejet.get_load_level.assert_called_once_with(ENTITY_OTHER_LIGHT_NUMBER)

    assert light.is_on(opp, ENTITY_LIGHT)
    assert light.is_on(opp, ENTITY_OTHER_LIGHT)
    assert opp.states.get(ENTITY_LIGHT).state == "on"
    assert opp.states.get(ENTITY_OTHER_LIGHT).state == "on"
    assert (
        int(opp.states.get(ENTITY_OTHER_LIGHT).attributes.get(ATTR_BRIGHTNESS)) == 103
    )
예제 #2
0
async def test_deactivated_event(opp, mock_litejet):
    """Test handling an event from LiteJet."""
    await async_init_integration(opp)

    # Initial state is on.
    mock_litejet.get_load_level.return_value = 99

    mock_litejet.load_activated_callbacks[ENTITY_OTHER_LIGHT_NUMBER]()
    await opp.async_block_till_done()

    assert light.is_on(opp, ENTITY_OTHER_LIGHT)

    # Event indicates it is off now.

    mock_litejet.get_load_level.reset_mock()
    mock_litejet.get_load_level.return_value = 0

    mock_litejet.load_deactivated_callbacks[ENTITY_OTHER_LIGHT_NUMBER]()
    await opp.async_block_till_done()

    # (Requesting the level is not strictly needed with a deactivated
    # event but the implementation happens to do it. This could be
    # changed to an assert_not_called in the future.)
    mock_litejet.get_load_level.assert_called_with(ENTITY_OTHER_LIGHT_NUMBER)

    assert not light.is_on(opp, ENTITY_OTHER_LIGHT)
    assert not light.is_on(opp, ENTITY_LIGHT)
    assert opp.states.get(ENTITY_LIGHT).state == "off"
    assert opp.states.get(ENTITY_OTHER_LIGHT).state == "off"
예제 #3
0
async def test_turn_off(opp):
    """Test light turn off method."""
    await opp.services.async_call(
        "light", "turn_on", {"entity_id": ENTITY_LIGHT}, blocking=True
    )

    assert light.is_on(opp, ENTITY_LIGHT)

    await opp.services.async_call(
        "light", "turn_off", {"entity_id": ENTITY_LIGHT}, blocking=True
    )

    assert not light.is_on(opp, ENTITY_LIGHT)
예제 #4
0
async def test_turn_off_without_entity_id(opp):
    """Test light turn off all lights."""
    await opp.services.async_call(
        "light", "turn_on", {"entity_id": "all"}, blocking=True
    )

    assert light.is_on(opp, ENTITY_LIGHT)

    await opp.services.async_call(
        "light", "turn_off", {"entity_id": "all"}, blocking=True
    )

    assert not light.is_on(opp, ENTITY_LIGHT)
예제 #5
0
async def test_state_attributes(opp):
    """Test light state attributes."""
    await common.async_turn_on(opp, ENTITY_LIGHT, xy_color=(0.4, 0.4), brightness=25)
    state = opp.states.get(ENTITY_LIGHT)
    assert light.is_on(opp, ENTITY_LIGHT)
    assert (0.4, 0.4) == state.attributes.get(light.ATTR_XY_COLOR)
    assert 25 == state.attributes.get(light.ATTR_BRIGHTNESS)
    assert (255, 234, 164) == state.attributes.get(light.ATTR_RGB_COLOR)
    assert "rainbow" == state.attributes.get(light.ATTR_EFFECT)
    await common.async_turn_on(
        opp, ENTITY_LIGHT, rgb_color=(251, 253, 255), white_value=254
    )
    state = opp.states.get(ENTITY_LIGHT)
    assert 254 == state.attributes.get(light.ATTR_WHITE_VALUE)
    assert (250, 252, 255) == state.attributes.get(light.ATTR_RGB_COLOR)
    assert (0.319, 0.326) == state.attributes.get(light.ATTR_XY_COLOR)
    await common.async_turn_on(opp, ENTITY_LIGHT, color_temp=400, effect="none")
    state = opp.states.get(ENTITY_LIGHT)
    assert 400 == state.attributes.get(light.ATTR_COLOR_TEMP)
    assert 153 == state.attributes.get(light.ATTR_MIN_MIREDS)
    assert 500 == state.attributes.get(light.ATTR_MAX_MIREDS)
    assert "none" == state.attributes.get(light.ATTR_EFFECT)
    await common.async_turn_on(opp, ENTITY_LIGHT, kelvin=3000, brightness_pct=50)
    state = opp.states.get(ENTITY_LIGHT)
    assert 333 == state.attributes.get(light.ATTR_COLOR_TEMP)
    assert 127 == state.attributes.get(light.ATTR_BRIGHTNESS)
예제 #6
0
async def setup_lights(opp, entities):
    """Set up the light component."""
    assert await async_setup_component(opp, light.DOMAIN,
                                       {light.DOMAIN: {
                                           "platform": "test"
                                       }})
    await opp.async_block_till_done()

    light_1, light_2 = entities
    light_1.supported_color_modes = ["brightness"]
    light_2.supported_color_modes = ["brightness"]

    await turn_off_lights(opp, [light_1.entity_id, light_2.entity_id])
    assert not light.is_on(opp, light_1.entity_id)
    assert not light.is_on(opp, light_2.entity_id)

    return light_1, light_2
예제 #7
0
async def async_set_lights_rgb(opp, lights, rgb, transition):
    """Set color of array of lights."""
    for light in lights:
        if is_on(opp, light):
            service_data = {ATTR_ENTITY_ID: light}
            if rgb is not None:
                service_data[ATTR_RGB_COLOR] = rgb
            if transition is not None:
                service_data[ATTR_TRANSITION] = transition
            await opp.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_ON, service_data)
예제 #8
0
async def test_config_yaml_alias_anchor(opp, entities,
                                        enable_custom_integrations):
    """Test the usage of YAML aliases and anchors.

    The following test scene configuration is equivalent to:

    scene:
      - name: test
        entities:
          light_1: &light_1_state
            state: 'on'
            brightness: 100
          light_2: *light_1_state

    When encountering a YAML alias/anchor, the PyYAML parser will use a
    reference to the original dictionary, instead of creating a copy, so
    care needs to be taken to not modify the original.
    """
    light_1, light_2 = await setup_lights(opp, entities)
    entity_state = {"state": "on", "brightness": 100}

    assert await async_setup_component(
        opp,
        scene.DOMAIN,
        {
            "scene": [{
                "name": "test",
                "entities": {
                    light_1.entity_id: entity_state,
                    light_2.entity_id: entity_state,
                },
            }]
        },
    )
    await opp.async_block_till_done()

    await activate(opp, "scene.test")

    assert light.is_on(opp, light_1.entity_id)
    assert light.is_on(opp, light_2.entity_id)
    assert light_1.last_call("turn_on")[1].get("brightness") == 100
    assert light_2.last_call("turn_on")[1].get("brightness") == 100
예제 #9
0
async def test_activate_scene(opp, entities, enable_custom_integrations):
    """Test active scene."""
    light_1, light_2 = await setup_lights(opp, entities)

    assert await async_setup_component(
        opp,
        scene.DOMAIN,
        {
            "scene": [{
                "name": "test",
                "entities": {
                    light_1.entity_id: "on",
                    light_2.entity_id: {
                        "state": "on",
                        "brightness": 100
                    },
                },
            }]
        },
    )
    await opp.async_block_till_done()
    await activate(opp, "scene.test")

    assert light.is_on(opp, light_1.entity_id)
    assert light.is_on(opp, light_2.entity_id)
    assert light_2.last_call("turn_on")[1].get("brightness") == 100

    await turn_off_lights(opp, [light_2.entity_id])

    calls = async_mock_service(opp, "light", "turn_on")

    await opp.services.async_call(scene.DOMAIN, "turn_on", {
        "transition": 42,
        "entity_id": "scene.test"
    })
    await opp.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].domain == "light"
    assert calls[0].service == "turn_on"
    assert calls[0].data.get("transition") == 42
예제 #10
0
async def async_set_lights_temp(opp, lights, mired, brightness, transition):
    """Set color of array of lights."""
    for light in lights:
        if is_on(opp, light):
            service_data = {ATTR_ENTITY_ID: light}
            if mired is not None:
                service_data[ATTR_COLOR_TEMP] = int(mired)
            if brightness is not None:
                service_data[ATTR_BRIGHTNESS] = brightness
            if transition is not None:
                service_data[ATTR_TRANSITION] = transition
            await opp.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_ON, service_data)
예제 #11
0
    def test_light_profiles(self):
        """Test light profiles."""
        platform = getattr(self.opp.components, "test.light")
        platform.init()

        user_light_file = self.opp.config.path(light.LIGHT_PROFILES_FILE)

        with open(user_light_file, "w") as user_file:
            user_file.write("id,x,y,brightness\n")
            user_file.write("test,.4,.6,100\n")
            user_file.write("test_off,0,0,0\n")

        assert setup_component(self.opp, light.DOMAIN,
                               {light.DOMAIN: {
                                   CONF_PLATFORM: "test"
                               }})

        ent1, _, _ = platform.ENTITIES

        common.turn_on(self.opp, ent1.entity_id, profile="test")

        self.opp.block_till_done()

        _, data = ent1.last_call("turn_on")

        assert light.is_on(self.opp, ent1.entity_id)
        assert {
            light.ATTR_HS_COLOR: (71.059, 100),
            light.ATTR_BRIGHTNESS: 100
        } == data

        common.turn_on(self.opp, ent1.entity_id, profile="test_off")

        self.opp.block_till_done()

        _, data = ent1.last_call("turn_off")

        assert not light.is_on(self.opp, ent1.entity_id)
        assert {} == data
예제 #12
0
async def async_set_lights_xy(opp, lights, x_val, y_val, brightness, transition):
    """Set color of array of lights."""
    for light in lights:
        if is_on(opp, light):
            service_data = {ATTR_ENTITY_ID: light}
            if x_val is not None and y_val is not None:
                service_data[ATTR_XY_COLOR] = [x_val, y_val]
            if brightness is not None:
                service_data[ATTR_BRIGHTNESS] = brightness
                service_data[ATTR_WHITE_VALUE] = brightness
            if transition is not None:
                service_data[ATTR_TRANSITION] = transition
            await opp.services.async_call(LIGHT_DOMAIN, SERVICE_TURN_ON, service_data)
예제 #13
0
async def test_config_yaml_bool(opp, entities, enable_custom_integrations):
    """Test parsing of booleans in yaml config."""
    light_1, light_2 = await setup_lights(opp, entities)

    config = ("scene:\n"
              "  - name: test\n"
              "    entities:\n"
              f"      {light_1.entity_id}: on\n"
              f"      {light_2.entity_id}:\n"
              "        state: on\n"
              "        brightness: 100\n")

    with io.StringIO(config) as file:
        doc = yaml_loader.yaml.safe_load(file)

    assert await async_setup_component(opp, scene.DOMAIN, doc)
    await opp.async_block_till_done()

    await activate(opp, "scene.test")

    assert light.is_on(opp, light_1.entity_id)
    assert light.is_on(opp, light_2.entity_id)
    assert light_2.last_call("turn_on")[1].get("brightness") == 100
예제 #14
0
async def test_on_brightness(opp, mock_litejet):
    """Test turning the light on with brightness."""
    await async_init_integration(opp)

    assert opp.states.get(ENTITY_LIGHT).state == "off"
    assert opp.states.get(ENTITY_OTHER_LIGHT).state == "off"

    assert not light.is_on(opp, ENTITY_LIGHT)

    await opp.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: ENTITY_LIGHT, ATTR_BRIGHTNESS: 102},
        blocking=True,
    )
    mock_litejet.activate_load_at.assert_called_with(ENTITY_LIGHT_NUMBER, 39, 0)
예제 #15
0
async def test_on_off(opp, mock_litejet):
    """Test turning the light on and off."""
    await async_init_integration(opp)

    assert opp.states.get(ENTITY_LIGHT).state == "off"
    assert opp.states.get(ENTITY_OTHER_LIGHT).state == "off"

    assert not light.is_on(opp, ENTITY_LIGHT)

    await opp.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_ON,
        {ATTR_ENTITY_ID: ENTITY_LIGHT},
        blocking=True,
    )
    mock_litejet.activate_load.assert_called_with(ENTITY_LIGHT_NUMBER)

    await opp.services.async_call(
        light.DOMAIN,
        SERVICE_TURN_OFF,
        {ATTR_ENTITY_ID: ENTITY_LIGHT},
        blocking=True,
    )
    mock_litejet.deactivate_load.assert_called_with(ENTITY_LIGHT_NUMBER)
예제 #16
0
    def test_methods(self):
        """Test if methods call the services as expected."""
        # Test is_on
        self.opp.states.set("light.test", STATE_ON)
        assert light.is_on(self.opp, "light.test")

        self.opp.states.set("light.test", STATE_OFF)
        assert not light.is_on(self.opp, "light.test")

        # Test turn_on
        turn_on_calls = mock_service(self.opp, light.DOMAIN, SERVICE_TURN_ON)

        common.turn_on(
            self.opp,
            entity_id="entity_id_val",
            transition="transition_val",
            brightness="brightness_val",
            rgb_color="rgb_color_val",
            xy_color="xy_color_val",
            profile="profile_val",
            color_name="color_name_val",
            white_value="white_val",
        )

        self.opp.block_till_done()

        assert 1 == len(turn_on_calls)
        call = turn_on_calls[-1]

        assert light.DOMAIN == call.domain
        assert SERVICE_TURN_ON == call.service
        assert "entity_id_val" == call.data.get(ATTR_ENTITY_ID)
        assert "transition_val" == call.data.get(light.ATTR_TRANSITION)
        assert "brightness_val" == call.data.get(light.ATTR_BRIGHTNESS)
        assert "rgb_color_val" == call.data.get(light.ATTR_RGB_COLOR)
        assert "xy_color_val" == call.data.get(light.ATTR_XY_COLOR)
        assert "profile_val" == call.data.get(light.ATTR_PROFILE)
        assert "color_name_val" == call.data.get(light.ATTR_COLOR_NAME)
        assert "white_val" == call.data.get(light.ATTR_WHITE_VALUE)

        # Test turn_off
        turn_off_calls = mock_service(self.opp, light.DOMAIN, SERVICE_TURN_OFF)

        common.turn_off(self.opp,
                        entity_id="entity_id_val",
                        transition="transition_val")

        self.opp.block_till_done()

        assert 1 == len(turn_off_calls)
        call = turn_off_calls[-1]

        assert light.DOMAIN == call.domain
        assert SERVICE_TURN_OFF == call.service
        assert "entity_id_val" == call.data[ATTR_ENTITY_ID]
        assert "transition_val" == call.data[light.ATTR_TRANSITION]

        # Test toggle
        toggle_calls = mock_service(self.opp, light.DOMAIN, SERVICE_TOGGLE)

        common.toggle(self.opp,
                      entity_id="entity_id_val",
                      transition="transition_val")

        self.opp.block_till_done()

        assert 1 == len(toggle_calls)
        call = toggle_calls[-1]

        assert light.DOMAIN == call.domain
        assert SERVICE_TOGGLE == call.service
        assert "entity_id_val" == call.data[ATTR_ENTITY_ID]
        assert "transition_val" == call.data[light.ATTR_TRANSITION]
예제 #17
0
    def test_services(self):
        """Test the provided services."""
        platform = getattr(self.opp.components, "test.light")

        platform.init()
        assert setup_component(self.opp, light.DOMAIN,
                               {light.DOMAIN: {
                                   CONF_PLATFORM: "test"
                               }})

        ent1, ent2, ent3 = platform.ENTITIES

        # Test init
        assert light.is_on(self.opp, ent1.entity_id)
        assert not light.is_on(self.opp, ent2.entity_id)
        assert not light.is_on(self.opp, ent3.entity_id)

        # Test basic turn_on, turn_off, toggle services
        common.turn_off(self.opp, entity_id=ent1.entity_id)
        common.turn_on(self.opp, entity_id=ent2.entity_id)

        self.opp.block_till_done()

        assert not light.is_on(self.opp, ent1.entity_id)
        assert light.is_on(self.opp, ent2.entity_id)

        # turn on all lights
        common.turn_on(self.opp)

        self.opp.block_till_done()

        assert light.is_on(self.opp, ent1.entity_id)
        assert light.is_on(self.opp, ent2.entity_id)
        assert light.is_on(self.opp, ent3.entity_id)

        # turn off all lights
        common.turn_off(self.opp)

        self.opp.block_till_done()

        assert not light.is_on(self.opp, ent1.entity_id)
        assert not light.is_on(self.opp, ent2.entity_id)
        assert not light.is_on(self.opp, ent3.entity_id)

        # turn off all lights by setting brightness to 0
        common.turn_on(self.opp)

        self.opp.block_till_done()

        common.turn_on(self.opp, brightness=0)

        self.opp.block_till_done()

        assert not light.is_on(self.opp, ent1.entity_id)
        assert not light.is_on(self.opp, ent2.entity_id)
        assert not light.is_on(self.opp, ent3.entity_id)

        # toggle all lights
        common.toggle(self.opp)

        self.opp.block_till_done()

        assert light.is_on(self.opp, ent1.entity_id)
        assert light.is_on(self.opp, ent2.entity_id)
        assert light.is_on(self.opp, ent3.entity_id)

        # toggle all lights
        common.toggle(self.opp)

        self.opp.block_till_done()

        assert not light.is_on(self.opp, ent1.entity_id)
        assert not light.is_on(self.opp, ent2.entity_id)
        assert not light.is_on(self.opp, ent3.entity_id)

        # Ensure all attributes process correctly
        common.turn_on(self.opp,
                       ent1.entity_id,
                       transition=10,
                       brightness=20,
                       color_name="blue")
        common.turn_on(self.opp,
                       ent2.entity_id,
                       rgb_color=(255, 255, 255),
                       white_value=255)
        common.turn_on(self.opp, ent3.entity_id, xy_color=(0.4, 0.6))

        self.opp.block_till_done()

        _, data = ent1.last_call("turn_on")
        assert {
            light.ATTR_TRANSITION: 10,
            light.ATTR_BRIGHTNESS: 20,
            light.ATTR_HS_COLOR: (240, 100),
        } == data

        _, data = ent2.last_call("turn_on")
        assert {
            light.ATTR_HS_COLOR: (0, 0),
            light.ATTR_WHITE_VALUE: 255
        } == data

        _, data = ent3.last_call("turn_on")
        assert {light.ATTR_HS_COLOR: (71.059, 100)} == data

        # Ensure attributes are filtered when light is turned off
        common.turn_on(self.opp,
                       ent1.entity_id,
                       transition=10,
                       brightness=0,
                       color_name="blue")
        common.turn_on(
            self.opp,
            ent2.entity_id,
            brightness=0,
            rgb_color=(255, 255, 255),
            white_value=0,
        )
        common.turn_on(self.opp,
                       ent3.entity_id,
                       brightness=0,
                       xy_color=(0.4, 0.6))

        self.opp.block_till_done()

        assert not light.is_on(self.opp, ent1.entity_id)
        assert not light.is_on(self.opp, ent2.entity_id)
        assert not light.is_on(self.opp, ent3.entity_id)

        _, data = ent1.last_call("turn_off")
        assert {light.ATTR_TRANSITION: 10} == data

        _, data = ent2.last_call("turn_off")
        assert {} == data

        _, data = ent3.last_call("turn_off")
        assert {} == data

        # One of the light profiles
        prof_name, prof_h, prof_s, prof_bri = "relax", 35.932, 69.412, 144

        # Test light profiles
        common.turn_on(self.opp, ent1.entity_id, profile=prof_name)
        # Specify a profile and a brightness attribute to overwrite it
        common.turn_on(self.opp,
                       ent2.entity_id,
                       profile=prof_name,
                       brightness=100)

        self.opp.block_till_done()

        _, data = ent1.last_call("turn_on")
        assert {
            light.ATTR_BRIGHTNESS: prof_bri,
            light.ATTR_HS_COLOR: (prof_h, prof_s),
        } == data

        _, data = ent2.last_call("turn_on")
        assert {
            light.ATTR_BRIGHTNESS: 100,
            light.ATTR_HS_COLOR: (prof_h, prof_s),
        } == data

        # Test bad data
        common.turn_on(self.opp)
        common.turn_on(self.opp, ent1.entity_id, profile="nonexisting")
        common.turn_on(self.opp, ent2.entity_id, xy_color=["bla-di-bla", 5])
        common.turn_on(self.opp, ent3.entity_id, rgb_color=[255, None, 2])

        self.opp.block_till_done()

        _, data = ent1.last_call("turn_on")
        assert {} == data

        _, data = ent2.last_call("turn_on")
        assert {} == data

        _, data = ent3.last_call("turn_on")
        assert {} == data

        # faulty attributes will not trigger a service call
        common.turn_on(self.opp,
                       ent1.entity_id,
                       profile=prof_name,
                       brightness="bright")
        common.turn_on(self.opp, ent1.entity_id, rgb_color="yellowish")
        common.turn_on(self.opp, ent2.entity_id, white_value="high")

        self.opp.block_till_done()

        _, data = ent1.last_call("turn_on")
        assert {} == data

        _, data = ent2.last_call("turn_on")
        assert {} == data
예제 #18
0
async def test_lights_turn_on_when_coming_home_after_sun_set_person(
        opp, scanner):
    """Test lights turn on when coming home after sun set."""
    device_1 = f"{DOMAIN}.device_1"
    device_2 = f"{DOMAIN}.device_2"

    test_time = datetime(2017, 4, 5, 3, 2, 3, tzinfo=dt_util.UTC)
    with patch("openpeerpower.util.dt.utcnow", return_value=test_time):
        await opp.services.async_call(light.DOMAIN,
                                      light.SERVICE_TURN_OFF,
                                      {ATTR_ENTITY_ID: "all"},
                                      blocking=True)
        opp.states.async_set(device_1, STATE_NOT_HOME)
        opp.states.async_set(device_2, STATE_NOT_HOME)
        await opp.async_block_till_done()

        assert all(not light.is_on(opp, ent_id)
                   for ent_id in opp.states.async_entity_ids("light"))
        assert opp.states.get(device_1).state == "not_home"
        assert opp.states.get(device_2).state == "not_home"

        assert await async_setup_component(
            opp,
            "person",
            {
                "person": [{
                    "id": "me",
                    "name": "Me",
                    "device_trackers": [device_1]
                }]
            },
        )

        assert await async_setup_component(opp, "group", {})
        await opp.async_block_till_done()
        await group.Group.async_create_group(opp, "person_me", ["person.me"])

        assert await async_setup_component(
            opp,
            device_sun_light_trigger.DOMAIN,
            {
                device_sun_light_trigger.DOMAIN: {
                    "device_group": "group.person_me"
                }
            },
        )

        assert all(
            opp.states.get(ent_id).state == STATE_OFF
            for ent_id in opp.states.async_entity_ids("light"))
        assert opp.states.get(device_1).state == "not_home"
        assert opp.states.get(device_2).state == "not_home"
        assert opp.states.get("person.me").state == "not_home"

        # Unrelated device has no impact
        opp.states.async_set(device_2, STATE_HOME)
        await opp.async_block_till_done()

        assert all(
            opp.states.get(ent_id).state == STATE_OFF
            for ent_id in opp.states.async_entity_ids("light"))
        assert opp.states.get(device_1).state == "not_home"
        assert opp.states.get(device_2).state == "home"
        assert opp.states.get("person.me").state == "not_home"

        # person home switches on
        opp.states.async_set(device_1, STATE_HOME)
        await opp.async_block_till_done()
        await opp.async_block_till_done()

        assert all(
            opp.states.get(ent_id).state == light.STATE_ON
            for ent_id in opp.states.async_entity_ids("light"))
        assert opp.states.get(device_1).state == "home"
        assert opp.states.get(device_2).state == "home"
        assert opp.states.get("person.me").state == "home"