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 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 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 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 get_solar_radiation(lat, lon, date): """ date should be in UTC """ solarAlt = solar.get_altitude(lat, lon, date) if solarAlt <= 0: return 0 return radiation.get_radiation_direct(date, solarAlt)
def getSunPosData(self): # in case quadra not functioning import pytz tz = pytz.timezone('Europe/Berlin') date = datetime.now(tz) latitude_deg = 51.05667 # positive in the northern hemisphere (Drongen 51.05) longitude_deg = 3.66410 # negative reckoning west from prime meridian in Greenwich, England (Drongen # 3.66) from pysolar.solar import get_position from pysolar.radiation import get_radiation_direct sun_azimuth, sun_altitude = get_position(latitude_deg, longitude_deg, date,elevation=4) expectedRad = get_radiation_direct(date, latitude_deg) return sun_azimuth, sun_altitude ,expectedRad
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 getRadiation(day_sample, interval): secs = interval * 60 * sample_interval_minutes day = day_sample * sample_interval_days dt = start_date + d.timedelta(day, secs) alt = get_altitude(lat, lon, dt) azi = get_azimuth(lat, lon, dt) if (alt < 0): direct_radiation = 0 else: direct_radiation = get_radiation_direct(dt, alt) # get_azimuth returns bearing with respect to north, positive clockwise. Rotate so x is west, y is south azi_rad = math.radians(270 - azi) alt_rad = math.radians(alt) sun_vec = np.array( (math.cos(alt_rad) * math.cos(azi_rad), math.cos(alt_rad) * math.sin(azi_rad), math.sin(alt_rad))) rad = [max(0, sun_vec @ v * direct_radiation) for v in tilt_vecs] return rad
def sun_positionAndFlux( coords, date ): """ Obtient la position et le flux solaire pour une date particulière coords: tuple gps date: datetime object return: ( flux solaire (W/m2), sunAzimuth, sunAltitude ) """ # 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 if isUpperHorizon( phi_S_deg, beta_deg ): I0 = radiation.get_radiation_direct( date, beta_deg ) # W/m2 else: I0 = 0 return (I0, phi_S_deg, beta_deg)
def test_numpy_radiation(): """ get_radiation_direct with lat, lon, and date as arrays """ pysolar.use_numpy() lat = np.array([45., 40., 40.]) lon = np.array([3., 4., 3.]) time = np.array([ '2018-05-08T12:15:00', '2018-05-08T15:00:00', '2018-05-08T03:00:00', ], dtype='datetime64') altitude = solar.get_altitude_fast(lat, lon, time) rad_results = radiation.get_radiation_direct(time, altitude) assert rad_results[2] == 0 print(rad_results)
def current_global_irradiance(site_properties, solar_properties, timestamp): """Calculate the clear-sky POA (plane of array) irradiance for a specific time (seconds timestamp).""" dt = datetime.datetime.fromtimestamp(timestamp=timestamp, tz=tz.gettz(site_properties.tz)) n = dt.timetuple().tm_yday sigma = math.radians(solar_properties.tilt) rho = solar_properties.get('rho', 0.0) C = 0.095 + 0.04 * math.sin(math.radians((n - 100) / 365)) sin_sigma = math.sin(sigma) cos_sigma = math.cos(sigma) altitude = get_altitude(latitude_deg=site_properties.latitude, longitude_deg=site_properties.longitude, when=dt) beta = math.radians(altitude) sin_beta = math.sin(beta) cos_beta = math.cos(beta) azimuth = get_azimuth(latitude_deg=site_properties.latitude, longitude_deg=site_properties.longitude, when=dt) phi_s = math.radians(180 - azimuth) phi_c = math.radians(180 - solar_properties.azimuth) phi = phi_s - phi_c cos_phi = math.cos(phi) # Workaround for a quirk of pvsolar since the airmass for the sun ele===altitude of zero # is infinite and very small numbers close to zero result in NaNs being returned rather # than zero if altitude < 0.0: altitude = -1.0 cos_theta = cos_beta * cos_phi * sin_sigma + sin_beta * cos_sigma ib = get_radiation_direct(when=dt, altitude_deg=altitude) ibc = ib * cos_theta idc = C * ib * (1 + cos_sigma) / 2 irc = rho * ib * (sin_beta + C) * ((1 - cos_sigma) / 2) igc = ibc + idc + irc # If we still get a bad result just return 0 if math.isnan(igc): igc = 0.0 return igc
def __init__(self, lat, lng, cloud_data, cmap, prop): """ """ print('Creating Solar Irradiance Plot.') self.cmap = plt.get_cmap(cmap) self.prop = prop tf = timezonefinder.TimezoneFinder() self.time_zone = pytz.timezone(tf.certain_timezone_at(lng=lng, lat=lat)) date_rng = pd.date_range( start='1/1/{}'.format(datetime.datetime.now().year), end='1/1/{}'.format(datetime.datetime.now().year + 1), freq='H', tz=self.time_zone)[:-1] alts = get_altitude_fast(lat, lng, date_rng.values) irradiances = np.array([ get_radiation_direct(date, alt) if alt > 0 else 0 for date, alt in zip(date_rng, alts) ]) irr = pd.DataFrame({ 'Month': date_rng.month, 'Day': date_rng.day, 'irradiance': irradiances }) irr_by_day = irr.groupby(['Month', 'Day']).irradiance.sum() / 1000.0 irr = pd.DataFrame({ 'Mean': irr_by_day.groupby('Month').mean(), 'Std': irr_by_day.groupby('Month').std() }) self.irr = irr self.clouds = cloud_data.clouds
def handle(self, *args, **options): sun_altitude = get_altitude(51.462246, -0.182502, timezone.now()) radiation = get_radiation_direct(timezone.now(), sun_altitude) fields = { 'sun_altitude': sun_altitude, 'sun_clearsky_radiation': radiation } entries = [] for field, value in fields.items(): if value is None: continue entries.append(Entry( source = 'solar', field = field, value = value )) Entry.objects.bulk_create(entries) self.stdout.write(self.style.SUCCESS(f"Successfully calculated solar data"))
def get_radiation_direct(dutc): alt_deg = get_altitude(dutc) rad_wm2 = radiation.get_radiation_direct(dutc, alt_deg) * np.sin( np.radians(alt_deg)) return rad_wm2
def findSoilBankArea(waterMass, waterSurfaceArea, soilBedMass, soilBedSurfaceArea, minimumTemperature, greenhouseDimensions, startingTemperature=15, year=2015, debug=False): import pdb from pysolar import radiation from pysolar import solar greenhouseVolume = greenhouseDimensions[0] * greenhouseDimensions[ 1] * greenhouseDimensions[2] greenhouseHeight = greenhouseDimensions[2] greenhouseSurfaceArea = greenhouseDimensions[0] * greenhouseDimensions[1] airMass = greenhouseVolume * ThermalConstants.Density.air soilBankMass = 10 #g soilBedVolume = soilBedMass / ThermalConstants.Density.soil pexRadius = 1.5875 #cm surfaceAreaPex = (2 * math.pi * pexRadius) / 100 #m^2 solar_efficiency = 0.7 greenhouse_effect = 0.10 #you will regain this percentage of radiated energy fail = True failDate = None failTemperature = None while fail: water = Water(mass=waterMass, temperature=startingTemperature) soilBank = Soil(mass=soilBankMass, temperature=startingTemperature) soilBed = Soil(mass=soilBedMass, temperature=startingTemperature) greenhouse = Soil(mass=greenhouseSurfaceArea * ThermalConstants.Density.soil, temperature=startingTemperature) air = Air(mass=airMass, temperature=startingTemperature) air_outside = Air(mass=99999999999999, temperature=startingTemperature) soilBankVolume = soilBankMass / ThermalConstants.Density.soil fail = False date = datetime(year, 1, 1) for day in range(364): if hasOtherSide: pyotherside.send("day", day + 1) if fail: break minAirTemp, maxAirTemp, observations = wuGetAirTemperature(date) condition = "Clear" outsideAirTemp = float(minAirTemp) print( "calculating day: {}. Soil bed: {}, water: {}, greenhouse: {}" .format(date, soilBed.temperature, water.temperature, greenhouse.temperature)) air_high_temp = 15 "run through every second in the day" for second in range(86400): solarAlt = solar.get_altitude(45.542384, -122.961576, date) solarPower = 0 cond = weatherGetConditions(date, observations) if cond: condition = cond if solarAlt > 0: solarPower = radiation.get_radiation_direct(date, solarAlt) "factor in clouds " solarPower = solarPower * getRadiationVisibilityCoefficient( condition) if solarPower >= 1: outsideAirTemp = float(maxAirTemp) #debugOut("solarInput: {0}".format(solarPower * greenhouseSurfaceArea)) else: outsideAirTemp = float(minAirTemp) air_outside.temperature = outsideAirTemp "add solar energy to system:" water.energy += solarPower * waterSurfaceArea * solar_efficiency greenhouse.energy += solarPower * greenhouseSurfaceArea * solar_efficiency "the soil bed is likely shadowed by plants" #soilBed.energy += solarPower * soilBedSurfaceArea * solar_efficiency "transfer energy first to soil bed then remove the energy transferred from the water" pl = pexLength(surfaceAreaPex, soilBedVolume) water.transferTo(soilBed, pl, length=0.22) "now transfer energy to the soil bank from water:" pl = pexLength(surfaceAreaPex, soilBankVolume) water.transferTo(soilBank, pl, length=0.22) "radiant aisle heating" pl = pexLength(surfaceAreaPex, greenhouseSurfaceArea * 0.06) water.transferTo(greenhouse, pl) "greenhouse surface area can xfer to soilBed too" greenhouse.transferTo(soilBed, soilBedSurfaceArea) "caculate losses to the air." greenhouse.transferTo(air, greenhouseSurfaceArea) soilBed.transferTo(air, soilBedSurfaceArea) water.transferTo(air, waterSurfaceArea) "determine air loss to outside air" airInsulationThickness = 0.127 #m air.transferTo(air_outside, greenhouseSurfaceArea, length=airInsulationThickness) "radiate to the outside world minus greenhouse effect" greenhouse.energy += greenhouse.radiate() * greenhouse_effect water.energy += water.radiate() * greenhouse_effect soilBed.energy += soilBed.radiate() * greenhouse_effect #air.radiate() if air.temperature > air_high_temp: air_high_temp = air.temperature if debug: pdb.set_trace() "emit updated results to UI" if hasOtherSide: pyotherside.send("waterTemperature", waterTemp) pyotherside.send("soilBedTemp", soilBedTemp) pyotherside.send("soilBankTemp", soilBankTemp) pyotherside.send("date", str(date)) pyotherside.send("soilBankVolume", soilBankVolume) pyotherside.send("airTemp", airTemp) pyotherside.send("condition", condition) "Check to see if bank temp is higher than soilBed or water. If so, we need to transfer energy from the bank to the soil" date += timedelta(seconds=1) print("daily high air temp: {}".format(air_high_temp)) "check to see if we are colder than the min temperature" if soilBed.temperature < minimumTemperature: failDate = date failTemperature = soilBed.temperature fail = True if hasOtherSide: pyotherside.send("failDate", failDate) print( "We failed at {0} with soil bed temperature = {1}C and soil bank mass = {2}g" .format(failDate, failTemperature, soilBankMass)) print("air temps: inside: {}C outside: {}C".format( air.temperature, air_outside.temperature)) if fail: "we kinda failed, so let's double our soilBankVolume and try again" soilBankMass += soilBankMass print("success with soil bank mass: {0}".format(soilBankMass))
def getglobalvar(varname): global SysVars, suntimesupported svname = varname.strip().lower() par = "" if ("-" in svname): resarr = svname.split("-") svname = resarr[0] par = "-"+resarr[1] if ("+" in svname): resarr = svname.split("+") svname = resarr[0] par = "+"+resarr[1] res = "" if svname in SysVars: if svname==SysVars[0]: #%systime% 01:23:54 return datetime.now().strftime('%H:%M:%S') elif svname==SysVars[1]: #%systm_hm% 01:23 return datetime.now().strftime('%H:%M') elif svname==SysVars[2]: #%lcltime% 2018-03-16 01:23:54 return datetime.now().strftime('%Y-%m-%d %H:%M:%S') elif svname==SysVars[3]: #%syshour% 11 Current hour (hh) return int(datetime.now().strftime('%H')) elif svname==SysVars[4]: #%sysmin% 22 Current minute (mm) return int(datetime.now().strftime('%M')) elif svname==SysVars[5]: #%syssec% 33 Current second (ss) return int(datetime.now().strftime('%S')) elif svname==SysVars[6]: #%sysday% 16 Current day of month (DD) return int(datetime.now().strftime('%d')) elif svname==SysVars[7]: #%sysmonth% 3 Current month (MM) return int(datetime.now().strftime('%m')) elif svname==SysVars[8]: #%sysyear% 2018 4 digits (YYYY) return datetime.now().strftime('%Y') elif svname==SysVars[9]: #%sysyears% 18 2 digits (YY) return datetime.now().strftime('%y') elif svname==SysVars[10]: #%sysweekday% 5 Weekday (integer) - 1, 2, 3... (1=Sunday, 2=Monday etc.) return str(int(datetime.now().strftime('%w'))+1) elif svname==SysVars[11]: #%sysweekday_s% Fri Weekday (verbose) - Sun, Mon, Tue return datetime.now().strftime('%a') elif svname==SysVars[12]: #%unixtime% 1521731277 Unix time (seconds since epoch, 1970-01-01 00:00:00) return str(int(time.time())) elif svname==SysVars[13]: #%uptime% 3244 Uptime in minutes return str(rpieTime.getuptime(2)) elif svname==SysVars[14]: #%rssi% -45 WiFi signal strength (dBm) return str(OS.get_rssi()) elif svname==SysVars[15]: #%ip% 192.168.0.123 Current IP address return str(OS.get_ip()) elif svname==SysVars[16]: #%ip4% ipcim 4.byte res2 = str(OS.get_ip()) resarr = res2.split(".") if len(resarr)>3: return resarr[3] elif svname==SysVars[17]: #%sysname% name return Settings.Settings["Name"] elif svname==SysVars[18]: #%unit% 32 Unit number return Settings.Settings["Unit"] elif svname==SysVars[19]: #%ssid% H4XX0R njietwork! wdev = False try: wdev = Settings.NetMan.getfirstwirelessdev() except: wdev = False if wdev: res = str(Network.get_ssid(wdev)) elif svname==SysVars[20]: #%mac% 00:14:22:01:23:45 MAC address pd = -1 try: pd = Settings.NetMan.getprimarydevice() except: pd = -1 if pd<0 and len(Settings.NetworkDevices)>0: pd = 0 if pd!="" and pd>=0: return Settings.NetworkDevices[pd].mac elif svname==SysVars[21]: #%mac_int% 2212667 MAC address in integer to be used in rules (only the last 24 bit) pd = -1 try: pd = Settings.NetMan.getprimarydevice() except: pd = -1 if pd<0 and len(Settings.NetworkDevices)>0: pd = 0 if pd>=0: try: res2 = Settings.NetworkDevices[pd].mac resarr = res2.split(":") if len(resarr)>5: res = str(int("0x"+resarr[3]+resarr[4]+resarr[5],16)) except: res = "" return res elif svname==SysVars[22]: #%build% bstr = str(rpieGlobals.BUILD) return bstr elif svname==SysVars[23]: #sunrise try: from suntime import Sun suntimesupported = 1 except: suntimesupported = 0 if suntimesupported==1: try: sun = Sun(Settings.AdvSettings["Latitude"],Settings.AdvSettings["Longitude"]) abd_sr = sun.get_local_sunrise_time(datetime.now()) if par!="": abd_sr = addtoTime(abd_sr,par) res = abd_sr.strftime('%H:%M') except Exception as e: res = "00:00" return res elif svname==SysVars[24]: #sunset try: from suntime import Sun suntimesupported = 1 except: suntimesupported = 0 if suntimesupported==1: try: sun = Sun(Settings.AdvSettings["Latitude"],Settings.AdvSettings["Longitude"]) abd_ss = sun.get_local_sunset_time(datetime.now()) if par!="": abd_ss = addtoTime(abd_ss,par) res = abd_ss.strftime('%H:%M') except Exception as e: res = "00:00" return res elif svname==SysVars[25]: #sun altitude try: from pytz import reference from pysolar.solar import get_altitude pysolarsupported = 1 except: pysolarsupported = 0 res = "0" if pysolarsupported==1: try: localtime = reference.LocalTimezone() today = datetime.now(localtime) res = get_altitude(Settings.AdvSettings["Latitude"],Settings.AdvSettings["Longitude"], today) except Exception as e: print(e) res = "0" return res elif svname==SysVars[26]: #sun azimuth try: from pytz import reference from pysolar.solar import get_azimuth pysolarsupported = 1 except: pysolarsupported = 0 res = "0" if pysolarsupported==1: try: localtime = reference.LocalTimezone() today = datetime.now(localtime) res = get_azimuth(Settings.AdvSettings["Latitude"],Settings.AdvSettings["Longitude"], today) except Exception as e: print(e) res = "0" return res elif svname==SysVars[27]: #sun radiation try: from pytz import reference from pysolar.solar import get_altitude from pysolar.radiation import get_radiation_direct pysolarsupported = 1 except: pysolarsupported = 0 res = "-1" if pysolarsupported==1: try: localtime = reference.LocalTimezone() today = datetime.now(localtime) altitude_deg = get_altitude(Settings.AdvSettings["Latitude"],Settings.AdvSettings["Longitude"], today) res = get_radiation_direct(today, altitude_deg) except Exception as e: print(e) return res elif svname==SysVars[28]: #%br% return str("\r\n") elif svname==SysVars[29]: #%lf% return str("\n") elif svname==SysVars[30]: #%tab% return str(" ") return res
for date in dates: previous_solar_center_x = None previous_solar_center_y = None print('-----------------------------------------------------') print(date) print('{:10} {:20} {:20} {}'.format('time', 'elevation', 'azimuth', 'radiation_w_m2')) for hour in range(0, 24): for minute in [0, 15, 30, 45]: sample_time = tz.localize(datetime(*date, hour, minute, 0), is_dst=None) elevation = solar.get_altitude(*position, sample_time) # Move the 0 point to the north azimuth = (540 - solar.get_azimuth(*position, sample_time)) % 360 radiation_w_m2 = radiation.get_radiation_direct(sample_time, elevation) print('{:10} {:20} {:20} {}'.format(sample_time.strftime('%H:%M %Z'), elevation, azimuth, radiation_w_m2)) if elevation < 0: previous_solar_center_x = None previous_solar_center_y = None continue distance_pixel = calculateDistance(elevation) elevation_pixel = calculateX(distance_pixel, azimuth) azimuth_pixel = calculateY(distance_pixel, azimuth) # radius = radiation_w_m2 / 20 # # if radius > 50:
def radiation(self, t: [int, datetime, time.struct_time] = None) -> float: """Calculates the clear-sky irradiation in W/m^2""" dt = self.__getdatetime(t) alt = self.altitude(t) return alt > 0 and radiation.get_radiation_direct(dt, alt) or 0.0
#시간데이터 대신 시간별 태양고도데이터로 대체 df_data['Forecast_time'] = df_data['fcst_date'].astype(str).str.slice( 0, 10).map(str) + ' ' + df_data['fcst_hour'].astype(str) + ':00' df_data['altitude'] = df_data.apply(lambda x: get_altitude( x['lat'], x['long'], datetime.strptime(x['Forecast_time'], '%Y-%m-%d %H:%M').replace(tzinfo=KST) ), axis=1) df_data['altitude'] = df_data['altitude'].apply(lambda x: x if x >= 0 else 0) df_data['angle'] = df_data.apply(lambda x: get_azimuth( x['lat'], x['long'], datetime.strptime(x['Forecast_time'], '%Y-%m-%d %H:%M').replace(tzinfo=KST) ), axis=1) df_data['radiation'] = df_data.apply(lambda x: get_radiation_direct( datetime.strptime(x['Forecast_time'], '%Y-%m-%d %H:%M').replace( tzinfo=KST), x['altitude']), axis=1) df_data.to_csv('data/df_data.csv') #2월 예측을 위한 Test dataset 생성 df_real_test = df_fcst_avg[(df_fcst_avg['fcst_date'] >= '2021-02-01') & (df_fcst_avg['fcst_date'] <= '2021-02-28')].copy() #시간데이터 대신 시간별 태양고도데이터로 대체 df_real_test['Forecast_time'] = df_real_test['fcst_date'].astype( str).str.slice( 0, 10).map(str) + ' ' + df_real_test['fcst_hour'].astype(str) + ':00' df_real_test['altitude'] = df_real_test.apply(lambda x: get_altitude( x['lat'], x['long'], datetime.strptime(x['Forecast_time'], '%Y-%m-%d %H:%M').replace(tzinfo=KST)