Пример #1
0
def test_get_states(hass_recorder):
    """Test getting states at a specific point in time."""
    hass = hass_recorder()
    now, future, states = _setup_get_states(hass)
    # Get states returns everything before POINT for all entities
    for state1, state2 in zip(
            states,
            sorted(history.get_states(hass, future),
                   key=lambda state: state.entity_id),
    ):
        assert state1 == state2

    # Get states returns everything before POINT for tested entities
    entities = [f"test.point_in_time_{i % 5}" for i in range(5)]
    for state1, state2 in zip(
            states,
            sorted(
                history.get_states(hass, future, entities),
                key=lambda state: state.entity_id,
            ),
    ):
        assert state1 == state2

    # Test get_state here because we have a DB setup
    assert states[0] == history.get_state(hass, future, states[0].entity_id)

    time_before_recorder_ran = now - timedelta(days=1000)
    assert history.get_states(hass, time_before_recorder_ran) == []

    assert history.get_state(hass, time_before_recorder_ran, "demo.id") is None
Пример #2
0
def test_get_states(hass_recorder):
    """Test getting states at a specific point in time."""
    hass = hass_recorder()
    states = []

    now = dt_util.utcnow()
    with patch("homeassistant.components.recorder.dt_util.utcnow",
               return_value=now):
        for i in range(5):
            state = ha.State(
                f"test.point_in_time_{i % 5}",
                f"State {i}",
                {"attribute_test": i},
            )

            mock_state_change_event(hass, state)

            states.append(state)

        wait_recording_done(hass)

    future = now + timedelta(seconds=1)
    with patch("homeassistant.components.recorder.dt_util.utcnow",
               return_value=future):
        for i in range(5):
            state = ha.State(
                f"test.point_in_time_{i % 5}",
                f"State {i}",
                {"attribute_test": i},
            )

            mock_state_change_event(hass, state)

        wait_recording_done(hass)

    # Get states returns everything before POINT
    for state1, state2 in zip(
            states,
            sorted(history.get_states(hass, future),
                   key=lambda state: state.entity_id),
    ):
        assert state1 == state2

    # Test get_state here because we have a DB setup
    assert states[0] == history.get_state(hass, future, states[0].entity_id)

    time_before_recorder_ran = now - timedelta(days=1000)
    assert history.get_states(hass, time_before_recorder_ran) == []

    assert history.get_state(hass, time_before_recorder_ran, "demo.id") is None
Пример #3
0
    def _update(self, start, end, now_timestamp, start_timestamp,
                end_timestamp):
        # Get history between start and end
        history_list = history.state_changes_during_period(
            self.hass, start, end, str(self._entity_id), no_attributes=True)

        if self._entity_id not in history_list:
            return

        # Get the first state
        last_state = history.get_state(self.hass,
                                       start,
                                       self._entity_id,
                                       no_attributes=True)
        last_state = last_state is not None and last_state in self._entity_states
        last_time = start_timestamp
        elapsed = 0
        count = 0

        # Make calculations
        for item in history_list.get(self._entity_id):
            current_state = item.state in self._entity_states
            current_time = item.last_changed.timestamp()

            if last_state:
                elapsed += current_time - last_time
            if current_state and not last_state:
                count += 1

            last_state = current_state
            last_time = current_time

        # Count time elapsed between last history state and end of measure
        if last_state:
            measure_end = min(end_timestamp, now_timestamp)
            elapsed += measure_end - last_time

        # Save value in hours
        self.value = elapsed / 3600

        # Save counter
        self.count = count
Пример #4
0
def get_state(hass, utc_point_in_time, entity_id, run=None):
    """Return a state at a specific point in time."""
    return history.get_state(hass, utc_point_in_time, entity_id, run=None)
Пример #5
0
    def _update_state(self):  # pylint: disable=r0914,r0912,r0915
        """Update the sensor state."""
        _LOGGER.debug('Updating sensor "%s"', self.name)
        start = end = start_ts = end_ts = None
        p_period = self._period

        # Parse templates
        self._update_period()

        if self._period is not None:
            now = datetime.datetime.now()
            start, end = self._period
            if p_period is None:
                p_start = p_end = now
            else:
                p_start, p_end = p_period

            # Convert times to UTC
            start = dt_util.as_utc(start)
            end = dt_util.as_utc(end)
            p_start = dt_util.as_utc(p_start)
            p_end = dt_util.as_utc(p_end)

            # Compute integer timestamps
            now_ts = math.floor(dt_util.as_timestamp(now))
            start_ts = math.floor(dt_util.as_timestamp(start))
            end_ts = math.floor(dt_util.as_timestamp(end))
            p_start_ts = math.floor(dt_util.as_timestamp(p_start))
            p_end_ts = math.floor(dt_util.as_timestamp(p_end))

            # If period has not changed and current time after the period end..
            if start_ts == p_start_ts and end_ts == p_end_ts and end_ts <= now_ts:
                # Don't compute anything as the value cannot have changed
                return

        self.available_sources = 0
        values = []
        self.count = 0
        self.min_value = self.max_value = None

        # pylint: disable=too-many-nested-blocks
        for entity_id in self.sources:
            _LOGGER.debug('Processing entity "%s"', entity_id)

            state = self.hass.states.get(entity_id)  # type: LazyState

            if state is None:
                _LOGGER.error('Unable to find an entity "%s"', entity_id)
                continue

            self._init_mode(state)

            value = 0
            elapsed = 0

            if self._period is None:
                # Get current state
                value = self._get_state_value(state)
                _LOGGER.debug("Current state: %s", value)

            else:
                # Get history between start and now
                history_list = history.state_changes_during_period(
                    self.hass, start, end, str(entity_id)
                )

                if entity_id not in history_list.keys():
                    value = self._get_state_value(state)
                    _LOGGER.warning(
                        'Historical data not found for entity "%s". '
                        "Current state used: %s",
                        entity_id,
                        value,
                    )
                else:
                    # Get the first state
                    item = history.get_state(self.hass, start, entity_id)
                    _LOGGER.debug("Initial historical state: %s", item)
                    last_state = None
                    last_time = start_ts
                    if item is not None and self._has_state(item.state):
                        last_state = self._get_state_value(item)

                    # Get the other states
                    for item in history_list.get(entity_id):
                        _LOGGER.debug("Historical state: %s", item)
                        current_state = self._get_state_value(item)
                        current_time = item.last_changed.timestamp()

                        if last_state is not None:
                            last_elapsed = current_time - last_time
                            value += last_state * last_elapsed
                            elapsed += last_elapsed

                        last_state = current_state
                        last_time = current_time

                    # Count time elapsed between last history state and now
                    if last_state is not None:
                        last_elapsed = end_ts - last_time
                        value += last_state * last_elapsed
                        elapsed += last_elapsed

                    if elapsed:
                        value /= elapsed
                    _LOGGER.debug("Historical average state: %s", value)

            if isinstance(value, numbers.Number):
                values.append(value)
                self.available_sources += 1

        if values:
            self._attr_state = round(sum(values) / len(values), self._precision)
            if self._precision < 1:
                self._attr_state = int(self._attr_state)
        else:
            self._attr_state = None
        _LOGGER.debug("Total average state: %s", self._attr_state)