iotdata, by Data Frontieriot
data
Solar energy

Soiling and shading losses: how monitoring reveals them

Soiling drags generation down slowly, across every string; shading and faults knock it down in a step, on just a few. How string comparison and the expected curve from irradiance tell one from the other, and the simple math that says when cleaning the plant pays off.

Data Frontier Engineering· Published September 8, 2026

A solar plant loses generation along two paths that look the same in the monthly total but differ in cause: soiling, which builds up slowly on every module, and shading or faults, which hit a few modules suddenly. The fix is different, and the only way to know which is which without climbing onto the roof is to look at the data the right way.

This article shows the three charts that make that distinction and ends with the math that tells you whether cleaning pays for itself.

Starting point: what the plant should generate

It all starts with irradiance measured in the plane of the modules. From it, the expected power of each string at any moment is approximately:

P_expected = P_nominal × (G / 1,000) × [1 + coef × (T_module − 25)]

Where P_nominal is the string’s power at standard test conditions, G is irradiance in W/m², T_module is module temperature in °C, and coef is the datasheet temperature coefficient, a negative number around −0.003 to −0.004 per °C. Fixed cable and inverter losses are also deducted; they are calibrated once with the plant clean.

The difference between expected and measured is the loss. What matters is how that loss behaves over the days and across strings.

Chart 1: string comparison

All strings with the same orientation receive the same sun. If one string’s current is 8% below the average of its siblings, the problem is that string’s: a cracked module, an open bypass diode, a corroded connector, shade from a pole, a concentrated patch of bird droppings.

If all of them are below expected by the same proportion, the problem is shared: uniform soiling, a dirty pyranometer (yes, it gets dirty too), or the expected value is wrong.

For each string, the platform computes the ratio between its current and the group median, day by day. A line that drifts away from the others is an alert.

Chart 2: loss over time

Soiling has its own signature: the loss grows a little every day during the dry season and drops suddenly with the first heavy rain. On a chart of performance ratio over weeks, it is a downward ramp followed by a step up when it rains or when the modules are washed.

Shading has a different one: it shows up at the same time every day, on specific strings, and the time shifts slowly through the year with the position of the sun. A tree that has grown or a new structure shows up this way.

A fault is a step down that doesn’t recover: a string that dropped 100% is a fuse or a connector; one that dropped by a third, on a string with three modules in parallel per input, is a module out.

Chart 3: power versus irradiance

Plot string power against irradiance at the same instant and a clean plant draws a straight line. Uniform soiling tilts the line down (less power for the same sun, across the whole range). Partial shading bends it: normal at low irradiance, flattened around mid-day when the shadow reaches the modules. Inverter power limiting flattens the curve only at the top.

Three charts, three answers, and nobody has to leave the office.

The cleaning math

Cleaning costs money, and the decision should be made with the plant’s own generation. The inputs:

  • E_expected: energy the plant would generate clean over the period, from the formula above, in kWh/day
  • p: soiling loss measured by the monitoring, as a fraction (0.05 for 5%)
  • tariff: what each kWh is worth to you, per kWh in your currency (the grid energy it saves you or the credit it earns, or the price the plant sells at)
  • C_cleaning: the cost of one full cleaning, in your currency

The daily loss in money is:

Loss_day = E_expected × p × tariff

And cleaning pays for itself in:

Days = C_cleaning / Loss_day

An example with hypothetical values, just to show the shape of the math: a 1,000 kWp plant generating 4,800 kWh/day when clean, 5% soiling, a tariff of 0.60 per kWh. Loss_day = 4,800 × 0.05 × 0.60 = 144 per day. If cleaning costs 6,000, it pays for itself in 42 days. If the dry season still has 90 days to go and soiling will only grow, clean. If the rain arrives in two weeks, wait.

Plug in your own numbers. The monitoring provides E_expected and p; the tariff and the cleaning cost are yours.

What the monitoring needs for this to work

  • Plane-of-array irradiance, with a clean sensor (include cleaning it in the routine, or the expected value drops along with the plant).
  • Current per string or, at the very least, per inverter input.
  • Module temperature, so the expected value doesn’t confuse heat with soiling.
  • History long enough to see the ramp and the step. Three months already show it; a year shows the seasonality.
  • Alerts for deviation between strings and for performance ratio falling below target.

What to do now

  1. Calibrate the expected value with the plant clean: one week of data after a cleaning or a heavy rain.
  2. Turn on string comparison and set the deviation that triggers an alert (5% is a reasonable start, adjusted to what the plant shows).
  3. Log every cleaning on the platform. The step on the chart is the proof of how much it returned, and it is the data that calibrates the next decision.

If you’d like to discuss a project, talk to one of our engineers.


Sources: IEC 61724-1, Photovoltaic system performance, Part 1: Monitoring (performance ratio and temperature correction); PV module datasheets (temperature coefficient of power); SunSpec Inverter Models (SunSpec Alliance), for per-input current registers.