예제 #1
0
def test_run_information(hass_recorder):
    """Ensure run_information returns expected data."""
    before_start_recording = dt_util.utcnow()
    hass = hass_recorder()
    run_info = run_information_from_instance(hass)
    assert isinstance(run_info, RecorderRuns)
    assert run_info.closed_incorrect is False

    with session_scope(hass=hass) as session:
        run_info = run_information_with_session(session)
        assert isinstance(run_info, RecorderRuns)
        assert run_info.closed_incorrect is False

    run_info = run_information(hass)
    assert isinstance(run_info, RecorderRuns)
    assert run_info.closed_incorrect is False

    hass.states.set("test.two", "on", {})
    wait_recording_done(hass)
    run_info = run_information(hass)
    assert isinstance(run_info, RecorderRuns)
    assert run_info.closed_incorrect is False

    run_info = run_information(hass, before_start_recording)
    assert run_info is None

    run_info = run_information(hass, dt_util.utcnow())
    assert isinstance(run_info, RecorderRuns)
    assert run_info.closed_incorrect is False
예제 #2
0
def get_states(utc_point_in_time, entity_ids=None, run=None, filters=None):
    """Return the states at a specific point in time."""
    if run is None:
        run = recorder.run_information(utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    states = recorder.get_model('States')
    most_recent_state_ids = recorder.query(
        func.max(states.state_id).label('max_state_id')
    ).filter(
        (states.created >= run.start) &
        (states.created < utc_point_in_time) &
        (~states.domain.in_(IGNORE_DOMAINS)))
    if filters:
        most_recent_state_ids = filters.apply(most_recent_state_ids,
                                              entity_ids)

    most_recent_state_ids = most_recent_state_ids.group_by(
        states.entity_id).subquery()

    query = recorder.query('States').join(most_recent_state_ids, and_(
        states.state_id == most_recent_state_ids.c.max_state_id))

    for state in recorder.execute(query):
        if not state.attributes.get(ATTR_HIDDEN, False):
            yield state
예제 #3
0
def get_states(utc_point_in_time, entity_ids=None, run=None):
    """ Returns the states at a specific point in time. """
    if run is None:
        run = recorder.run_information(utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    where = run.where_after_start_run + "AND created < ? "
    where_data = [utc_point_in_time]

    if entity_ids is not None:
        where += "AND entity_id IN ({}) ".format(",".join(['?'] *
                                                          len(entity_ids)))
        where_data.extend(entity_ids)

    query = """
        SELECT * FROM states
        INNER JOIN (
            SELECT max(state_id) AS max_state_id
            FROM states WHERE {}
            GROUP BY entity_id)
        WHERE state_id = max_state_id
    """.format(where)

    return recorder.query_states(query, where_data)
예제 #4
0
def get_states(utc_point_in_time, entity_ids=None, run=None):
    """ Returns the states at a specific point in time. """
    if run is None:
        run = recorder.run_information(utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    where = run.where_after_start_run + "AND created < ? "
    where_data = [utc_point_in_time]

    if entity_ids is not None:
        where += "AND entity_id IN ({}) ".format(
            ",".join(['?'] * len(entity_ids)))
        where_data.extend(entity_ids)

    query = """
        SELECT * FROM states
        INNER JOIN (
            SELECT max(state_id) AS max_state_id
            FROM states WHERE {}
            GROUP BY entity_id)
        WHERE state_id = max_state_id
    """.format(where)

    return recorder.query_states(query, where_data)
예제 #5
0
def get_states(utc_point_in_time, entity_ids=None, run=None):
    """Return the states at a specific point in time."""
    if run is None:
        run = recorder.run_information(utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    states = recorder.get_model("States")
    most_recent_state_ids = recorder.query(func.max(states.state_id).label("max_state_id")).filter(
        (states.created >= run.start) & (states.created < utc_point_in_time)
    )

    if entity_ids is not None:
        most_recent_state_ids = most_recent_state_ids.filter(states.entity_id.in_(entity_ids))

    most_recent_state_ids = most_recent_state_ids.group_by(states.entity_id).subquery()

    query = recorder.query("States").join(
        most_recent_state_ids, and_(states.state_id == most_recent_state_ids.c.max_state_id)
    )

    return recorder.execute(query)
예제 #6
0
def get_states(utc_point_in_time, entity_ids=None, run=None):
    """Return the states at a specific point in time."""
    if run is None:
        run = recorder.run_information(utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    states = recorder.get_model('States')
    most_recent_state_ids = recorder.query(
        func.max(states.state_id).label(
            'max_state_id')).filter((states.created >= run.start)
                                    & (states.created < utc_point_in_time))

    if entity_ids is not None:
        most_recent_state_ids = most_recent_state_ids.filter(
            states.entity_id.in_(entity_ids))

    most_recent_state_ids = most_recent_state_ids.group_by(
        states.entity_id).subquery()

    query = recorder.query('States').join(
        most_recent_state_ids,
        and_(states.state_id == most_recent_state_ids.c.max_state_id))

    return recorder.execute(query)
예제 #7
0
def get_states(hass, utc_point_in_time, entity_ids=None, run=None,
               filters=None):
    """Return the states at a specific point in time."""
    from homeassistant.components.recorder.models import States

    if run is None:
        run = recorder.run_information(hass, utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    with session_scope(hass=hass) as session:
        most_recent_state_ids = session.query(
            func.max(States.state_id).label('max_state_id')
        ).filter(
            (States.created >= run.start) &
            (States.created < utc_point_in_time) &
            (~States.domain.in_(IGNORE_DOMAINS)))

        if filters:
            most_recent_state_ids = filters.apply(most_recent_state_ids,
                                                  entity_ids)

        most_recent_state_ids = most_recent_state_ids.group_by(
            States.entity_id).subquery()

        query = session.query(States).join(most_recent_state_ids, and_(
            States.state_id == most_recent_state_ids.c.max_state_id))

        return [state for state in execute(query)
                if not state.attributes.get(ATTR_HIDDEN, False)]
예제 #8
0
def get_states(hass,
               utc_point_in_time,
               entity_ids=None,
               run=None,
               filters=None):
    """Return the states at a specific point in time."""
    from homeassistant.components.recorder.models import States

    if run is None:
        run = recorder.run_information(hass, utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    with session_scope(hass=hass) as session:
        if entity_ids and len(entity_ids) == 1:
            # Use an entirely different (and extremely fast) query if we only
            # have a single entity id
            most_recent_state_ids = session.query(
                States.state_id.label('max_state_id')).filter(
                    (States.created < utc_point_in_time)
                    & (States.entity_id.in_(entity_ids))).order_by(
                        States.created.desc())

            if filters:
                most_recent_state_ids = filters.apply(most_recent_state_ids,
                                                      entity_ids)

            most_recent_state_ids = most_recent_state_ids.limit(1)

        else:
            # We have more than one entity to look at (most commonly we want
            # all entities,) so we need to do a search on all states since the
            # last recorder run started.
            most_recent_state_ids = session.query(
                func.max(States.state_id).label('max_state_id')).filter(
                    (States.created >= run.start)
                    & (States.created < utc_point_in_time)
                    & (~States.domain.in_(IGNORE_DOMAINS)))

            if filters:
                most_recent_state_ids = filters.apply(most_recent_state_ids,
                                                      entity_ids)

            most_recent_state_ids = most_recent_state_ids.group_by(
                States.entity_id)

        most_recent_state_ids = most_recent_state_ids.subquery()

        query = session.query(States).join(
            most_recent_state_ids,
            and_(States.state_id == most_recent_state_ids.c.max_state_id))

        return [
            state for state in execute(query)
            if not state.attributes.get(ATTR_HIDDEN, False)
        ]
예제 #9
0
def get_states(hass,
               utc_point_in_time,
               entity_ids=None,
               run=None,
               filters=None):
    """Return the states at a specific point in time."""
    from homeassistant.components.recorder.models import States

    if run is None:
        run = recorder.run_information(hass, utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    with session_scope(hass=hass) as session:
        most_recent_state_ids = session.query(
            func.max(States.state_id).label(
                'max_state_id')).filter((States.created >= run.start)
                                        & (States.created < utc_point_in_time)
                                        & (~States.domain.in_(IGNORE_DOMAINS)))

        if filters:
            most_recent_state_ids = filters.apply(most_recent_state_ids,
                                                  entity_ids)

        most_recent_state_ids = most_recent_state_ids.group_by(
            States.entity_id).subquery()

        query = session.query(States).join(
            most_recent_state_ids,
            and_(States.state_id == most_recent_state_ids.c.max_state_id))

        return [
            state for state in execute(query)
            if not state.attributes.get(ATTR_HIDDEN, False)
        ]
예제 #10
0
def get_states(hass, utc_point_in_time, entity_ids=None, run=None,
               filters=None):
    """Return the states at a specific point in time."""
    from homeassistant.components.recorder.models import States

    if run is None:
        run = recorder.run_information(hass, utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    from sqlalchemy import and_, func

    with session_scope(hass=hass) as session:
        if entity_ids and len(entity_ids) == 1:
            # Use an entirely different (and extremely fast) query if we only
            # have a single entity id
            most_recent_state_ids = session.query(
                States.state_id.label('max_state_id')
            ).filter(
                (States.last_updated < utc_point_in_time) &
                (States.entity_id.in_(entity_ids))
            ).order_by(
                States.last_updated.desc())

            most_recent_state_ids = most_recent_state_ids.limit(1)

        else:
            # We have more than one entity to look at (most commonly we want
            # all entities,) so we need to do a search on all states since the
            # last recorder run started.

            most_recent_states_by_date = session.query(
                States.entity_id.label('max_entity_id'),
                func.max(States.last_updated).label('max_last_updated')
            ).filter(
                (States.last_updated >= run.start) &
                (States.last_updated < utc_point_in_time)
            )

            if entity_ids:
                most_recent_states_by_date.filter(
                    States.entity_id.in_(entity_ids))

            most_recent_states_by_date = most_recent_states_by_date.group_by(
                States.entity_id)

            most_recent_states_by_date = most_recent_states_by_date.subquery()

            most_recent_state_ids = session.query(
                func.max(States.state_id).label('max_state_id')
            ).join(most_recent_states_by_date, and_(
                States.entity_id == most_recent_states_by_date.c.max_entity_id,
                States.last_updated == most_recent_states_by_date.c.
                max_last_updated))

            most_recent_state_ids = most_recent_state_ids.group_by(
                States.entity_id)

        most_recent_state_ids = most_recent_state_ids.subquery()

        query = session.query(States).join(
            most_recent_state_ids,
            States.state_id == most_recent_state_ids.c.max_state_id
        ).filter((~States.domain.in_(IGNORE_DOMAINS)))

        if filters:
            query = filters.apply(query, entity_ids)

        return [state for state in execute(query)
                if not state.attributes.get(ATTR_HIDDEN, False)]
예제 #11
0
    def _restore_states(service):
        """Restore states."""
        run = recorder.run_information(dt_util.utcnow())
        if run is None:
            return

        from sqlalchemy import and_, func

        states = recorder.get_model('States')
        most_recent_state_ids = recorder.query(
            func.max(states.state_id).label('max_state_id'))

        most_recent_state_ids = most_recent_state_ids.group_by(
            states.entity_id).subquery()

        query = recorder.query('States').join(
            most_recent_state_ids,
            and_(states.state_id == most_recent_state_ids.c.max_state_id))

        states = recorder.execute(query)

        data = {ATTR_ENTITY_ID: 'group.all_automations'}
        hass.services.call('homeassistant', SERVICE_TURN_OFF, data, True)

        last_services = []
        for state in states:
            if state.domain == group.DOMAIN:
                continue
            if state.domain == input_number.DOMAIN:
                data = {
                    ATTR_ENTITY_ID: state.entity_id,
                    input_number.ATTR_VALUE: state.state
                }
                service = input_number.SERVICE_SELECT_VALUE
            elif state.domain == input_select.DOMAIN:
                data = {
                    ATTR_ENTITY_ID: state.entity_id,
                    input_select.ATTR_OPTION: state.state
                }
                service = input_select.SERVICE_SELECT_OPTION
            elif state.domain == climate.DOMAIN:
                data = {
                    ATTR_ENTITY_ID: state.entity_id,
                    climate.ATTR_TEMPERATURE:
                    state.attributes.get('temperature')
                }
                service = climate.SERVICE_SET_TEMPERATURE
            elif (state.domain in [input_boolean.DOMAIN, automation.DOMAIN]):
                #or state.attributes.get('assumed_state')):
                data = {ATTR_ENTITY_ID: state.entity_id}
                if state.state == STATE_OFF:
                    service = SERVICE_TURN_OFF
                if state.state == STATE_ON:
                    service = SERVICE_TURN_ON
                else:
                    continue
                if state.domain == light.DOMAIN:
                    continue
                if state.domain == automation.DOMAIN:
                    last_services.append((state.domain, service, data))
                    continue
            elif (state.domain in [switch.DOMAIN]):
                continue
            else:
                continue
            if hass.states.get(state.entity_id) is None:
                continue
            hass.services.call(state.domain, service, data, True)

        for (domain, service, data) in last_services:
            hass.services.call(domain, service, data, True)
예제 #12
0
def get_states(hass,
               utc_point_in_time,
               entity_ids=None,
               run=None,
               filters=None):
    """Return the states at a specific point in time."""

    if run is None:
        run = recorder.run_information(hass, utc_point_in_time)

        # History did not run before utc_point_in_time
        if run is None:
            return []

    with session_scope(hass=hass) as session:
        query = session.query(States)

        if entity_ids and len(entity_ids) == 1:
            # Use an entirely different (and extremely fast) query if we only
            # have a single entity id
            query = (query.filter(
                States.last_updated >= run.start,
                States.last_updated < utc_point_in_time,
                States.entity_id.in_(entity_ids),
            ).order_by(States.last_updated.desc()).limit(1))

        else:
            # We have more than one entity to look at (most commonly we want
            # all entities,) so we need to do a search on all states since the
            # last recorder run started.

            most_recent_states_by_date = session.query(
                States.entity_id.label("max_entity_id"),
                func.max(States.last_updated).label("max_last_updated"),
            ).filter((States.last_updated >= run.start)
                     & (States.last_updated < utc_point_in_time))

            if entity_ids:
                most_recent_states_by_date.filter(
                    States.entity_id.in_(entity_ids))

            most_recent_states_by_date = most_recent_states_by_date.group_by(
                States.entity_id)

            most_recent_states_by_date = most_recent_states_by_date.subquery()

            most_recent_state_ids = session.query(
                func.max(States.state_id).label("max_state_id")).join(
                    most_recent_states_by_date,
                    and_(
                        States.entity_id ==
                        most_recent_states_by_date.c.max_entity_id,
                        States.last_updated ==
                        most_recent_states_by_date.c.max_last_updated,
                    ),
                )

            most_recent_state_ids = most_recent_state_ids.group_by(
                States.entity_id)

            most_recent_state_ids = most_recent_state_ids.subquery()

            query = query.join(
                most_recent_state_ids,
                States.state_id == most_recent_state_ids.c.max_state_id,
            ).filter(~States.domain.in_(IGNORE_DOMAINS))

            if filters:
                query = filters.apply(query, entity_ids)

        return [
            state for state in execute(query)
            if not state.attributes.get(ATTR_HIDDEN, False)
        ]