Calculating energy production from weather forecast in Python

In a previous post, I’ve used Python Data Tools to fetch and visualize weather data using Datahub API (sign up for a free API key to try it). Today I’m going to solve another simple use-case using few other Python-based tools and the very same data and API.

One of the heavily-influenced weather-dependent industries is Renewable Energy. For example, a pretty common problem such as forecasting energy production could be derived from the weather forecast. Let’s take a look at how simple forecasting solution could be created for the wind energy since it’s a little more complex comparing to solar.

Choosing a modeling solution

If I simplify wind power production forecasting enough, then solutions boil down to two main modeling aspects: physical modeling via computational fluid dynamics and mathematical modeling via regular linear algebra. Simple mathematical modeling alone doesn’t provide enough accuracy, but it might satisfy common use-cases like estimation of maximum power production.

Additionally, modeling results can be enhanced via statistical analysis of hyper-local time series (meteorological data and energy production data). But today we’re going to take the simplest example and use a linear equation to calculate ideal power production.

Each wind turbine manufacturer provides an ideal energy production curve for their turbines. Here is a brief overview about what it means:

The power curve of a wind turbine presents the electrical power output ratings of the machine for different wind speeds. A typical wind turbine power curve has three main characteristic speeds: 1) cut-in (Vc ); 2) rated (Vr ); and 3) cut-out (Vs) speeds. The turbine starts generating power when the wind speed reaches the cut-in value. The rated speed is the wind speed at which the generator is producing the machine’s rated power. When the wind speed reaches the cut-out speed, the power generation is shut down to prevent defects and damages. Theoretical power curves are supplied by manufacturers assuming ideal meteorological and topographical conditions. In practice, however, wind turbines are never used under ideal conditions, and the empirical power curves could be substantially different from the theoretical ones due to the location of the turbine, air density, wind velocity distribution, wind direction, mechanical and control issues, as well as uncertainties in measurements.

(Source: )

So as we see these “ideal power curves” are simply describing potentially maximum output, which is pretty useful for basic estimations.


Let’s see what we can do to improve accuracy. Here are most well-known options:

  1. Using more accurate weather forecast would naturally influence the quality of derived energy production forecast. For that matter, there are commercial systems that use sophisticated hyper-local models taking into account relief and in-situ meteorological data.
  2. Another solution might involve various statistical methods, Machine Learning, etc. But again all these methodologies require statistically significant periods of observations.

In our example case we don’t have historical data which we could use for statistical improvements, so we left to the option of using power curve provided by turbine manufacturer in combination with the most accurate hyper-local forecast.

Since quality hyper-local forecasts are usually tailor-made for specific areas, we will use global one (GFS) so that the demo case would be reproducible for any location. But you can clone and modify that example code (linked at the end of article) and feed any quality custom data feed with the same weather variables.

In my previous example, I’ve used Python + Pandas data framework to fetch and visualize weather data. Now, I’m going to add some wind-to-energy calculations using open source Python library containing predefined equations and a bunch of known power curves for conventional wind turbines —

Crunching numbers

I’ll skip some details of conversion from API to Pandas covered in the previous post and jump on how to solve our particular case with the very same tools.

  1. To calculate energy production, we need to acquire these weather data variables: pressure, air temperature, wind speed. In the best case scenario, these variables should be provided at heights as close as possible to the wind turbine hub height.
  2. We need to pick the location of our “imagined” turbine, then particular turbine model with its power curve.
  3. The third constant parameter is Roughness length, which is determined by turbine location.

So let’s initialize turbine model with VESTAS V 90 parameters:

sample_wind_turbine = {
  'h_hub': 70, # meters
  'd_rotor': 90, # meters
  'wind_conv_type': 'VESTAS V 90 3000'

You can notice the power curve definition of that turbine in the windpowerlib data file (CSV, line #62). In the same file, you can see all supported wind turbines. It’s also possible to feed custom power curve for any other wind turbine not listed there.

In the previous example, I’ve used gridded data query for animation. The new example takes advantage of other API query/output type — query time series by particular LonLat point. So the resulting data structure looks a bit different.

In this example, we make API requests while looping over a list of variables (air temperature, air pressure, wind speed) then merge resulting time-series by time index.

Now, as soon as we get the weather data into Pandas DataFrame we need to add our static roughness parameter — full_data_frame['z0'] = roughness.

At that point we pretty much done and what’s left is to make a plot and see the relationship between the weather and estimated energy production.


To wrap up this post I’d like to share the final script so everybody can reproduce that example and tweak it further to match their own cases.

The only requirements are: signup for Datahub API key and installation of Python with a few required modules (pip install docopt pandas slumber matplotlib seaborn windpowerlib).

Here is an example command that I’ve used to produce graph shared earlier.

python -- 4.418889 52.606111 --rotor=90 --hub_height=70 --apikey=<your_api_key>

You can get <your_api_key> at your account page after signup/sign-in.

You can also run python --help to see all available options.