def add_solar_angle(df): for i in df.index: obs_id = df.loc[i, 'obs_id'] latitude, longitude = lookup_lat_lon(obs_id) local_tz = lookup_timezone(obs_id) naive_gmt_time = df.loc[i, 'valid_time_gmt'] prev_naive_gmt_time = df.loc[i, 'prev_valid_time_gmt'] gmt_timestamp = datetime.datetime.fromtimestamp(naive_gmt_time) prev_gmt_timestamp = datetime.datetime.fromtimestamp( prev_naive_gmt_time) # local_time = local_tz.localize(gmt_timestamp) # prev_local_time = local_tz.localize(prev_gmt_timestamp) local_time = local_tz.fromutc(gmt_timestamp) prev_local_time = local_tz.fromutc(prev_gmt_timestamp) solar_angle = get_altitude(latitude, longitude, local_time) prev_solar_angle = get_altitude(latitude, longitude, prev_local_time) print(gmt_timestamp) print(local_time) print(solar_angle) df.loc[i, 'solar_angle'] = solar_angle df.loc[i, 'prev_solar_angle'] = prev_solar_angle return df
def get_day_data(latitude,longitude): latitude_deg = latitude # positive in the northern hemisphere longitude_deg = longitude # negative reckoning west from prime meridian in Greenwich, England ##date = datetime.datetime(2018, 9, 26, 10, 11, 1, 130320, tzinfo=datetime.timezone.utc) date = datetime.datetime.utcnow() date = date.replace(tzinfo=datetime.timezone.utc) sod = date.replace(hour=0,minute=0,tzinfo=datetime.timezone.utc) eod = date.replace(hour=23,minute=58,tzinfo=datetime.timezone.utc) altitude_deg = get_altitude(latitude_deg, longitude_deg, date) minutes = 0 date = sod day_data = {} while date < eod: minutes += 1 date = sod + datetime.timedelta(minutes=minutes) altitude_deg = get_altitude(latitude_deg, longitude_deg, date) position = get_altitude(latitude_deg, longitude_deg, date) try: power = radiation.get_radiation_direct(date, altitude_deg) except OverflowError: continue if position > 1: time_frame = date.strftime("%H:%M") day_data[time_frame] = {} day_data[time_frame]['position'] = position day_data[time_frame]['power'] = power return day_data
def test_fail_with_math(): pysolar.use_math() lat = np.array([45., 40.]) lon = np.array([3., 4.]) time = datetime(2018, 5, 8, 12, 0, 0, tzinfo=pytz.UTC) solar.get_altitude(lat, lon, time)
def add_solar_angle_of_observations(dict_items, prev_dict_items, station="KSEA"): latitude = 47.33 longitude = -122.19 local_tz = lookup_timezone(station) epoch_time = dict_items['valid_time_gmt'] prev_epoch_time = prev_dict_items['valid_time_gmt'] dt_obj = datetime.datetime.fromtimestamp(epoch_time) prev_dt_obj = datetime.datetime.fromtimestamp(prev_epoch_time) solar_angle = get_altitude(latitude, longitude, dt_obj) prev_solar_angle = get_altitude(latitude, longitude, prev_dt_obj) return solar_angle, prev_solar_angle
def action_sunlight(self, lights): """Take action; set light source to match sun. :param lights: ``[String]`` light names """ log.debug('event sunlight for lights: %s', lights) # todo: move to configuration MIN_BRIGHT = 20 # was 50 MAX_BRIGHT = 100 MIN_KELVIN = 2500 MAX_KELVIN = 6500 now_utc = datetime.datetime.now(tz=datetime.timezone.utc) midday_utc = datetime.datetime.now(tz=datetime.timezone.utc)\ .replace(hour=12, minute=0) longitude = self._config['location']['longitude'] latitude = self._config['location']['latitude'] sun_angle = get_altitude(longitude, latitude, now_utc) sun_angle_max = get_altitude(longitude, latitude, midday_utc) # angle if sun_angle < 0: sun_angle = 0.01 # avoid division by zero elif sun_angle > 180: sun_angle = 180 kelvin = _value_sunangle(MIN_KELVIN, MAX_KELVIN, sun_angle, sun_angle_max) # brightness range, 50-100, cast to 2 decimals brightness = _value_sunangle(MIN_BRIGHT, MAX_BRIGHT, sun_angle, sun_angle_max) log.debug('max=%s, current=%s, brightness=%s', sun_angle_max, sun_angle, brightness) # handle if sun is not at top at noon if kelvin > 6500: kelvin = 6500 if brightness > 100: brightness = 100 for light in lights: self.light_adapter.set_state(light, color=[255, 255, 255], brightness=brightness, kelvin=kelvin, duration=45)
def find_solar_angles(parameters, year=2017, localzone='US/Eastern'): hour = int(parameters['timeUTC']) #Computes the hour from the given time minute = int( (parameters['timeUTC'] - hour) * 60) #Converts decimal min to minute #Instanciates the date based on the given time and daynumber given in UTC date = datetime.datetime(year, 1, 1, hour, minute, 0, tzinfo=pytz.utc) + \ datetime.timedelta(parameters['dayNumber'] - 1) #Converts the UTC date to the local Timezone and takes care of daylight savings timestampEST = date.astimezone(pytz.timezone(localzone)) latitude = parameters['latitude'] #Pulls the latitude from the parameters longitude = parameters[ 'longitude'] #Pulls the longitude from the parameters #Computes the solar altitude above the horizon altitude = ps.get_altitude(latitude, -1 * longitude, timestampEST) zenith = 90 - altitude #Converts the solar altitude to zenith angle #Computes the azimuth angle from the south azimuth = ps.get_azimuth(latitude, -1 * longitude, timestampEST) azimuth = (180 - azimuth) % 360 #Converts azimuth to be measured from the north solarAngles = {"solarZenith": zenith, "solarAzimuth": azimuth} return solarAngles
def __call__(self, row_in): row_out = pd.Series() dt = pd.Timestamp(row_in.name).to_pydatetime() alt = solar.get_altitude(self.lat, self.lng, dt) row_out['SolarAltitude'] = alt if alt < 0: row_out['SolarRadiationNorm'] = 0 row_out['SolarRadiationHoriz'] = 0 return row_out # SolarRadiationNorm is the solar radiation on a surface which is always # normal (i.e. perpendicular) to the angle of the sun. This is usually not # what you want. norm_rad = radiation.get_radiation_direct(dt, alt) row_out['SolarRadiationNorm'] = norm_rad # alt is angle from horizon to sun; we want angle from normal (which is # vertical) so we subtract alt from 90 degrees (or pi / 2). theta = math.pi / 2 - math.radians(alt) row_out['alt_rad'] = math.radians(alt) row_out['theta'] = theta # SolarRadiationHoriz is the solar radiation on a surface which is # horizontal (like the ground). row_out['SolarRadiationHoriz'] = math.cos(theta) * norm_rad return row_out
def solar_position(date_time, lattitude, longitude): """Returns solar position.""" return ( get_altitude(lattitude, longitude, date_time.datetime), get_azimuth(lattitude, longitude, date_time.datetime), )
def calculateMaxSunLight(self): # Calculates the max sun radiation at given positions and dates (and returns zero for night time) # # The method is using the third party library PySolar : https://pysolar.readthedocs.io/en/latest/# # # # some other available options: # https://pypi.org/project/solarpy/ # https://github.com/trondkr/pyibm/blob/master/light.py # use calclight from Kino Module here : https://github.com/trondkr/KINO-ROMS/tree/master/Romagnoni-2019-OpenDrift/kino # ERcore : dawn and sunset times : https://github.com/metocean/ercore/blob/ercore_opensrc/ercore/lib/suncalc.py # https://nasa-develop.github.io/dnppy/modules/solar.html#examples # from pysolar import solar date = self.time date = date.replace( tzinfo=timezone.utc ) # make the datetime object aware of timezone, set to UTC logger.debug('Assuming UTC time for solar calculations') # longitude convention in pysolar, consistent with Opendrift : negative reckoning west from prime meridian in Greenwich, England # the particle longitude should be converted to the convention [-180,180] if that is not the case sun_altitude = solar.get_altitude(self.elements.lat, self.elements.lon, date) # get sun altitude in degrees sun_azimut = solar.get_azimuth(self.elements.lat, self.elements.lon, date) # get sun azimuth in degrees sun_radiation = np.zeros(len(sun_azimut)) # not ideal get_radiation_direct doesnt accept arrays... for elem_i, alt in enumerate(sun_altitude): sun_radiation[elem_i] = solar.radiation.get_radiation_direct( date, alt) # watts per square meter [W/m2] for that time of day # save compute light for each particle self.elements.light = sun_radiation * 4.6 #Converted from W/m2 to umol/m2/s-1"" - 1 W/m2 ≈ 4.6 μmole.m2/s logger.debug('Solar radiation from %s to %s [W/m2]' % (sun_radiation.min(), sun_radiation.max()))
def compute_radiation_at_45_deg_angle(timestamp, total_radiation, diffuse_radiation): direct_radiation = total_radiation - diffuse_radiation # Pysolar: south is zero degree, clockwise negative, e.g. south east = - 315 degree, south west = -45 degree azimuth = get_azimuth(when=datetime.datetime.fromtimestamp(timestamp), latitude_deg=LATITUDE_DEG, longitude_deg=LONGITUDE_DEG, elevation=EVALUATION) # In the calculation north is defined as zero degree, clockwise positive, the following conversion is required if azimuth < -180: azimuth = abs(azimuth) - 180 else: azimuth = abs(azimuth) + 180 altitude = get_altitude(when=datetime.datetime.fromtimestamp(timestamp), latitude_deg=LATITUDE_DEG, longitude_deg=LONGITUDE_DEG, elevation=EVALUATION) # Formula from "Lehrbuch der Bauphysik, Fischer, 2008, Page 651" radiation_at_45_deg_angle = diffuse_radiation + direct_radiation * ( cos(radians(ALPHA)) + sin(radians(ALPHA)) * (cos(radians(azimuth - BETA)) / tan(radians(altitude)))) if radiation_at_45_deg_angle < 0.0: radiation_at_45_deg_angle = 0.0 return radiation_at_45_deg_angle
def get_weather(): f = FMI(place='Kumpula') latestWeather = f.observations()[-1] date = datetime.now(pytz.timezone("Europe/Helsinki")) sun_altitude = get_altitude(60.188137, 24.953949, date) return latestWeather, sun_altitude
def altitude(self): """ Get the altitude of the sun position based on the latitude, longitude and date""" if self.manual: return self._altitude if self.simulation: self.add_time() return get_altitude(self.latitude_deg, self.longitude_deg, self.date)
def get_flux_total( coords, date ): # Sun position beta_deg = solar.get_altitude( *coords, date ) # deg, altitude angle of the sun I0 = get_radiation_direct( d, beta_deg ) # W/m2 return I0
def get_flux_surface( coords, date, sigma, phi_C ): """ coords: gps deg ( ) date: datetime object Surface orientation : sigma : deg, vertical angle of the surface, ref. to the horizontal phi_C : deg, azimuth, relative to south, with positive values in the southeast direction and negative values in the southwest return: flux solaire (W/m2) """ # Sun position phi_S_deg = solar.get_azimuth( *coords, date ) # deg, azimuth of the sun,relative to south beta_deg = solar.get_altitude( *coords, date ) # deg, altitude angle of the sun I0 = radiation.get_radiation_direct( date, beta_deg ) # W/m2 I0 = I0* isUpperHorizon( phi_S_deg, beta_deg ) # Projection: beta = beta_deg*math.pi/180 # rad phi_S = phi_S_deg*math.pi/180 #rad sigma = sigma*math.pi/180 phi_C = phi_C*math.pi/180 cosTheta = math.cos(beta)*math.cos( phi_S - phi_C )*math.sin( sigma ) + math.cos( sigma )*math.sin( beta ) if cosTheta >0 : Isurf = I0*cosTheta # flux projeté, W/m2 else: Isurf = 0 # mais diffuse... ? return Isurf
def compute_sun_angle( position, pose, utc_datetime, sensor_orientation, ): """ compute the sun angle using pysolar functions""" altitude = 0 azimuth = 0 import warnings with warnings.catch_warnings( ): # Ignore pysolar leap seconds offset warning warnings.simplefilter("ignore") try: altitude = pysolar.get_altitude(position[0], position[1], utc_datetime) azimuth = pysolar.get_azimuth(position[0], position[1], utc_datetime) except AttributeError: # catch 0.6 version of pysolar required for python 2.7 support altitude = pysolar.GetAltitude(position[0], position[1], utc_datetime) azimuth = 180 - pysolar.GetAzimuth(position[0], position[1], utc_datetime) sunAltitude = np.radians(np.array(altitude)) sunAzimuth = np.radians(np.array(azimuth)) sunAzimuth = sunAzimuth % (2 * np.pi) # wrap range 0 to 2*pi nSun = ned_from_pysolar(sunAzimuth, sunAltitude) nSensor = np.array(get_orientation(pose, sensor_orientation)) angle = np.arccos(np.dot(nSun, nSensor)) return nSun, nSensor, angle, sunAltitude, sunAzimuth
def payload(self, time): ts = time lat = self.config.latitude lng = self.config.longitude paz = self.config.panel_azimuth palt = self.config.panel_altitude effective_area = self.config.system_efficiency * self.config.panel_count * self.config.panel_area fields = dict(self.default_fields) fields['altitude'] = solar.get_altitude(lat, lng, ts) fields['azimuth'] = solar.get_azimuth(lat, lng, ts) % 360 az_diff = paz - fields['azimuth'] az_projection = max(0, math.cos(math.pi * az_diff / 180.0)) alt_diff = (90 - palt) - fields['altitude'] alt_projection = max(0, math.cos(math.pi * alt_diff / 180.0)) fields['alt_projection'] = float(alt_projection) fields['az_projection'] = float(az_projection) fields['total_projection'] = float(az_projection * alt_projection) if fields['altitude'] > 0: fields['direct_flux'] = solar.radiation.get_radiation_direct( ts, fields['altitude']) fields['projected_flux'] = fields['direct_flux'] * fields[ 'total_projection'] fields['max_direct_power'] = effective_area * fields['direct_flux'] fields['projected_direct_power'] = effective_area * fields[ 'projected_flux'] tags = { 'location': self.config.location_tag, } return PySolarPayload(tags, fields, time)
def add_solar_angle(station="KBFI"): client, collection = setup_mongo_client( 'capstone', 'flickr_rainbow_seattle_w_dates', address='mongodb://localhost:27017/') local_tz = lookup_timezone(station) latitude, longitude = lookup_lat_lon(station) cursor = collection.find({"snoqualmie": 0}, no_cursor_timeout=True) pattern = '%Y-%m-%d %H:%M:%S' added_counter = 0 for record in cursor: string_time = record['raw_json']['datetaken'] dt_obj = datetime.datetime.strptime(string_time, pattern) date_time = local_tz.localize(dt_obj) solar_angle = get_altitude(latitude, longitude, date_time) print(string_time) print(date_time) print(solar_angle) print("\n") collection.update_one({"_id": record["_id"]}, {"$set": { "raw_json.solar_angle": solar_angle }}) added_counter += 1 print("added {}".format(added_counter)) client.close()
def shade_factor(lat_deg, lon_deg, dx, dy, t): altitude = np.pi * solar.get_altitude(lat_deg, lon_deg, t) / 180. azimuth = np.pi * solar.get_azimuth(lat_deg, lon_deg, t) / 180. theta_a = np.zeros(dx.shape) theta_a[dx >= 0] = np.arctan2(dy[dx >= 0], dx[dx >= 0]) theta_a[dx < 0] = np.pi - np.arctan2(dy[dx < 0], np.abs(dx[dx < 0])) return 0.5 * (1 - np.sin(theta_a + azimuth)) * np.cos(altitude)
def check_next_sunrise(self): """Check azimuth of next sunrise""" new_date = self.date while(solar.get_altitude(self.latitude, self.longitude, new_date) < 15.0): print(new_date) new_date += datetime.timedelta(minutes=10) return self.offset(solar.get_azimuth(self.latitude, self.longitude, new_date))
def get_data(lat, lon, date_): data = { 'altitude': sol.get_altitude(lat, lon, date_), 'azimuth': sol.get_azimuth(lat, lon, date_), 'timestamp': date_.timestamp() } return data
def get_sun_position(ref_point, tim): """Get sun position for reference point and time at 10km distance reprojected on l72 ref_point -- a 3d vector in Lambert72 tim -- a datetime returns a records.SunPosition """ utc_time = tim.astimezone(utc) px, py, pz = ref_point lon, lat, z = transform(l72, wgs, px, py, pz) azimut = solar.get_azimuth(lat, lon, utc_time, z) altitude = solar.get_altitude(lat, lon, utc_time, z) saa = azimut - 180 # solar azimuth angle (degrees between -180 to +180, 0 at South) sza = 90 - altitude # solar zenit angle (0 = zenit, 90 = horizon) if altitude < 1: return SunPosition([0, 0, 0], 0, 0, False, tim, 0, 0) coords = _get_coords_from_angles(ref_point, np.deg2rad(altitude), np.deg2rad(azimut)) return SunPosition(coords, azimut, altitude, True, tim, sza, saa)
def sunposition(request, year, month, day, hour, minute, lat, long, elevation): # do some sanity checks # TODO: ... # perform the calculation via pysolar # FIXME: what to do with the timezone? (make it configurable in the settings or selectable in the client?) date = datetime.datetime(int(year), int(month), int(day), int(hour), int(minute), 0, 0, tzinfo=datetime.timezone.utc) azimuth = solar.get_azimuth(float(lat), float(long), date, float(elevation)) altitude = solar.get_altitude(float(lat), float(long), date, float(elevation)) # construct the answer result = { 'azimuth': azimuth, 'altitude': altitude, } return JsonResponse(result)
def test_scalar_with_numpy(): pysolar.use_numpy() lat = 50.63 lon = 3.05 time = datetime(2018, 5, 8, 12, 0, 0, tzinfo=pytz.UTC) print(solar.get_altitude(lat, lon, time)) print(solar.get_azimuth(lat, lon, time))
def zenith(df): """ Calculates solar zenith for dataframe index and adds new zen column""" dfzen = df.copy() zenlist = [] for t in df.index: zen = solar.get_altitude(38.291969, 21.788156, t) zenlist.append(zen) dfzen['zen'] = zenlist return dfzen
def test_scalar_with_math(): pysolar.use_math() lat = 45. lon = 3. time = datetime(2018, 5, 8, 12, 0, 0, tzinfo=pytz.UTC) print(solar.get_altitude(lat, lon, time)) print(solar.get_azimuth(lat, lon, time))
def get_solar_radiation(lat, lon, date): solarAlt = solar.get_altitude(lat, lon, date) solarPower = 0 if solarAlt <= 0: return 0 return radiation.get_radiation_direct(date, solarAlt)
def testGetAltitudeFast(self): # location is in NZ, use relevant timezone day = datetime.datetime( 2016, 12, 19, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(hours=12))) for hour in range(7, 19): when = day + datetime.timedelta(hours=hour) al = solar.get_altitude_fast(-43, 172, when) al_expected = solar.get_altitude(-43, 172, when) self.assertAlmostEqual(al, al_expected, delta=1)
def solar_calc(longitude, latitude, date, high_accuracy=False): """ numpy vectorize func """ altitude_deg = None if high_accuracy: altitude_deg = get_altitude(latitude, longitude, date) else: altitude_deg = get_altitude_fast(latitude, longitude, date) return get_radiation_direct(date, altitude_deg)
def getpos(lat, lon, date, elevation=0): date = _pd.to_datetime(date) alt = _np.deg2rad( _solar.get_altitude(lat, lon, date, elevation=elevation)) azi = _np.deg2rad( _np.mod( abs(_solar.get_azimuth(lat, lon, date, elevation=elevation)) - 180, 360)) airmass = 1 / _np.sin(alt) return alt, azi, airmass
def undistort(self, rgb=True, day_only=True): """ Undistort the raw image, set rgb, red, rbr, cos_g Input: rgb and day_only flags Output: rgb, red, rbr, cos_g will be specified. """ #####get the image acquisition time, this need to be adjusted whenever the naming convention changes t_cur=datetime.strptime(self.fn[-18:-4],'%Y%m%d%H%M%S'); t_std = t_cur-timedelta(hours=5) #####adjust UTC time into local standard time sz = 90-ps.get_altitude(self.cam.lat,self.cam.lon,t_std); sz*=deg2rad; self.sz = sz if day_only and sz>85*deg2rad: return saz = 360-ps.get_azimuth(self.cam.lat,self.cam.lon,t_std); saz=(saz%360)*deg2rad; self.saz = saz try: im0=plt.imread(self.fn); except: print('Cannot read file:', self.fn) return None im0=im0[self.cam.roi] im0[~self.cam.valid0,:]=0 cos_sz=np.cos(sz) cos_g=cos_sz*np.cos(self.cam.theta0)+np.sin(sz)*np.sin(self.cam.theta0)*np.cos(self.cam.phi0-saz); red0=im0[:,:,0].astype(np.float32); red0[red0<=0]=np.nan rbr0=(red0-im0[:,:,2])/(im0[:,:,2]+red0) if np.nanmean(red0[(cos_g>0.995) & (red0>=1)])>230: mk=cos_g>0.98 red0[mk]=np.nan rbr0[mk]=np.nan rbr=st.fast_bin_average2(rbr0,self.cam.weights); rbr=st.fill_by_mean2(rbr,7, mask=(np.isnan(rbr)) & self.cam.valid) self.rbr=rbr red0-=st.rolling_mean2(red0,300,ignore=np.nan) red=st.fast_bin_average2(red0,self.cam.weights); red=st.fill_by_mean2(red,7, mask=(np.isnan(red)) & self.cam.valid) red[red>50]=50; red[red<-50]=-50 red=(red+51)*2.5+0.5; self.red=red.astype(np.uint8) if rgb: im=np.zeros((self.cam.ny,self.cam.nx,3),dtype=im0.dtype) for i in range(3): im[:,:,i]=st.fast_bin_average2(im0[:,:,i],self.cam.weights); im[:,:,i]=st.fill_by_mean2(im[:,:,i],7, ignore=0, mask=(im[:,:,i]==0) & (self.cam.valid)) # im[:,:,i]=st.fill_by_mean2(im[:,:,i],7, ignore=0, mask=np.isnan(red)) im[red<=0]=0 self.rgb=im
def test_with_fixed_time(): """ get_altitude and get_azimuth, with scalar date """ pysolar.use_numpy() lat = np.array([45., 40.]) lon = np.array([3., 4.]) time = datetime(2018, 5, 8, 12, 0, 0, tzinfo=pytz.UTC) print(solar.get_altitude(lat, lon, time)) print(solar.get_azimuth(lat, lon, time)) print(solar.get_altitude_fast(lat, lon, time)) print(solar.get_azimuth_fast(lat, lon, time))
def test_solar(self): latitude_deg = 42.364908 longitude_deg = -71.112828 d = datetime.datetime.utcnow() thirty_minutes = datetime.timedelta(hours=0.5) for i in range(48): timestamp = d.ctime() altitude_deg = solar.get_altitude(latitude_deg, longitude_deg, d) azimuth_deg = solar.get_azimuth(latitude_deg, longitude_deg, d) power = radiation.get_radiation_direct(d, altitude_deg) if altitude_deg > 0: # TODO: save results as a fixture and apply assertion # print(timestamp, "UTC", altitude_deg, azimuth_deg, power) pass d = d + thirty_minutes
def time_update(args): args.current_time = datetime.now() args.current_time = args.current_time - timedelta(seconds=args.debug_time_of_day_offset) if is_dst(args.timezone): args.utc_time = args.current_time - timedelta(seconds=(4*(60*60))) else: args.utc_time = args.current_time - timedelta(seconds=(5*(60*60))) args.sun_alt_deg = solar.get_altitude(args.latitude, args.longitude, args.utc_time) #args.sun_azimuth_deg = Pysolar.GetAzimuth(args.latitude, args.longitude, args.utc_time) determine_day_mode(args) seconds_passed_today = time_to_seconds(args.current_time.hour, args.current_time.minute, args.current_time.second) args.day_past_percentage = seconds_to_percent_of_day(seconds_passed_today) convert_sun_time(args) pygame.time.set_timer(DEF_TIME_UPDATE_EVENT, 500);
def solarAngleCorrection(mtime): from pysolar import solar import pytz from datetime import datetime from datetime import timedelta import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates lat, long = 52.2398473,5.6908362 time = mtime - 2/24 date = mdates.num2date(time) altitude = solar.get_altitude(lat, long, date, elevation = 90) #correctionFactor = np.cos(altitude*np.pi/180) correctionFactor = 1/np.tan(altitude*np.pi/180) return correctionFactor
def sunPosFromCoord(latitude, longitude, time_, elevation=0): """ Find azimuth annd elevation of the sun using the pysolar library. Takes latitude(deg), longitude(deg) and a datetime object. Return tuple conaining (elevation, azimuth) TODO verify if timezone influences the results. """ # import datetime # time_ = datetime.datetime(2014, 10, 11, 9, 55, 28) azim = solar.get_azimuth(latitude, longitude, time_, elevation) alti = solar.get_altitude(latitude, longitude, time_, elevation) # Convert to radians azim = np.radians(-azim) elev = np.radians(90-alti) if azim > np.pi: azim = azim - 2*np.pi if elev > np.pi: elev = elev - 2*np.pi return elev, azim
def testGetAltitude(self): al = solar.get_altitude(-43, 172, TestApi.test_when) self.assertAlmostEqual(al, 63.0922058)
# Outputs sun elevation for a given geographical position and date range import argparse from datetime import datetime, timedelta from pysolar import solar def valid_date(s): try: return datetime.strptime(s, "%Y-%m-%d") except ValueError: message = "Invalid date representation: '%s'" % s raise argparse.ArgumentTypeError(message) # Prepare arguments for command line invocation parser = argparse.ArgumentParser(add_help=True) parser.add_argument("-x", "--lon", action="store", help="Longitude of the geographical position in decimal degrees", dest="lon", required=True, type=float) parser.add_argument("-y", "--lat", action="store", help="Latitude of the geographical position in decimal degress", dest="lat", required=True, type=float) #parser.add_argument("-z", "--elev", action="store", help="Elevation in meters", dest="elevation", required=True, type=float) parser.add_argument("-s", "--start", action="store", help="The first date of the interval", dest="start", required=True, type=valid_date) parser.add_argument("-e", "--end", action="store", help="The last date for the interval", dest="end", required=True, type=valid_date) args = parser.parse_args() hour = timedelta(hours=1) date = args.start while date < args.end: sun_elev = solar.get_altitude(args.lat, args.lon, date) print("%s, %f" % (date, sun_elev)) date = date + hour