Esempio n. 1
0
def test_get_next_sun_event_time_and_type_happy() -> None:
    observer = astral.Observer()

    now = datetime.datetime(year=2000,
                            month=1,
                            day=1,
                            hour=0,
                            tzinfo=datetime.timezone.utc)
    date, type = get_next_sun_event_time_and_type(observer, now)
    assert date == datetime.datetime(2000,
                                     1,
                                     1,
                                     8,
                                     5,
                                     57,
                                     311165,
                                     tzinfo=datetime.timezone.utc)
    assert type == solarblinds2.config.EventType.SUNRISE

    now = datetime.datetime(year=2000,
                            month=1,
                            day=1,
                            hour=12,
                            tzinfo=datetime.timezone.utc)
    date, type = get_next_sun_event_time_and_type(observer, now)
    assert date == datetime.datetime(2000,
                                     1,
                                     1,
                                     16,
                                     0,
                                     49,
                                     698951,
                                     tzinfo=datetime.timezone.utc)
    assert type == solarblinds2.config.EventType.SUNSET
Esempio n. 2
0
def test_get_next_sun_event_time_and_type_close_to_event() -> None:
    observer = astral.Observer()

    now = datetime.datetime(2000,
                            1,
                            1,
                            8,
                            5,
                            57,
                            311165 - 1,
                            tzinfo=datetime.timezone.utc)
    date, type = get_next_sun_event_time_and_type(observer, now)
    assert date == datetime.datetime(2000,
                                     1,
                                     1,
                                     8,
                                     5,
                                     57,
                                     311165,
                                     tzinfo=datetime.timezone.utc)
    assert type == solarblinds2.config.EventType.SUNRISE

    now = datetime.datetime(2000,
                            1,
                            1,
                            8,
                            5,
                            57,
                            311165,
                            tzinfo=datetime.timezone.utc)
    date, type = get_next_sun_event_time_and_type(observer, now)
    assert date == datetime.datetime(2000,
                                     1,
                                     1,
                                     16,
                                     0,
                                     49,
                                     698951,
                                     tzinfo=datetime.timezone.utc)
    assert type == solarblinds2.config.EventType.SUNSET

    now = datetime.datetime(2000,
                            1,
                            1,
                            8,
                            5,
                            57,
                            311165 + 1,
                            tzinfo=datetime.timezone.utc)
    date, type = get_next_sun_event_time_and_type(observer, now)
    assert date == datetime.datetime(2000,
                                     1,
                                     1,
                                     16,
                                     0,
                                     49,
                                     698951,
                                     tzinfo=datetime.timezone.utc)
    assert type == solarblinds2.config.EventType.SUNSET
Esempio n. 3
0
    def func(self):
        """Show server time data in a table."""
        lat, lon, ele = 33.43, -112.07, 24
        here = self.character.location
        if here:
            x = float(here.tags.get(category="coordx", default=0))
            y = float(here.tags.get(category="coordy", default=0))
            # z = here.tags.get(category="coordz")
            if x and y:
                lat, lon = float(y/10000), float(x/10000)
                print('Using location coordinates: {}, {}'.format(lat, lon))

        place = astral.LocationInfo(timezone='UTC', latitude=lat, longitude=lon)
        obsr = astral.Observer(latitude=lat, longitude=lon, elevation=ele)


        def time_dif(at, when):
            diff = abs(at - when)
            return 'now' if diff.total_seconds() < 60 else (utils.time_format(diff.total_seconds(), 2) +
                                                          (' ago' if at > when else ''))

        def moon_phase(days):
            """
            Summarize the visible portion, given days into cycle
            Args:
                days (int or float): days into current cycle
            Returns:
                phase (str): summary of view of visible portion
            """
            phases = ('new', 'waxing crescent', 'First quarter', 'waxing gibbous',
                      'full', 'waning gibbous', 'last quarter', 'waning crescent')
            percent = float((float(days) + 0.5) / 29.53)
            phase = int((percent - int(percent)) * len(phases))
            return phases[phase]
        try:
            sun = astral.sun.sun(date=datetime.date.today(), observer=obsr)
        except Exception as e:
            return
        else:
            past = here.tags.get('past', category='realm')
            moon = astral.moon.phase(date=datetime.date.today())
            now = timezone.now()
            moment = ['dawn', 'sunrise', 'noon', 'sunset', 'dusk']
            events = zip([each.capitalize() + ':' for each in moment], [time_dif(now, sun[each]) for each in moment])
            table1 = EvTable("|wServer", '|wtime', align='l', width=75)
            table1.add_row('Current uptime', utils.time_format(gametime.uptime(), 3))
            table1.add_row('First start', time_dif(datetime.datetime.now(),
                                                   datetime.datetime.fromtimestamp(gametime.server_epoch())))
            if here.tags.get('past', category='realm'):
                table1.add_row('Moon phase', moon_phase(moon))
            table1.reformat_column(0, width=20)
            up = self.cmdstring == 'uptime'  # User asking for uptime mode
            self.msg(('Current uptime: ' + utils.time_format(gametime.uptime(), 3)) if up else str(table1))
            if past:  # Astral events are to be displayed while in past realm
                table2 = EvTable("|wEvent", "|wTime until", align="l", width=75)
                for entry in events:
                    table2.add_row(entry[0], entry[1])
                table2.reformat_column(0, width=20)
                self.msg(str(table2) if self.cmdstring == 'events' else ('\n' + str(table2)))
Esempio n. 4
0
def is_it_light_outside():
    t = astral_sun(astral.Observer(MY_LAT, MY_LON), date=datetime.date.today())
    tolerance = datetime.timedelta(minutes=45)
    sunrise = t['sunrise'] + tolerance
    sunset = t['sunset'] - tolerance
    ahora = datetime.datetime.now(t['sunset'].tzinfo)
    sun_out = ahora > sunrise and ahora < sunset
    return sun_out
Esempio n. 5
0
def is_it_late_night():
    t = astral_sun(astral.Observer(MY_LAT, MY_LON), date=datetime.date.today())
    sunset = t['dusk']
    next_sunrise = t['sunrise'] + datetime.timedelta(hours=24)
    ahora = datetime.datetime.now(t['sunset'].tzinfo)
    if ahora < sunset:
        return False
    if ahora > sunset and ahora < next_sunrise:
        local_hour = datetime.datetime.now().hour  # no tz, just local hour
        if local_hour >= LATE_NIGHT_START_HOUR or local_hour <= next_sunrise.hour:
            return True
    return False
Esempio n. 6
0
def load_config(config_file: typing.Union[str, pathlib.Path]) -> Configuration:
    with open(config_file) as f:
        config = yaml.safe_load(f)["configuration"]
    config["connection"] = ConnectionData(**config["connection"])
    config["login"] = LoginData(**config["login"])
    config["observer"] = astral.Observer(**config["observer"])
    config["events"] = {
        EventType[key]: Event(
            delay=datetime.timedelta(seconds=event["delay_s"]),
            commands=[CommandData(**command) for command in event["commands"]],
        )
        for key, event in config["events"].items()
    }
    return Configuration(**config)
Esempio n. 7
0
    def __init__(
        self,
        date=dt.datetime.now(),
        location=Location(),
        hebrew=True,
        candle_lighting_offset=18,
        havdalah_offset=0,
    ):
        """
        Initialize the Zmanim object.

        As the timezone is expected to be part of the location object, any
        tzinfo passed along is discarded. Essentially making the datetime
        object non-timezone aware.

        The time zone information is appended to the date received based on the
        location object. After which it is transformed to UTC for all internal
        calculations.
        """
        self.location = location
        self.hebrew = hebrew
        self.candle_lighting_offset = candle_lighting_offset
        self.havdalah_offset = havdalah_offset

        # If a non-timezone aware date is received, use timezone from location
        # to make it timezone aware and change to UTC for calculations.

        # If timezone aware is received as date, we expect it to match the
        # timezone specified by location, so it can be overridden and changed
        # to UTC for calculations as above.
        if isinstance(date, dt.datetime):
            _LOGGER.debug("Date input is of type datetime: %r", date)
            self.date = date.date()
            self.time = date.replace(tzinfo=None)
        elif isinstance(date, dt.date):
            _LOGGER.debug("Date input is of type date: %r", date)
            self.date = date
            self.time = dt.datetime.now()
        else:
            raise TypeError

        _LOGGER.debug("Resetting timezone to UTC for calculations")
        self.time = location.timezone.localize(self.time).astimezone(pytz.utc)

        if _USE_ASTRAL:
            self.astral_observer = astral.Observer(
                latitude=self.location.latitude, longitude=self.location.longitude
            )
            self.astral_sun = astral.sun.sun(self.astral_observer, self.date)
Esempio n. 8
0
def test_NorwaySunUp():
    """Test location in Norway where the sun doesn't set in summer."""
    june = datetime(2019, 6, 5, tzinfo=pytz.utc)
    obs = astral.Observer(69.6, 18.8, 0.0)

    with pytest.raises(ValueError):
        sun.sunrise(obs, june)
    with pytest.raises(ValueError):
        sun.sunset(obs, june)

    # Find the next sunset and sunrise:
    next_sunrise = _next_event(obs, june, "sunrise")
    next_sunset = _next_event(obs, june, "sunset")

    assert next_sunset < next_sunrise
Esempio n. 9
0
def test_loop(do_command_mock: mock.MagicMock) -> None:
    mock_config = mock.Mock()
    mock_config.observer = astral.Observer()
    mock_config.events = {
        config.EventType.SUNRISE:
        config.Event(datetime.timedelta(), [config.CommandData(1, 0, 0, 0)]),
        config.EventType.SUNSET:
        config.Event(datetime.timedelta(), [config.CommandData(2, 0, 0, 0)]),
    }
    sb = solarblinds2.Solarblinds2(mock_config)

    sb.run()

    do_command_mock.assert_has_calls([
        mock.call(config.CommandData(pid=2, oid=0, did=0, value=0)),
        mock.call(config.CommandData(pid=1, oid=0, did=0, value=0)),
        mock.call(config.CommandData(pid=2, oid=0, did=0, value=0)),
        mock.call(config.CommandData(pid=1, oid=0, did=0, value=0)),
        mock.call(config.CommandData(pid=2, oid=0, did=0, value=0)),
    ])
Esempio n. 10
0
def set_location(latitude, longitude):
    global local_stations
    global local_radolan_idx
    global observer
    
    # Find 2 local forecast stations
    api = Wetterdienst(provider = 'dwd', kind = 'forecast')
    stations = api(parameter="large", mosmix_type=DwdMosmixType.LARGE)
    local_stations = stations.filter_by_rank(latitude=latitude, longitude=longitude, rank=2)
    
    # Determine local index in the radolan grid
    proj_stereo = wrl.georef.create_osr("dwd-radolan")
    proj_wgs = osr.SpatialReference()
    proj_wgs.ImportFromEPSG(4326)
    radolan_grid_xy = wrl.georef.get_radolan_grid(900, 900)
    coord_xy = wrl.georef.reproject([longitude, latitude], projection_source=proj_wgs, projection_target=proj_stereo)
    distance_xy = np.hypot(radolan_grid_xy[:, :, 0] - coord_xy[0], radolan_grid_xy[:, :, 1] - coord_xy[1])
    local_radolan_idx = np.argwhere(distance_xy < 10)
    
    # Define observer for sun position
    observer = astral.Observer(latitude=latitude, longitude=longitude)
Esempio n. 11
0
    def pull_weather(self):
        r = requests.get('https://api.openweathermap.org/data/2.5/weather', 
                         params={
                            'lat':self.lat, 
                            'lon':self.lon, 
                            'appid': self.key,}
                        )
        r.raise_for_status()
        request_data = r.json()
        self.data = {}

        self.data['temperature'] = request_data['main']['temp']
        self.data['clouds'] = request_data['clouds']['all']
        self.data['feels_like'] = request_data['main']['feels_like']
        self.data['humidity'] = request_data['main']['humidity']
        self.data['pressure'] = request_data['main']['pressure']
        self.data['wind_deg'] = request_data['wind'].get('deg', 0)
        self.data['wind_speed'] = request_data['wind'].get('speed', 0)
        # data += f",dew_point={self.data['current']['dew_point']}"
        # data += f",uvi={self.data['current']['uvi']}"
        # data += f",wind_gust={self.data['current'].get('wind_gust', 0)}"

        if 'visibility' in request_data:
            self.data['visibility'] = request_data['visibility']

        if 'rain' in request_data and '1h' in request_data['rain']:
            self.data['rain_1h'] = request_data['rain']['1h']
        else:
            self.data['rain_1h'] = 0

        if 'snow' in request_data and '1h' in request_data['snow']:
            self.data['snow_1h'] = request_data['snow']['1h']
        else:
            self.data['snow_1h'] = 0

        observer = astral.Observer(self.lat, self.lon)
        self.data['sun_elivation'] = astral.sun.elevation(observer)
        self.data['sun_azimuth'] = astral.sun.azimuth(observer)

        return self
Esempio n. 12
0
def main():
    args = parse_arguments()
    a = astral.Observer(latitude=args.latlong[0],
                        longitude=args.latlong[1],
                        elevation=args.altitude)
    thisday = datetime.datetime(args.year, args.month, args.day)
    lastday = thisday + datetime.timedelta(days=args.numdays)
    if args.icsfile:
        c = ics.Calendar()
    while thisday < lastday:
        suntime = astral.sun.time_at_elevation(a,
                                               date=thisday,
                                               elevation=args.elevation,
                                               tzinfo=args.timezone)
        print(suntime)
        thisday = thisday + datetime.timedelta(days=1)
        if args.icsfile:
            # TODO, add an argument for the title of the calendar entry.
            e = ics.event.Event(name='Sun time',
                                begin=suntime,
                                duration={'minutes': 10})
            c.events.add(e)
    if args.icsfile:
        args.icsfile.write(str(c))
Esempio n. 13
0
def sun_for(day: datetime.datetime, *, latitude: float, longitude: float):
    observer = astral.Observer(latitude, longitude)
    return astral.sun.sun(observer,
                          date=day,
                          tzinfo=tf.timezone_at(lat=latitude, lng=longitude))
Esempio n. 14
0
class screen(Widget):
    # all of the variables that the ui pulls data from
    alpha = NumericProperty()
    otto_info = {'lat': 38.662644, 'long': -121.527298, 'tz': 'US/Pacific'}
    otto_obs = astral.Observer(latitude=otto_info['lat'],
                               longitude=otto_info['long'])

    day_length_yesterday_str = StringProperty()
    day_length_today_str = StringProperty()
    day_length_tomorrow_str = StringProperty()
    yesterday_today_delta_str = StringProperty()
    today_tomorrow_delta_str = StringProperty()
    date = StringProperty()
    current_time = StringProperty()

    day_transition_1 = StringProperty()
    day_transition_2 = StringProperty()

    pdt_or_pst_completion_str = StringProperty()
    year_transition_1 = StringProperty()
    year_transition_2 = StringProperty()

    # update all of the numbers that change by-the-minute
    def update_minute_info(self):
        # current time, used in many of following calculations
        rn = datetime.datetime.now(tz=pytz.timezone(self.otto_info['tz']))
        self.current_time = rn.strftime('%H:%M')

        # update alpha brightness according to time of day
        if rn.time() < datetime.time(6):
            self.alpha = 0.25
        elif rn.time() < datetime.time(20):
            self.alpha = 0.80
        else:
            self.alpha = 0.25

        # TODO: change references from datetime.datetime.today() to rn
        otto_sun_today = astral.sun.sun(self.otto_obs,
                                        rn,
                                        tzinfo=self.otto_info['tz'])
        otto_sun_tomorrow = astral.sun.sun(self.otto_obs,
                                           rn + datetime.timedelta(days=1),
                                           tzinfo=self.otto_info['tz'])

        # find next 2 important daily transitions
        if rn < otto_sun_today['dawn']:  # rn before today.dawn
            #transitions are today.dawn, today.dusk
            self.day_transition_1 = f'dawn {otto_sun_today["dawn"].strftime("%H:%M")}'
            self.ids.lbl_daymom_tom_1.color = (1, 1, 0, 0)
            self.day_transition_2 = f'dusk {otto_sun_today["dusk"].strftime("%H:%M")}'
            self.ids.lbl_daymom_tom_2.color = (1, 1, 0, 0)
        elif rn < otto_sun_today['dusk']:  # rn before today.dusk:
            # transitions are today.dusk, tomorrow.dawn
            self.day_transition_1 = f'dusk {otto_sun_today["dusk"].strftime("%H:%M")}'
            self.ids.lbl_daymom_tom_1.color = (1, 1, 0, 0)
            self.day_transition_2 = f'dawn {otto_sun_tomorrow["dawn"].strftime("%H:%M")}'
            self.ids.lbl_daymom_tom_2.color = (1, 1, 0, self.alpha)
        else:
            # transitions are tomorrow.dawn, tomorrow.dusk
            self.day_transition_1 = f'dawn {otto_sun_tomorrow["dawn"].strftime("%H:%M")}'
            self.ids.lbl_daymom_tom_1.color = (1, 1, 0, self.alpha)
            self.day_transition_2 = f'dusk {otto_sun_tomorrow["dusk"].strftime("%H:%M")}'
            self.ids.lbl_daymom_tom_2.color = (1, 1, 0, self.alpha)

    # update all of the numbers that change once per day
    def update_daily_info(self):
        # current time, used in many of following calculations
        rn = datetime.datetime.now(tz=pytz.timezone(self.otto_info['tz']))

        # get sun times for 3 days
        otto_sun_yesterday = astral.sun.sun(self.otto_obs,
                                            datetime.datetime.today() -
                                            datetime.timedelta(days=1),
                                            tzinfo=self.otto_info['tz'])
        otto_sun_today = astral.sun.sun(self.otto_obs,
                                        datetime.datetime.today(),
                                        tzinfo=self.otto_info['tz'])
        otto_sun_tomorrow = astral.sun.sun(self.otto_obs,
                                           datetime.datetime.today() +
                                           datetime.timedelta(days=1),
                                           tzinfo=self.otto_info['tz'])

        # compute day lengths
        day_length_yesterday = otto_sun_yesterday[
            'sunset'] - otto_sun_yesterday['sunrise']
        self.day_length_yesterday_str = self.daylen_tostr(day_length_yesterday)
        day_length_today = otto_sun_today['sunset'] - otto_sun_today['sunrise']
        self.day_length_today_str = self.daylen_tostr(day_length_today)
        day_length_tomorrow = otto_sun_tomorrow['sunset'] - otto_sun_tomorrow[
            'sunrise']
        self.day_length_tomorrow_str = self.daylen_tostr(day_length_tomorrow)

        # compute how much longer today was vs yesterday, change delta text color
        self.yesterday_today_delta_str = self.daydelta_tostr(
            day_length_today - day_length_yesterday)
        if self.yesterday_today_delta_str[1] == '+':
            self.ids.yest_delta.color = (0, 1, 0, self.alpha)
        else:
            self.ids.yest_delta.color = (1, 0, 0, self.alpha)

        # compute how much longer tomorrow will be vs today, change delta text color
        self.today_tomorrow_delta_str = self.daydelta_tostr(
            day_length_tomorrow - day_length_today)
        if self.today_tomorrow_delta_str[1] == '+':
            self.ids.tom_delta.color = (0, 1, 0, self.alpha)
        else:
            self.ids.tom_delta.color = (1, 0, 0, self.alpha)

        # update today's date
        self.date = rn.strftime('%Y.%m.%d')

        # compute PST or PDT completion percentage
        daylight_trans_dates = [
            x.date() for x in pytz.timezone('US/Pacific')._utc_transition_times
            if x.year >= rn.year - 1 and x.year <= rn.year + 1
        ]  # has daylight times last year to next year
        if rn.date(
        ) < daylight_trans_dates[2]:  # before this year's spring forward)
            # useful dates are last year's fall back and this year's spring forward. currently PST
            pst_duration_days = daylight_trans_dates[2] - daylight_trans_dates[
                1]
            pst_completed_days = rn.date() - daylight_trans_dates[1]
            self.pdt_or_pst_completion_str = f'PST is {pst_completed_days/pst_duration_days*100:.2f}% done.'
        elif rn.date(
        ) < daylight_trans_dates[3]:  # between [spring forward and fall back)
            # useful dates: this year's spring forward, fall back. currently PDT :)
            pdt_duration_days = daylight_trans_dates[3] - daylight_trans_dates[
                2]
            pdt_completed_days = rn.date() - daylight_trans_dates[2]
            self.pdt_or_pst_completion_str = f'PDT is {pdt_completed_days/pdt_duration_days*100:.2f}% done.'
        else:  # you're after this year's fall back]
            # useful dates: this year's fall back, next year's spring forward. currently PST
            pst_duration_days = daylight_trans_dates[4] - daylight_trans_dates[
                3]
            pst_completed_days = rn.date() - daylight_trans_dates[3]
            self.pdt_or_pst_completion_str = f'PST is {pst_completed_days/pst_duration_days*100:.2f}% done.'

        # find next 2 important yearly transitions. include time changes, equinoxes, solstices
        year_transitions = [['spring forward', daylight_trans_dates[2]],
                            ['fall back', daylight_trans_dates[3]]]
        year_transitions.append([
            'spring equinox',
            ephem.next_spring_equinox(str(rn.year)).datetime().date()
        ])
        year_transitions.append([
            'summer solstice',
            ephem.next_summer_solstice(str(rn.year)).datetime().date()
        ])
        year_transitions.append([
            'fall equinox',
            ephem.next_fall_equinox(str(rn.year)).datetime().date()
        ])
        year_transitions.append([
            'winter solstice',
            ephem.next_winter_solstice(str(rn.year)).datetime().date()
        ])
        year_transitions.append(['spring forward', daylight_trans_dates[4]])
        year_transitions.append([
            'spring equinox',
            ephem.next_spring_equinox(str(rn.year + 1)).datetime().date()
        ])
        # sort the transitions. (are these astronomical events always guaranteed to be in the same order?)
        year_transitions.sort(key=lambda x: x[1])
        year_transitions = [x for x in year_transitions if rn.date() <= x[1]]
        self.year_transition_1 = f'{year_transitions[0][0]}  {year_transitions[0][1].strftime("%Y.%m.%d")}  ' \
                                 f'Δ{(year_transitions[0][1] - rn.date()).days}d'
        self.year_transition_2 = f'{year_transitions[1][0]}  {year_transitions[1][1].strftime("%Y.%m.%d")}  ' \
                                 f'Δ{(year_transitions[1][1] - rn.date()).days}d'

    def daylen_tostr(self, td):
        rtn = f'{td.seconds // 3600:02}h ' \
              f'{(td.seconds % 3600) // 60:02}m ' \
              f'{(td.seconds % 60):02}s'
        return rtn

    def daydelta_tostr(self, td):
        rtn = 'Δ'
        if td < datetime.timedelta():
            td = -td
            rtn += '-'
        else:
            rtn += '+'
        rtn += f'{(td.seconds % 3600) // 60:02}m:' \
               f'{(td.seconds % 60):02}s'
        return rtn
Esempio n. 15
0
def fft_shading_test_process(time,
                             lat,
                             lon,
                             data,
                             shad_freq_lower=None,
                             shad_freq_upper=None,
                             ratio_thresh=None,
                             time_interval=None):
    """
    Processing function to do the FFT calculations/thresholding

    Parameters
    ----------
    time : datetime
        Center time of calculation used for calculating sunrise/sunset
    lat : float
        Latitude used for calculating sunrise/sunset
    lon : float
        Longitude used for calculating sunrise/sunset
    data : list
        Data for run through fft processing
    shad_freq_lower : list
        Lower limits of freqencies to look for shading issues
    shad_freq_upper : list
        Upper limits of freqencies to look for shading issues
    ratio_thresh : list
        Thresholds to apply, corresponding to frequencies chosen
    time_interval : float
        Time interval of data


    Returns
    -------
    shading : int
        Binary to indicate shading problem (1) or not (0)

    """

    # Get sunrise/sunset that are on same days
    # This is used to help in the processing and easily exclude
    # nighttime data from processing
    if ASTRAL:
        astral.solar_depression = 0
        obs = astral.Observer(latitude=float(lat), longitude=float(lon))
        s = sun(obs, pd.Timestamp(time))
    else:
        a = astral.Astral()
        a.solar_depression = 0
        s = a.sun_utc(pd.Timestamp(time), float(lat), float(lon))

    sr = s['sunrise'].replace(tzinfo=None)
    ss = s['sunset'].replace(tzinfo=None)
    delta = ss.date() - sr.date()
    if delta > datetime.timedelta(days=0):
        if ASTRAL:
            s = sun(obs, pd.Timestamp(time) - datetime.timedelta(days=1))
        else:
            s = a.sun_utc(pd.Timestamp(time), float(lat), float(lon))
        ss = s['sunset'].replace(tzinfo=None)

    # Set if night or not
    shading = 0
    night = False
    if sr < ss:
        if (pd.Timestamp(time) < sr) or (pd.Timestamp(time) > ss):
            night = True
    if sr > ss:
        if (pd.Timestamp(time) < sr) and (pd.Timestamp(time) > ss):
            night = True

    # Return shading of 0 if no valid data or it's night
    if len(data) == 0 or night is True:
        return shading

    # FFT Algorithm
    fftv = abs(rfft(data))
    freq = rfftfreq(fftv.size, d=time_interval)

    # Get FFT data under threshold
    idx = (fftv < 1.)
    index = np.where(idx)
    fftv = fftv[index]
    freq = freq[index]

    # Return if FFT is empty
    if len(fftv) == 0:
        return 0
    # Commented out as it seems to work better without smoothing
    # fftv=pd.DataFrame(data=fftv).rolling(min_periods=3,window=3,center=True).mean().values.flatten()

    ratio = []
    # Calculates the ratio (size) of the peaks in the FFT to the surrounding
    # data
    wind = 3

    # Run through each frequency to look for peaks
    # Calculate threshold of peak value to surrounding values
    for i in range(len(shad_freq_lower)):
        idx = np.logical_and(freq > shad_freq_lower[i],
                             freq < shad_freq_upper[i])

        index = np.where(idx)
        if len(index[0]) == 0:
            continue
        peak = max(fftv[index])
        index = index[0]

        sind = index[0] - wind
        if sind < 0:
            sind = 0
        eind = index[-1] + wind
        if eind > len(fftv):
            eind = len(fftv)

        if len(range(sind, index[0])) == 0 or len(range(index[-1], eind)) == 0:
            ratio.append(0.0)
        else:
            # Calculates to the left/right of each peak
            peak_l = max(fftv[range(sind, index[0])])
            peak_r = max(fftv[range(index[-1], eind)])
            ratio.append(peak / np.mean([peak_l, peak_r]))

    # Checks ratios against thresholds for each freq range
    shading = 0
    if len(ratio) > 0:
        pass1 = False
        pass2 = False
        if ratio[0] > ratio_thresh[0]:
            pass1 = True
        if len(ratio) > 1:
            if ratio[1] > ratio_thresh[1]:
                pass2 = True
        else:
            pass2 = True

        if pass1 and pass2:
            shading = 1

    return shading