From 3d6ebda0fb41d6e010d60d2aac6a9467239b4f0f Mon Sep 17 00:00:00 2001 From: bill-becker Date: Wed, 30 Apr 2025 14:37:14 -0600 Subject: [PATCH 1/6] Fix submodule linkage for EVI-EnSitePy --- EVI-EnSitePy | 1 + 1 file changed, 1 insertion(+) create mode 160000 EVI-EnSitePy diff --git a/EVI-EnSitePy b/EVI-EnSitePy new file mode 160000 index 000000000..5a582d20c --- /dev/null +++ b/EVI-EnSitePy @@ -0,0 +1 @@ +Subproject commit 5a582d20c20e6cf0de99ec2c4240efa6c01909d0 From eec88f35a2f96b242f9afeeda45ff72358667831 Mon Sep 17 00:00:00 2001 From: bill-becker Date: Wed, 30 Apr 2025 14:59:22 -0600 Subject: [PATCH 2/6] Add git submodule for EVI-EnSitePy for ...barebone branch compat with Py 3.8 --- .gitmodules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitmodules b/.gitmodules index e69de29bb..9f44da9cc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "EVI-EnSitePy"] + path = EVI-EnSitePy + url = https://github.nrel.gov/AVCI/EVI-EnSitePy.git + branch = dev_enlitepy_api_barebone \ No newline at end of file From 40e6a4dedc29225c7db68a3fe351f49198df1db5 Mon Sep 17 00:00:00 2001 From: bill-becker Date: Wed, 30 Apr 2025 15:00:17 -0600 Subject: [PATCH 3/6] Conditionally install EVI-EnSitePy in Django container if submodule directory is present --- Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Dockerfile b/Dockerfile index f013a9acd..27dbea3f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,5 +16,9 @@ COPY . /opt/reopt WORKDIR /opt/reopt RUN ["pip", "install", "-r", "requirements.txt"] +RUN if [ -d "EVI-EnSitePy" ]; then \ + cd EVI-EnSitePy && pip install -e .; \ +fi + EXPOSE 8000 ENTRYPOINT ["/bin/bash", "-c"] From ea1786c96a129fe44cf97d6975851f781cd022fa Mon Sep 17 00:00:00 2001 From: bill-becker Date: Wed, 30 Apr 2025 15:01:08 -0600 Subject: [PATCH 4/6] Add mock barebones ensitepy view/URL in load_builder app available at GET stable/ensite with no inputs --- load_builder/urls.py | 1 + load_builder/views.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/load_builder/urls.py b/load_builder/urls.py index f31cfc794..5e707b5e5 100644 --- a/load_builder/urls.py +++ b/load_builder/urls.py @@ -5,4 +5,5 @@ urlpatterns = [ re_path(r'^load_builder/?$', views.load_builder), + re_path(r'^ensite/?$', views.ensite_view), ] \ No newline at end of file diff --git a/load_builder/views.py b/load_builder/views.py index 58614936e..0778be3b2 100644 --- a/load_builder/views.py +++ b/load_builder/views.py @@ -7,6 +7,22 @@ from django.http import JsonResponse from reo.exceptions import UnexpectedError +try: + import ensitepy # Ensure the submodule is initialized and accessible + from ensitepy import SystemSimulator + + def ensite_view(request): + # Use the private package functionality + sim = SystemSimulator(t_start=0 * 3600, dt=30, t_end=2 * 24 * 3600) + # ...existing code... + + return JsonResponse({"message": "Ensite view and SystemSimulator function called successfully."}) +except ImportError: + print("Cannot import ensitepy or failure to call ensitepy function") + # raise ImportError( + # "The EVI-EnSitePy (ensitepy) package is required in the PROD environment. " + # "Ensure the submodule is initialized and accessible." + # ) def check_load_builder_inputs(loads_table): required_inputs = ["Power (W)", "Quantity", "% Run Time", "Start Mo.", "Stop Mo.", "Start Hr.", "Stop Hr."] From ce1075669746fa307615e7310958dfc6ddcdd512 Mon Sep 17 00:00:00 2001 From: bill-becker Date: Wed, 30 Apr 2025 15:21:20 -0600 Subject: [PATCH 5/6] Avoid trying to install EVI-EnSitePy if not cloned/initialized with git submodule --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 27dbea3f5..332d20bd0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ COPY . /opt/reopt WORKDIR /opt/reopt RUN ["pip", "install", "-r", "requirements.txt"] -RUN if [ -d "EVI-EnSitePy" ]; then \ +RUN if [ -d "EVI-EnSitePy" ] && [ "$(ls -A EVI-EnSitePy)" ]; then \ cd EVI-EnSitePy && pip install -e .; \ fi From d814a95dbfc9a88b388c488789d21fc7da96fb8e Mon Sep 17 00:00:00 2001 From: wbecker Date: Wed, 30 Apr 2025 20:20:06 -0600 Subject: [PATCH 6/6] Wrap ensitepy and modules inside a function to avoid errors when not installed --- load_builder/views.py | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/load_builder/views.py b/load_builder/views.py index 0778be3b2..4c0694f70 100644 --- a/load_builder/views.py +++ b/load_builder/views.py @@ -7,22 +7,33 @@ from django.http import JsonResponse from reo.exceptions import UnexpectedError -try: - import ensitepy # Ensure the submodule is initialized and accessible - from ensitepy import SystemSimulator - - def ensite_view(request): - # Use the private package functionality - sim = SystemSimulator(t_start=0 * 3600, dt=30, t_end=2 * 24 * 3600) - # ...existing code... - - return JsonResponse({"message": "Ensite view and SystemSimulator function called successfully."}) -except ImportError: - print("Cannot import ensitepy or failure to call ensitepy function") - # raise ImportError( - # "The EVI-EnSitePy (ensitepy) package is required in the PROD environment. " - # "Ensure the submodule is initialized and accessible." - # ) +def get_ensitepy_simulator(): + """ + Attempts to import ensitepy and return the SystemSimulator class. + If the package is not available, returns None. + """ + try: + import ensitepy + from ensitepy import SystemSimulator + return SystemSimulator + except ImportError: + print("Cannot import ensitepy or failure to call ensitepy function") + return None + + +def ensite_view(request): + """ + View to use the ensitepy SystemSimulator if available. + """ + SystemSimulator = get_ensitepy_simulator() + if SystemSimulator is None: + return JsonResponse({"Error": "ensitepy package is not available."}, status=500) + + # Use the private package functionality + sim = SystemSimulator(t_start=0 * 3600, dt=30, t_end=2 * 24 * 3600) + # ...existing code... + + return JsonResponse({"message": "Ensite view and SystemSimulator function called successfully."}) def check_load_builder_inputs(loads_table): required_inputs = ["Power (W)", "Quantity", "% Run Time", "Start Mo.", "Stop Mo.", "Start Hr.", "Stop Hr."]