示例#1
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
示例#2
0
def drawdaytime(clockface, city):
    """drawdaytime - Set all the LEDs around the clock to yellow (daytime) or blue (night time)

    Args:
        clockface: The 60 Neopixels to draw into
        city:      The location to calculate sunrise/sunset for

    Notes:
        TODO: Unhandled exception for locations in the polar regions
    """
    sunrise = sun.sunrise(city.observer, tzinfo=city.tzinfo)
    sunset = sun.sunset(city.observer, tzinfo=city.tzinfo)

    # Convert sunrise and sunset to LED numbers
    daystart = int(((sunrise.hour * 60) + sunrise.minute) / 24)
    dayend = int(((sunset.hour * 60) + sunset.minute) / 24)

    # Set the "day" LEDs to dim yellow, night LEDs to dark blue
    for led in range(0, daystart):
        clockface[led] = (0, 0, 4)

    for led in range(daystart, dayend + 1):
        clockface[led] = (1, 1, 0)

    for led in range(dayend + 1, 60):
        clockface[led] = (0, 0, 4)
示例#3
0
    def plotNighttime(self, axes=None, plot=True):
        dayList = [
            (self.timerange[0] + dt.timedelta(days=x - 1)).date()
            for x in range((self.timerange[1] - self.timerange[0]).days + 3)
        ]
        for day in dayList:
            day = dt.datetime.combine(day, dt.datetime.min.time())
            sunrise = sun.sunrise(self.loc.observer,
                                  date=day,
                                  tzinfo=self.to_tzone)
            sunset = sun.sunset(self.loc.observer,
                                date=day,
                                tzinfo=self.to_tzone)
            # print(F"#DEBUG: sunrise: {sunrise}, sunset: {sunset}")
            timelist = [
                day, sunrise - dt.timedelta(seconds=1), sunrise, sunset,
                sunset + dt.timedelta(seconds=1), day + dt.timedelta(days=1)
            ]

            if plot:
                axes.autoscale(enable=False)
                limits = axes.get_ylim()
                axes.fill_between(timelist,
                                  np.full(len(timelist), limits[0]),
                                  np.full(len(timelist), limits[1]),
                                  where=[True, True, False, False, True, True],
                                  facecolor='black',
                                  alpha=0.05)
        return timelist
示例#4
0
def clean_post(frame):
    frame = frame.dropna()
    post = frame.to_dict()
    post['dateandtime'] = (post['dateandtime'].replace(tzinfo=to_tzone)
                                              .astimezone(db_tzone)
                                              .to_pydatetime())

    del post['Date']
    del post['Time']

    sunrise = sun.sunrise(loc.observer, date=post['dateandtime'].date(),
                          tzinfo=to_tzone).astimezone(db_tzone)
    sunset = sun.sunset(loc.observer, date=post['dateandtime'].date(),
                        tzinfo=to_tzone).astimezone(db_tzone)
    post['daylight'] = ((post['dateandtime'] > sunrise)
                        and (post['dateandtime'] < sunset)) * 1

    return post
示例#5
0
async def getWELData(ip):
    tic = time.time()
    url = "http://" + ip + ":5150/data.xml"

    post = {}
    local_now = (dt.datetime.now()
                 .replace(microsecond=0)
                 .replace(tzinfo=TO_TZONE))
    sunrise = sun.sunrise(LOC.observer, date=local_now.date(),
                          tzinfo=TO_TZONE).astimezone(DB_TZONE)
    sunset = sun.sunset(LOC.observer, date=local_now.date(),
                        tzinfo=TO_TZONE).astimezone(DB_TZONE)
    post['daylight'] = ((local_now > sunrise)
                        and (local_now < sunset)) * 1

    try:
        response = requests.get(url)
    except ConnectionError:
        message("Error in connecting to WEL, waiting 10 sec then trying again",
                mssgType='WARNING')
        time.sleep(10)
        try:
            response = requests.get(url)
        except ConnectionError:
            message("Second error in connecting to WEL, "
                    "excluding WEL from post.",
                    mssgType='ERROR')
            return post

    response_data = xmltodict.parse(response.content)['Devices']['Device']

    for item in response_data:
        try:
            post[item['@Name']] = float(item['@Value'])
        except ValueError:
            post[item['@Name']] = item['@Value']

    del post['Date']
    del post['Time']

    message([F"{'Getting WEL:': <20}", F"{time.time() - tic:.1f} s"],
            mssgType='TIMING')
    return post
示例#6
0
 def sunrise_sunset(date, lat, lon):
     """
     Calculate sunrise and sunset times in utc for given date,
     lat and lon.
     Parameters
     ----------
     date : datetime.date
         Date in yyyy-mm-dd.
     lat : float
         Latitude.
     lon : float
         Longitude.
     Returns
     -------
     sunrise : datetime
         Sunrise time.
     sunset : datetime
         Sunset time.
     """
     obs = Observer(latitude=lat, longitude=lon, elevation=0.0)
     sunrise = sun.sunrise(observer=obs, date=date)
     sunset = sun.sunset(observer=obs, date=date)
     return sunrise, sunset
示例#7
0
def draw_astronomical(city_name, geo_data, config):
    datetime_day_start = datetime.datetime.now().replace(hour=0,
                                                         minute=0,
                                                         second=0,
                                                         microsecond=0)

    city = LocationInfo()
    city.latitude = geo_data["latitude"]
    city.longitude = geo_data["longitude"]
    city.timezone = geo_data["timezone"]

    answer = ""
    moon_line = ""
    for time_interval in range(72):

        current_date = (datetime_day_start +
                        datetime.timedelta(hours=1 * time_interval)).replace(
                            tzinfo=pytz.timezone(geo_data["timezone"]))

        try:
            dawn = sun.dawn(city.observer, date=current_date)
        except ValueError:
            dawn = current_date

        try:
            dusk = sun.dusk(city.observer, date=current_date)
        except ValueError:
            dusk = current_date + datetime.timedelta(hours=24)

        try:
            sunrise = sun.sunrise(city.observer, date=current_date)
        except ValueError:
            sunrise = current_date

        try:
            sunset = sun.sunset(city.observer, date=current_date)
        except ValueError:
            sunset = current_date + datetime.timedelta(hours=24)

        char = "."
        if current_date < dawn:
            char = " "
        elif current_date > dusk:
            char = " "
        elif dawn <= current_date and current_date <= sunrise:
            char = u"─"
        elif sunset <= current_date and current_date <= dusk:
            char = u"─"
        elif sunrise <= current_date and current_date <= sunset:
            char = u"━"

        answer += char

        if config.get("view") in ["v2n", "v2d"]:
            moon_phases = constants.MOON_PHASES_WI
            moon_phases = [" %s" % x for x in moon_phases]
        else:
            moon_phases = constants.MOON_PHASES

        # moon
        if time_interval in [0, 23, 47, 69]:  # time_interval % 3 == 0:
            moon_phase = moon.phase(date=datetime_day_start +
                                    datetime.timedelta(hours=time_interval))
            moon_phase_emoji = moon_phases[int(
                math.floor(moon_phase * 1.0 / 28.0 * 8 + 0.5)) %
                                           len(moon_phases)]
            #    if time_interval in [0, 24, 48, 69]:
            moon_line += moon_phase_emoji  # + " "
        elif time_interval % 3 == 0:
            if time_interval not in [24, 28]:  #se:
                moon_line += "   "
            else:
                moon_line += " "

    answer = moon_line + "\n" + answer + "\n"
    answer += "\n"
    return answer
示例#8
0
def test_Sunset_NoDate(london):
    ans = pytz.utc.localize(datetime.datetime(2015, 12, 1, 15, 55))
    assert datetime_almost_equal(sun.sunset(london.observer), ans)
示例#9
0
def test_Sunset(day, sunset, london):
    sunset = pytz.utc.localize(sunset)
    sunset_utc = sun.sunset(london.observer, day)
    assert datetime_almost_equal(sunset, sunset_utc)
示例#10
0
文件: geo_utils.py 项目: Cracert/ACT
def add_solar_variable(obj,
                       latitude=None,
                       longitude=None,
                       solar_angle=0.,
                       dawn_dusk=False):
    """
    Calculate solar times depending on location on earth.

    Astral 2.2 is recommended for best performance and for the dawn/dusk feature as it
    seems like the dawn calculations are wrong with earlier versions.

    Parameters
    ----------
    obj : act object
        ACT object
    latitude : str
        Latitude variable, default will look for matching variables
        in object
    longitude : str
        Longitude variable, default will look for matching variables
        in object
    solar_angle : float
        Number of degress to use for dawn/dusk calculations
    dawn_dusk : boolean
         If set to True, will add values 2 (dawn) and 3 (dusk) to the solar variable

    Returns
    -------
    obj : act object
        ACT object
    """

    variables = list(obj.keys())

    # Get coordinate variables
    if latitude is None:
        latitude = [s for s in variables if "latitude" in s]
        if len(latitude) == 0:
            latitude = [s for s in variables if "lat" in s]
        if len(latitude) == 0:
            raise ValueError(
                "Latitude variable not set and could not be discerned from the data"
            )

    if longitude is None:
        longitude = [s for s in variables if "longitude" in s]
        if len(longitude) == 0:
            longitude = [s for s in variables if "lon" in s]
        if len(longitude) == 0:
            raise ValueError(
                "Longitude variable not set and could not be discerned from the data"
            )

    # Get lat/lon variables
    lat = obj[latitude[0]].values
    lon = obj[longitude[0]].values

    # Set the the number of degrees the sun must be below the horizon
    # for the dawn/dusk calculation. Need to do this so when the calculation
    # sends an error it is not going to be an inacurate switch to setting
    # the full day.
    if ASTRAL:
        astral.solar_depression = solar_angle
    else:
        a = astral.Astral()
        a.solar_depression = 0.

    # If only one lat/lon value then set up the observer location
    # for Astral.  If more than one, it will get set up in the loop
    if lat.size == 1 and ASTRAL:
        loc = Observer(latitude=lat, longitude=lon)

    # Loop through each time to ensure that the sunrise/set calcuations
    # are correct for each time and lat/lon if multiple
    results = []
    time = obj['time'].values
    for i in range(len(time)):
        # Set up an observer if multiple lat/lon
        if lat.size > 1:
            if ASTRAL:
                loc = Observer(latitude=lat[i], longitude=lon[i])
            else:
                s = a.sun_utc(pd.to_datetime(time[i]), lat[i], lon[i])
        elif ASTRAL is False:
            s = a.sun_utc(pd.to_datetime(time[i]), float(lat), float(lon))

        # Get sunrise and sunset
        if ASTRAL:
            sr = sunrise(loc, pd.to_datetime(time[i]))
            ss = sunset(loc, pd.to_datetime(time[i]))
        else:
            sr = s['sunrise']
            ss = s['sunset']

        # Set longname
        longname = 'Daylight indicator; 0-Night; 1-Sun'

        # Check to see if dawn/dusk calculations can be performed before preceeding
        if dawn_dusk:
            try:
                if ASTRAL:
                    dwn = dawn(loc, pd.to_datetime(time[i]))
                    dsk = dusk(loc, pd.to_datetime(time[i]))
                else:
                    if lat.size > 1:
                        dsk = a.dusk_utc(pd.to_datetime(time[i]), lat[i],
                                         lon[i])
                        dwn = a.dawn_utc(pd.to_datetime(time[i]), lat[i],
                                         lon[i])
                    else:
                        dsk = a.dusk_utc(pd.to_datetime(time[i]), float(lat),
                                         float(lon))
                        dwn = a.dawn_utc(pd.to_datetime(time[i]), float(lat),
                                         float(lon))
            except ValueError:
                print(
                    'Dawn/Dusk calculations are not available at this location'
                )
                dawn_dusk = False

        if dawn_dusk and ASTRAL:
            # If dawn_dusk is True, add 2 more indicators
            longname += '; 2-Dawn; 3-Dusk'
            # Need to ensure if the sunset if off a day to grab the previous
            # days value to catch the early UTC times
            if ss.day > sr.day:
                if ASTRAL:
                    ss = sunset(
                        loc, pd.to_datetime(time[i] - np.timedelta64(1, 'D')))
                    dsk = dusk(
                        loc, pd.to_datetime(time[i] - np.timedelta64(1, 'D')))
                else:
                    if lat.size > 1:
                        dsk = a.dusk_utc(
                            pd.to_datetime(time[i]) - np.timedelta64(1, 'D'),
                            lat[i], lon[i])
                        s = a.sun_utc(
                            pd.to_datetime(time[i]) - np.timedelta64(1, 'D'),
                            lat[i], lon[i])
                    else:
                        dsk = a.dusk_utc(
                            pd.to_datetime(time[i]) - np.timedelta64(1, 'D'),
                            float(lat), float(lon))
                        s = a.sun_utc(
                            pd.to_datetime(time[i]) - np.timedelta64(1, 'D'),
                            float(lat), float(lon))
                    ss = s['sunset']

                if dwn <= pd.to_datetime(time[i], utc=True) < sr:
                    results.append(2)
                elif ss <= pd.to_datetime(time[i], utc=True) < dsk:
                    results.append(3)
                elif not (dsk <= pd.to_datetime(time[i], utc=True) < dwn):
                    results.append(1)
                else:
                    results.append(0)
            else:
                if dwn <= pd.to_datetime(time[i], utc=True) < sr:
                    results.append(2)
                elif sr <= pd.to_datetime(time[i], utc=True) < ss:
                    results.append(1)
                elif ss <= pd.to_datetime(time[i], utc=True) < dsk:
                    results.append(3)
                else:
                    results.append(0)
        else:
            if ss.day > sr.day:
                if ASTRAL:
                    ss = sunset(
                        loc, pd.to_datetime(time[i] - np.timedelta64(1, 'D')))
                else:
                    s = a.sun_utc(
                        pd.to_datetime(time[i]) - np.timedelta64(1, 'D'), lat,
                        lon)
                    ss = s['sunset']
                results.append(
                    int(not (ss < pd.to_datetime(time[i], utc=True) < sr)))
            else:
                results.append(
                    int(sr < pd.to_datetime(time[i], utc=True) < ss))

    # Add results to object and return
    obj['sun_variable'] = ('time', np.array(results), {
        'long_name': longname,
        'units': ' '
    })

    return obj
示例#11
0
    def __init__(self, _location, _main_loop):
        self.location = _location
        self.main_loop = _main_loop
        self.id = f'urn:dev:ops:{self.location}-vorraum-led'
        self.name = f'{self.location}-LED_Strip'
        Thing.__init__(self, self.id, self.name, ['OnOffSwitch', 'Light'],
                       'A web connected LED-Strip')
        # GPIO18 (P26) pwm on Linkit Smart 7688
        self.pwm = mraa.Pwm(26)
        self.pwm.period_us(20000)  # 20ms period ==> 50Hz
        self.pwm.enable(True)  # Start sending PWM signal

        # relay2 (P18) on Linkit Smart 7688
        self.relay2 = mraa.Gpio(18)
        # relay1 (P19) on Linkit Smart 7688
        self.relay1 = mraa.Gpio(19)
        self.relay2.dir(mraa.DIR_OUT)  # set as OUTPUT pin
        # set as INPUT pin, its a pullup, so its High when the switch is open.
        self.relay1.dir(mraa.DIR_IN)
        self.relay1_read()  # get initial Value of Relay1
        self.r1_previous = False

        self.main_loop_time = None
        self.async_timeout = None

        self.locality = LocationInfo('Zürich', 'Switzerland', 'Europe/Zurich',
                                     47.39, 8.07)
        logging.info(
            f'Information for {self.locality.name}/{self.locality.region}, '
            f'Timezone: {self.locality.timezone}, '
            f'Latitude: {self.locality.latitude:.02f}; '
            f'Longitude: {self.locality.longitude:.02f}')
        self.day_time_start = sun.sunrise(
            self.locality.observer,
            date=datetime.now(),
            tzinfo=self.locality.timezone) - timedelta(minutes=30)
        logging.debug(f'LedStrip: day_time_start:{self.day_time_start}')
        self.day_time_stop = sun.sunset(
            self.locality.observer,
            date=datetime.now(),
            tzinfo=self.locality.timezone) + timedelta(minutes=30)
        logging.debug(f'LedStrip: day_time_stop:{self.day_time_stop}')

        self.state = Value(self.get_state(), self.toggle_digitalswitch)
        self.add_property(
            Property(self,
                     'digitalswitch',
                     self.state,
                     metadata={
                         '@type': 'OnOffProperty',
                         'title': f'{self.name}-digitalswitch',
                         'type': 'boolean',
                         'description': 'Whether the Strip is turned on',
                     }))

        self.brightness = Value(self.get_brightness(), self.set_brightness)
        self.add_property(
            Property(self,
                     'brightness',
                     self.brightness,
                     metadata={
                         '@type': 'LevelProperty',
                         'title': 'Helligkeit',
                         'type': 'integer',
                         'description': 'The level of light from 0-100%',
                         'minimum': 0,
                         'maximum': 100,
                         'unit': 'percent',
                     }))

        self.add_available_action(
            'fade', {
                'title': 'Helligkeitswert über eine Zeitdauer einstellen',
                'description': 'Fade the lamp to a given level',
                'input': {
                    'type': 'object',
                    'required': [
                        'brightness',
                        'duration',
                    ],
                    'properties': {
                        'brightness': {
                            'type': 'integer',
                            'minimum': 0,
                            'maximum': 100,
                            'unit': 'percent',
                        },
                        'duration': {
                            'type': 'integer',
                            'minimum': 1,
                            'unit': 'milliseconds',
                        },
                    },
                },
            }, FadeLedStrip)

        self.motion_detection_delay = Value(self.get_motion_detection_delay(),
                                            self.set_motion_detection_delay)
        self.add_property(
            Property(self,
                     'motion_detection_delay',
                     self.motion_detection_delay,
                     metadata={
                         '@type': 'LevelProperty',
                         'title': 'Verzögertes Aus bei Bewegung (in Minuten)',
                         'type': 'integer',
                         'description': 'The delay in minutes',
                         'minimum': 0,
                         'maximum': 20,
                         'unit': 'minutes',
                     }))

        self.motion_detection_active = Value(
            self.get_motion_detection_active(),
            self.set_motion_detection_active)
        self.add_property(
            Property(self,
                     'motion_detection_active',
                     self.motion_detection_active,
                     metadata={
                         '@type': 'BooleanProperty',
                         'title': 'Auf Bewegung reagieren?',
                         'type': 'boolean',
                         'description': 'Set Motion detection active or not',
                     }))

        self.motion_detection_follower = Value(self.get_motion(),
                                               self.set_motion)
        self.add_property(
            Property(self,
                     'motion_detection_follower',
                     self.motion_detection_follower,
                     metadata={
                         '@type': 'MotionProperty',
                         'title': 'Bewegungs Sensor',
                         'type': 'boolean',
                         'description': 'motion=true, nomotion=false',
                     }))

        self.timer = tornado.ioloop.PeriodicCallback(self.get_r1, 1000)
        self.timer.start()
示例#12
0
# from https://stackoverflow.com/a/1060330
def daterange(start_date, end_date):
    for n in range(int((end_date - start_date).days)):
        yield start_date + timedelta(n)


# could possibly also use dateutil module

for loc_date in daterange(date_start, date_end):

    ### time vars

    time_dawn = dawn(loc.observer, loc_date, tzinfo=loc_tz)
    time_rise = sunrise(loc.observer, loc_date, tzinfo=loc_tz)
    time_set = sunset(loc.observer, loc_date, tzinfo=loc_tz)
    time_dusk = dusk(loc.observer, loc_date, tzinfo=loc_tz)

    ### description vars

    event_title_rise = '↑ {0}'.format(time_rise.strftime("%H:%M"))
    event_title_set = '↓ {0}'.format(time_set.strftime("%H:%M"))

    # could move coordinates to 'GEO' property, see https://www.kanzaki.com/docs/ical/geo.html
    event_location = vText('{0} / {1}, {2}'.format(loc_name, loc_lat,
                                                   loc_long))

    # timedelta doesn't allow strftime, find a way to format it better, see https://stackoverflow.com/questions/538666/format-timedelta-to-string
    event_desc_rise = 'Dawn at {0}, sunrise at {1}. Total sunlight time {2}'.format(
        time_dawn.strftime("%H:%M"), time_rise.strftime("%H:%M"),
        str(time_set - time_rise))
示例#13
0
city = LocationInfo("London", "England", "Europe/London", 51.5, -0.116)

print((f"Information for {city.name}/{city.region}\n"
       f"Timezone: {city.timezone}\n"
       f"Latitude: {city.latitude:.02f}; Longitude: {city.longitude:.02f}\n"))

today = datetime.today()
observer = city.observer

timeformat = "%H:%M:%S"

dawnAngle = 18.0
duskAngle = 18.0

dawn = datetime.fromtimestamp(dawn(observer, today,
                                   dawnAngle).timestamp()).strftime(timeformat)
sunrise = datetime.fromtimestamp(sunrise(
    observer, today).timestamp()).strftime(timeformat)
noon = datetime.fromtimestamp(noon(observer,
                                   today).timestamp()).strftime(timeformat)
sunset = datetime.fromtimestamp(sunset(observer,
                                       today).timestamp()).strftime(timeformat)
dusk = datetime.fromtimestamp(dusk(observer, today,
                                   duskAngle).timestamp()).strftime(timeformat)

print((f"Dawn: {dawn}\n"
       f"Sunrise: {sunrise}\n"
       f"Noon: {noon}\n"
       f"Sunset: {sunset}\n"
       f"Dusk: {dusk}\n"))