User Tools

Site Tools


Flight-Control

<
Previous mounth
04/15/2025
>
Next mounth
SMTWFTS
16
13
13
14
14
15
15
16171819
1720212223242526
1827282930010203
1904050607080910
2011121314151617









Hot Projects

SEEDStack

SEEDStack - Open 3D printable seed/sprouting systemDIY Food Hacking

UCSSPM

UCSSPM - Unified Clear-Sky Solar Prediction ModelOpen Solar Power

picoReflow

picoReflow - DIY PID Reflow Oven Controller based on RaspberryPiDIY Reflow Soldering

PiGI

PiGI - DIY Geiger Counter based on RaspberryPiRasPi Geiger Counter

DIY ARA-2000

Active Wideband Receiver Antenna for SDR - ARA-2000Wideband Antenna

DSpace

DSPace - Map everythingMap everything!

Mission-Tags

Share & Donate

This is an old revision of the document!


Solar-Output prediction model

Using the sun as a renewable energy source isn't really a new invention. Plants have been relying on it for millions of years and our - mostly - green friends seem to handle it pretty well on an instinctive method of operation.

Let's have a simplified look on how much we already depend on solar energy:

  • Global freshwater distribution (oceans→clouds→rain)
  • Global atmospheric conditions/weather/temperature (direct) → flora/fauna
  • Global flora → atmospheric conditions/weather/temperature (indirect)

and which parts we use technically:

  • Agriculture (photosynthesis) → Food
  • Solar energy conversion to heat (mirror/focus)
  • Direct solid-state photon→electron conversion for electrical power

Global solar radiation (Rs) is of funfamental importance for human life on earth. We're depending very much on knowing how much solar energy can be harvested on a certain point on the planet's surface, yet we still commonly refer to 1000W/m2 on any point on Earth as a clear-sky reference. The following model is an open-resource based starting point for a new common model to predict the convertible solar output on a clear-sky day and incorporate any given conversion technique (currently only PV).

Use-Cases

Photo-Voltaic Systems

  • being able to have a more accurate prediction of maximum PV output for a given site/configuration
  • keep PV panel at optimum elevation without a separate optical solar tracker

Solar-Ovens

The system can be easily extended to estimate the optimum parabolic oven-reflector size, to satisfy the energy needs for a given community and their specific position on the planet.

Pyranometer Reference Model

Possibility to calibrate a pyranometer in the field, without another calibrated reference, on a clear-sky day.

Agricultural

Usable as basis for agricultural applications (growth/photosynthetic calculations)

Development

This model is based on algorithms developed by the Environmental and Water Resources Institute of the American Society of Civil Engineers and a few common NOAA/NASA calculations. Apollo-NG's energy management, prediction and logging system fuses this rational prediction model with real time sensor data in order to predict the nominal output power of a PV system and compares the actual output to it.

By now it has become a very advanced clear-sky prediction model, incorporating the following factors:

  • Position on Earth
  • Day of Year
  • Distance Sun-Earth
  • Angle through atmosphere
  • Water in atmosphere
  • Atmospheric turbidity (smog, dust etc.)
  • Direct/diffuse beam radiation
  • PV-Module surface/type/temperature/age

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
########################################################################
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
 
import math, calendar
from math import pi
 
# Solar constant for the mean distance between the Earth and sun #######
 
sol_const       =               1367.8
 
########################################################################
# GEO Parameters (to be fed from GPS)
 
lat             =               23
lon             =               11
alt             =               0
 
########################################################################
# Time and Offsets (to be fed from GPS)
 
day             =               22
month           =               06
year            =               2011
ToD             =               12
tz_off_deg      =               0+lon
dst_off         =               0
 
########################################################################
# Atmospheric Parameters (to be fed from Argus current sensor data)
 
# air temperature
 
atm_temp        =               25.0   
 
# relative humidity
 
atm_hum         =               20.0   
 
# turbidity coefficient - 0 < tc < 1.0 - where tc = 1.0 for clean air
# and tc < 0.5 for extremely turbid, dusty or polluted air
 
atm_tc          =               0.8
 
########################################################################
# PV System Parameters (actual PV data of Odysseys modules)
 
# Solar Panel Surface in m²
 
pv_a            =               1.67
 
# Module Efficiency %
 
pv_eff          =               20
 
# Mod. neg. Temp. Coeff (0.35=mono)
 
pv_tk           =               0.35
 
# Mod. Temperature in °C - should be measured on the back of module
 
pv_temp         =               30
 
# Mod. Age related Coeff (95% after 1-2y)
 
pv_ak           =               0.98
 
 
 
########################################################################
##  MAIN
########################################################################
 
# get Julian Day (Day of Year)
 
if                              calendar.isleap(year):
 
    # Leap year, 366 days
    lMonth      =       [0,31,60,91,121,152,182,213,244,274,305,335,366]
 
else:
 
    # Normal year, 365 days
    lMonth      =       [0,31,59,90,120,151,181,212,243,273,304,334,365]
 
DoY             =               lMonth[month-1] + day
 
print "--------------------------------------------------------------"
 
print "%d.%d.%d | %d | %f | " % (day, month, year, DoY, ToD, )
 
print "--------------------------------------------------------------"
 
print "Solar Constant                               : %s" % sol_const
print "Atmospheric turbidity coefficient            : %s" % atm_tc
 
print "--------------------------------------------------------------"
 
 
# inverse relative distance factor for distance between Earth and Sun ##
 
sun_rel_dist_f  = 1.0/(1.0-9.464e-4*math.sin(DoY)-                      \
                + 0.01671*math.cos(DoY)-                                \
                + 1.489e-4*math.cos(2.0*DoY)-2.917e-5*math.sin(3.0*DoY)-\
                + 3.438e-4*math.cos(4.0*DoY))**2
 
print "Inverse relative distance factor             : %s" % sun_rel_dist_f
 
 
# solar declination ####################################################
 
sun_decl        = (math.asin(0.39785*(math.sin(((278.97+(0.9856*DoY))   \
                + (1.9165*(math.sin((356.6+(0.9856*DoY))                \
                * (math.pi/180)))))*(math.pi/180))))*180)               \
                / math.pi
 
 
print "Sun declination                              : %s°" % sun_decl
 
 
# equation of time #####################################################
 
eqt             = (((5.0323-(430.847*math.cos((((2*math.pi)*DoY)/366)+4.8718)))\
                + (12.5024*(math.cos(2*((((2*math.pi)*DoY)/366)+4.8718))))\
                + (18.25*(math.cos(3*((((2*math.pi)*DoY)/366)+4.8718))))\
                - (100.976*(math.sin((((2*math.pi)*DoY)/366)+4.8718))))\
                + (595.275*(math.sin(2*((((2*math.pi)*DoY)/366)+4.8718))))\
                + (3.6858*(math.sin(3*((((2*math.pi)*DoY)/366)+4.871))))\
                - (12.47*(math.sin(4*((((2*math.pi)*DoY)/366)+4.8718)))))\
                / 60
 
print "Equation of time                             : %s min" % eqt
 
 
# time of solar noon ###################################################
 
sol_noon        = ((12+dst_off)-(eqt/60))-((tz_off_deg-lon)/15)
 
print "Solar Noon                                   : %s " % sol_noon
 
 
# solar zenith angle in DEG ############################################
 
sol_zen         = math.acos(((math.sin(lat*(math.pi/180)))              \
                * (math.sin(sun_decl*(math.pi/180))))                   \
                + (((math.cos(lat*((math.pi/180))))                     \
                * (math.cos(sun_decl*(math.pi/180))))                   \
                * (math.cos((ToD-sol_noon)*(math.pi/12)))))             \
                * (180/math.pi)
 
# in extreme latitude, values over 90 may occurs.
#if sol_zen > 90:
 
print "Solar Zenith Angle                           : %s° " % sol_zen
 
 
# barometric pressure of the measurement site
# (this should be replaced by the real measured value) in kPa
 
atm_press       = 101.325                                               \
                * math.pow(((288-(0.0065*(alt-0)))/288)                 \
                , (9.80665/(0.0065*287)))
 
atm_press=100.5
 
print "Estimated Barometric Pressure at site        : %s kPa" % atm_press
 
 
# Estimated air vapor pressure in kPa ###################################
 
atm_vapor_press = (0.61121*math.exp((17.502*atm_temp)                   \
                / (240.97+atm_temp)))                                   \
                * (atm_hum/100)
 
print "Estimated Vapor Pressure at site             : %s kPa" % atm_vapor_press
 
 
# extraterrestrial radiation in W/m2 ###################################
 
extra_terr_rad  = (sol_const*sun_rel_dist_f)                            \
                * (math.cos(sol_zen*(math.pi/180)))
 
print "Estimated Extraterrestrial radiation         : %s W/m²" % extra_terr_rad
 
 
# precipitable water in the atmosphere in mm ###########################
 
atm_prec_h2o    = ((0.14*atm_vapor_press)*atm_press)+2.1
 
print "Estimated precipitable water in Atmosphere   : %s mm" % atm_prec_h2o
 
 
# clearness index for direct beam radiation [unitless] #################
 
clr_idx_beam_rad= 0.98*(math.exp(((-0.00146*atm_press)                  \
                / (atm_tc*(math.sin((90-sol_zen)*(math.pi/180)))))      \
                - (0.075*(math.pow((atm_prec_h2o                        \
                / (math.sin((90-sol_zen)*(math.pi/180)))),0.4)))))
 
print "Clearness index for direct beam radiation    : %s" % clr_idx_beam_rad
 
 
# transmissivity index for diffuse radiation [unitless] ################
 
if                              (clr_idx_beam_rad > 0.15):
    trns_idx_diff_rad=          0.35-(0.36*clr_idx_beam_rad)
else:
    trns_idx_diff_rad=          0.18+(0.82*clr_idx_beam_rad)
 
print "Transmissivity index for diffuse radiation   : %s" % trns_idx_diff_rad
 
 
# Model Estimated Shortwave Radiation (W/m2) ###########################
 
est_sol_rad     =               (clr_idx_beam_rad + trns_idx_diff_rad)  \
                *               extra_terr_rad
 
print "--------------------------------------------------------------"
print "Model Estimated Shortwave Radiation (RSO)    : \033[1;33m%3.1f W/m²\033[0m" % est_sol_rad
 
 
# Estimate Output of Odyssey (solar panels at nominal Efficiency) ######
 
est_p_out       =               (est_sol_rad*pv_a) / 100 * pv_eff
 
print "Model Estimated Max. PV-Power Output         : \033[1;31m%3.1f W\033[0m \033[1;37m@ %d%% Mod Eff\033[0m" % (est_p_out, pv_eff)
 
 
# Estimate conversion loss due to module temperature ###################
 
if                              ( pv_temp > 25 ):
     
    pv_p_loss   =               (pv_temp-25 ) * pv_tk
    pv_p_loss_p =               (est_p_out/100) * pv_p_loss
 
print "Model estimated PV-Module temp conv. loss       : \033[1;37m%2.1f W / %2.1f%%\033[0m" % (pv_p_loss_p, pv_p_loss)
 
# Estimate conversion loss due to module age
 
est_pv_age_loss =               est_p_out - (est_p_out*pv_ak)
 
print "Model estimated PV-Module aging loss            : \033[1;37m%03.1f W\033[0m" % est_pv_age_loss
 
# Optimal PV Module Angle to Sun
 
print "Model recommends PV-Module angle to Sun      : \033[1;37m%02.1f°\033[0m" % sol_zen
 
# Estime Power output of Odyssey (solar panels at corrected Efficiency)
 
est_real_p_out  =               est_p_out - est_pv_age_loss-pv_p_loss_p
 
print "--------------------------------------------------------------"
print "Model Estimated Real PV-Power Output         : \033[1;31m%3.1f W\033[0m" % est_real_p_out

Download:
Source Code

Please feel free to contribute by verifying these calculations or extend them to an even more accurate/versatile model for all of us.

# python solar-prediction.py 
--------------------------------------------------------------
22.6.2011 | 173 | 12.000000 | 
--------------------------------------------------------------
Solar constant                               : 1367.8
Atmospheric turbidity coefficient            : 0.8
--------------------------------------------------------------
Inverse relative distance factor             : 0.968392237142
Sun declination                              : 23.4438070502°
Equation of time                             : -1.71440597602 min
Solar Noon                                   : 12.0285734329 
Solar zenith angle                           : 0.593383030197° 
Estimated barometric Pressure at site        : 100.5 kPa
Estimated vapor pressure at site             : 0.633406906142 kPa
Estimated extraterrestrial radiation         : 1324.49586817 W/m²
Estimated precipitable water in atmosphere   : 11.0120351694 mm
Clearness index for direct beam radiation    : 0.670704071246
Transmissivity index for diffuse radiation   : 0.108546534352
--------------------------------------------------------------
Model estimated shortwave radiation (RSO)    : 1032.1 W/m²
Model estimated max. PV-Power output         : 344.7 W @ 20% Mod Eff
Model estimated PV-Module temp conv. loss    : 6.0 W / 1.8%
Model estimated PV-Module aging loss         : 6.9 W
Model recommends PV-Module angle to Sun      : 0.6°
--------------------------------------------------------------
Model estimated real PV-Power output         : 331.8 W

Sources