Skip to content

Commit

Permalink
make adjuster work for non 15 miniute data
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdudfield committed Nov 12, 2024
1 parent 367342f commit 3355221
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 13 deletions.
21 changes: 16 additions & 5 deletions india_forecast_app/adjuster.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pvsite_datamodel.sqlmodels import ForecastValueSQL, GenerationSQL, ForecastSQL

Check failure on line 1 in india_forecast_app/adjuster.py

View workflow job for this annotation

GitHub Actions / lint_and_test / Lint the code and run the tests

Ruff (D100)

india_forecast_app/adjuster.py:1:1: D100 Missing docstring in public module
from sqlalchemy.sql import func
from sqlalchemy import cast, INT, text

from datetime import datetime, timedelta
import pandas as pd
Expand Down Expand Up @@ -30,7 +31,9 @@
"""


def get_me_values(session, hour: int, start_datetime: Optional[datetime] = None) -> pd.DataFrame:
def get_me_values(

Check failure on line 34 in india_forecast_app/adjuster.py

View workflow job for this annotation

GitHub Actions / lint_and_test / Lint the code and run the tests

Ruff (D417)

india_forecast_app/adjuster.py:34:5: D417 Missing argument description in the docstring for `get_me_values`: `site_uuid`
session, hour: int, site_uuid: str, start_datetime: Optional[datetime] = None
) -> pd.DataFrame:
"""
Get the ME values for the last 7 days for a given hour, for a given hour creation time
Expand All @@ -51,15 +54,24 @@ def get_me_values(session, hour: int, start_datetime: Optional[datetime] = None)

# join
query = query.join(ForecastSQL)
query = query.filter(GenerationSQL.start_utc == ForecastValueSQL.start_utc)

# round Generation start_utc and join to forecast start_utc
start_utc_minute_rounded = (
cast(func.date_part("minute", GenerationSQL.start_utc), INT)
/ 15
* text("interval '15 min'")
)
start_utc_hour = func.date_trunc("hour", GenerationSQL.start_utc)
generation_start_utc = start_utc_hour + start_utc_minute_rounded
query = query.filter(generation_start_utc == ForecastValueSQL.start_utc)

# only include the last 7 days
query = query.filter(ForecastValueSQL.start_utc >= start_datetime)
query = query.filter(GenerationSQL.start_utc >= start_datetime)

# filter on site
query = query.filter(ForecastSQL.site_uuid == "adaf6be8-4e30-4c98-ac27-964447e9c8e6")
query = query.filter(GenerationSQL.site_uuid == "adaf6be8-4e30-4c98-ac27-964447e9c8e6")
query = query.filter(ForecastSQL.site_uuid == site_uuid)
query = query.filter(GenerationSQL.site_uuid == site_uuid)

# filter on created_utc
query = query.filter((func.extract("hour", ForecastSQL.created_utc) == hour))
Expand All @@ -75,4 +87,3 @@ def get_me_values(session, hour: int, start_datetime: Optional[datetime] = None)
me_df = pd.DataFrame(me, columns=["me_kw", "horizon_minutes"])

return me_df

34 changes: 26 additions & 8 deletions india_forecast_app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import pandas as pd
import sentry_sdk
from pvsite_datamodel import DatabaseConnection
from pvsite_datamodel.read import get_pv_generation_by_sites, get_sites_by_country
from pvsite_datamodel.read import get_pv_generation_by_sites, get_sites_by_country, get_site_by_uuid
from pvsite_datamodel.sqlmodels import SiteAssetType, SiteSQL
from pvsite_datamodel.write import insert_forecast_values
from sqlalchemy.orm import Session
Expand Down Expand Up @@ -242,27 +242,45 @@ def save_forecast(

if use_adjuster:
log.info(f"Adjusting forecast for site_id={forecast_meta['site_uuid']}...")
me_values = get_me_values(db_session, forecast_meta["timestamp_utc"].hour)
me_values = get_me_values(
db_session, forecast_meta["timestamp_utc"].hour, site_uuid=forecast_meta["site_uuid"]
)

log.info(f"ME values: {me_values}")

# TODO
# should we put some sort of limits on the adjuster
# perhaps 10% of capacity?
# clip me values by 10% of the capacity
site = get_site_by_uuid(db_session, forecast_meta["site_uuid"])
capacity = site.capacity_kw
me_values["me_kw"].clip(lower=-0.1 * capacity, upper=0.1 * capacity, inplace=True)

# join forecast_values_df with me_values on horizon_minutes
forecast_values_df_adjust = forecast_values_df.copy()
forecast_values_df_adjust = forecast_values_df_adjust.merge(me_values, on="horizon_minutes", how="left")
forecast_values_df_adjust = forecast_values_df_adjust.merge(
me_values, on="horizon_minutes", how="left"
)

# if me_kw is null, set to 0
forecast_values_df_adjust["me_kw"].fillna(0, inplace=True)

# adjust forecast_power_kw by ME values
forecast_values_df_adjust["forecast_power_kw"] = forecast_values_df_adjust["forecast_power_kw"] - forecast_values_df_adjust["me_kw"]
forecast_values_df_adjust["forecast_power_kw"] = (
forecast_values_df_adjust["forecast_power_kw"] - forecast_values_df_adjust["me_kw"]
)

# drop me_kw column
forecast_values_df_adjust.drop(columns=["me_kw"], inplace=True)

# clip negative values to 0
forecast_values_df_adjust["forecast_power_kw"].clip(lower=0, inplace=True)

log.info(forecast_values_df_adjust)

if write_to_db:
insert_forecast_values(
db_session,
forecast_meta,
forecast_values_df_adjust,
ml_model_name=f'{ml_model_name}_adjust',
ml_model_name=f"{ml_model_name}_adjust",
ml_model_version=ml_model_version,
)

Expand Down

0 comments on commit 3355221

Please sign in to comment.