Пример #1
0
def sun(
    opp: OpenPeerPower,
    before: Optional[str] = None,
    after: Optional[str] = None,
    before_offset: Optional[timedelta] = None,
    after_offset: Optional[timedelta] = None,
) -> bool:
    """Test if current time matches sun requirements."""
    utcnow = dt_util.utcnow()
    today = dt_util.as_local(utcnow).date()
    before_offset = before_offset or timedelta(0)
    after_offset = after_offset or timedelta(0)

    sunrise_today = get_astral_event_date(opp, SUN_EVENT_SUNRISE, today)
    sunset_today = get_astral_event_date(opp, SUN_EVENT_SUNSET, today)

    sunrise = sunrise_today
    sunset = sunset_today
    if today > dt_util.as_local(cast(
            datetime, sunrise_today)).date() and SUN_EVENT_SUNRISE in (before,
                                                                       after):
        tomorrow = dt_util.as_local(utcnow + timedelta(days=1)).date()
        sunrise_tomorrow = get_astral_event_date(opp, SUN_EVENT_SUNRISE,
                                                 tomorrow)
        sunrise = sunrise_tomorrow

    if today > dt_util.as_local(cast(
            datetime, sunset_today)).date() and SUN_EVENT_SUNSET in (before,
                                                                     after):
        tomorrow = dt_util.as_local(utcnow + timedelta(days=1)).date()
        sunset_tomorrow = get_astral_event_date(opp, SUN_EVENT_SUNSET,
                                                tomorrow)
        sunset = sunset_tomorrow

    if sunrise is None and SUN_EVENT_SUNRISE in (before, after):
        # There is no sunrise today
        return False

    if sunset is None and SUN_EVENT_SUNSET in (before, after):
        # There is no sunset today
        return False

    if before == SUN_EVENT_SUNRISE and utcnow > cast(datetime,
                                                     sunrise) + before_offset:
        return False

    if before == SUN_EVENT_SUNSET and utcnow > cast(datetime,
                                                    sunset) + before_offset:
        return False

    if after == SUN_EVENT_SUNRISE and utcnow < cast(datetime,
                                                    sunrise) + after_offset:
        return False

    if after == SUN_EVENT_SUNSET and utcnow < cast(datetime,
                                                   sunset) + after_offset:
        return False

    return True
Пример #2
0
 def find_stop_time(self, now):
     """Return dusk or stop_time if given."""
     if self._stop_time:
         dusk = now.replace(
             hour=self._stop_time.hour, minute=self._stop_time.minute, second=0
         )
     else:
         dusk = get_astral_event_date(self.opp, "dusk", now.date())
     return dusk
Пример #3
0
 def find_start_time(self, now):
     """Return sunrise or start_time if given."""
     if self._start_time:
         sunrise = now.replace(
             hour=self._start_time.hour, minute=self._start_time.minute, second=0
         )
     else:
         sunrise = get_astral_event_date(self.opp, SUN_EVENT_SUNRISE, now.date())
     return sunrise
Пример #4
0
    def _calculate_boudary_time(self):
        """Calculate internal absolute time boundaries."""
        nowutc = dt_util.utcnow()
        # If after value is a sun event instead of absolute time
        if is_sun_event(self._after):
            # Calculate the today's event utc time or
            # if not available take next
            after_event_date = get_astral_event_date(
                self.opp, self._after, nowutc) or get_astral_event_next(
                    self.opp, self._after, nowutc)
        else:
            # Convert local time provided to UTC today
            # datetime.combine(date, time, tzinfo) is not supported
            # in python 3.5. The self._after is provided
            # with opp configured TZ not system wide
            after_event_date = self._naive_time_to_utc_datetime(self._after)

        self._time_after = after_event_date

        # If before value is a sun event instead of absolute time
        if is_sun_event(self._before):
            # Calculate the today's event utc time or  if not available take
            # next
            before_event_date = get_astral_event_date(
                self.opp, self._before, nowutc) or get_astral_event_next(
                    self.opp, self._before, nowutc)
            # Before is earlier than after
            if before_event_date < after_event_date:
                # Take next day for before
                before_event_date = get_astral_event_next(
                    self.opp, self._before, after_event_date)
        else:
            # Convert local time provided to UTC today, see above
            before_event_date = self._naive_time_to_utc_datetime(self._before)

            # It is safe to add timedelta days=1 to UTC as there is no DST
            if before_event_date < after_event_date + self._after_offset:
                before_event_date += timedelta(days=1)

        self._time_before = before_event_date

        # Add offset to utc boundaries according to the configuration
        self._time_after += self._after_offset
        self._time_before += self._before_offset
Пример #5
0
def test_date_events(opp):
    """Test retrieving next sun events."""
    utc_now = datetime(2016, 11, 1, 8, 0, 0, tzinfo=dt_util.UTC)
    from astral import LocationInfo
    import astral.sun

    utc_today = utc_now.date()

    location = LocationInfo(latitude=opp.config.latitude,
                            longitude=opp.config.longitude)

    dawn = astral.sun.dawn(location.observer, utc_today)
    dusk = astral.sun.dusk(location.observer, utc_today)
    midnight = astral.sun.midnight(location.observer, utc_today)
    noon = astral.sun.noon(location.observer, utc_today)
    sunrise = astral.sun.sunrise(location.observer, utc_today)
    sunset = astral.sun.sunset(location.observer, utc_today)

    assert dawn == sun.get_astral_event_date(opp, "dawn", utc_today)
    assert dusk == sun.get_astral_event_date(opp, "dusk", utc_today)
    assert midnight == sun.get_astral_event_date(opp, "midnight", utc_today)
    assert noon == sun.get_astral_event_date(opp, "noon", utc_today)
    assert sunrise == sun.get_astral_event_date(opp, SUN_EVENT_SUNRISE,
                                                utc_today)
    assert sunset == sun.get_astral_event_date(opp, SUN_EVENT_SUNSET,
                                               utc_today)
Пример #6
0
def test_norway_in_june(opp):
    """Test location in Norway where the sun doesn't set in summer."""
    opp.config.latitude = 69.6
    opp.config.longitude = 18.8

    june = datetime(2016, 6, 1, tzinfo=dt_util.UTC)

    print(
        sun.get_astral_event_date(opp, SUN_EVENT_SUNRISE,
                                  datetime(2017, 7, 25)))
    print(
        sun.get_astral_event_date(opp, SUN_EVENT_SUNSET, datetime(2017, 7,
                                                                  25)))

    print(
        sun.get_astral_event_date(opp, SUN_EVENT_SUNRISE,
                                  datetime(2017, 7, 26)))
    print(
        sun.get_astral_event_date(opp, SUN_EVENT_SUNSET, datetime(2017, 7,
                                                                  26)))

    assert sun.get_astral_event_next(opp, SUN_EVENT_SUNRISE,
                                     june) == datetime(2016,
                                                       7,
                                                       24,
                                                       22,
                                                       59,
                                                       45,
                                                       689645,
                                                       tzinfo=dt_util.UTC)
    assert sun.get_astral_event_next(opp, SUN_EVENT_SUNSET,
                                     june) == datetime(2016,
                                                       7,
                                                       25,
                                                       22,
                                                       17,
                                                       13,
                                                       503932,
                                                       tzinfo=dt_util.UTC)
    assert sun.get_astral_event_date(opp, SUN_EVENT_SUNRISE, june) is None
    assert sun.get_astral_event_date(opp, SUN_EVENT_SUNSET, june) is None
Пример #7
0
    async def async_flux_update(self, utcnow=None):
        """Update all the lights using flux."""
        if utcnow is None:
            utcnow = dt_utcnow()

        now = as_local(utcnow)

        sunset = get_astral_event_date(self.opp, SUN_EVENT_SUNSET, now.date())
        start_time = self.find_start_time(now)
        stop_time = self.find_stop_time(now)

        if stop_time <= start_time:
            # stop_time does not happen in the same day as start_time
            if start_time < now:
                # stop time is tomorrow
                stop_time += datetime.timedelta(days=1)
        elif now < start_time:
            # stop_time was yesterday since the new start_time is not reached
            stop_time -= datetime.timedelta(days=1)

        if start_time < now < sunset:
            # Daytime
            time_state = "day"
            temp_range = abs(self._start_colortemp - self._sunset_colortemp)
            day_length = int(sunset.timestamp() - start_time.timestamp())
            seconds_from_start = int(now.timestamp() - start_time.timestamp())
            percentage_complete = seconds_from_start / day_length
            temp_offset = temp_range * percentage_complete
            if self._start_colortemp > self._sunset_colortemp:
                temp = self._start_colortemp - temp_offset
            else:
                temp = self._start_colortemp + temp_offset
        else:
            # Night time
            time_state = "night"

            if now < stop_time:
                if stop_time < start_time and stop_time.day == sunset.day:
                    # we need to use yesterday's sunset time
                    sunset_time = sunset - datetime.timedelta(days=1)
                else:
                    sunset_time = sunset

                night_length = int(stop_time.timestamp() - sunset_time.timestamp())
                seconds_from_sunset = int(now.timestamp() - sunset_time.timestamp())
                percentage_complete = seconds_from_sunset / night_length
            else:
                percentage_complete = 1

            temp_range = abs(self._sunset_colortemp - self._stop_colortemp)
            temp_offset = temp_range * percentage_complete
            if self._sunset_colortemp > self._stop_colortemp:
                temp = self._sunset_colortemp - temp_offset
            else:
                temp = self._sunset_colortemp + temp_offset
        rgb = color_temperature_to_rgb(temp)
        x_val, y_val, b_val = color_RGB_to_xy_brightness(*rgb)
        brightness = self._brightness if self._brightness else b_val
        if self._disable_brightness_adjust:
            brightness = None
        if self._mode == MODE_XY:
            await async_set_lights_xy(
                self.opp, self._lights, x_val, y_val, brightness, self._transition
            )
            _LOGGER.debug(
                "Lights updated to x:%s y:%s brightness:%s, %s%% "
                "of %s cycle complete at %s",
                x_val,
                y_val,
                brightness,
                round(percentage_complete * 100),
                time_state,
                now,
            )
        elif self._mode == MODE_RGB:
            await async_set_lights_rgb(self.opp, self._lights, rgb, self._transition)
            _LOGGER.debug(
                "Lights updated to rgb:%s, %s%% of %s cycle complete at %s",
                rgb,
                round(percentage_complete * 100),
                time_state,
                now,
            )
        else:
            # Convert to mired and clamp to allowed values
            mired = color_temperature_kelvin_to_mired(temp)
            await async_set_lights_temp(
                self.opp, self._lights, mired, brightness, self._transition
            )
            _LOGGER.debug(
                "Lights updated to mired:%s brightness:%s, %s%% "
                "of %s cycle complete at %s",
                mired,
                brightness,
                round(percentage_complete * 100),
                time_state,
                now,
            )
Пример #8
0
def sun(
    opp: OpenPeerPower,
    before: str | None = None,
    after: str | None = None,
    before_offset: timedelta | None = None,
    after_offset: timedelta | None = None,
) -> bool:
    """Test if current time matches sun requirements."""
    utcnow = dt_util.utcnow()
    today = dt_util.as_local(utcnow).date()
    before_offset = before_offset or timedelta(0)
    after_offset = after_offset or timedelta(0)

    sunrise_today = get_astral_event_date(opp, SUN_EVENT_SUNRISE, today)
    sunset_today = get_astral_event_date(opp, SUN_EVENT_SUNSET, today)

    sunrise = sunrise_today
    sunset = sunset_today
    if today > dt_util.as_local(
        cast(datetime, sunrise_today)
    ).date() and SUN_EVENT_SUNRISE in (before, after):
        tomorrow = dt_util.as_local(utcnow + timedelta(days=1)).date()
        sunrise_tomorrow = get_astral_event_date(opp, SUN_EVENT_SUNRISE, tomorrow)
        sunrise = sunrise_tomorrow

    if today > dt_util.as_local(
        cast(datetime, sunset_today)
    ).date() and SUN_EVENT_SUNSET in (before, after):
        tomorrow = dt_util.as_local(utcnow + timedelta(days=1)).date()
        sunset_tomorrow = get_astral_event_date(opp, SUN_EVENT_SUNSET, tomorrow)
        sunset = sunset_tomorrow

    if sunrise is None and SUN_EVENT_SUNRISE in (before, after):
        # There is no sunrise today
        condition_trace_set_result(False, message="no sunrise today")
        return False

    if sunset is None and SUN_EVENT_SUNSET in (before, after):
        # There is no sunset today
        condition_trace_set_result(False, message="no sunset today")
        return False

    if before == SUN_EVENT_SUNRISE:
        wanted_time_before = cast(datetime, sunrise) + before_offset
        condition_trace_update_result(wanted_time_before=wanted_time_before)
        if utcnow > wanted_time_before:
            return False

    if before == SUN_EVENT_SUNSET:
        wanted_time_before = cast(datetime, sunset) + before_offset
        condition_trace_update_result(wanted_time_before=wanted_time_before)
        if utcnow > wanted_time_before:
            return False

    if after == SUN_EVENT_SUNRISE:
        wanted_time_after = cast(datetime, sunrise) + after_offset
        condition_trace_update_result(wanted_time_after=wanted_time_after)
        if utcnow < wanted_time_after:
            return False

    if after == SUN_EVENT_SUNSET:
        wanted_time_after = cast(datetime, sunset) + after_offset
        condition_trace_update_result(wanted_time_after=wanted_time_after)
        if utcnow < wanted_time_after:
            return False

    return True