def export_status_data_to_pvoutput(self, whenlight=True): if whenlight: rightnow = datetime.datetime.utcnow() dusk = sun.dusk(self.installpoint.observer, date=datetime.datetime.utcnow()) dawn = sun.dawn(self.installpoint.observer, date=datetime.datetime.utcnow()) if not (rightnow > dawn.replace(tzinfo=None) and rightnow < dusk.replace(tzinfo=None) + datetime.timedelta(hours=1)) : return False self.pv = PVOutput(apikey=self.pvoutputkey, systemid=int(self.pvoutputsystemid)) data_to_send = { "c1": 1, "v1": self.ecudata["generation_of_current_day"], "v2": self.ecudata["last_system_power"] } if "max_temp" in self.ecudata: data_to_send["v5"] = self.ecudata["max_temp"] if "max_volts" in self.ecudata: data_to_send["v6"] = self.ecudata["max_volts"] result = self.pv.addstatus(data=data_to_send) return result
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
def test_Dawn_Astronomical(day, dawn, london): dawn = pytz.utc.localize(dawn) dawn_utc = sun.dawn(london.observer, day, 18) assert datetime_almost_equal(dawn, dawn_utc)
def test_Dawn_NoDate(london): ans = pytz.utc.localize(datetime.datetime(2015, 12, 1, 7, 4)) assert datetime_almost_equal(sun.dawn(london.observer), ans)
def test_Dawn_Civil(day, dawn, london): dawn = pytz.utc.localize(dawn) dawn_utc = sun.dawn(london.observer, day, Depression.CIVIL) assert datetime_almost_equal(dawn, dawn_utc)
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
cal.add('version', '2.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(
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"))