PV+Storage Example with Subhourly Inputs

[1]:
import time
import os
from generation_models import (BatteryParams, PVSystemDesign, PVGenerationModel, DCExternalGenerationModel,
                               PVStorageModel, MultiStorageInputs, SingleAxisTracking, TableCapDegradationModel,
                               DARTPrices, StorageCoupling, TermUnits, SolarResource, SolarResourceTimeSeries,
                               DCProductionProfile)
from tyba_client.client import Client
import numpy as np
import pandas as pd
[2]:
PAT = os.environ["TYBA_PAT"]
client = Client(PAT, host=os.getenv("HOST", "https://dev.tybaenergy.com"))

Example 1: Subhourly irradiance and prices

Build model

[19]:
solar_resource = SolarResource(
    typical=False,
    latitude=40.0,
    longitude=-80.0,
    time_zone_offset=-7.0,
    elevation=354,
    monthly_albedo=12 * [0.6],
    data=SolarResourceTimeSeries(
        **pd.read_csv("tgy-30min-06-01-to-06-07.csv").to_dict(orient="list")
    )
)

pv = PVGenerationModel(
    project_term=168,
    project_term_units=TermUnits.hours,
    time_interval_mins=30,
    solar_resource=solar_resource,
    inverter="Delta Electronics: M80U_XXX [480V]",
    pv_module="Boviet Solar Technology Co._ Ltd. BVM6612M-315",
    system_design=PVSystemDesign(
        dc_capacity=2000.0,
        ac_capacity=1500.0,
        poi_limit=15000.0,
        gcr=0.38,
        tracking=SingleAxisTracking(rotation_limit=45.0,
                                    backtrack=True)
    ),
    array_degradation_mode=None
)

battery = BatteryParams(
                power_capacity=2000.0,
                energy_capacity=4000.0,
                charge_efficiency=0.93,
                discharge_efficiency=0.93,
                capacity_degradation_model=TableCapDegradationModel(annual_capacity_derates=[1.0, 0.]),
                term=1
)

storage_inputs = MultiStorageInputs(batteries=[battery])

prices = DARTPrices(
    rtm=np.random.random(336).tolist(),
    dam=np.random.random(168).tolist()
)

import_limit = (-np.random.random(336) * 2000).tolist()

model = PVStorageModel(
    energy_prices=prices,
    time_interval_mins=30,
    import_limit=import_limit,
    storage_inputs=storage_inputs,
    storage_coupling=StorageCoupling.dc,
    pv_inputs=pv,
)

Run model

[20]:
res = client.schedule(model)
[21]:
id_ = res.json()["id"]
[22]:
res = client.wait_on_result_v1(id_)
[24]:
res["hourly"]["poi"]["power_kW"].sum()
[24]:
197144.83167240454

Example 2: Subhourly external generation and prices

Build model

[25]:
pv = DCExternalGenerationModel(
    project_term=24,
    project_term_units=TermUnits.hours,
    time_interval_mins=15,
    system_design=model.pv_inputs.system_design,
    inverter=model.pv_inputs.inverter,
    production_override=DCProductionProfile(
        **(pd.read_csv("dc-external-generation-15min-06-01.csv").
           rename(columns={"array_dc_power": "power", "array_dc_voltage": "voltage"}).
           to_dict(orient="list"))
    )
)

prices = DARTPrices(
    rtm=np.random.random(96).tolist(),
    dam=np.random.random(24).tolist()
)

import_limit = (-np.random.random(96) * 2000).tolist()

model = PVStorageModel(
    energy_prices=prices,
    time_interval_mins=15,
    import_limit=import_limit,
    storage_inputs=storage_inputs,
    storage_coupling=StorageCoupling.dc,
    pv_inputs=pv,
)

Run model

[26]:
res = client.schedule(model)
[27]:
id_ = res.json()["id"]
[28]:
res = client.wait_on_result_v1(id_)
[30]:
res["hourly"]["poi"]["power_kW"].sum()
[30]:
88357.40427243654

Example 3: Hourly irradiance and subhourly prices

Build model

[31]:
irradiance_30min = pd.read_csv("tgy-30min-06-01-to-06-07.csv")
irradiance_30min.index = pd.date_range(start="1990-06-01T00:00:00", periods=336, freq="30T")
irradiance_hourly = irradiance_30min.resample("H").mean()

solar_resource = SolarResource(
    typical=False,
    latitude=40.0,
    longitude=-80.0,
    time_zone_offset=-7.0,
    elevation=354,
    monthly_albedo=12 * [0.6],
    data=SolarResourceTimeSeries(
        **irradiance_hourly.to_dict(orient="list")
    )
)

pv = PVGenerationModel(
    project_term=168,
    project_term_units=TermUnits.hours,
    time_interval_mins=60,  # this is where we indicate that it is an hourly solar resource
    solar_resource=solar_resource,
    inverter="Delta Electronics: M80U_XXX [480V]",
    pv_module="Boviet Solar Technology Co._ Ltd. BVM6612M-315",
    system_design=PVSystemDesign(
        dc_capacity=2000.0,
        ac_capacity=1500.0,
        poi_limit=15000.0,
        gcr=0.38,
        tracking=SingleAxisTracking(rotation_limit=45.0,
                                    backtrack=True)
    ),
    array_degradation_mode=None
)

prices = DARTPrices(
    rtm=np.random.random(672).tolist(),
    dam=np.random.random(168).tolist()
)

import_limit = (-np.random.random(672) * 2000).tolist()

model = PVStorageModel(
    energy_prices=prices,
    time_interval_mins=15,  # this is where we indicate that our prices are subhourly
    import_limit=import_limit,
    storage_inputs=storage_inputs,
    storage_coupling=StorageCoupling.dc,
    pv_inputs=pv,
)

Run model

[32]:
res = client.schedule(model)
[33]:
_id = res.json()["id"]
[36]:
res = client.wait_on_result_v1(id_)
[37]:
res["hourly"]["poi"]["power_kW"].sum()
[37]:
88357.40427243654
[ ]: