Ejemplo n.º 1
0
def get_significant_states(start_time, end_time=None, entity_id=None):
    """
    Return states changes during UTC period start_time - end_time.

    Significant states are all states where there is a state change,
    as well as all states from certain domains (for instance
    thermostat so that we get current temperature in our graphs).
    """
    states = recorder.get_model('States')
    query = recorder.query(
        'States').filter((states.domain.in_(SIGNIFICANT_DOMAINS)
                          | (states.last_changed == states.last_updated))
                         & ((~states.domain.in_(IGNORE_DOMAINS))
                            & (states.last_updated > start_time)))

    if end_time is not None:
        query = query.filter(states.last_updated < end_time)

    if entity_id is not None:
        query = query.filter_by(entity_id=entity_id.lower())

    states = (state for state in recorder.execute(
        query.order_by(states.entity_id, states.last_updated))
              if _is_significant(state))

    return states_to_json(states, start_time, entity_id)
Ejemplo n.º 2
0
 def update(self):
     """Get the latest data and update the states."""
     data = self.speedtest_client.data
     if data is None:
         entity_id = 'sensor.speedtest_' + self._name.lower()
         states = recorder.get_model('States')
         try:
             last_state = recorder.execute(
                 recorder.query('States').filter(
                     (states.entity_id == entity_id) &
                     (states.last_changed == states.last_updated) &
                     (states.state != 'unknown')
                 ).order_by(states.state_id.desc()).limit(1))
         except TypeError:
             return
         except RuntimeError:
             return
         if not last_state:
             return
         self._state = last_state[0].state
     elif self.type == 'ping':
         self._state = data['ping']
     elif self.type == 'download':
         self._state = data['download']
     elif self.type == 'upload':
         self._state = data['upload']
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
 def get_results():
     """Query DB for results."""
     events = recorder.get_model('Events')
     query = recorder.query('Events').filter((
         events.time_fired > start_day) & (events.time_fired < end_day))
     events = recorder.execute(query)
     return _exclude_events(events, self.config)
Ejemplo n.º 5
0
 def update(self):
     """Get the latest data and update the states."""
     data = self.speedtest_client.data
     if data is None:
         entity_id = 'sensor.speedtest_' + self._name.lower()
         states = recorder.get_model('States')
         try:
             last_state = recorder.execute(
                 recorder.query('States').filter(
                     (states.entity_id == entity_id)
                     & (states.last_changed == states.last_updated)
                     & (states.state != 'unknown')).order_by(
                         states.state_id.desc()).limit(1))
         except TypeError:
             return
         except RuntimeError:
             return
         if not last_state:
             return
         self._state = last_state[0].state
     elif self.type == 'ping':
         self._state = data['ping']
     elif self.type == 'download':
         self._state = data['download']
     elif self.type == 'upload':
         self._state = data['upload']
Ejemplo n.º 6
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
Ejemplo n.º 7
0
    def test_saving_event(self):
        """Test saving and restoring an event."""
        event_type = 'EVENT_TEST'
        event_data = {'test_attr': 5, 'test_attr_10': 'nice'}

        events = []

        def event_listener(event):
            """Record events from eventbus."""
            if event.event_type == event_type:
                events.append(event)

        self.hass.bus.listen(MATCH_ALL, event_listener)

        self.hass.bus.fire(event_type, event_data)

        self.hass.block_till_done()
        recorder._INSTANCE.block_till_done()

        db_events = recorder.execute(
            recorder.query('Events').filter_by(event_type=event_type))

        assert len(events) == 1
        assert len(db_events) == 1

        event = events[0]
        db_event = db_events[0]

        assert event.event_type == db_event.event_type
        assert event.data == db_event.data
        assert event.origin == db_event.origin

        # Recorder uses SQLite and stores datetimes as integer unix timestamps
        assert event.time_fired.replace(microsecond=0) == \
            db_event.time_fired.replace(microsecond=0)
Ejemplo n.º 8
0
def get_significant_states(start_time, end_time=None, entity_id=None,
                           filters=None):
    """
    Return states changes during UTC period start_time - end_time.

    Significant states are all states where there is a state change,
    as well as all states from certain domains (for instance
    thermostat so that we get current temperature in our graphs).
    """
    entity_ids = (entity_id.lower(), ) if entity_id is not None else None
    states = recorder.get_model('States')
    query = recorder.query('States').filter(
        (states.domain.in_(SIGNIFICANT_DOMAINS) |
         (states.last_changed == states.last_updated)) &
        (states.last_updated > start_time))
    if filters:
        query = filters.apply(query, entity_ids)

    if end_time is not None:
        query = query.filter(states.last_updated < end_time)

    states = (
        state for state in recorder.execute(
            query.order_by(states.entity_id, states.last_updated))
        if (_is_significant(state) and
            not state.attributes.get(ATTR_HIDDEN, False)))

    return states_to_json(states, start_time, entity_id, filters)
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
def get_significant_states(start_time, end_time=None, entity_id=None):
    """
    Return states changes during UTC period start_time - end_time.

    Significant states are all states where there is a state change,
    as well as all states from certain domains (for instance
    thermostat so that we get current temperature in our graphs).
    """
    states = recorder.get_model("States")
    query = recorder.query("States").filter(
        (states.domain.in_(SIGNIFICANT_DOMAINS) | (states.last_changed == states.last_updated))
        & ((~states.domain.in_(IGNORE_DOMAINS)) & (states.last_updated > start_time))
    )

    if end_time is not None:
        query = query.filter(states.last_updated < end_time)

    if entity_id is not None:
        query = query.filter_by(entity_id=entity_id.lower())

    states = (
        state
        for state in recorder.execute(query.order_by(states.entity_id, states.last_updated))
        if _is_significant(state)
    )

    return states_to_json(states, start_time, entity_id)
Ejemplo n.º 11
0
 def get_results():
     """Query DB for results."""
     events = recorder.get_model('Events')
     query = recorder.query('Events').filter(
         (events.time_fired > start_day) &
         (events.time_fired < end_day))
     events = recorder.execute(query)
     return _exclude_events(events, self.config)
Ejemplo n.º 12
0
def last_5_states(entity_id):
    """Return the last 5 states for entity_id."""
    entity_id = entity_id.lower()

    states = recorder.get_model('States')
    return recorder.execute(
        recorder.query('States').filter((states.entity_id == entity_id) & (
            states.last_changed == states.last_updated)).order_by(
                states.state_id.desc()).limit(5))
Ejemplo n.º 13
0
def last_5_states(entity_id):
    """Return the last 5 states for entity_id."""
    entity_id = entity_id.lower()

    states = recorder.get_model('States')
    return recorder.execute(
        recorder.query('States').filter(
            (states.entity_id == entity_id) &
            (states.last_changed == states.last_updated)
        ).order_by(states.state_id.desc()).limit(5))
Ejemplo n.º 14
0
def _add_entities(hass, entity_ids):
    """Add entities."""
    attributes = {'test_attr': 5, 'test_attr_10': 'nice'}
    for idx, entity_id in enumerate(entity_ids):
        hass.states.set(entity_id, 'state{}'.format(idx), attributes)
        hass.block_till_done()
    recorder._INSTANCE.block_till_done()
    db_states = recorder.query('States')
    states = recorder.execute(db_states)
    assert db_states[0].event_id is not None
    return states
Ejemplo n.º 15
0
def _add_entities(hass, entity_ids):
    """Add entities."""
    attributes = {'test_attr': 5, 'test_attr_10': 'nice'}
    for idx, entity_id in enumerate(entity_ids):
        hass.states.set(entity_id, 'state{}'.format(idx), attributes)
        hass.block_till_done()
    recorder._INSTANCE.block_till_done()
    db_states = recorder.query('States')
    states = recorder.execute(db_states)
    assert db_states[0].event_id is not None
    return states
Ejemplo n.º 16
0
    def get(self, request, datetime=None):
        """Retrieve logbook entries."""
        start_day = dt_util.as_utc(datetime or dt_util.start_of_local_day())
        end_day = start_day + timedelta(days=1)

        events = recorder.get_model('Events')
        query = recorder.query('Events').filter(
            (events.time_fired > start_day) &
            (events.time_fired < end_day))
        events = recorder.execute(query)

        return self.json(humanify(events))
Ejemplo n.º 17
0
    def get(self, request, datetime=None):
        """Retrieve logbook entries."""
        start_day = dt_util.as_utc(datetime or dt_util.start_of_local_day())
        end_day = start_day + timedelta(days=1)

        events = recorder.get_model('Events')
        query = recorder.query('Events').filter(
            (events.time_fired > start_day) &
            (events.time_fired < end_day))
        events = recorder.execute(query)

        return self.json(humanify(events))
Ejemplo n.º 18
0
def test_recorder_bad_execute(hass_recorder):
    """Bad execute, retry 3 times."""
    hass_recorder()

    def to_native():
        """Rasie exception."""
        from sqlalchemy.exc import SQLAlchemyError
        raise SQLAlchemyError()

    mck1 = MagicMock()
    mck1.to_native = to_native

    with patch('homeassistant.components.recorder.time.sleep') as e_mock:
        res = recorder.execute((mck1, ))
    assert res == []
    assert e_mock.call_count == 3
Ejemplo n.º 19
0
def state_changes_during_period(start_time, end_time=None, entity_id=None):
    """Return states changes during UTC period start_time - end_time."""
    states = recorder.get_model("States")
    query = recorder.query("States").filter(
        (states.last_changed == states.last_updated) & (states.last_changed > start_time)
    )

    if end_time is not None:
        query = query.filter(states.last_updated < end_time)

    if entity_id is not None:
        query = query.filter_by(entity_id=entity_id.lower())

    states = recorder.execute(query.order_by(states.entity_id, states.last_updated))

    return states_to_json(states, start_time, entity_id)
Ejemplo n.º 20
0
def test_recorder_bad_execute(hass_recorder):
    """Bad execute, retry 3 times."""
    hass_recorder()

    def to_native():
        """Rasie exception."""
        from sqlalchemy.exc import SQLAlchemyError
        raise SQLAlchemyError()

    mck1 = MagicMock()
    mck1.to_native = to_native

    with patch('homeassistant.components.recorder.time.sleep') as e_mock:
        res = recorder.execute((mck1,))
    assert res == []
    assert e_mock.call_count == 3
Ejemplo n.º 21
0
def state_changes_during_period(start_time, end_time=None, entity_id=None):
    """Return states changes during UTC period start_time - end_time."""
    states = recorder.get_model('States')
    query = recorder.query('States').filter(
        (states.last_changed == states.last_updated) &
        (states.last_changed > start_time))

    if end_time is not None:
        query = query.filter(states.last_updated < end_time)

    if entity_id is not None:
        query = query.filter_by(entity_id=entity_id.lower())

    states = recorder.execute(
        query.order_by(states.entity_id, states.last_updated))

    return states_to_json(states, start_time, entity_id)
Ejemplo n.º 22
0
    def test_saving_state(self):
        """Test saving and restoring a state."""
        entity_id = 'test.recorder'
        state = 'restoring_from_db'
        attributes = {'test_attr': 5, 'test_attr_10': 'nice'}

        self.hass.states.set(entity_id, state, attributes)

        self.hass.block_till_done()
        recorder._INSTANCE.block_till_done()

        db_states = recorder.query('States')
        states = recorder.execute(db_states)

        assert db_states[0].event_id is not None

        self.assertEqual(1, len(states))
        self.assertEqual(self.hass.states.get(entity_id), states[0])
Ejemplo n.º 23
0
    def test_saving_state(self):
        """Test saving and restoring a state."""
        entity_id = 'test.recorder'
        state = 'restoring_from_db'
        attributes = {'test_attr': 5, 'test_attr_10': 'nice'}

        self.hass.states.set(entity_id, state, attributes)

        self.hass.block_till_done()
        recorder._INSTANCE.block_till_done()

        db_states = recorder.query('States')
        states = recorder.execute(db_states)

        assert db_states[0].event_id is not None

        self.assertEqual(1, len(states))
        self.assertEqual(self.hass.states.get(entity_id), states[0])
Ejemplo n.º 24
0
    def test_saving_event(self):
        """Test saving and restoring an event."""
        event_type = 'EVENT_TEST'
        event_data = {'test_attr': 5, 'test_attr_10': 'nice'}

        events = []

        @callback
        def event_listener(event):
            """Record events from eventbus."""
            if event.event_type == event_type:
                events.append(event)

        self.hass.bus.listen(MATCH_ALL, event_listener)

        self.hass.bus.fire(event_type, event_data)

        self.hass.block_till_done()
        recorder._INSTANCE.block_till_done()

        db_events = recorder.execute(
            recorder.query('Events').filter_by(
                event_type=event_type))

        assert len(events) == 1
        assert len(db_events) == 1

        event = events[0]
        db_event = db_events[0]

        assert event.event_type == db_event.event_type
        assert event.data == db_event.data
        assert event.origin == db_event.origin

        # Recorder uses SQLite and stores datetimes as integer unix timestamps
        assert event.time_fired.replace(microsecond=0) == \
            db_event.time_fired.replace(microsecond=0)
Ejemplo n.º 25
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)