Skip to content

Commit

Permalink
added max soc input to Storage components
Browse files Browse the repository at this point in the history
  • Loading branch information
t-kwasnik committed Jan 19, 2021
1 parent 4dbbd10 commit 98f8ac9
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 8 deletions.
18 changes: 18 additions & 0 deletions reo/migrations/0078_storagemodel_soc_max_pct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.10 on 2021-01-19 18:51

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('reo', '0077_auto_20201210_2229'),
]

operations = [
migrations.AddField(
model_name='storagemodel',
name='soc_max_pct',
field=models.FloatField(blank=True, null=True),
),
]
1 change: 1 addition & 0 deletions reo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ class StorageModel(models.Model):
inverter_efficiency_pct = models.FloatField()
rectifier_efficiency_pct = models.FloatField()
soc_min_pct = models.FloatField()
soc_max_pct = models.FloatField(null=True, blank=True)
soc_init_pct = models.FloatField()
canGridCharge = models.BooleanField()
installed_cost_us_dollars_per_kw = models.FloatField()
Expand Down
4 changes: 4 additions & 0 deletions reo/nested_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,10 @@ def list_of_int(input):
"type": "float", "min": 0.0, "max": 1.0, "default": 0.2,
"description": "Minimum allowable battery state of charge"
},
"soc_max_pct": {
"type": "float", "min": 0.0, "max": 1.0, "default": 1.0,
"description": "Maximum allowable battery state of charge"
},
"soc_init_pct": {
"type": "float", "min": 0.0, "max": 1.0, "default": 0.5,
"description": "Battery state of charge at first hour of optimization"
Expand Down
4 changes: 3 additions & 1 deletion reo/src/data_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ def finalize(self):
'TimeStepScaling': 8760.0 / self.n_timesteps,
'AnnualElecLoadkWh': self.load.annual_kwh,
'StorageMinChargePcent': self.storage.soc_min_pct,
'StorageMaxChargePcent': self.storage.soc_max_pct,
'InitSOC': self.storage.soc_init_pct,
'NMILLimits': NMILLimits,
'TechToNMILMapping': TechToNMILMapping,
Expand Down Expand Up @@ -1131,6 +1132,7 @@ def finalize(self):
'TimeStepScaling': 8760.0 / self.n_timesteps,
'AnnualElecLoadkWh': self.load.annual_kwh,
'StorageMinChargePcent': self.storage.soc_min_pct,
'StorageMaxChargePcent': self.storage.soc_max_pct,
'InitSOC': self.storage.soc_init_pct,
'NMILLimits': NMILLimits_bau,
'TechToNMILMapping': TechToNMILMapping_bau,
Expand Down Expand Up @@ -1178,4 +1180,4 @@ def finalize(self):
'ElectricDerate': electric_derate_bau,
'TechsByNMILRegime': TechsByNMILRegime_bau,
'TechsCannotCurtail': techs_cannot_curtail_bau
}
}
3 changes: 2 additions & 1 deletion reo/src/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Storage(object):

def __init__(self, dfm, min_kw, max_kw, min_kwh, max_kwh,
internal_efficiency_pct, inverter_efficiency_pct, rectifier_efficiency_pct,
soc_min_pct, soc_init_pct, canGridCharge,
soc_min_pct, soc_max_pct, soc_init_pct, canGridCharge,
installed_cost_us_dollars_per_kw, installed_cost_us_dollars_per_kwh,
replace_cost_us_dollars_per_kw, replace_cost_us_dollars_per_kwh,
inverter_replacement_year, battery_replacement_year,
Expand All @@ -82,6 +82,7 @@ def __init__(self, dfm, min_kw, max_kw, min_kwh, max_kwh,
self.roundtrip_efficiency = internal_efficiency_pct * inverter_efficiency_pct * rectifier_efficiency_pct

self.soc_min_pct = soc_min_pct
self.soc_max_pct = soc_max_pct
self.soc_init_pct = soc_init_pct
self.canGridCharge = canGridCharge

Expand Down
28 changes: 22 additions & 6 deletions reo/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -850,21 +850,37 @@ def check_min_less_than_max(self, object_name_path, template_values=None, real_v
if object_name_path[-1] in ['PV','Storage','Generator','Wind']:
if real_values.get('min_kw') > real_values.get('max_kw'):
self.input_data_errors.append(
'min_kw (%s) in %s is larger than the max_kw value (%s)' % ( real_values.get('min_kw'),location , real_values.get('max_kw'))
'min_kw (%s) in %s is larger than the max_kw value (%s)' % (
real_values.get('min_kw'),location , real_values.get('max_kw'))
)
if object_name_path[-1] in ['Storage']:
if real_values.get('min_kwh') > real_values.get('max_kwh'):
self.input_data_errors.append(
'min_kwh (%s) in %s is larger than the max_kwh value (%s)' % ( real_values.get('min_kwh'), self.object_name_string(object_name_path), real_values.get('max_kwh'))
'min_kwh (%s) in %s is larger than the max_kwh value (%s)' % (
real_values.get('min_kwh'), self.object_name_string(object_name_path),
real_values.get('max_kwh'))
)
if real_values.get('soc_min_pct') > real_values.get('soc_max_pct'):
self.input_data_errors.append(
'soc_min_pct (%s) in %s is larger than the soc_max_pct value (%s)' % (
real_values.get('soc_min_pct'), self.object_name_string(object_name_path),
real_values.get('soc_max_pct'))
)

if object_name_path[-1] in ['LoadProfile']:
if real_values.get('outage_start_hour') is not None and real_values.get('outage_end_hour') is not None:
if real_values.get('outage_start_hour') is not None and \
real_values.get('outage_end_hour') is not None:
if real_values.get('outage_start_hour') >= real_values.get('outage_end_hour'):
self.input_data_errors.append('LoadProfile outage_end_hour must be larger than outage_end_hour and these inputs cannot be equal')
self.input_data_errors.append((
'LoadProfile outage_end_hour must be larger than outage_end_hour and'
' these inputs cannot be equal'))

if real_values.get('outage_start_time_step') is not None and real_values.get('outage_end_time_step') is not None:
if real_values.get('outage_start_time_step') is not None and \
real_values.get('outage_end_time_step') is not None:
if real_values.get('outage_start_time_step') >= real_values.get('outage_end_time_step'):
self.input_data_errors.append('LoadProfile outage_end_time_step must be larger than outage_start_time_step and these inputs cannot be equal')
self.input_data_errors.append((
'LoadProfile outage_end_time_step must be larger than outage_start_time_step'
' and these inputs cannot be equal'))

def check_for_nans(self, object_name_path, template_values=None, real_values=None, number=1, input_isDict=None):
"""
Expand Down

0 comments on commit 98f8ac9

Please sign in to comment.