示例#1
0
文件: test_dt.py 项目: jcgoette/core
def test_find_next_time_expression_tenth_second_pattern_does_not_drift_entering_dst():
    """Test finding next time expression tenth second pattern does not drift entering dst."""
    tz = dt_util.get_time_zone("America/Chicago")
    dt_util.set_default_time_zone(tz)
    tenth_second_pattern = (None, None, "10")
    # Entering DST, clocks go forward
    test_time = datetime(2021, 3, 15, 2, 30, 0, tzinfo=tz, fold=0)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *tenth_second_pattern
    )
    next_time = dt_util.find_next_time_expression_time(
        test_time, matching_seconds, matching_minutes, matching_hours
    )
    assert next_time == datetime(2021, 3, 15, 2, 30, 10, tzinfo=tz)
    prev_target = next_time
    for i in range(1000):
        next_target = dt_util.find_next_time_expression_time(
            prev_target.replace(microsecond=999999) + timedelta(seconds=1),
            matching_seconds,
            matching_minutes,
            matching_hours,
        )
        assert (next_target - prev_target).total_seconds() == 60
        assert next_target.second == 10
        prev_target = next_target
示例#2
0
    async def async_reset_workday_timer(self):
        """the workday polling timer has finished"""
        @callback
        async def async_workday_timer_finished(_now):
            """perform daily polling of the workday entity"""
            _LOGGER.debug("Performing daily update of workday sensor")
            await self.async_reset_workday_timer()
            async_dispatcher_send(self.hass,
                                  const.EVENT_WORKDAY_SENSOR_UPDATED)

        now = dt_util.as_local(dt_util.utcnow())
        ts = dt_util.find_next_time_expression_time(now,
                                                    seconds=[0],
                                                    minutes=[5],
                                                    hours=[0])
        today = now.date()
        while ts.date() == today:
            # ensure the timer is set for the next day
            now = now + datetime.timedelta(days=1)
            ts = dt_util.find_next_time_expression_time(now,
                                                        seconds=[0],
                                                        minutes=[5],
                                                        hours=[0])

        if self._workday_timer:
            self._workday_timer()

        self._workday_timer = async_track_point_in_time(
            self.hass, async_workday_timer_finished, ts)
示例#3
0
文件: test_dt.py 项目: jcgoette/core
    def find(dt, hour, minute, second):
        """Call test_find_next_time_expression_time."""
        seconds = dt_util.parse_time_expression(second, 0, 59)
        minutes = dt_util.parse_time_expression(minute, 0, 59)
        hours = dt_util.parse_time_expression(hour, 0, 23)

        return dt_util.find_next_time_expression_time(dt, seconds, minutes, hours)
示例#4
0
def test_find_next_time_expression_day_before_dst_change_the_same_time():
    """Test the day before DST to establish behavior without DST."""
    tz = dt_util.get_time_zone("America/Chicago")
    dt_util.set_default_time_zone(tz)

    # Not in DST yet
    hour_minute_second = (12, 30, 1)
    test_time = datetime(2021, 10, 7, *hour_minute_second, tzinfo=tz, fold=0)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *hour_minute_second)
    next_time = dt_util.find_next_time_expression_time(test_time,
                                                       matching_seconds,
                                                       matching_minutes,
                                                       matching_hours)
    assert next_time == datetime(2021,
                                 10,
                                 7,
                                 *hour_minute_second,
                                 tzinfo=tz,
                                 fold=0)
    assert next_time.fold == 0
    assert dt_util.as_utc(next_time) == datetime(2021,
                                                 10,
                                                 7,
                                                 17,
                                                 30,
                                                 1,
                                                 tzinfo=dt_util.UTC)
示例#5
0
    def update(now=None):
        #   request
        r = requests.get(url, headers)
        response = r.content.decode("utf-8")
        jsonstring = json.loads(response)
        inner = jsonstring["data"]

        prayer = inner["timings"]

        fajr = prayer["Fajr"]
        sunrise = prayer["Sunrise"]
        dhuhr = prayer["Dhuhr"]
        asr = prayer["Asr"]
        maghrib = prayer["Maghrib"]
        isha = prayer["Isha"]

        hass.states.set('Gebedstijden.Fajr', fajr)
        hass.states.set('Gebedstijden.Sunrise', sunrise)
        hass.states.set('Gebedstijden.Dhuhr', dhuhr)
        hass.states.set('Gebedstijden.Asr', asr)
        hass.states.set('Gebedstijden.Maghrib', maghrib)
        hass.states.set('Gebedstijden.Isha', isha)

        # Run again at next (local) midnight.
        track_point_in_time(
            hass, update,
            dt_util.find_next_time_expression_time(dt_util.now(), [0], [0], [0]))
示例#6
0
    def calculate_next(now: datetime) -> None:
        """Calculate and set the next time the trigger should fire."""
        nonlocal next_time

        localized_now = dt_util.as_local(now) if local else now
        next_time = dt_util.find_next_time_expression_time(
            localized_now, matching_seconds, matching_minutes, matching_hours)
示例#7
0
def test_find_next_time_expression_time_leave_dst_chicago_inside_the_fold_ahead_10_min(
):
    """Test leaving daylight saving time for find_next_time_expression_time."""
    tz = dt_util.get_time_zone("America/Chicago")
    dt_util.set_default_time_zone(tz)

    # Leaving DST, clocks are rolled back

    # Find 10m later while we are in the fold
    # Start at 01:30:01 fold=0
    # Reach to 01:40:01 fold=1
    hour_minute_second = (1, 40, 1)
    test_time = datetime(2021, 11, 7, 1, 30, 1, tzinfo=tz, fold=1)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *hour_minute_second)

    next_time = dt_util.find_next_time_expression_time(test_time,
                                                       matching_seconds,
                                                       matching_minutes,
                                                       matching_hours)
    assert next_time == datetime(2021,
                                 11,
                                 7,
                                 *hour_minute_second,
                                 tzinfo=tz,
                                 fold=1)
    assert next_time.fold == 1  # time is ambiguous
    assert dt_util.as_utc(next_time) == datetime(2021,
                                                 11,
                                                 7,
                                                 7,
                                                 40,
                                                 1,
                                                 tzinfo=dt_util.UTC)
示例#8
0
def test_find_next_time_expression_time_leave_dst_chicago_past_the_fold_ahead_2_hour_10_min(
):
    """Test leaving daylight saving time for find_next_time_expression_time."""
    tz = dt_util.get_time_zone("America/Chicago")
    dt_util.set_default_time_zone(tz)

    # Leaving DST, clocks are rolled back

    # Find 1h 10m after into the fold
    # Start at 01:30:01 fold=0
    # Reach to 02:20:01 past the fold
    hour_minute_second = (2, 20, 1)
    test_time = datetime(2021, 11, 7, 1, 30, 1, tzinfo=tz, fold=0)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *hour_minute_second)

    next_time = dt_util.find_next_time_expression_time(test_time,
                                                       matching_seconds,
                                                       matching_minutes,
                                                       matching_hours)
    assert next_time == datetime(2021,
                                 11,
                                 7,
                                 *hour_minute_second,
                                 tzinfo=tz,
                                 fold=1)
    assert next_time.fold == 0  # Time is no longer ambiguous
    assert dt_util.as_utc(next_time) == datetime(2021,
                                                 11,
                                                 7,
                                                 8,
                                                 20,
                                                 1,
                                                 tzinfo=dt_util.UTC)
示例#9
0
def test_find_next_time_expression_time_leave_dst_chicago_before_the_fold_30_s(
):
    """Test leaving daylight saving time for find_next_time_expression_time 30s into the future."""
    tz = dt_util.get_time_zone("America/Chicago")
    dt_util.set_default_time_zone(tz)

    # Leaving DST, clocks are rolled back

    # Move ahead 30 seconds not folded yet
    hour_minute_second = (1, 30, 31)
    test_time = datetime(2021, 11, 7, 1, 30, 1, tzinfo=tz, fold=0)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *hour_minute_second)
    next_time = dt_util.find_next_time_expression_time(test_time,
                                                       matching_seconds,
                                                       matching_minutes,
                                                       matching_hours)
    assert next_time == datetime(2021, 11, 7, 1, 30, 31, tzinfo=tz, fold=0)
    assert dt_util.as_utc(next_time) == datetime(2021,
                                                 11,
                                                 7,
                                                 6,
                                                 30,
                                                 31,
                                                 tzinfo=dt_util.UTC)
    assert next_time.fold == 0
示例#10
0
def test_find_next_time_expression_time_leave_dst_chicago_into_the_fold_same_time(
):
    """Test leaving daylight saving time for find_next_time_expression_time."""
    tz = dt_util.get_time_zone("America/Chicago")
    dt_util.set_default_time_zone(tz)

    # Leaving DST, clocks are rolled back

    # Find the same time inside the fold
    hour_minute_second = (1, 30, 1)
    test_time = datetime(2021, 11, 7, *hour_minute_second, tzinfo=tz, fold=0)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *hour_minute_second)

    next_time = dt_util.find_next_time_expression_time(test_time,
                                                       matching_seconds,
                                                       matching_minutes,
                                                       matching_hours)
    assert next_time == datetime(2021,
                                 11,
                                 7,
                                 *hour_minute_second,
                                 tzinfo=tz,
                                 fold=1)
    assert next_time.fold == 0
    assert dt_util.as_utc(next_time) == datetime(2021,
                                                 11,
                                                 7,
                                                 6,
                                                 30,
                                                 1,
                                                 tzinfo=dt_util.UTC)
示例#11
0
def set_update_interval(instances_count: int,
                        requests_remaining: int) -> timedelta:
    """
    Return data update interval.

    The number of requests is reset at midnight UTC so we calculate the update
    interval based on number of minutes until midnight, the number of Airly instances
    and the number of remaining requests.
    """
    now = dt_util.utcnow()
    midnight = dt_util.find_next_time_expression_time(now,
                                                      seconds=[0],
                                                      minutes=[0],
                                                      hours=[0])
    minutes_to_midnight = (midnight - now).total_seconds() / 60
    interval = timedelta(minutes=min(
        max(
            ceil(minutes_to_midnight / requests_remaining * instances_count),
            MIN_UPDATE_INTERVAL,
        ),
        MAX_UPDATE_INTERVAL,
    ))

    _LOGGER.debug("Data will be update every %s", interval)

    return interval
示例#12
0
        def find(dt, hour, minute, second):
            """Call test_find_next_time_expression_time."""
            seconds = dt_util.parse_time_expression(second, 0, 59)
            minutes = dt_util.parse_time_expression(minute, 0, 59)
            hours = dt_util.parse_time_expression(hour, 0, 23)

            return dt_util.find_next_time_expression_time(
                dt, seconds, minutes, hours)
示例#13
0
 def _round_to_next_five_minutes(now):
     """Rounds the provided time to the next 5 minutes."""
     matching_seconds = [0]
     matching_minutes = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
     matching_hours = dt_util.parse_time_expression('*', 0, 23)
     return dt_util.find_next_time_expression_time(now, matching_seconds,
                                                   matching_minutes,
                                                   matching_hours)
示例#14
0
def test_find_next_time_expression_microseconds():
    """Test finding next time expression with microsecond clock drift."""
    hour_minute_second = (None, "5", "10")
    test_time = datetime(2022, 5, 13, 0, 5, 9, tzinfo=dt_util.UTC)
    matching_hours, matching_minutes, matching_seconds = _get_matches(
        *hour_minute_second)
    next_time = dt_util.find_next_time_expression_time(test_time,
                                                       matching_seconds,
                                                       matching_minutes,
                                                       matching_hours)
    assert next_time == datetime(2022, 5, 13, 0, 5, 10, tzinfo=dt_util.UTC)
    next_time_last_microsecond_plus_one = next_time.replace(
        microsecond=999999) + timedelta(seconds=1)
    time_after = dt_util.find_next_time_expression_time(
        next_time_last_microsecond_plus_one,
        matching_seconds,
        matching_minutes,
        matching_hours,
    )
    assert time_after == datetime(2022, 5, 13, 1, 5, 10, tzinfo=dt_util.UTC)
示例#15
0
def test_find_next_time_expression_exiting_dst(now_dt, expected_dt):
    """Test exiting daylight saving time for find_next_time_expression_time."""
    tz = dt_util.get_time_zone("Europe/Vienna")
    dt_util.set_default_time_zone(tz)
    # match on 02:30:00 every day
    pattern_seconds = dt_util.parse_time_expression(0, 0, 59)
    pattern_minutes = dt_util.parse_time_expression(30, 0, 59)
    pattern_hours = dt_util.parse_time_expression(2, 0, 59)

    now_dt = now_dt.replace(tzinfo=tz)
    expected_dt = expected_dt.replace(tzinfo=tz)

    res_dt = dt_util.find_next_time_expression_time(now_dt, pattern_seconds,
                                                    pattern_minutes,
                                                    pattern_hours)
    assert dt_util.as_utc(res_dt) == dt_util.as_utc(expected_dt)
示例#16
0
    def calculate_timestamp(self,
                            time_str,
                            now: datetime.datetime = None,
                            iteration: int = 0) -> datetime.datetime:
        """calculate the next occurence of a time string"""
        if time_str is None:
            return None
        if now is None:
            now = dt_util.as_local(dt_util.utcnow())

        res = has_sun(time_str)
        if not res:
            # fixed time
            time = dt_util.parse_time(time_str)
            ts = dt_util.find_next_time_expression_time(
                now, [time.second], [time.minute], [time.hour])
        else:
            # relative to sunrise/sunset
            sun = self.hass.states.get(const.SUN_ENTITY)
            if not sun:
                return None
            ts = None
            if (res.group(1) == const.SUN_EVENT_SUNRISE
                    and ATTR_NEXT_RISING in sun.attributes):
                ts = dt_util.parse_datetime(sun.attributes[ATTR_NEXT_RISING])
            elif (res.group(1) == const.SUN_EVENT_SUNSET
                  and ATTR_NEXT_SETTING in sun.attributes):
                ts = dt_util.parse_datetime(sun.attributes[ATTR_NEXT_SETTING])
            if not ts:
                return None
            ts = dt_util.as_local(ts)
            ts = ts.replace(second=0)
            time_sun = datetime.timedelta(hours=ts.hour,
                                          minutes=ts.minute,
                                          seconds=ts.second)
            offset = dt_util.parse_time(res.group(3))
            offset = datetime.timedelta(hours=offset.hour,
                                        minutes=offset.minute,
                                        seconds=offset.second)
            if res.group(2) == "-":
                if (time_sun - offset).total_seconds() >= 0:
                    ts = ts - offset
                else:
                    # prevent offset to shift the time past the extends of the day
                    ts = ts.replace(hour=0, minute=0, second=0)
            else:
                if (time_sun + offset).total_seconds() <= 86340:
                    ts = ts + offset
                else:
                    # prevent offset to shift the time past the extends of the day
                    ts = ts.replace(hour=23, minute=59, second=0)
            ts = dt_util.find_next_time_expression_time(
                now, [ts.second], [ts.minute], [ts.hour])

        time_delta = datetime.timedelta(seconds=1)

        if self.day_in_weekdays(ts) and ((ts - now).total_seconds() > 0
                                         or iteration > 0):

            if self._start_date and days_until_date(self._start_date, ts) > 0:
                # start date is more than a week in the future, jump to start date
                time_delta = datetime.timedelta(
                    days=days_until_date(self._start_date, ts))

            elif self._end_date and days_until_date(self._end_date, ts) < 0:
                # end date is in the past, jump to end date
                time_delta = datetime.timedelta(
                    days=days_until_date(self._end_date, ts))

            else:
                # date restrictions are met
                return ts

        # calculate next timestamp
        next_day = dt_util.find_next_time_expression_time(
            now + time_delta, [0], [0], [0])
        if iteration > 7:
            _LOGGER.warning(
                "failed to calculate next timeslot for schedule {}".format(
                    self.id))
            return None
        return self.calculate_timestamp(time_str, next_day, iteration + 1)
示例#17
0
 def calculate_next(now: datetime) -> datetime:
     """Calculate and set the next time the trigger should fire."""
     ts_now = now.astimezone(tz) if tz else now
     return dt_util.find_next_time_expression_time(
         ts_now, matching_seconds, matching_minutes, matching_hours
     )
 def rounder(t):
     matching_seconds = [0]
     matching_minutes = [2]
     matching_hours = dt_util.parse_time_expression("*", 0, 23)
     return dt_util.find_next_time_expression_time(
         t, matching_seconds, matching_minutes, matching_hours)