diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a227b61..e9e838ce6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Classify the change according to the following categories: - Truncate the last day of the year instead of the leap day for leap years ##### Added - Option for ASHP to `force_dispatch` (default = true) which maximizes ASHP thermal output +- Added `min_duration_hours` and `max_duration_hours` for limitting electric storage's energy capacity ## v3.10.2 ### Minor Updates diff --git a/reoptjl/migrations/0077_electricstorageinputs_max_duration_hours_and_more.py b/reoptjl/migrations/0077_electricstorageinputs_max_duration_hours_and_more.py new file mode 100644 index 000000000..9678b3991 --- /dev/null +++ b/reoptjl/migrations/0077_electricstorageinputs_max_duration_hours_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 4.0.7 on 2025-01-27 05:41 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('reoptjl', '0076_ashpspaceheaterinputs_force_dispatch_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='electricstorageinputs', + name='max_duration_hours', + field=models.FloatField(blank=True, default=100000.0, help_text='Maximum amount of time storage can discharge at its rated power capacity', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1000000000.0)]), + ), + migrations.AddField( + model_name='electricstorageinputs', + name='min_duration_hours', + field=models.FloatField(blank=True, default=0.0, help_text='Minimum amount of time storage can discharge at its rated power capacity', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1000000000.0)]), + ), + ] diff --git a/reoptjl/models.py b/reoptjl/models.py index f6a5680eb..7f375aa83 100644 --- a/reoptjl/models.py +++ b/reoptjl/models.py @@ -3449,6 +3449,24 @@ class ElectricStorageInputs(BaseModel, models.Model): blank=True, help_text="Rebate based on installed energy capacity" ) + min_duration_hours = models.FloatField( + default=0.0, + validators=[ + MinValueValidator(0), + MaxValueValidator(1.0e9) + ], + blank=True, + help_text="Minimum amount of time storage can discharge at its rated power capacity" + ) + max_duration_hours = models.FloatField( + default=100000.0, + validators=[ + MinValueValidator(0), + MaxValueValidator(1.0e9) + ], + blank=True, + help_text="Maximum amount of time storage can discharge at its rated power capacity" + ) class ElectricStorageOutputs(BaseModel, models.Model): diff --git a/reoptjl/test/posts/all_inputs_test.json b/reoptjl/test/posts/all_inputs_test.json index fbc26998a..fa2e13683 100644 --- a/reoptjl/test/posts/all_inputs_test.json +++ b/reoptjl/test/posts/all_inputs_test.json @@ -152,6 +152,8 @@ "max_kw": 100.0, "min_kwh": 200.0, "max_kwh": 200.0, + "min_duration_hours": 2.0, + "max_duration_hours": 2.0, "internal_efficiency_fraction": 0.975, "inverter_efficiency_fraction": 0.96, "rectifier_efficiency_fraction": 0.96,