PVWATTS_LOSSES
This function combines multiple PV system loss assumptions into a single total derate percentage using the PVWatts compounding-loss formulation. Each input is a percentage loss for one mechanism such as soiling, shading, mismatch, or equipment availability.
PVWatts multiplies the retained fractions for each loss component and converts the remaining derate back to a total loss percentage:
L_{total}(\%) = 100 \left[1 - \prod_i \left(1 - \frac{L_i}{100}\right)\right]
Because the model compounds retained performance, the total loss is not simply the arithmetic sum of the inputs except in very small-loss approximations.
Excel Usage
=PVWATTS_LOSSES(soiling, shading, snow, mismatch, wiring, connections, lid, nameplate_rating, age, availability)
soiling(float, optional, default: 2): Loss due to soiling (%).shading(float, optional, default: 3): Loss due to shading (%).snow(float, optional, default: 0): Loss due to snow (%).mismatch(float, optional, default: 2): Loss due to mismatch (%).wiring(float, optional, default: 2): Loss due to wiring (%).connections(float, optional, default: 0.5): Loss due to connections (%).lid(float, optional, default: 1.5): Light induced degradation (%).nameplate_rating(float, optional, default: 1): Nameplate rating loss (%).age(float, optional, default: 0): Loss due to age (%).availability(float, optional, default: 3): Loss due to availability (%).
Returns (float): Total system losses (%), or an error string.
Example 1: Standard PVWatts default losses
Inputs:
| soiling | shading | snow | mismatch | wiring | connections | lid | nameplate_rating | age | availability |
|---|---|---|---|---|---|---|---|---|---|
| 2 | 3 | 0 | 2 | 2 | 0.5 | 1.5 | 1 | 0 | 3 |
Excel formula:
=PVWATTS_LOSSES(2, 3, 0, 2, 2, 0.5, 1.5, 1, 0, 3)
Expected output:
14.0757
Example 2: No modeled losses
Inputs:
| soiling | shading | snow | mismatch | wiring | connections | lid | nameplate_rating | age | availability |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Excel formula:
=PVWATTS_LOSSES(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
Expected output:
0
Example 3: Single age loss component
Inputs:
| soiling | shading | snow | mismatch | wiring | connections | lid | nameplate_rating | age | availability |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | 0 |
Excel formula:
=PVWATTS_LOSSES(0, 0, 0, 0, 0, 0, 0, 0, 5, 0)
Expected output:
5
Example 4: Higher aggregate project losses
Inputs:
| soiling | shading | snow | mismatch | wiring | connections | lid | nameplate_rating | age | availability |
|---|---|---|---|---|---|---|---|---|---|
| 5 | 8 | 1 | 3 | 2.5 | 1 | 2 | 1.5 | 1 | 4 |
Excel formula:
=PVWATTS_LOSSES(5, 8, 1, 3, 2.5, 1, 2, 1.5, 1, 4)
Expected output:
25.6764
Python Code
Show Code
from pvlib.pvsystem import pvwatts_losses as result_func
def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2, connections=0.5, lid=1.5, nameplate_rating=1, age=0, availability=3):
"""
Implement NREL's PVWatts system loss model.
See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.pvwatts_losses.html
This example function is provided as-is without any representation of accuracy.
Args:
soiling (float, optional): Loss due to soiling (%). Default is 2.
shading (float, optional): Loss due to shading (%). Default is 3.
snow (float, optional): Loss due to snow (%). Default is 0.
mismatch (float, optional): Loss due to mismatch (%). Default is 2.
wiring (float, optional): Loss due to wiring (%). Default is 2.
connections (float, optional): Loss due to connections (%). Default is 0.5.
lid (float, optional): Light induced degradation (%). Default is 1.5.
nameplate_rating (float, optional): Nameplate rating loss (%). Default is 1.
age (float, optional): Loss due to age (%). Default is 0.
availability (float, optional): Loss due to availability (%). Default is 3.
Returns:
float: Total system losses (%), or an error string.
"""
try:
l_soiling = float(soiling) if soiling is not None else 2.0
l_shading = float(shading) if shading is not None else 3.0
l_snow = float(snow) if snow is not None else 0.0
l_mismatch = float(mismatch) if mismatch is not None else 2.0
l_wiring = float(wiring) if wiring is not None else 2.0
l_conn = float(connections) if connections is not None else 0.5
l_lid = float(lid) if lid is not None else 1.5
l_nameplate = float(nameplate_rating) if nameplate_rating is not None else 1.0
l_age = float(age) if age is not None else 0.0
l_avail = float(availability) if availability is not None else 3.0
res = result_func(
soiling=l_soiling,
shading=l_shading,
snow=l_snow,
mismatch=l_mismatch,
wiring=l_wiring,
connections=l_conn,
lid=l_lid,
nameplate_rating=l_nameplate,
age=l_age,
availability=l_avail
)
return float(res)
except Exception as e:
return f"Error: {str(e)}"