Ejemplo n.º 1
0
async def test_state_saved_on_remove(hass):
    """Test that we save entity state on removal."""
    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b0"
    await entity.async_internal_added_to_hass()

    now = dt_util.utcnow()
    hass.states.async_set("input_boolean.b0", "on",
                          {"complicated": {
                              "value": {1, 2, now}
                          }})

    data = await RestoreStateData.async_get_instance(hass)

    # No last states should currently be saved
    assert not data.last_states

    await entity.async_remove()

    # We should store the input boolean state when it is removed
    state = data.last_states["input_boolean.b0"].state
    assert state.state == "on"
    assert isinstance(state.attributes["complicated"]["value"], list)
    assert set(
        state.attributes["complicated"]["value"]) == {1, 2,
                                                      now.isoformat()}
Ejemplo n.º 2
0
async def test_restoring_invalid_entity_id(hass, hass_storage):
    """Test restoring invalid entity IDs."""
    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "test.invalid__entity_id"
    now = dt_util.utcnow().isoformat()
    hass_storage[STORAGE_KEY] = {
        "version":
        1,
        "key":
        STORAGE_KEY,
        "data": [{
            "state": {
                "entity_id": "test.invalid__entity_id",
                "state": "off",
                "attributes": {},
                "last_changed": now,
                "last_updated": now,
                "context": {
                    "id": "3c2243ff5f30447eb12e7348cfd5b8ff",
                    "user_id": None,
                },
            },
            "last_seen": dt_util.utcnow().isoformat(),
        }],
    }

    state = await entity.async_get_last_state()
    assert state is None
Ejemplo n.º 3
0
async def test_restoring_invalid_entity_id(hass, hass_storage):
    """Test restoring invalid entity IDs."""
    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = 'test.invalid__entity_id'
    now = dt_util.utcnow().isoformat()
    hass_storage[STORAGE_KEY] = {
        'version':
        1,
        'key':
        STORAGE_KEY,
        'data': [{
            'state': {
                'entity_id': 'test.invalid__entity_id',
                'state': 'off',
                'attributes': {},
                'last_changed': now,
                'last_updated': now,
                'context': {
                    'id': '3c2243ff5f30447eb12e7348cfd5b8ff',
                    'user_id': None
                }
            },
            'last_seen': dt_util.utcnow().isoformat()
        }]
    }

    state = await entity.async_get_last_state()
    assert state is None
Ejemplo n.º 4
0
async def test_caching_data(hass):
    """Test that we cache data."""
    now = dt_util.utcnow()
    stored_states = [
        StoredState(State("input_boolean.b0", "on"), None, now),
        StoredState(State("input_boolean.b1", "on"), None, now),
        StoredState(State("input_boolean.b2", "on"), None, now),
    ]

    data = await RestoreStateData.async_get_instance(hass)
    await hass.async_block_till_done()
    await data.store.async_save([state.as_dict() for state in stored_states])

    # Emulate a fresh load
    hass.data.pop(DATA_RESTORE_STATE_TASK)

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"

    # Mock that only b1 is present this run
    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        state = await entity.async_get_last_state()
        await hass.async_block_till_done()

    assert state is not None
    assert state.entity_id == "input_boolean.b1"
    assert state.state == "on"

    assert mock_write_data.called
Ejemplo n.º 5
0
async def test_caching_data(hass):
    """Test that we cache data."""
    now = dt_util.utcnow()
    stored_states = [
        StoredState(State('input_boolean.b0', 'on'), now),
        StoredState(State('input_boolean.b1', 'on'), now),
        StoredState(State('input_boolean.b2', 'on'), now),
    ]

    data = await RestoreStateData.async_get_instance(hass)
    await data.store.async_save([state.as_dict() for state in stored_states])

    # Emulate a fresh load
    hass.data[DATA_RESTORE_STATE_TASK] = None

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b1'

    # Mock that only b1 is present this run
    with patch('homeassistant.helpers.restore_state.Store.async_save'
               ) as mock_write_data:
        state = await entity.async_get_last_state()

    assert state is not None
    assert state.entity_id == 'input_boolean.b1'
    assert state.state == 'on'

    assert mock_write_data.called
Ejemplo n.º 6
0
async def test_load_error(hass):
    """Test that we cache data."""
    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b1'

    with patch('homeassistant.helpers.storage.Store.async_load',
               return_value=mock_coro(exception=HomeAssistantError)):
        state = await entity.async_get_last_state()

    assert state is None
Ejemplo n.º 7
0
async def test_load_error(hass):
    """Test that we cache data."""
    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"

    with patch(
            "homeassistant.helpers.storage.Store.async_load",
            side_effect=HomeAssistantError,
    ):
        state = await entity.async_get_last_state()

    assert state is None
Ejemplo n.º 8
0
async def test_save_persistent_states(hass):
    """Test that we cancel the currently running job, save the data, and verify the perdiodic job continues."""
    data = await RestoreStateData.async_get_instance(hass)
    await hass.async_block_till_done()
    await data.store.async_save([])

    # Emulate a fresh load
    hass.data.pop(DATA_RESTORE_STATE_TASK)

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        await entity.async_get_last_state()
        await hass.async_block_till_done()

    # Startup Save
    assert mock_write_data.called

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=10))
        await hass.async_block_till_done()

    # Not quite the first interval
    assert not mock_write_data.called

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        await RestoreStateData.async_save_persistent_states(hass)
        await hass.async_block_till_done()

    assert mock_write_data.called

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=20))
        await hass.async_block_till_done()
    # Verify still saving
    assert mock_write_data.called

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
        await hass.async_block_till_done()
    # Verify normal shutdown
    assert mock_write_data.called
Ejemplo n.º 9
0
async def test_dump_error(hass):
    """Test that we cache data."""
    states = [
        State("input_boolean.b0", "on"),
        State("input_boolean.b1", "on"),
        State("input_boolean.b2", "on"),
    ]

    entity = Entity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b0"
    await entity.async_internal_added_to_hass()

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"
    await entity.async_internal_added_to_hass()

    data = await RestoreStateData.async_get_instance(hass)

    with patch(
            "homeassistant.helpers.restore_state.Store.async_save",
            side_effect=HomeAssistantError,
    ) as mock_write_data, patch.object(hass.states,
                                       "async_all",
                                       return_value=states):
        await data.async_dump_states()

    assert mock_write_data.called
Ejemplo n.º 10
0
async def test_dump_error(hass):
    """Test that we cache data."""
    states = [
        State('input_boolean.b0', 'on'),
        State('input_boolean.b1', 'on'),
        State('input_boolean.b2', 'on'),
    ]

    entity = Entity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b0'
    await entity.async_internal_added_to_hass()

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b1'
    await entity.async_internal_added_to_hass()

    data = await RestoreStateData.async_get_instance(hass)

    with patch('homeassistant.helpers.restore_state.Store.async_save',
               return_value=mock_coro(exception=HomeAssistantError)
               ) as mock_write_data, patch.object(hass.states,
                                                  'async_all',
                                                  return_value=states):
        await data.async_dump_states()

    assert mock_write_data.called
Ejemplo n.º 11
0
async def test_hass_starting(hass):
    """Test that we cache data."""
    hass.state = CoreState.starting

    now = dt_util.utcnow()
    stored_states = [
        StoredState(State("input_boolean.b0", "on"), None, now),
        StoredState(State("input_boolean.b1", "on"), None, now),
        StoredState(State("input_boolean.b2", "on"), None, now),
    ]

    data = await RestoreStateData.async_get_instance(hass)
    await hass.async_block_till_done()
    await data.store.async_save([state.as_dict() for state in stored_states])

    # Emulate a fresh load
    hass.state = CoreState.not_running
    hass.data.pop(DATA_RESTORE_STATE_TASK)

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"

    # Mock that only b1 is present this run
    states = [State("input_boolean.b1", "on")]
    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data, patch.object(hass.states,
                                                  "async_all",
                                                  return_value=states):
        state = await entity.async_get_last_state()
        await hass.async_block_till_done()

    assert state is not None
    assert state.entity_id == "input_boolean.b1"
    assert state.state == "on"

    # Assert that no data was written yet, since hass is still starting.
    assert not mock_write_data.called

    # Finish hass startup
    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data:
        hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
        await hass.async_block_till_done()

    # Assert that this session states were written
    assert mock_write_data.called
Ejemplo n.º 12
0
    def async_added_to_hass(self):
        state = yield from RestoreEntity(self.hass, self.entity_id)

        if state is not None:
            self._target_temperature = state.attributes['temperature']
            self._current_operation = state.attributes['operation_mode']
            self._current_fan_mode = state.attributes['fan_mode']
            self._current_swing_mode = state.attributes['swing_mode']
Ejemplo n.º 13
0
async def test_state_saved_on_remove(hass):
    """Test that we save entity state on removal."""
    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b0'
    await entity.async_internal_added_to_hass()

    hass.states.async_set('input_boolean.b0', 'on')

    data = await RestoreStateData.async_get_instance(hass)

    # No last states should currently be saved
    assert not data.last_states

    await entity.async_remove()

    # We should store the input boolean state when it is removed
    assert data.last_states['input_boolean.b0'].state.state == 'on'
async def test_periodic_write(hass):
    """Test that we write periodiclly but not after stop."""
    data = await RestoreStateData.async_get_instance(hass)
    await hass.async_block_till_done()
    await data.store.async_save([])

    # Emulate a fresh load
    hass.data[DATA_RESTORE_STATE_TASK] = None

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"

    with patch(
        "homeassistant.helpers.restore_state.Store.async_save"
    ) as mock_write_data:
        await entity.async_get_last_state()
        await hass.async_block_till_done()

    assert mock_write_data.called

    with patch(
        "homeassistant.helpers.restore_state.Store.async_save"
    ) as mock_write_data:
        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=15))
        await hass.async_block_till_done()

    assert mock_write_data.called

    with patch(
        "homeassistant.helpers.restore_state.Store.async_save"
    ) as mock_write_data:
        hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
        await hass.async_block_till_done()

    assert mock_write_data.called

    with patch(
        "homeassistant.helpers.restore_state.Store.async_save"
    ) as mock_write_data:
        async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=30))
        await hass.async_block_till_done()

    assert not mock_write_data.called
Ejemplo n.º 15
0
async def test_dump_data(hass):
    """Test that we cache data."""
    states = [
        State("input_boolean.b0", "on"),
        State("input_boolean.b1", "on"),
        State("input_boolean.b2", "on"),
        State("input_boolean.b5", "unavailable", {"restored": True}),
    ]

    entity = Entity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b0"
    await entity.async_internal_added_to_hass()

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = "input_boolean.b1"
    await entity.async_internal_added_to_hass()

    data = await RestoreStateData.async_get_instance(hass)
    now = dt_util.utcnow()
    data.last_states = {
        "input_boolean.b0":
        StoredState(State("input_boolean.b0", "off"), None, now),
        "input_boolean.b1":
        StoredState(State("input_boolean.b1", "off"), None, now),
        "input_boolean.b2":
        StoredState(State("input_boolean.b2", "off"), None, now),
        "input_boolean.b3":
        StoredState(State("input_boolean.b3", "off"), None, now),
        "input_boolean.b4":
        StoredState(
            State("input_boolean.b4", "off"),
            None,
            datetime(1985, 10, 26, 1, 22, tzinfo=dt_util.UTC),
        ),
        "input_boolean.b5":
        StoredState(State("input_boolean.b5", "off"), None, now),
    }

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data, patch.object(hass.states,
                                                  "async_all",
                                                  return_value=states):
        await data.async_dump_states()

    assert mock_write_data.called
    args = mock_write_data.mock_calls[0][1]
    written_states = args[0]

    # b0 should not be written, since it didn't extend RestoreEntity
    # b1 should be written, since it is present in the current run
    # b2 should not be written, since it is not registered with the helper
    # b3 should be written, since it is still not expired
    # b4 should not be written, since it is now expired
    # b5 should be written, since current state is restored by entity registry
    assert len(written_states) == 3
    assert written_states[0]["state"]["entity_id"] == "input_boolean.b1"
    assert written_states[0]["state"]["state"] == "on"
    assert written_states[1]["state"]["entity_id"] == "input_boolean.b3"
    assert written_states[1]["state"]["state"] == "off"
    assert written_states[2]["state"]["entity_id"] == "input_boolean.b5"
    assert written_states[2]["state"]["state"] == "off"

    # Test that removed entities are not persisted
    await entity.async_remove()

    with patch("homeassistant.helpers.restore_state.Store.async_save"
               ) as mock_write_data, patch.object(hass.states,
                                                  "async_all",
                                                  return_value=states):
        await data.async_dump_states()

    assert mock_write_data.called
    args = mock_write_data.mock_calls[0][1]
    written_states = args[0]
    assert len(written_states) == 2
    assert written_states[0]["state"]["entity_id"] == "input_boolean.b3"
    assert written_states[0]["state"]["state"] == "off"
    assert written_states[1]["state"]["entity_id"] == "input_boolean.b5"
    assert written_states[1]["state"]["state"] == "off"
Ejemplo n.º 16
0
async def test_dump_data(hass):
    """Test that we cache data."""
    states = [
        State('input_boolean.b0', 'on'),
        State('input_boolean.b1', 'on'),
        State('input_boolean.b2', 'on'),
    ]

    entity = Entity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b0'
    await entity.async_internal_added_to_hass()

    entity = RestoreEntity()
    entity.hass = hass
    entity.entity_id = 'input_boolean.b1'
    await entity.async_internal_added_to_hass()

    data = await RestoreStateData.async_get_instance(hass)
    now = dt_util.utcnow()
    data.last_states = {
        'input_boolean.b0':
        StoredState(State('input_boolean.b0', 'off'), now),
        'input_boolean.b1':
        StoredState(State('input_boolean.b1', 'off'), now),
        'input_boolean.b2':
        StoredState(State('input_boolean.b2', 'off'), now),
        'input_boolean.b3':
        StoredState(State('input_boolean.b3', 'off'), now),
        'input_boolean.b4':
        StoredState(State('input_boolean.b4', 'off'),
                    datetime(1985, 10, 26, 1, 22, tzinfo=dt_util.UTC)),
    }

    with patch('homeassistant.helpers.restore_state.Store.async_save'
               ) as mock_write_data, patch.object(hass.states,
                                                  'async_all',
                                                  return_value=states):
        await data.async_dump_states()

    assert mock_write_data.called
    args = mock_write_data.mock_calls[0][1]
    written_states = args[0]

    # b0 should not be written, since it didn't extend RestoreEntity
    # b1 should be written, since it is present in the current run
    # b2 should not be written, since it is not registered with the helper
    # b3 should be written, since it is still not expired
    # b4 should not be written, since it is now expired
    assert len(written_states) == 2
    assert written_states[0]['state']['entity_id'] == 'input_boolean.b1'
    assert written_states[0]['state']['state'] == 'on'
    assert written_states[1]['state']['entity_id'] == 'input_boolean.b3'
    assert written_states[1]['state']['state'] == 'off'

    # Test that removed entities are not persisted
    await entity.async_remove()

    with patch('homeassistant.helpers.restore_state.Store.async_save'
               ) as mock_write_data, patch.object(hass.states,
                                                  'async_all',
                                                  return_value=states):
        await data.async_dump_states()

    assert mock_write_data.called
    args = mock_write_data.mock_calls[0][1]
    written_states = args[0]
    assert len(written_states) == 1
    assert written_states[0]['state']['entity_id'] == 'input_boolean.b3'
    assert written_states[0]['state']['state'] == 'off'