Build a solar generation forecast dashboard in Python

Solar producers need more than a weather forecast. They need to know how much power a system will actually generate, hour by hour, so they can plan curtailment, storage, or grid bidding.

17. 08. 2026

This tutorial builds a small dashboard that turns a solar forecast API into something visual, using Python and Streamlit. By the end, you'll have a working local app where you enter a location and system size, and get a generation forecast chart built on professional, accurate data from Meteosource Weather API.

What you'll need

  • Python 3.10 or later
  • A Meteosource account on the Renewables tier. Solar and wind power prediction are not part of the free plan, but there's a free 10 day trial.
  • Ten minutes

Create a virtual environment and install the three libraries this tutorial uses:


python3 -m venv venv            # Windows: python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install streamlit pandas requests

Step 1: Understand the data

Meteosource's solar prediction endpoint returns an hourly forecast for a given location and system size. A simplified response looks like this:


{
  "hourly": {
    "data": [
      {
        "date": "2026-06-07T08:00:00",
        "production": 3.31,
        "ghi": 370.1,
        "dni": 552.15,
        "dhi": 119.35,
        "temperature": 13.7
      }
    ]
  }
}

production is the estimated power output for that hour, and it's the number we'll chart. Sum it across the day and you get the day's total generation.

Timestamps are UTC by default; pass the optional timezone parameter (a tzinfo name like Europe/London) if you want the hours, and the daily total, in local time.

The three irradiance values explain why production looks the way it does. ghi is global horizontal irradiance, the total solar energy reaching a horizontal surface at ground level. dni is the direct beam component and dhi is the diffuse component, the light scattered by cloud and atmosphere. On an overcast day dni collapses and dhi carries most of the total.

One limit to know about up front: the Renewables tier forecasts five days ahead. Pick a date further out and you won't get data back.

Step 2: Build the app

Create a file called app.py:


import streamlit as st
import pandas as pd
import requests
from datetime import date

API_KEY = "YOUR-API-KEY"
BASE_URL = "https://www.meteosource.com/api/v1/renewables/solar_prediction"

st.set_page_config(page_title="Solar Forecast Dashboard", layout="centered")
st.title("Solar Generation Forecast")

col1, col2, col3 = st.columns(3)
with col1:
    lat = st.number_input("Latitude", value=51.5, format="%.4f")
with col2:
    lon = st.number_input("Longitude", value=0.0, format="%.4f")
with col3:
    module_kw = st.number_input("System size (kW)", value=5.0, min_value=0.1)

forecast_date = st.date_input("Forecast date", value=date.today())

if st.button("Get forecast"):
    params = {
        "lat": lat,
        "lon": lon,
        "date": f"{forecast_date}T00:00:00",
        "module_kw": module_kw,
        "key": API_KEY,
    }

    response = requests.get(BASE_URL, params=params , timeout=10)

    if response.status_code != 200:
        st.error(f"API request failed: {response.status_code}")
        st.stop()

    data = response.json().get("hourly", {}).get("data", [])

    if not data:
        st.warning("No data. Try a date within the next five days.")
        st.stop()

    df = pd.DataFrame(data)
    df["date"] = pd.to_datetime(df["date"])
    df = df.set_index("date")

    total = df["production"].sum()
    st.metric("Estimated generation", f"{total:.1f} kWh")

    st.line_chart(df["production"])

    with st.expander("See raw hourly data"):
        st.dataframe(df[["production", "ghi", "dni", "dhi", "temperature"]])

Replace YOUR-API-KEY with your actual key from your Meteosource dashboard.

If you ever push this app to a public repo, move the key out of the code first - an environment variable or Streamlit's st.secrets both work.

Step 3: Run it


streamlit run app.py

This opens a browser tab with your dashboard. Enter a latitude, longitude, and system size, pick a date, and hit “Get forecast.” You'll see the estimated total generation for that date and an hourly chart of expected output.

What this is doing, in plain terms

  • requests calls the API and gets back raw hourly data
  • pandas turns that into a table, indexed by time, so it's easy to work with
  • streamlit takes that table and renders it as a chart and a summary number, with almost no extra code

Where to go from here

A few natural next steps once the basic version works.

Describe the actual array. The endpoint accepts tilt and orientation in degrees, plus inverter_kw. A south-facing 35 degree array and a flat east-facing one produce very different curves from the same weather, so passing real values is the single biggest accuracy improvement you can make here.

Add wind. The /renewables/wind_prediction endpoint takes total_capacity, turbine_count and hub_height and returns the same hourly structure. If you plot both on one chart, normalise them or use a second axis, because wind production comes back at a very different magnitude to a rooftop PV system.

Compare against a flat estimate. Chart the forecast next to a naive fixed daily average to see how much the weather actually moves the number. This is usually the chart that convinces a stakeholder.

Cache the response. Wrap the API call in @st.cache_data so a page refresh doesn't burn another request.

Switch to 15 minute resolution. The same parameters work against /api/v1/renewables/15min/solar_prediction on the PRO variant, which matters if you're bidding into an intraday market.

If you're running this for more than one site, the Renewables tier is priced per location for exactly this kind of use case.

Do you like this article?
Please share it with your friends