Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6faf124
Add solver list
jgu2 Sep 17, 2024
d4a3380
Manage sover access via Django admin
jgu2 Sep 17, 2024
2b2f934
Update default solver management
jgu2 Sep 18, 2024
489e63a
Adjust ace editor height
jgu2 Sep 18, 2024
a41399c
Re-enable flower container
jgu2 Sep 18, 2024
d07ae34
Upgrade Django
jgu2 Oct 9, 2024
4c507e5
Merge pull request #233 from NREL/vulns-fix-20241009
jgu2 Oct 9, 2024
f48fae8
Merge pull request #214 from NREL/enable-flower
jgu2 Oct 11, 2024
e0b43d0
Merge pull request #213 from NREL/solver-access
jgu2 Oct 11, 2024
d590d7c
Bugfixes after dev deploy
jgu2 Oct 12, 2024
09fe624
set weights values to be numbers
hanna-fields Dec 6, 2024
e4322ce
Bump django from 4.2.16 to 4.2.17 in /calliope_app
dependabot[bot] Dec 6, 2024
3a28271
Gradient links and storage fix
jmorrisnrel Dec 9, 2024
9ce6f16
Fixing timeseries code
jmorrisnrel Dec 9, 2024
8ca376d
Set calliope logging critical verbosity
jgu2 Dec 10, 2024
ac6f5e9
Merge pull request #244 from NREL/c6-logging-update
jgu2 Dec 10, 2024
c75c551
Set Clustered run default False
jgu2 Dec 10, 2024
938a915
Merge pull request #241 from NREL/dependabot/pip/calliope_app/django-…
jgu2 Dec 10, 2024
7a323b1
Merge pull request #240 from NREL/ENGAGE-164-Weights-of-cost-classes-…
hanna-fields Dec 10, 2024
53dfeef
Patch for highs solver running through
jgu2 Dec 18, 2024
ffa3705
Update set log_to_console=False
jgu2 Dec 18, 2024
93d914c
Update set log_to_console=False
jgu2 Dec 18, 2024
df5aebe
Merge pull request #246 from NREL/engage158-highs-solver-patch
jgu2 Dec 20, 2024
11c3472
Merge pull request #245 from NREL/engage183-clustered-run-default-dis…
jgu2 Dec 20, 2024
bc7698c
Bump the version to 1.1.5
jgu2 Dec 20, 2024
e8e6b18
Merge branch 'dev' into gradient-storage-fix
jgu2 Dec 20, 2024
ee49a42
Bump pysam from 2.1.5.dev3 to 2.2.0
jgu2 Jan 10, 2025
eed383d
Fixing minor issue
jmorrisnrel Jan 14, 2025
e8d8481
Merge pull request #243 from jmorrisnrel/gradient-storage-fix
jmorrisnrel Jan 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion calliope_app/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
Scenario_Loc_Tech, Scenario_Param, Job_Meta, Carrier
from api.models.outputs import Run
from api.models.engage import User_Profile, ComputeEnvironment
from api.forms import ComputeEnvironmentModelForm


class ComputeEnvironmentAdmin(admin.ModelAdmin):
form = ComputeEnvironmentModelForm
filter_horizontal = ("users",)
list_display = ['id', 'name', 'full_name', 'is_default', 'solver', 'ncpu', 'memory', 'type', '_users']
list_display = ['id', 'name', 'full_name', 'is_default', 'solvers', 'ncpu', 'memory', 'type', '_users']

@staticmethod
def _users(instance):
Expand Down
313 changes: 170 additions & 143 deletions calliope_app/api/calliope_utils.py

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions calliope_app/api/engage.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@
from django.core.mail.message import sanitize_address


ENGAGE_SOLVERS = [
{
"name": "appsi_highs",
"pretty_name": "HiGHS",
"order": 1,
"is_active": True
},
{
"name": "cbc",
"pretty_name": "CBC",
"order": 2,
"is_active": True
},
{
"name": "amplxpress",
"pretty_name": "Xpress",
"order": 3,
"is_active": False
}
]


def aws_ses_configured():
"""
Check the configuration of AWS SES settings
Expand Down
15 changes: 15 additions & 0 deletions calliope_app/api/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

from django import forms

from client.widgets import JSONEditorWidget

from api.models.engage import ComputeEnvironment


class ComputeEnvironmentModelForm(forms.ModelForm):
class Meta:
model = ComputeEnvironment
fields = '__all__'
widgets = {
'solvers': JSONEditorWidget()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.15 on 2024-09-17 03:26

import api.models.engage
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0067_auto_20240613_1706'),
]

operations = [
migrations.RemoveField(
model_name='computeenvironment',
name='solver',
),
migrations.AddField(
model_name='computeenvironment',
name='solvers',
field=models.JSONField(default=api.models.engage.default_solvers),
),
]
10 changes: 8 additions & 2 deletions calliope_app/api/models/engage.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from django.urls import reverse
from django.utils.html import mark_safe

from api.engage import ENGAGE_SOLVERS

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -102,6 +104,10 @@ def activate(cls, activation_uuid):
return True


def default_solvers():
return ENGAGE_SOLVERS


class ComputeEnvironment(models.Model):

ENV_TYPES = [
Expand All @@ -114,11 +120,11 @@ class ComputeEnvironment(models.Model):
full_name = models.CharField(max_length=120)
is_default = models.BooleanField(default=False)
type = models.CharField(max_length=60, choices=ENV_TYPES)
solver = models.CharField(max_length=60, null=True, blank=True)
ncpu = models.PositiveSmallIntegerField(null=True, blank=True)
memory = models.PositiveSmallIntegerField(null=True, blank=True)
cmd = models.TextField(blank=True, null=True)
users = models.ManyToManyField(User, related_name="compute_environments", blank=True)
solvers = models.JSONField(default=default_solvers)

class Meta:
db_table = "compute_environments"
Expand All @@ -141,4 +147,4 @@ class Meta:
verbose_name_plural = "[Admin] Request Rate Limits"

def __str__(self):
return f"{self.year}, {self.month}, {self.total}"
return f"{self.year}, {self.month}, {self.total}"
2 changes: 2 additions & 0 deletions calliope_app/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@
path('upload_outputs/',
outputs_views.upload_outputs,
name='upload_outputs'),
path('solvers/', outputs_views.solvers,
name="solvers"),

# Bulk Data
path('upload_locations/',
Expand Down
45 changes: 34 additions & 11 deletions calliope_app/api/views/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
import io
import logging
import os
import shutil
import zipfile
import sys
from re import match

from datetime import datetime, timedelta
from urllib.parse import urljoin
import requests
import pandas as pd
import pint

from celery import current_app,chain
from django.views.decorators.csrf import csrf_protect
Expand All @@ -30,19 +27,45 @@
from api.models.calliope import Abstract_Tech, Abstract_Tech_Param, Parameter, Run_Parameter
from api.models.configuration import (
Model, ParamsManager, User_File, Location, Technology,
Tech_Param, Loc_Tech, Loc_Tech_Param, Timeseries_Meta, Carrier, Scenario_Param
Tech_Param, Loc_Tech, Loc_Tech_Param, Timeseries_Meta, Carrier
)

from api.models.engage import ComputeEnvironment
from api.engage import ENGAGE_SOLVERS
from api.utils import zip_folder, initialize_units, convert_units, noconv_units
from batch.managers import AWSBatchJobManager
from taskmeta.models import CeleryTask, BatchTask, batch_task_status

from calliope_app.celery import app

logger = logging.getLogger(__name__)


@csrf_protect
def solvers(request):
env_name = request.GET.get("env_name", None)
if not env_name:
env_name = "default"

flag = True
try:
env = ComputeEnvironment.objects.get(name=env_name)
except ComputeEnvironment.DoesNotExist:
flag = False

if (not flag) or (not env.solvers) or (not isinstance(env.solvers, list)):
solvers = ENGAGE_SOLVERS
else:
solvers = env.solvers

candidates = []
for solver in solvers:
is_active = solver.get("is_active", "false")
if (is_active is True) or (is_active == "true"):
candidates.append(solver)
payload = sorted(candidates, key=lambda x: x["order"])

return HttpResponse(json.dumps(payload), content_type="application/json")


@csrf_protect
def build(request):
"""
Expand Down Expand Up @@ -156,13 +179,13 @@ def build(request):
)
inputs_path = inputs_path.lower().replace(" ", "-")
os.makedirs(inputs_path, exist_ok=True)

run.run_options = []
for id in parameters.keys():
run_parameter= Run_Parameter.objects.get(pk=int(id))
run.run_options.append({'root':run_parameter.root,'name':run_parameter.name,'value':parameters[id]})
# Celery task

# Celery task
async_result = build_model.apply_async(
kwargs={
"inputs_path": inputs_path,
Expand Down Expand Up @@ -300,7 +323,7 @@ def optimize(request):
r.batch_job.status = batch_task_status.FAILED
r.batch_job.save()
r.save()

if not all_complete:
payload = {
"status": "BLOCKED",
Expand Down Expand Up @@ -344,7 +367,7 @@ def optimize(request):
else:
logger.info("Found a subsequent gradient model for year %s but it was not built.",next_run.year)
break

# Unknown environment, not supported
else:
raise Exception("Failed to submit job, unknown compute environment")
Expand Down
8 changes: 4 additions & 4 deletions calliope_app/calliope-files/backend/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ def run_plan(

# NOTE: pyomo==6.7.0 opt does not have name attribute
# Disable this for use 'appsi_highs' solver, which does not have 'persistent' in name.
# if "persistent" in opt.name and persistent is True:
# results.attrs["objective_function_value"] = opt.get_model_attr("ObjVal")
# else:
results.attrs["objective_function_value"] = backend_model.obj()
if "appsi_highs" not in solver and "persistent" in opt.name and persistent is True:
results.attrs["objective_function_value"] = opt.get_model_attr("ObjVal")
else:
results.attrs["objective_function_value"] = backend_model.obj()
else:
results = xr.Dataset(attrs={"termination_condition": termination})

Expand Down
Loading
Loading