if recursive:
for c in self.cells:
c._recalc()
- # array Voc is sum of cells
+ # subpanel Voc is sum of cells
self.Voc = 0
for c in self.cells:
self.Voc += c.V(0)
- # array Isc is min of cells
+ # subpanel Isc is min of cells
self.Isc = self.cells[0].I(0)
for c in self.cells:
if c.I(0) < self.Isc:
for c in self.subpanels:
self.Voc += c.V(0)
- # array Isc is min of cells
+ # panel Isc is max of cells. It is the maximum
+ # not the minimum due to the effect of the bypass diodes
+ # on the subpanels
self.Isc = self.subpanels[0].I(0)
for c in self.subpanels:
- if c.I(0) < self.Isc:
+ if c.I(0) > self.Isc:
self.Isc = c.I(0)
def V(self, I):
if recursive:
for p in self.panels:
p._recalc(recursive)
- # array Isc is min of cells
+ # string Isc is max of the panel currents
+ # it is max, not min, as any underperforming
+ # panels will go into bypass
self.Isc = self.panels[0].I(0)
for c in self.panels:
- if c.I(0) < self.Isc:
+ if c.I(0) > self.Isc:
self.Isc = c.I(0)
- # array Voc is sum of cells
+ # string Voc is sum of panels
self.Voc = 0
for c in self.panels:
self.Voc += c.V(0)
@cacheobj
def V(self, I):
def Ierr(x):
- return abs(I - self.I(x))
+ ret = abs(I - self.I(x))
+ return ret
if I < 0:
lower = 0
upper = panel_Voc*len(self.strings[0].panels)
lower = 0
upper = panel_Voc*opts.string_length
print "aV I=%g lower=%g upper=%g" % (I, lower, upper)
- return find_best(Ierr, lower, upper)
+ return find_best2(Ierr, lower, upper)
def P(self, V):
if V < inverter_range[0] or V > inverter_range[1]:
print("A1=%.2f A2=%.2f MPPP=%.2fW (%d shaded)" % (Pa1, Pa2, Pa1+Pa2, i+1))
+def panel_shading():
+ '''plot shading effects on 1 panel'''
+ p = panel()
+ maxv = p.Voc
+ minv = 0
+ plotit(p.P, minv, maxv, label='Unshaded', loc='upper left')
+
+ pylab.xlabel('Voltage (V)')
+ pylab.ylabel('Power (W)')
+ pylab.title("1 Panel")
+
+ for i in range(0, opts.num_subpanels):
+ p.subpanels[i].set_irradiance(opts.irradiance * opts.shade_factor)
+ p._recalc(True)
+ plotit(p.P, minv, maxv, label='%d shaded' % (i+1), loc='upper left')
+ pylab.show()
+
+def panel_shading_IV():
+ '''plot shading effects on 1 panel'''
+ p = panel()
+ maxv = p.Voc
+ minv = 0
+ plotit(p.I, minv, maxv, label='Unshaded', loc='upper left')
+
+ pylab.xlabel('Voltage (V)')
+ pylab.ylabel('Current (A)')
+ pylab.title("1 Panel")
+
+ for i in range(0, opts.num_subpanels):
+ p.subpanels[i].set_irradiance(opts.irradiance * opts.shade_factor)
+ p._recalc(True)
+ plotit(p.I, minv, maxv, label='%d shaded' % (i+1), loc='upper left')
+ pylab.show()
+
+def panel_shading_VI():
+ '''plot shading effects on 1 panel'''
+ p = panel()
+ maxi = p.Isc
+ mini = 0
+ plotit(p.V, mini, maxi, label='Unshaded', loc='upper left')
+
+ pylab.xlabel('Current (A)')
+ pylab.ylabel('Voltage (V)')
+ pylab.title("1 Panel")
+
+ for i in range(0, opts.num_subpanels):
+ p.subpanels[i].set_irradiance(opts.irradiance * opts.shade_factor)
+ p._recalc(True)
+ plotit(p.V, mini, maxi, label='%d shaded' % (i+1), loc='upper left')
+ pylab.show()
+
def mpp_loss():
'''show loss from not having separate MPPTs per string'''
n=opts.string_length
if err > tolerance:
raise Exception("%s: v1=%f v2=%g" % (tag, v1, v2))
- def check_IV(tag, m, tolerance=1.0):
+ def check_IV(tag, m, tolerance=10.0):
irange = numpy.arange(-m.Isc, m.Isc*2, (3*m.Isc/100))
for i in irange:
check('%s: I=%g Isc=%g' % (tag, i, m.Isc), m.I(m.V(i)), i,
p2 = c.P(cell_Vmp)
check("irradiance", p1, p2/2, tolerance=10)
- check("leakage", c.I(c.Voc+1), -1.0/(opts.panel_Roc/cell_scale))
+ check("leakage", c.I(c.Voc+1), -1.0/(opts.panel_Roc/cell_scale), tolerance=10)
check("Voc", cell_Voc*opts.cells_per_subpanel, s.V(0))
check("Isc", panel_Isc, s.I(0))
check("Vmp", cell_Vmp*opts.cells_per_subpanel, s.V(panel_Imp))
- check("Imp", panel_Imp, s.I(panel_Vmp*opts.cells_per_subpanel))
+ check("Imp", panel_Imp, s.I(panel_Vmp/opts.num_subpanels))
check_IV("subpanel IV", s)
s2=subpanel()
s2.set_irradiance(500)
check_IV("subpanel IV 500W/m2", s2, tolerance=2.0)
- Vmp = panel_Vmp/opts.cells_per_subpanel
+ Vmp = panel_Vmp/opts.num_subpanels
check("irradiance", s2.P(Vmp), s.P(Vmp)/2, tolerance=10)
check("bypass1", s.I(-1.0) - s.Isc, 1.0/subpanel_Rbp)
check("Isc", panel_Isc, p.I(0))
check("Vmp", panel_Vmp, p.V(panel_Imp))
check("Imp", panel_Imp, p.I(Vmp))
- check("bypass", p.I(-1.0) - p.Isc, 1.0/subpanel_Rbp)
+ check("bypass", p.I(-1.0) - p.Isc, 1.0/(subpanel_Rbp*opts.num_subpanels))
check_IV("panel IV", p)
p2=subpanel()
p2.set_irradiance(500)
check_IV("panel IV 500W/m2", p2, tolerance=2.0)
- check("irradiance", p2.P(Vmp), p.P(Vmp)/2, tolerance=10)
+ Vmp = panel_Vmp/opts.num_subpanels
+ check("irradiance", p2.P(Vmp), p.P(Vmp)/2, tolerance=15)
print "Checking string behaviour"
s=string(opts.string_length)
check("Isc", panel_Isc, s.I(0))
check("Vmp", panel_Vmp*opts.string_length, s.V(panel_Imp))
check("Imp", panel_Imp, s.I(panel_Vmp*opts.string_length))
- check("bypass", s.I(-1.0*opts.string_length) - s.Isc, 1.0/subpanel_Rbp)
+ check("bypass", s.I(-1.0*opts.string_length) - s.Isc, 1.0/(subpanel_Rbp*opts.num_subpanels))
check_IV("string IV", s, tolerance=5.0)
check("Isc", panel_Isc*2, a.I(0))
# check("Vmp", panel_Vmp*opts.string_length, a.V(panel_Imp*2))
check("Imp", panel_Imp*2, a.I(panel_Vmp*opts.string_length))
- check("bypass", a.I(-1.0*opts.string_length) - a.Isc, 2.0/subpanel_Rbp)
+ check("bypass", a.I(-1.0*opts.string_length) - a.Isc, 2.0/(opts.num_subpanels*subpanel_Rbp))
check_IV("array IV", a, tolerance=2.0)
"panel_IV_T" : panel_IV_T,
"panel_L" : panel_L,
"panel_IV_L" : panel_IV_L,
+ "panel-shading": panel_shading,
+ "panel-shadingIV": panel_shading_IV,
+ "panel-shadingVI": panel_shading_VI,
"string_P" : string_P,
"string_IV" : string_IV,
"string_VI" : string_VI,
parser.add_option("", "--irradiance", dest="irradiance", help="light level (W/m2)",type='float', default=1000)
parser.add_option("", "--shade-factor", dest="shade_factor", help="shading factor",type='float', default=0.05)
parser.add_option("", "--subpanels", dest="num_subpanels", help="subpanels per panel",
- type='int', default=1)
+ type='int', default=3)
parser.add_option("", "--cells-per-subpanel", dest="cells_per_subpanel", help="cells per subpanel",
type='int', default=1)
parser.add_option("", "--blocking-diodes", dest="blocking_diodes",