Skip to content

Commit

Permalink
Implement forecast generation and combining script (#75)
Browse files Browse the repository at this point in the history
* script created

* Update README.md

* updated test cases

* added test case

* Calling lat lon cap using function declaration

* added forecast init time in csv
  • Loading branch information
ombhojane authored Mar 21, 2024
1 parent 945e6e6 commit cf59c50
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ Which gives the following prediction

![https://github.com/openclimatefix/Open-Source-Quartz-Solar-Forecast/blob/main/predictions.png?raw=true](https://github.com/openclimatefix/Open-Source-Quartz-Solar-Forecast/blob/main/predictions.png?raw=true)

## Generating Forecasts
To generate solar forecasts and save them into a CSV file, follow these steps:
1. Navigate to the scripts directory
```bash
cd scripts
```
2. Run the forecast_csv.py script with desired inputs
```bash
python forecast_csv.py
```
Replace the --init_time_freq, --start_datetime, --end_datetime, and --site_name with your desired forecast initialization frequency (in hours), start datetime, end datetime, and the name of the forecast or site, respectively.

Output

The script will generate solar forecasts at the specified intervals between the start and end datetimes. The results will be combined into a CSV file named using the site name, start and end datetimes, and the frequency of forecasts. This file will be saved in the scripts/csv_forecasts directory.

## Installation

The source code is currently hosted on GitHub at: https://github.com/openclimatefix/Open-Source-Quartz-Solar-Forecast
Expand Down
97 changes: 97 additions & 0 deletions scripts/forecast_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import os
import pandas as pd
from datetime import datetime, timedelta
from quartz_solar_forecast.forecast import run_forecast
from quartz_solar_forecast.pydantic_models import PVSite
import unittest
from unittest.mock import patch

def generate_forecast(init_time_freq, start_datetime, end_datetime, site_name, latitude, longitude, capacity_kwp):
"""
Generates forecasts at specified intervals and saves them into a CSV file.
Args:
init_time_freq (int): The frequency in hours at which the forecasts are generated.
start_datetime (str): The starting date and time for generating forecasts.
end_datetime (str): The ending date and time for generating forecasts.
site_name (str): The name of the site for which the forecasts are generated.
latitude (float): The latitude of the PV site.
longitude (float): The longitude of the PV site.
capacity_kwp (float): The capacity of the PV site in kilowatts peak (kWp).
"""
start = datetime.strptime(start_datetime, "%Y-%m-%d %H:%M:%S")
start_date = start.date()
end = datetime.strptime(end_datetime, "%Y-%m-%d %H:%M:%S")
end_date = end.date()
all_forecasts = pd.DataFrame()
site = PVSite(latitude=latitude, longitude=longitude, capacity_kwp=capacity_kwp)

init_time = start
while init_time <= end:
print(f"Running forecast for initialization time: {init_time}")
predictions_df = run_forecast(site=site, ts=init_time.strftime("%Y-%m-%d %H:%M:%S"))
predictions_df.reset_index(inplace=True)
predictions_df.rename(columns={'index': 'datetime'}, inplace=True)
predictions_df['forecast_init_time'] = init_time
all_forecasts = pd.concat([all_forecasts, predictions_df])
init_time += timedelta(hours=init_time_freq)

output_dir = os.path.join(os.getcwd(), 'csv_forecasts')
if not os.path.exists(output_dir):
os.makedirs(output_dir)
output_file_name = f"forecast_{site_name}_{start_date}_{end_date}.csv"
output_file_path = os.path.join(output_dir, output_file_name)
all_forecasts.to_csv(output_file_path, index=False)
print(f"Forecasts saved to {output_file_path}")

if __name__ == "__main__":
# please change the site name, start_datetime and end_datetime, latitude, longitude and capacity_kwp as per your requirement
generate_forecast(
init_time_freq=6,
start_datetime="2024-03-10 00:00:00",
end_datetime="2024-03-11 00:00:00",
site_name="Test",
latitude=51.75,
longitude=-1.25,
capacity_kwp=1.25
)

class TestGenerateForecast(unittest.TestCase):
def setUp(self):
self.site_name = "TestCase"
self.latitude = 51.75
self.longitude = -1.25
self.capacity_kwp = 1.25
self.start_datetime = "2024-03-10 00:00:00"
self.end_datetime = "2024-03-11 00:00:00"
self.init_time_freq = 6
self.output_dir = os.path.join(os.getcwd(), 'csv_forecasts')
self.output_file_name = f"forecast_{self.site_name}_{self.start_datetime[:10]}_{self.end_datetime[:10]}.csv"
self.output_file_path = os.path.join(self.output_dir, self.output_file_name)

@patch('forecast_csv.run_forecast')
def test_generate_forecast(self, mock_run_forecast):
mock_df = pd.DataFrame({
'datetime': [datetime(2024, 3, 10, 0, 0) + timedelta(hours=6 * i) for i in range(4)],
'power_kw': [0.1, 0.5, 0.8, 0.6],
'forecast_init_time': [datetime(2024, 3, 10, 0, 0)] * 4
})
mock_run_forecast.return_value = mock_df

if not os.path.exists(self.output_dir):
os.makedirs(self.output_dir)

generate_forecast(self.init_time_freq,
self.start_datetime,
self.end_datetime,
self.site_name,
self.latitude,
self.longitude,
self.capacity_kwp
)

self.assertTrue(os.path.exists(self.output_file_path))
os.remove(self.output_file_path)

if __name__ == '__main__':
unittest.main()

0 comments on commit cf59c50

Please sign in to comment.