Example #1
0
def test_dc():
    model = batt.default("GenericBatteryCommercial")
    model.BatteryCell.batt_chem = 1
    model.Inverter.inverter_model = 0
    model.Inverter.inv_snl_eff_cec = 50
    model.BatterySystem.batt_ac_or_dc = 0
    PySAM.BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        400, 5))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        100, 20))
    assert (model.BatterySystem.batt_power_charge_max_kwac == pytest.approx(
        200, 5))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        100, 2))

    model.Inverter.inv_snl_eff_cec = 100
    model.BatterySystem.batt_ac_or_dc = 0
    PySAM.BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        400, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        100, 1))
    print(model.BatterySystem.batt_power_charge_max_kwac)
    print(model.BatterySystem.batt_power_charge_max_kwdc)
Example #2
0
def test_liion():
    model = batt.default("GenericBatteryCommercial")
    model.BatteryCell.batt_chem = 1
    PySAM.BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        400, 5))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        100, 20))
Example #3
0
def test_reopt_sizing_pvsam(solar_resource):
    import PySAM.Utilityrate5 as ur
    sys = pvsam.default("FlatPlatePVCommercial")
    fin = ur.from_existing(sys, "FlatPlatePVCommercial")
    bt = stbt.from_existing(sys, "GenericBatteryCommercial")

    sys.SolarResource.solar_resource_file = solar_resource
    bt.Load.crit_load = [0] * 8760
    post = sys.Reopt_size_battery_post()

    assert ('Scenario' in post['reopt_post'])
    assert (
        post['reopt_post']['Scenario']['Site']['latitude'] == pytest.approx(
            33.6, 0.1))
Example #4
0
def test_leadacid():
    model = batt.default("GenericBatteryCommercial")
    model.BatteryCell.batt_chem = 0
    assert(model.BatterySystem.batt_computed_bank_capacity != pytest.approx(100, .5))
    assert(model.BatterySystem.batt_power_charge_max_kwdc != pytest.approx(50, 0.5))

    PySAM.BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert(model.BatterySystem.batt_computed_strings == 370)
    assert(model.BatterySystem.batt_computed_series == 139)
    assert(model.BatterySystem.batt_computed_bank_capacity == pytest.approx(416, 1))
    assert(model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(104, 1))

    PySAM.BatteryTools.battery_model_sizing(model, 100, 400, 500, 50, 60, 30)
    assert(model.BatterySystem.batt_computed_bank_capacity == pytest.approx(416, 1))
    assert(model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(104, 1))
    assert(model.BatteryCell.LeadAcid_q10_computed == pytest.approx(50, 5))
    assert(model.BatteryCell.LeadAcid_q20_computed == pytest.approx(60, 5))
    assert(model.BatteryCell.LeadAcid_qn_computed == pytest.approx(30, 5))
Example #5
0
@author: brtietz
"""

import PySAM.StandAloneBattery as battery_model
import PySAM.Pvsamv1 as pvsam
from PySAM.PySSC import *

weather_file = sys.argv[1]  # .csv weather file with tmy format

analysis_period = 1  # years
days_in_year = 365

# Create the detailed residential pv model using PySAM's defaults
system_model = pvsam.default("FlatPlatePVResidential")
# Create the battery model based on the PV defaults
battery = battery_model.from_existing(system_model, "BatteryNone")

# Default model does not include a weather file, so set that based on the command line path
system_model.SolarResource.solar_resource_file = weather_file

# 24 hours of dispatch data, duplicated for each day. Would need to extend daily_dispatch for subhourly
lifetime_dispatch = []
daily_dispatch = [
    0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -1, 0, 0, 0, 0, 2, 4, 2, 2, 0, 0,
    0
]  # kW, negative is charging
# Extend daily lists for entire analysis period
for i in range(0, days_in_year * analysis_period):
    lifetime_dispatch.extend(daily_dispatch)

# Change from default dispatch to custom dispatch
Example #6
0
import PySAM.CashloanModel as cashloan
from PySAM.PySSC import *

ssc = PySSC()

# I generated json files using "Generate Code" option in example.sam in pysam-examples and exporting as json.
# Battery data is captured through detailed PV model, but will be used with PVWatts here
with open(os.path.join('pysam_inputs', "pvwatts.json")) as f:
    dic = json.load(f)
    pvwatts_dat = dict_to_ssc_table(dic, "pvwattsv5")
    pv = pvwatts.wrap(pvwatts_dat)

with open(os.path.join('pysam_inputs', "pvsamv1.json")) as f:
    dic = json.load(f)
    batt_dat = dict_to_ssc_table(dic, "battery")
    batt = battery.wrap(batt_dat)
    utility_dat = dict_to_ssc_table(dic, "utilityrate5")
    utilityrate = utility.wrap(utility_dat)
    loan_dat = dict_to_ssc_table(dic, "cashloan")
    loan = cashloan.wrap(loan_dat)

# run PV model
pv.execute()
ac = pv.Outputs.ac  # W
gen = [i / 1000 for i in ac]

# run Battery model
batt.System.gen = gen

# because version of PySAM is a little behind the development version I exported json from
batt.Battery.batt_power_discharge_max = 5.06
Additional financial models, inputs, and outputs can be found at https://nrel-pysam.readthedocs.io/en/2.0.2/modules/StandAloneBattery.html

Most recently tested against PySAM 2.1.4

@author: brtietz
"""

import PySAM.StandAloneBattery as battery_model
from PySAM.PySSC import *

analysis_period = 1  # years
steps_in_year = 8760  # currently hours in year, multiply this for subhourly tests (example * 12 for 5 minute tests)
days_in_year = 365

# Create the model using PySAM's defaults
battery = battery_model.default("GenericBatterySingleOwner")

# Set up inputs needed by the model.
battery.BatteryCell.batt_room_temperature_celsius = [20] * (
    steps_in_year * analysis_period
)  # degrees C, room temperature. Would normally come from weather file

# 24 hours of data to duplicate for the test. Would need to add data here for subhourly
lifetime_generation = []
lifetime_dispatch = []
daily_generation = [
    0, 0, 0, 0, 0, 0, 0, 200, 400, 600, 800, 1000, 1000, 1000, 1000, 800, 600,
    400, 200, 0, 0, 0, 0, 0
]  # kW
daily_dispatch = [
    0, 0, 0, 0, 0, 0, 0, -200, -400, -600, -800, -1000, -1000, 0, 0, 200, 400,
Example #8
0
Additional financial models, inputs, and outputs can be found at https://nrel-pysam.readthedocs.io/en/2.0.2/modules/StandAloneBattery.html

Most recently tested against PySAM 2.0.2

@author: brtietz
"""

import PySAM.StandAloneBattery as battery_model
from PySAM.PySSC import *

analysis_period = 1  # years
steps_in_year = 8760  # currently hours in year, multiply this for subhourly tests (example * 12 for 5 minute tests)
days_in_year = 365

# Create the model using PySAM's defaults
battery = battery_model.default("GenericSystemSingleOwner")

# Set up inputs needed by the model.
battery.BatteryCell.batt_room_temperature_celsius = [20] * (
    steps_in_year * analysis_period
)  # degrees C, room temperature. Would normally come from weather file

# 24 hours of data to duplicate for the test. Would need to add data here for subhourly
lifetime_generation = []
lifetime_dispatch = []
daily_generation = [
    0, 0, 0, 0, 0, 0, 0, 200, 400, 600, 800, 1000, 1000, 1000, 1000, 800, 600,
    400, 200, 0, 0, 0, 0, 0
]  # kW
daily_dispatch = [
    0, 0, 0, 0, 0, 0, 0, -200, -400, -600, -800, -1000, -1000, 0, 0, 200, 400,
Example #9
0
File: models.py Project: NREL/vapor
    def run_battery(self):
        self.battery = stbt.from_existing(
            self.generator
        )  # Simualtion, Lifetime, BatterySystem, SystemOutput, Load, BatteryCell, Inverter, Losses, batteryDispatch, ElectricityRates, FuelCell, PriceSignal
        self.battery.Lifetime.system_use_lifetime_output = 1  #needed for wind
        self.battery.Lifetime.analysis_period = self.cambium.analysis_period  #needed for wind
        self.battery.SystemOutput.gen = self.gen_profile_no_batt  #this isn't inherited if tech is wind, and there is no lifetime output for wind, so we need to manually assign this
        self.battery.SystemOutput.capacity_factor = self.generator.Outputs.capacity_factor
        self.battery.SystemOutput.annual_energy = self.generator.Outputs.annual_energy
        self.battery.Load.load = self.load.as_array()
        self.battery.BatterySystem.en_batt = 1
        self.battery.BatterySystem.batt_meter_position = 0  # 0: BTM, 1: FTM
        self.battery.BatterySystem.batt_ac_or_dc = 1  # 0: dc, 1: ac
        self.battery.BatterySystem.batt_dc_ac_efficiency = 96
        self.battery.BatterySystem.batt_dc_dc_efficiency = 98
        self.battery.BatterySystem.batt_ac_dc_efficiency = 98
        self.battery.BatterySystem.batt_current_choice = 1
        self.battery.BatterySystem.batt_replacement_capacity = 50
        self.battery.BatterySystem.batt_replacement_option = 1
        self.battery.BatterySystem.batt_surface_area = (1.586**2) * 6
        self.battery.BatterySystem.batt_mass = 10133.271
        self.battery.BatterySystem.batt_inverter_efficiency_cutoff = 90

        self.battery.BatteryDispatch.batt_dispatch_choice = 2  # target power
        self.battery.BatteryDispatch.batt_target_choice = 1
        self.battery.BatteryDispatch.batt_target_power = np.full(
            8760,
            0)  #charge when net load is negative, discharge when positive
        self.battery.BatteryDispatch.batt_target_power_monthly = np.full(12, 0)

        self.battery.BatteryDispatch.batt_dispatch_auto_can_clipcharge = 1
        self.battery.BatteryDispatch.batt_dispatch_auto_can_charge = 1
        self.battery.BatteryDispatch.batt_dispatch_auto_can_gridcharge = 0  # can't grid charge
        self.battery.BatteryCell.batt_chem = 1
        self.battery.BatteryCell.batt_Vnom_default = 3.6
        self.battery.BatteryCell.batt_Qfull = 2.25
        self.battery.BatteryCell.batt_Qfull_flow = 0
        self.battery.BatteryCell.batt_Qexp = 0.04
        self.battery.BatteryCell.batt_Qnom = 2.0
        self.battery.BatteryCell.batt_C_rate = 0.2
        self.battery.BatteryCell.batt_Vfull = 4.1
        self.battery.BatteryCell.batt_Vexp = 4.05
        self.battery.BatteryCell.batt_Vnom = 3.4
        self.battery.BatteryCell.batt_resistance = 0.001
        self.battery.BatteryCell.batt_initial_SOC = 50
        self.battery.BatteryCell.batt_minimum_SOC = 10
        self.battery.BatteryCell.batt_maximum_SOC = 100
        self.battery.BatteryCell.batt_minimum_modetime = 0
        self.battery.BatteryCell.batt_calendar_choice = 0
        self.battery.BatteryCell.batt_lifetime_matrix = [[20, 0, 100],
                                                         [20, 5000, 80],
                                                         [20, 10000, 60],
                                                         [80, 0, 100],
                                                         [80, 1000, 80],
                                                         [80, 2000, 60]]
        self.battery.BatteryCell.batt_calendar_lifetime_matrix = [[0, 100],
                                                                  [3650, 80],
                                                                  [7300, 50]]
        self.battery.BatteryCell.batt_calendar_q0 = 1.02
        self.battery.BatteryCell.batt_calendar_a = 0.00266
        self.battery.BatteryCell.batt_calendar_b = -7280
        self.battery.BatteryCell.batt_calendar_c = 930
        self.battery.BatteryCell.batt_voltage_matrix = [[0, 0]]
        self.battery.BatteryCell.cap_vs_temp = [[-10, 60], [0, 80], [25, 100],
                                                [40, 100]]
        self.battery.BatteryCell.batt_Cp = 1004
        self.battery.BatteryCell.batt_h_to_ambient = 500
        self.battery.BatteryCell.batt_room_temperature_celsius = np.full(
            8760, fill_value=20)

        self._size_battery()
        self.battery.execute()