Forecasting

Do Solar Panels Need to be Cleaned?

December 09, 2020

It seems like my solar photovoltaic (PV) panel monitoring service, Enphase, started sending more emails recently. Or maybe because I recently wrote a blog (Residential Lighting Efficiency Really Does Make a Difference) during my PV true up period, I probably had solar on the brain. I just received an email recommending that I wash my panels before winter, and it made me start to wonder – my car is parked outside and gets filthy super quick, so do I need to climb up on the roof and clean the panels or hire someone to do it? Living in San Diego, it is true that there’s not much rain and the panels have been up there for four years now without a proper bath. It totally makes sense that general dust, dirt and fire-related ash would make them less efficient, right? But why would I do it before winter when it rains more? How on Earth do you wash them? Will I fall off the roof? All of this is a little counter-intuitive to what the dollar amount on my latest true up indicated, and although I looked at my lighting efficiency, I didn’t really look at the solar production over the years. I never considered that there might also be losses due to grime.

Some research indicates that cleaning your solar panels leads to small improvements in output, yet others say you should clean them twice a year. One site even suggested a 35% loss after two years, but it turns out that all of the cleaning recommendations tended to be from solar panel cleaning companies or from quoting stats via cleaning companies. Then I stumbled on a study by the Jacobs School of Engineering at UCSD that made me feel much better about not having given my panels any attention since they were installed. According to their research, due to the angle that the panels are mounted and being on a roof, they found that rain did a fine job of cleaning the panels as long as there are no bird droppings.

Again, having been part of the forecasting team for so long, I also had to look at the data and graph it:


Surprisingly, there has been a slight annual uptick in production (is that global warming?!). In any case, I definitely agree that my data and the research available are in alignment. I’m good with not cleaning my solar panels. If I wanted to increase my production a smidge during the summer, when there isn’t any rain in sight, I could clean them. But I don’t think it’s worth the effort, and hiring someone definitely would not offset the cost.

Se ha producido un error al procesar la plantilla.
The following has evaluated to null or missing:
==> authorContent.contentFields  [in template "44616#44647#114455" at line 9, column 17]

----
Tip: It's the step after the last dot that caused this error, not those before it.
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----

----
FTL stack trace ("~" means nesting-related):
	- Failed at: contentFields = authorContent.content...  [in template "44616#44647#114455" at line 9, column 1]
----
1<#assign 
2	webContentData = jsonFactoryUtil.createJSONObject(author.getData()) 
3	classPK = webContentData.classPK 
4/> 
5 
6<#assign 
7authorContent = restClient.get("/headless-delivery/v1.0/structured-contents/" + classPK + "?fields=contentFields%2CfriendlyUrlPath%2CtaxonomyCategoryBriefs") 
8contentFields = authorContent.contentFields 
9categories=authorContent.taxonomyCategoryBriefs 
10authorContentData = jsonFactoryUtil.createJSONObject(authorContent) 
11friendlyURL = authorContentData.friendlyUrlPath 
12authorCategoryId = "0" 
13/> 
14 
15<#list contentFields as contentField > 
16   <#assign  
17	 contentFieldData = jsonFactoryUtil.createJSONObject(contentField)  
18	 name = contentField.name 
19	 /> 
20	 <#if name == 'authorImage'> 
21	    <#if (contentField.contentFieldValue.image)??> 
22	        <#assign authorImageURL = contentField.contentFieldValue.image.contentUrl />	 
23			</#if> 
24	 </#if> 
25	 <#if name == 'authorName'> 
26	    <#assign authorName = contentField.contentFieldValue.data /> 
27			<#list categories as category > 
28         <#if authorName == category.taxonomyCategoryName> 
29				     <#assign authorCategoryId = category.taxonomyCategoryId /> 
30				 </#if> 
31      </#list> 
32	 </#if> 
33	 <#if name == 'authorDescription'> 
34	    <#assign authorDescription = contentField.contentFieldValue.data /> 
35			 
36	 </#if> 
37	  
38	 <#if name == 'authorJobTitle'> 
39	    <#assign authorJobTitle = contentField.contentFieldValue.data /> 
40			 
41	 </#if> 
42 
43</#list> 
44 
45<div class="blog-author-info"> 
46	<#if authorImageURL??> 
47		<img class="blog-author-img" id="author-image" src="${authorImageURL}" alt="" /> 
48	</#if> 
49	<#if authorName??> 
50		<#if authorName != ""> 
51			<p class="blog-author-name">By <a id="author-detail-page" href="/w/${friendlyURL}?filter_category_552298=${authorCategoryId}"><span id="author-full-name">${authorName}</span></a></p> 
52			<hr /> 
53		</#if> 
54	</#if> 
55	<#if authorJobTitle??> 
56		<#if authorJobTitle != ""> 
57			<p class="blog-author-title" id="author-job-title" >${authorJobTitle}</p> 
58			<hr /> 
59		</#if> 
60	</#if> 
61	<#if authorDescription??> 
62		<#if authorDescription != "" && authorDescription != "null" > 
63			<p class="blog-author-desc" id="author-job-desc">${authorDescription}</p> 
64			<hr /> 
65		</#if> 
66	</#if> 
67</div>