def test_sun_rise_set_transit_spa(expected_rise_set_spa, golden): # solution from NREL SAP web calculator south = Location(-35.0, 0.0, tz='UTC') times = pd.DatetimeIndex( [datetime.datetime(1996, 7, 5, 0), datetime.datetime(2004, 12, 4, 0)]).tz_localize('UTC') sunrise = pd.DatetimeIndex([ datetime.datetime(1996, 7, 5, 7, 8, 15), datetime.datetime(2004, 12, 4, 4, 38, 57) ]).tz_localize('UTC').tolist() sunset = pd.DatetimeIndex([ datetime.datetime(1996, 7, 5, 17, 1, 4), datetime.datetime(2004, 12, 4, 19, 2, 3) ]).tz_localize('UTC').tolist() transit = pd.DatetimeIndex([ datetime.datetime(1996, 7, 5, 12, 4, 36), datetime.datetime(2004, 12, 4, 11, 50, 22) ]).tz_localize('UTC').tolist() frame = pd.DataFrame( { 'sunrise': sunrise, 'sunset': sunset, 'transit': transit }, index=times) result = solarposition.sun_rise_set_transit_spa(times, south.latitude, south.longitude, delta_t=65.0) result_rounded = pd.DataFrame(index=result.index) # need to iterate because to_datetime does not accept 2D data # the rounding fails on pandas < 0.17 for col, data in result.iteritems(): result_rounded[col] = data.dt.round('1s') assert_frame_equal(frame, result_rounded) # test for Golden, CO compare to NREL SPA result = solarposition.sun_rise_set_transit_spa( expected_rise_set_spa.index, golden.latitude, golden.longitude, delta_t=65.0) # round to nearest minute result_rounded = pd.DataFrame(index=result.index) # need to iterate because to_datetime does not accept 2D data for col, data in result.iteritems(): result_rounded[col] = data.dt.round('s').tz_convert('MST') assert_frame_equal(expected_rise_set_spa, result_rounded)
def get_sunrise_and_sunset(time, location, pvlib_method='numba'): """ Get sunrise and sunset times :param time: :param location: :param pvlib_method: numpy or numba :return: """ # try: # time_utc = time.floor("D").tz_convert('UTC') # Use 'floor' to be sure we have sunrise/sunset of the right day # except TypeError: # time_utc = time.floor("D").tz_localize('UTC') # sun_rise_set = get_sun_rise_set_transit(time_utc, location.latitude, location.longitude) # sun_rise_set = get_sun_rise_set_transit(time, location.latitude, location.longitude) sun_rise_set = sun_rise_set_transit_spa(time, location.latitude, location.longitude, how=pvlib_method) # if time.tz is None: # to_tz = location.tz # else: # to_tz = time.tz # sunrise = DatetimeIndex(sun_rise_set["sunrise"].values, tz=time_utc.tz).tz_convert(to_tz) # sunset = DatetimeIndex(sun_rise_set["sunset"].values, tz=time_utc.tz).tz_convert(to_tz) # sunrise = DatetimeIndex(sun_rise_set["sunrise"]) # sunset = DatetimeIndex(sun_rise_set["sunset"]) # return sunrise, sunset return DatetimeIndex(sun_rise_set["sunrise"]), DatetimeIndex( sun_rise_set["sunset"])
def test_sun_rise_set_transit_spa(expected_rise_set_spa, golden): # solution from NREL SAP web calculator south = Location(-35.0, 0.0, tz='UTC') times = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 0), datetime.datetime(2004, 12, 4, 0)] ).tz_localize('UTC') sunrise = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 7, 8, 15), datetime.datetime(2004, 12, 4, 4, 38, 57)] ).tz_localize('UTC').tolist() sunset = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 17, 1, 4), datetime.datetime(2004, 12, 4, 19, 2, 3)] ).tz_localize('UTC').tolist() transit = pd.DatetimeIndex([datetime.datetime(1996, 7, 5, 12, 4, 36), datetime.datetime(2004, 12, 4, 11, 50, 22)] ).tz_localize('UTC').tolist() frame = pd.DataFrame({'sunrise': sunrise, 'sunset': sunset, 'transit': transit}, index=times) result = solarposition.sun_rise_set_transit_spa(times, south.latitude, south.longitude, delta_t=65.0) result_rounded = pd.DataFrame(index=result.index) # need to iterate because to_datetime does not accept 2D data # the rounding fails on pandas < 0.17 for col, data in result.iteritems(): result_rounded[col] = data.dt.round('1s') assert_frame_equal(frame, result_rounded) # test for Golden, CO compare to NREL SPA result = solarposition.sun_rise_set_transit_spa( expected_rise_set_spa.index, golden.latitude, golden.longitude, delta_t=65.0) # round to nearest minute result_rounded = pd.DataFrame(index=result.index) # need to iterate because to_datetime does not accept 2D data for col, data in result.iteritems(): result_rounded[col] = data.dt.round('s').tz_convert('MST') assert_frame_equal(expected_rise_set_spa, result_rounded)
def create_sunrise_sunset_data(self) -> pd.DataFrame: year_range = pd.date_range( f"01/01/{self.base_year} 00:00:00", f"31/12/{self.base_year} 23:00:00", freq="D", tz=self.timezone, ) data = solarposition.sun_rise_set_transit_spa(year_range, self.lat, self.lon) hour_function = lambda x: pd.to_datetime(x.strftime(format="%H:%M:%S"), format="%H:%M:%S") data["sunrise_hour"] = data["sunrise"].apply(hour_function) data["sunset_hour"] = data["sunset"].apply(hour_function) data["transit_hour"] = data["transit"].apply(hour_function) data["length_of_day"] = (data["sunset_hour"] - data["sunrise_hour"] + pd.to_datetime("1900-01-01")) return data
def get_atmospherics(self, times, stat_win): """ Using NASA meteorlogical data create wind & temp dataframes """ self.air_temp = None self.wind_spd = None lt = self.read_attrb('lat') ln = self.read_attrb('lon') if self.atmospherics is None: self.atmospherics = popup_notification(stat_win, 'Retrieving Atmospheric Data, Please Wait', LoadNasaData, lt,ln) if len(self.atmospherics) == 0: wm = 'Failed to load Atmospheric data, using fixed temp and wind speed' stat_win.show_message(wm, 'Warning') self.air_temp = PVSite.default_temp self.wind_spd = PVSite.default_wind_spd if self.air_temp is None and self.wind_spd is None and self.atmospherics is not None: # Build Arrays of Temps & Wind Speed by Hour temp =np.zeros([len(times)]) speed = np.zeros(len(times)) #sunlight = get_sun_rise_set_transit(times, lt, ln) sunlight = sun_rise_set_transit_spa(times, lt, ln) sunindx = list(sunlight.index.values) avt = self.atmospherics['T10M']['S-Mean'].values mxt = self.atmospherics['T10M_MAX']['S-Mean'].values mnt = self.atmospherics['T10M_MIN']['S-Mean'].values avw = self.atmospherics['WS10M']['S-Mean'].values mxw = self.atmospherics['WS10M_MAX']['S-Mean'].values mnw = self.atmospherics['WS10M_MIN']['S-Mean'].values for indx in range(len(sunindx)): doy = indx//24 sunrise= sunlight.iloc[indx, 0] sunset = sunlight.iloc[indx, 1] transit = sunlight.iloc[indx, 2] current = np.datetime_as_string(sunindx[indx]) temp[indx] = hourly_temp(avt[indx//24], mxt[indx//24], mnt[indx//24], current, sunrise, sunset, transit) speed[indx] = hourly_speed(avw[indx//24], mxw[indx//24], mnw[indx//24], current, sunrise, sunset, transit) self.air_temp = pd.DataFrame(data= temp, index= times, columns=['Air_Temp']) self.wind_spd = pd.DataFrame(data= speed, index= times, columns=['Wind_Spd'])
def calculate_sunRise_sunSet_sunNoon(self): date = str(self.dateEdit.date().year()) + '-' + str( self.dateEdit.date().month()) + '-' + str( self.dateEdit.date().day()) times = pd.date_range(start=date, end=date, freq=None, tz=self.tz) self.lat = self.spinBox_latitude.value() self.lon = self.spinBox_longitude.value() solpos = solarposition.sun_rise_set_transit_spa( times, self.lat, self.lon) solar_rise = solpos.sunrise.array hour = (str(solar_rise.hour[0]) if solar_rise.hour[0] >= 10 else ('0' + str(solar_rise.hour[0]))) minute = (str(solar_rise.minute[0]) if solar_rise.minute[0] >= 10 else ('0' + str(solar_rise.minute[0]))) second = (str(solar_rise.second[0]) if solar_rise.second[0] >= 10 else ('0' + str(solar_rise.second[0]))) result = hour + ':' + minute + ':' + second self.label_solarRise.setText(result) solar_set = solpos.sunset.array hour = (str(solar_set.hour[0]) if solar_set.hour[0] >= 10 else ('0' + str(solar_set.hour[0]))) minute = (str(solar_set.minute[0]) if solar_set.minute[0] >= 10 else ('0' + str(solar_set.minute[0]))) second = (str(solar_set.second[0]) if solar_set.second[0] >= 10 else ('0' + str(solar_set.second[0]))) result = hour + ':' + minute + ':' + second self.label_solarSet.setText(result) solar_noon = solpos.transit.array hour = (str(solar_noon.hour[0]) if solar_noon.hour[0] >= 10 else ('0' + str(solar_noon.hour[0]))) minute = (str(solar_noon.minute[0]) if solar_noon.minute[0] >= 10 else ('0' + str(solar_noon.minute[0]))) second = (str(solar_noon.second[0]) if solar_noon.second[0] >= 10 else ('0' + str(solar_noon.second[0]))) result = hour + ':' + minute + ':' + second self.label_solarNoon.setText(result)
def get_sun_rise_set_transit(self, times, method='pyephem', **kwargs): """ Calculate sunrise, sunset and transit times. Parameters ---------- times : DatetimeIndex Must be localized to the Location method : str, default 'pyephem' 'pyephem', 'spa', or 'geometric' kwargs are passed to the relevant functions. See solarposition.sun_rise_set_transit_<method> for details. Returns ------- result : DataFrame Column names are: ``sunrise, sunset, transit``. """ if method == 'pyephem': result = solarposition.sun_rise_set_transit_ephem( times, self.latitude, self.longitude, **kwargs) elif method == 'spa': result = solarposition.sun_rise_set_transit_spa( times, self.latitude, self.longitude, **kwargs) elif method == 'geometric': sr, ss, tr = solarposition.sun_rise_set_transit_geometric( times, self.latitude, self.longitude, **kwargs) result = pd.DataFrame(index=times, data={ 'sunrise': sr, 'sunset': ss, 'transit': tr }) else: raise ValueError('{} is not a valid method. Must be ' 'one of pyephem, spa, geometric'.format(method)) return result
def get_sun_times(self, times): """ Create a DataFrame with SunRise & Sunset Times for each of the 365 days in a year """ if self.suntimes is None: lt = self.read_attrb('lat') ln = self.read_attrb('lon') #st = get_sun_rise_set_transit(times, lt, ln) st = sun_rise_set_transit_spa(times, lt, ln) sunup = [] sundwn = [] transit = [] doy = [] for i in range(365): sunup.append(st.iloc[i*24]['sunrise']) sundwn.append(st.iloc[i*24]['sunset']) transit.append(st.iloc[i*24]['transit']) doy.append(times[i*24].date()) df_dict = {'Sunrise': sunup, 'Sunset':sundwn, 'Transit':transit} self.suntimes = pd.DataFrame(data= df_dict, index= doy) return self.suntimes
def get_sun_rise_set_transit(self, times, method='pyephem', **kwargs): """ Calculate sunrise, sunset and transit times. Parameters ---------- times : DatetimeIndex Must be localized to the Location method : str, default 'pyephem' 'pyephem', 'spa', or 'geometric' kwargs are passed to the relevant functions. See solarposition.sun_rise_set_transit_<method> for details. Returns ------- result : DataFrame Column names are: ``sunrise, sunset, transit``. """ if method == 'pyephem': result = solarposition.sun_rise_set_transit_ephem( times, self.latitude, self.longitude, **kwargs) elif method == 'spa': result = solarposition.sun_rise_set_transit_spa( times, self.latitude, self.longitude, **kwargs) elif method == 'geometric': sr, ss, tr = solarposition.sun_rise_set_transit_geometric( times, self.latitude, self.longitude, **kwargs) result = pd.DataFrame(index=times, data={'sunrise': sr, 'sunset': ss, 'transit': tr}) else: raise ValueError('{} is not a valid method. Must be ' 'one of pyephem, spa, geometric' .format(method)) return result
def thresh_find_el(self): now = datetime.datetime.now() date = str(now.year) + '-' + str(now.month) + '-' + str(now.day) times = pd.date_range(start=date, end=date, freq=None, tz=settings.timeZone) solpos = solarposition.sun_rise_set_transit_spa( times, settings.lat, settings.lon) noon = solpos.transit.array if ((globals.dt.V1 > self.startValue) and (globals.dt.V2 > self.startValue)) and ( (globals.dt.V3 > self.startValue) and (globals.dt.V4 > self.startValue)): # se si รจ prima del mezzogiorno if datetime.datetime.now( ).hour < noon.hour and datetime.datetime.now( ).minute < noon.minute: if globals.dt.P_el >= self.el_threshold: self.set_direction_el(dir='Down') self.slider_el_direction.setValue(0) self.in_finding_from_up = True if self.in_finding_from_up: if globals.dt.P_el > -self.el_threshold: self.move_el() else: self.not_move_el() self.in_finding_from_up = False else: if globals.dt.P_el <= -self.el_threshold - self.buffer_zone: self.set_direction_el(dir='Up') self.in_finding_from_down = True self.slider_el_direction.setValue(1) if self.in_finding_from_down: if (globals.dt.P_el < -self.el_threshold): self.move_el() else: self.not_move_el() self.in_finding_from_down = False # dopo mezzogiorno else: if globals.dt.P_el <= -self.el_threshold: self.set_direction_el(dir='Up') self.slider_el_direction.setValue(1) self.in_finding_from_down = True if self.in_finding_from_down: if globals.dt.P_el < self.el_threshold: self.move_el() else: self.not_move_el() self.in_finding_from_down = False else: if globals.dt.P_el >= self.el_threshold + self.buffer_zone: self.set_direction_el(dir='Down') self.in_finding_from_up = True self.slider_el_direction.setValue(0) if self.in_finding_from_up: if (globals.dt.P_el > self.el_threshold): self.move_el() else: self.not_move_el() self.in_finding_from_up = False else: self.not_move_el()