From 143a474871b9cb92a52f31ca2412ac649a4a9872 Mon Sep 17 00:00:00 2001 From: paulapreuss Date: Tue, 9 Dec 2025 10:00:47 +0100 Subject: [PATCH 01/28] Set webapp Dockerfile in captain-definition --- captain-definition | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/captain-definition b/captain-definition index e5ccb63..ea48c22 100644 --- a/captain-definition +++ b/captain-definition @@ -1,4 +1,4 @@ { "schemaVersion": 2, - "dockerfilePath": "task_queue/Dockerfile_dev" + "dockerfilePath": "fastapi_app/Dockerfile" } From 3657550f390a89eb60cea4693ac87a233ba703e2 Mon Sep 17 00:00:00 2001 From: paulapreuss Date: Tue, 9 Dec 2025 14:29:55 +0100 Subject: [PATCH 02/28] Clean json response --- fastapi_app/webapp.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/fastapi_app/webapp.py b/fastapi_app/webapp.py index 299ab7b..44b6b01 100644 --- a/fastapi_app/webapp.py +++ b/fastapi_app/webapp.py @@ -1,3 +1,4 @@ +import math import os import json import io @@ -189,7 +190,19 @@ async def check_task(task_id: str) -> JSONResponse: task["status"] = "ERROR" task["results"] = results_as_dict - return JSONResponse(content=jsonable_encoder(task)) + def clean_floats(obj): + if isinstance(obj, float): + if math.isnan(obj) or math.isinf(obj): + return None + if isinstance(obj, dict): + return {k: clean_floats(v) for k, v in obj.items()} + if isinstance(obj, list): + return [clean_floats(i) for i in obj] + return obj + + cleaned = clean_floats(task) + + return JSONResponse(content=jsonable_encoder(cleaned)) @app.get("/get_lp_file/{task_id}") From 6a7142b9fc840cfff3b53dc4eca22f0d4a195a18 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Wed, 25 Feb 2026 23:32:30 +0100 Subject: [PATCH 03/28] Rename open_plan queue to prod And add an url to fetch the version of the simulation server version via a celery task --- fastapi_app/webapp.py | 72 ++++++++++++++++++++++--------------------- fastapi_app/worker.py | 2 +- task_queue/tasks.py | 5 ++- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/fastapi_app/webapp.py b/fastapi_app/webapp.py index 44b6b01..266834a 100644 --- a/fastapi_app/webapp.py +++ b/fastapi_app/webapp.py @@ -2,28 +2,15 @@ import os import json import io -from fastapi import FastAPI, Request, Response, File, UploadFile +from fastapi import FastAPI, Request, Response, File, UploadFile, HTTPException from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.responses import StreamingResponse +from celery.exceptions import TimeoutError -from multi_vector_simulator import version as mvs_version - -from multi_vector_simulator.utils.constants_json_strings import ( - SIMULATION_SETTINGS, - OUTPUT_LP_FILE, - VALUE, - UNIT, -) - -MVS_DEV_VERSION = os.environ.get("MVS_DEV_VERSION", mvs_version.version_num) -MVS_OPEN_PLAN_VERSION = os.environ.get("MVS_OPEN_PLAN_VERSION", mvs_version.version_num) - -MVS_SERVER_VERSIONS = {"dev": MVS_DEV_VERSION, "open_plan": MVS_OPEN_PLAN_VERSION} - try: from worker import app as celery_app except ModuleNotFoundError: @@ -56,6 +43,7 @@ # Test Driven Development --> https://fastapi.tiangolo.com/tutorial/testing/ + @app.get("/debug/ping") async def debug_ping(): result = celery_app.send_task("dev.ping", queue="dev") @@ -78,19 +66,30 @@ async def debug_ping(): @app.get("/") def index(request: Request) -> Response: - return templates.TemplateResponse( "index.html", { "request": request, - "mvs_dev_version": MVS_DEV_VERSION, - "mvs_open_plan_version": MVS_OPEN_PLAN_VERSION, + "dev_version": get_worker_version("dev"), + "prod_version": get_worker_version("prod"), }, ) +def get_worker_version(queue): + task = celery_app.send_task(f"{queue}.get_version", queue=queue, kwargs={}) + try: + version = task.get(timeout=0.5) + except TimeoutError: + version = f"{queue} worker not available" + return version + + async def simulate_json_variable(request: Request, queue: str = "dev"): """Receive mvs simulation parameter in json post request and send it to simulator""" + + # TODO use jsonschema to verify metadata and data and then use the content of metadata to check data + input_dict = await request.json() # send the task to celery @@ -107,9 +106,9 @@ async def simulate_json_variable_dev(request: Request): return await simulate_json_variable(request, queue="dev") -@app.post("/sendjson/openplan") -async def simulate_json_variable_open_plan(request: Request): - return await simulate_json_variable(request, queue="open_plan") +@app.post("/sendjson/prod") +async def simulate_json_variable_prod(request: Request): + return await simulate_json_variable(request, queue="prod") @app.post("/uploadjson/dev") @@ -124,8 +123,8 @@ def simulate_uploaded_json_files_dev( return run_simulation(request, input_json=json_content) -@app.post("/uploadjson/open_plan") -def simulate_uploaded_json_files_open_plan( +@app.post("/uploadjson/prod") +def simulate_uploaded_json_files_prod( request: Request, json_file: UploadFile = File(...) ): """Receive mvs simulation parameter in json post request and send it to simulator @@ -133,7 +132,7 @@ def simulate_uploaded_json_files_open_plan( argument of this function """ json_content = jsonable_encoder(json_file.file.read()) - return run_simulation_open_plan(request, input_json=json_content) + return run_simulation_prod(request, input_json=json_content) def run_simulation(request: Request, input_json=None, queue="dev") -> Response: @@ -162,9 +161,9 @@ def run_simulation_dev(request: Request, input_json=None) -> Response: return run_simulation(request, input_json, queue="dev") -@app.post("/run_simulation_open_plan") -def run_simulation_open_plan(request: Request, input_json=None) -> Response: - return run_simulation(request, input_json, queue="open_plan") +@app.post("/run_simulation_prod") +def run_simulation_prod(request: Request, input_json=None) -> Response: + return run_simulation(request, input_json, queue="prod") @app.get("/check/{task_id}") @@ -172,7 +171,7 @@ async def check_task(task_id: str) -> JSONResponse: res = celery_app.AsyncResult(task_id) task = { "server_info": None, - "mvs_version": None, + "simulation_version": None, "id": task_id, "status": res.state, "results": None, @@ -182,9 +181,12 @@ async def check_task(task_id: str) -> JSONResponse: else: task["status"] = "DONE" results_as_dict = json.loads(res.result) - server_info = results_as_dict.pop("SERVER") - task["server_info"] = server_info - task["mvs_version"] = MVS_SERVER_VERSIONS.get(server_info, "unknown") + try: + task["server_info"] = results_as_dict.pop("SERVER") + task["simulation_version"] = results_as_dict.pop("VERSION") + except KeyError: + for k in ["server_info", "simulation_version"]: + task[k] = "Error: Could not retrieve simulation metadata" task["results"] = json.dumps(results_as_dict) if "ERROR" in task["results"]: task["status"] = "ERROR" @@ -203,6 +205,7 @@ def clean_floats(obj): cleaned = clean_floats(task) return JSONResponse(content=jsonable_encoder(cleaned)) + return JSONResponse(content=jsonable_encoder(task)) @app.get("/get_lp_file/{task_id}") @@ -210,7 +213,7 @@ async def get_lp_file(task_id: str) -> Response: res = celery_app.AsyncResult(task_id) task = { "server_info": None, - "mvs_version": mvs_version, + "simulation_version": None, "id": task_id, "status": res.state, "results": None, @@ -221,9 +224,8 @@ async def get_lp_file(task_id: str) -> Response: else: task["status"] = "DONE" results_as_dict = json.loads(res.result) - server_info = results_as_dict.pop("SERVER") - task["server_info"] = server_info - task["mvs_version"] = MVS_SERVER_VERSIONS.get(server_info, "unknown") + task["server_info"] = results_as_dict.pop("SERVER") + task["simulation_version"] = results_as_dict.pop("VERSION") task["results"] = json.dumps(results_as_dict) if "ERROR" in task["results"]: task["status"] = "ERROR" diff --git a/fastapi_app/worker.py b/fastapi_app/worker.py index d7a54eb..13032b8 100644 --- a/fastapi_app/worker.py +++ b/fastapi_app/worker.py @@ -11,5 +11,5 @@ app = Celery("tasks", broker=CELERY_BROKER_URL, backend=CELERY_RESULT_BACKEND) app.conf.task_queues = ( Queue("dev", routing_key="dev.#"), - Queue("open_plan", routing_key="open_plan.#"), + Queue("prod", routing_key="prod.#"), ) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index 66b3d47..7678b90 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -23,7 +23,9 @@ @app.task(name=f"{CELERY_TASK_NAME}.run_simulation") -def run_simulation(simulation_input: dict,) -> dict: +def run_simulation( + simulation_input: dict, +) -> dict: logger.info("Start new simulation") epa_json = deepcopy(simulation_input) dict_values = None @@ -47,6 +49,7 @@ def run_simulation(simulation_input: dict,) -> dict: ) return json.dumps(simulation_output) + @app.task(bind=True, name="dev.ping") def ping(self): return { From b0f96878de47cb6166c1f4e46b1642e1983178d6 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Wed, 25 Feb 2026 23:38:43 +0100 Subject: [PATCH 04/28] Update the landing page --- fastapi_app/templates/index.html | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/fastapi_app/templates/index.html b/fastapi_app/templates/index.html index 2341eb3..4646253 100644 --- a/fastapi_app/templates/index.html +++ b/fastapi_app/templates/index.html @@ -6,7 +6,7 @@ name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> - + - MVS SimServer + OpenPlan SimServer -

Welcome to MVS simulation server!

+

Welcome to OpenPlan simulation server!

+

This simulation server uses oemof-eesyplan as a backend, it recieves request as jsonified oemof-datapackage and returns a JSON with the oemof-solph results

Test simulation with custom json

-

Actual multi-vector-simulator's version for development: {{ mvs_dev_version }}

+

Actual oemof-eesyplan's version for development: {{ dev_version }}

-

Upload a mvs input json file and click on "Run simulation"

+

Upload a datapackage in JSON format and click on "Run simulation"

-

Actual multi-vector-simulator's version for open_plan: {{ mvs_open_plan_version }}

+

Actual oemof-eesyplan's version for OpenPlan production: {{ prod_version }}

-

Upload a mvs input json file and click on "Run simulation"

-
- - - +

Upload a datapackage in JSON format and click on "Run simulation"

+ + + +
@@ -45,7 +46,8 @@

Actual multi-vector-simulator's version for open_plan: {{ mvs_open_plan_vers {% block body %}{% endblock body%} From 2311551a6920d7c93c71b21568bd850b02b20691 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 10:37:02 +0100 Subject: [PATCH 05/28] Allow zipfiles of datapackage to be uploaded (caution zip bombs) --- fastapi_app/webapp.py | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/fastapi_app/webapp.py b/fastapi_app/webapp.py index 266834a..42e14dd 100644 --- a/fastapi_app/webapp.py +++ b/fastapi_app/webapp.py @@ -9,6 +9,9 @@ from fastapi.templating import Jinja2Templates from fastapi.responses import StreamingResponse from celery.exceptions import TimeoutError +import tempfile +import zipfile +from oemof.datapackage import datapackage # noqa try: @@ -119,7 +122,41 @@ def simulate_uploaded_json_files_dev( the value of `name` property of the input html tag should be `json_file` as the second argument of this function """ - json_content = jsonable_encoder(json_file.file.read()) + + if "json" in json_file.filename: + json_content = jsonable_encoder(json_file.file.read()) + elif "zip" in json_file.filename: + # TODO do the same with only pathlib and temp files + import uuid + import shutil + + ZIP_DIR = "zipped" + UNZIP_DIR = "unzipped" + zip_id = str(uuid.uuid4()) + from pathlib import Path + + unzip_path = os.path.join(UNZIP_DIR, zip_id) + os.makedirs(unzip_path) + zip_path = os.path.join(UNZIP_DIR, f"{zip_id}.zip") + with open(zip_path, "wb") as f: + shutil.copyfileobj(json_file.file, f) + with zipfile.ZipFile(zip_path, "r") as zipf: + zipf.extractall(unzip_path) + os.remove(zip_path) + unzip_path = Path(unzip_path) + extracted_name = [f for f in unzip_path.glob("*")] + extracted_name = extracted_name[0] + json_content = datapackage.export_dp_to_json(extracted_name) + + # with tempfile.TemporaryDirectory() as td: + # # Open the zip file + # with zipfile.ZipFile(json_file.file, 'r') as zip_ref: + # # Extract all the contents into the specified directory + # zip_ref.extractall(td) + # + # json_content = json.dumps(datapackage.export_dp_to_json(td)) + # json_content = datapackage.export_dp_to_json(td) + return run_simulation(request, input_json=json_content) @@ -187,7 +224,7 @@ async def check_task(task_id: str) -> JSONResponse: except KeyError: for k in ["server_info", "simulation_version"]: task[k] = "Error: Could not retrieve simulation metadata" - task["results"] = json.dumps(results_as_dict) + task["results"] = results_as_dict if "ERROR" in task["results"]: task["status"] = "ERROR" task["results"] = results_as_dict From 29e8bef2618a1ec23097be3b5dd6af467cd6305b Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 10:37:40 +0100 Subject: [PATCH 06/28] Add oemof-datapackage --- fastapi_app/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fastapi_app/Dockerfile b/fastapi_app/Dockerfile index 8db6403..33ba246 100644 --- a/fastapi_app/Dockerfile +++ b/fastapi_app/Dockerfile @@ -6,7 +6,8 @@ COPY fastapi_app/requirements.txt /tmp/ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt # install multi-vector-simulator's version pinned in docker-compose.yml file -RUN pip install multi-vector-simulator==1.0.7rc3 gunicorn +RUN pip install gunicorn +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" --no-cache-dir From 646c5b20a46e4bb8c36940f288c540ada780396b Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 10:45:15 +0100 Subject: [PATCH 07/28] Edit instruction for upload --- fastapi_app/templates/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi_app/templates/index.html b/fastapi_app/templates/index.html index 4646253..f7c09ac 100644 --- a/fastapi_app/templates/index.html +++ b/fastapi_app/templates/index.html @@ -25,7 +25,7 @@

Welcome to OpenPlan simulation server!

Test simulation with custom json

Actual oemof-eesyplan's version for development: {{ dev_version }}

-

Upload a datapackage in JSON format and click on "Run simulation"

+

Upload a JSONIFIED datapackage or a zipped datapackage and click on "Run simulation"

From ace6964f899ff5f882722f72504f8e18b3d570f1 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Wed, 25 Feb 2026 23:45:19 +0100 Subject: [PATCH 08/28] Set the structure of the eesyplan worker --- task_queue/tasks.py | 72 ++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index 7678b90..fbe169d 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -1,15 +1,13 @@ import os -import socket import time import traceback import json -from copy import deepcopy from celery import Celery from celery.utils.log import get_task_logger +import tempfile +from pathlib import Path -from multi_vector_simulator.server import run_simulation as mvs_simulation -from multi_vector_simulator.utils.data_parser import convert_epa_params_to_mvs - +SIMULATION_VERSION = os.environ.get("SIMULATION_VERSION", "no_version") logger = get_task_logger(__name__) CELERY_BROKER_URL = (os.environ.get("CELERY_BROKER_URL", "redis://localhost:6379"),) @@ -22,32 +20,52 @@ app = Celery(CELERY_TASK_NAME, broker=CELERY_BROKER_URL, backend=CELERY_RESULT_BACKEND) +def __run_simulation( + simulation_input): + logger.info("Start new simulation") + simulation_output = {"SERVER": CELERY_TASK_NAME, "VERSION": SIMULATION_VERSION} + + with tempfile.TemporaryDirectory(prefix="dp_") as td: + temp_path = Path(td) + # TODO implement in oemof-datapackage or oemof-eesyplan + # dp_path = rebuild_single_json(simulation_input, temp_path) + logger.debug("Converted datapackage in JSON format back to datapackage") + + # -------------- RUNNING THE SCENARIOS -------------- + # scenario = dp_path.name + # # set paths for scenario and result directories + # results_path = dp_path / "results" + # results_path.mkdir() + try: + # run eezyplan here + pass + # simulation_output["results"] = df.to_json() + except Exception as e: + logger.error( + "An exception occured in the simulation task: {}".format( + traceback.format_exc() + ) + ) + simulation_output.update( + dict( + ERROR="{}".format(traceback.format_exc()), + INPUT_JSON=simulation_input, + ) + ) + + return json.dumps(simulation_output) + + @app.task(name=f"{CELERY_TASK_NAME}.run_simulation") def run_simulation( simulation_input: dict, ) -> dict: - logger.info("Start new simulation") - epa_json = deepcopy(simulation_input) - dict_values = None - try: - dict_values = convert_epa_params_to_mvs(simulation_input) - logger.debug("Converted epa parameters to mvs input") - simulation_output = mvs_simulation(dict_values) - logger.info("Simulation finished") - simulation_output["SERVER"] = CELERY_TASK_NAME - except Exception as e: - logger.error( - "An exception occured in the simulation task: {}".format( - traceback.format_exc() - ) - ) - simulation_output = dict( - SERVER=CELERY_TASK_NAME, - ERROR="{}".format(traceback.format_exc()), - INPUT_JSON_EPA=simulation_input, - INPUT_JSON_MVS=dict_values, - ) - return json.dumps(simulation_output) + return __run_simulation(simulation_input) + + +@app.task(name=f"{CELERY_TASK_NAME}.get_version") +def get_version() -> str: + return SIMULATION_VERSION @app.task(bind=True, name="dev.ping") From d5ff838bc89f9263835946e3f653568008d0ed0e Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Wed, 25 Feb 2026 23:53:33 +0100 Subject: [PATCH 09/28] Update Dockerfile - erase unused duplicate Dockerfile for dev and prod - replace mvs by oemof-eesyplan --- captain-definition | 2 +- task_queue/Dockerfile | 17 +++++------------ task_queue/Dockerfile_dev | 27 --------------------------- 3 files changed, 6 insertions(+), 40 deletions(-) delete mode 100644 task_queue/Dockerfile_dev diff --git a/captain-definition b/captain-definition index ea48c22..b35c8ed 100644 --- a/captain-definition +++ b/captain-definition @@ -1,4 +1,4 @@ { "schemaVersion": 2, - "dockerfilePath": "fastapi_app/Dockerfile" + "dockerfilePath": "task_queue/Dockerfile" } diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index d0216c0..4d2044b 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -1,26 +1,19 @@ -FROM python:3.8-slim - -ARG mvs_version - -ENV MVS_VERSION $mvs_version - -ENV CELERY_BROKER_URL redis://redis:6379/0 -ENV CELERY_RESULT_BACKEND redis://redis:6379/0 +FROM python:3.10-slim RUN apt-get update && \ apt-get install -y git && \ apt-get install coinor-cbc -y && \ apt-get install graphviz -y -COPY requirements.txt /tmp/ +COPY task_queue/requirements.txt /tmp/ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt -# install multi-vector-simulator's version pinned in docker-compose.yml file -RUN pip install multi-vector-simulator==$MVS_VERSION importlib-metadata==4.13.0 pyomo==5.7.2 +# install oemof-eesyplan version from the ENV variable +RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn run echo $(pip freeze) -COPY . /queue +COPY task_queue/ /queue # avoid running as root user RUN useradd --create-home appuser diff --git a/task_queue/Dockerfile_dev b/task_queue/Dockerfile_dev deleted file mode 100644 index 801dcb0..0000000 --- a/task_queue/Dockerfile_dev +++ /dev/null @@ -1,27 +0,0 @@ -FROM python:3.10-slim - - - -RUN apt-get update && \ - apt-get install -y git && \ - apt-get install coinor-cbc -y && \ - apt-get install graphviz -y - -COPY task_queue/requirements.txt /tmp/ - -RUN python -m pip install --upgrade pip -RUN pip install -r /tmp/requirements.txt -# install multi-vector-simulator's version pinned in docker-compose.yml file -RUN pip install multi-vector-simulator==1.0.7rc3 importlib-metadata==4.13.0 oemof.network==0.5.0a5 - -run echo $(pip freeze) -COPY task_queue/ /queue - -# avoid running as root user -RUN useradd --create-home appuser -RUN chown -R appuser /queue -USER appuser - -WORKDIR /queue - -ENTRYPOINT celery -A tasks worker --loglevel=info --queues=$CELERY_TASK_NAME \ No newline at end of file From 6c0279cccbf3d98b2ce1b9daf9ae933e215123ba Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 00:06:47 +0100 Subject: [PATCH 10/28] First draft of eesyplan simulation task --- task_queue/tasks.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index fbe169d..f9fad21 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -1,4 +1,5 @@ import os + import time import traceback import json @@ -7,6 +8,16 @@ import tempfile from pathlib import Path +from oemof.datapackage import datapackage # noqa + +from oemof.eesyplan import export_results + +from oemof.eesyplan.datapackage.create_energy_system import ( + optimise, + create_energy_system_from_dp, +) + + SIMULATION_VERSION = os.environ.get("SIMULATION_VERSION", "no_version") logger = get_task_logger(__name__) @@ -20,6 +31,8 @@ app = Celery(CELERY_TASK_NAME, broker=CELERY_BROKER_URL, backend=CELERY_RESULT_BACKEND) + + def __run_simulation( simulation_input): logger.info("Start new simulation") @@ -27,19 +40,20 @@ def __run_simulation( with tempfile.TemporaryDirectory(prefix="dp_") as td: temp_path = Path(td) - # TODO implement in oemof-datapackage or oemof-eesyplan - # dp_path = rebuild_single_json(simulation_input, temp_path) - logger.debug("Converted datapackage in JSON format back to datapackage") - - # -------------- RUNNING THE SCENARIOS -------------- - # scenario = dp_path.name - # # set paths for scenario and result directories - # results_path = dp_path / "results" - # results_path.mkdir() + dp_path = datapackage.rebuild_dp_from_json(simulation_input, temp_path) try: - # run eezyplan here - pass - # simulation_output["results"] = df.to_json() + es = create_energy_system_from_dp(dp_path, plot="None") + + results = optimise(es) + + with tempfile.TemporaryDirectory(prefix="dp_results_") as tres: + results_path = Path(tres) + + export_results(results, path=results_path) + json_export = datapackage.export_dp_to_json(results_path) + simulation_output["raw_results"] = json.loads(json_export) + # imported_results = import_results(path=results_path, es=es) + except Exception as e: logger.error( "An exception occured in the simulation task: {}".format( From 85c24f1eacb88f08ed28817dedb6a83bc66065b8 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 00:17:37 +0100 Subject: [PATCH 11/28] Update the requirements This is still in testing phase --- task_queue/Dockerfile | 5 +++-- task_queue/requirements.txt | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 4d2044b..412a027 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -10,8 +10,9 @@ COPY task_queue/requirements.txt /tmp/ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt # install oemof-eesyplan version from the ENV variable -RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn - +#RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn +RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" run echo $(pip freeze) COPY task_queue/ /queue diff --git a/task_queue/requirements.txt b/task_queue/requirements.txt index 9fc707f..6c5947d 100644 --- a/task_queue/requirements.txt +++ b/task_queue/requirements.txt @@ -2,3 +2,4 @@ celery flower redis python-multipart +gunicorn From f269a11760da31ca8d154bf69dc8e81ed2fa7c28 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 00:27:07 +0100 Subject: [PATCH 12/28] Move gunicorn install to Dockerfile --- task_queue/Dockerfile | 2 ++ task_queue/requirements.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 412a027..380ae79 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -11,8 +11,10 @@ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt # install oemof-eesyplan version from the ENV variable #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn +RUN pip install gunicorn RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" + run echo $(pip freeze) COPY task_queue/ /queue diff --git a/task_queue/requirements.txt b/task_queue/requirements.txt index 6c5947d..9fc707f 100644 --- a/task_queue/requirements.txt +++ b/task_queue/requirements.txt @@ -2,4 +2,3 @@ celery flower redis python-multipart -gunicorn From 398e94e02b844413db10f8500cf8fb1249534a01 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 00:32:50 +0100 Subject: [PATCH 13/28] Add oemof.visio in requirements.txt --- task_queue/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 380ae79..69b0b80 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -14,6 +14,7 @@ RUN pip install -r /tmp/requirements.txt RUN pip install gunicorn RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" +RUN pip install oemof.visio run echo $(pip freeze) COPY task_queue/ /queue From d26f321f3f40b015176b40a6d0049861069cc8bc Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 09:45:32 +0100 Subject: [PATCH 14/28] Trigger rebuild --- task_queue/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 69b0b80..a802023 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -13,8 +13,9 @@ RUN pip install -r /tmp/requirements.txt #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn RUN pip install gunicorn RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" -RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" RUN pip install oemof.visio +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" + run echo $(pip freeze) COPY task_queue/ /queue From 2ac41c1e613187915515df2241982d92a14e5abe Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 09:53:31 +0100 Subject: [PATCH 15/28] Remove oemof.visio as now optional --- task_queue/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index a802023..3fbbf25 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -13,7 +13,6 @@ RUN pip install -r /tmp/requirements.txt #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn RUN pip install gunicorn RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" -RUN pip install oemof.visio RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" From f0beb33dee222a237f85787e43cc4dc2d2afbe95 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 09:55:35 +0100 Subject: [PATCH 16/28] Retrigger install of eesyplan --- task_queue/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 3fbbf25..fb9ffdc 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -11,10 +11,10 @@ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt # install oemof-eesyplan version from the ENV variable #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn -RUN pip install gunicorn + RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" - +RUN pip install gunicorn run echo $(pip freeze) COPY task_queue/ /queue From 797e51b171e1575238e4a20b0029794b77083089 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Sat, 28 Feb 2026 10:00:27 +0100 Subject: [PATCH 17/28] Set no cache for eesyplan and oemof-datapackage --- task_queue/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index fb9ffdc..aa5815b 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -12,8 +12,8 @@ RUN pip install -r /tmp/requirements.txt # install oemof-eesyplan version from the ENV variable #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn -RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" -RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" +RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" --no-cache-dir +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" --no-cache-dir RUN pip install gunicorn run echo $(pip freeze) From 3b823db6c9a4876a2785c106f5a6c731b9ecc5b1 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Mon, 2 Mar 2026 14:08:53 +0100 Subject: [PATCH 18/28] Change eesyplan and datapackage versions --- task_queue/Dockerfile | 4 ++-- task_queue/tasks.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index aa5815b..26a206a 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -12,8 +12,8 @@ RUN pip install -r /tmp/requirements.txt # install oemof-eesyplan version from the ENV variable #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn -RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@fix/create_scenario_from_dp" --no-cache-dir -RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" --no-cache-dir +RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@main" --no-cache-dir +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@dev" --no-cache-dir RUN pip install gunicorn run echo $(pip freeze) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index f9fad21..e054bb7 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -31,8 +31,6 @@ app = Celery(CELERY_TASK_NAME, broker=CELERY_BROKER_URL, backend=CELERY_RESULT_BACKEND) - - def __run_simulation( simulation_input): logger.info("Start new simulation") From 8c8702f422d4a4f2c433a422d23d4f4d1b292a3c Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Mon, 2 Mar 2026 14:29:27 +0100 Subject: [PATCH 19/28] Update python version --- task_queue/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 26a206a..b065fa9 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.10-slim +FROM python:3.12-slim RUN apt-get update && \ apt-get install -y git && \ From d4b763d832279e6d851a61061f66cba008c74f19 Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Mon, 2 Mar 2026 14:39:48 +0100 Subject: [PATCH 20/28] Update oemof-eesyplan imports --- task_queue/tasks.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index e054bb7..2edbe17 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -11,11 +11,8 @@ from oemof.datapackage import datapackage # noqa from oemof.eesyplan import export_results - -from oemof.eesyplan.datapackage.create_energy_system import ( - optimise, - create_energy_system_from_dp, -) +from oemof.eesyplan.datapackage.energy_system import create_energy_system_from_dp +from oemof.eesyplan.model import optimise SIMULATION_VERSION = os.environ.get("SIMULATION_VERSION", "no_version") From a76a0f50ca4ff0e599df314f453d3267577995dc Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Tue, 24 Mar 2026 22:16:19 +0100 Subject: [PATCH 21/28] Omit the plot argument when creating energy system --- task_queue/tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index 2edbe17..0406d98 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -37,7 +37,7 @@ def __run_simulation( temp_path = Path(td) dp_path = datapackage.rebuild_dp_from_json(simulation_input, temp_path) try: - es = create_energy_system_from_dp(dp_path, plot="None") + es = create_energy_system_from_dp(dp_path) results = optimise(es) From 71f24a4d888f5090f6dd995cbe08135f8dc333fa Mon Sep 17 00:00:00 2001 From: "pierre-francois.duc" Date: Wed, 3 Jun 2026 11:25:34 +0200 Subject: [PATCH 22/28] Change oemof-datapackage version for bugfixing --- task_queue/Dockerfile | 6 +++--- task_queue/tasks.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index b065fa9..5b7e0eb 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -11,10 +11,10 @@ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt # install oemof-eesyplan version from the ENV variable #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn - -RUN pip install "oemof-eesyplan @ git+https://github.com/oemof/oemof-eesyplan.git@main" --no-cache-dir -RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@dev" --no-cache-dir +RUN pip install "git+https://github.com/oemof/oemof-eesyplan.git@main" --no-cache-dir RUN pip install gunicorn +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@fix/multilevel-columns-resources" + run echo $(pip freeze) COPY task_queue/ /queue diff --git a/task_queue/tasks.py b/task_queue/tasks.py index 0406d98..e9319cd 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -9,6 +9,7 @@ from pathlib import Path from oemof.datapackage import datapackage # noqa +from oemof.datapackage import __version__ as dp_version from oemof.eesyplan import export_results from oemof.eesyplan.datapackage.energy_system import create_energy_system_from_dp @@ -32,7 +33,7 @@ def __run_simulation( simulation_input): logger.info("Start new simulation") simulation_output = {"SERVER": CELERY_TASK_NAME, "VERSION": SIMULATION_VERSION} - + logger.info(f"Using datapackage version: {dp_version}") with tempfile.TemporaryDirectory(prefix="dp_") as td: temp_path = Path(td) dp_path = datapackage.rebuild_dp_from_json(simulation_input, temp_path) From a2559f03d72d3fb769ec10d96cd1f9e98f283b91 Mon Sep 17 00:00:00 2001 From: paulapreuss Date: Tue, 23 Jun 2026 15:25:53 +0200 Subject: [PATCH 23/28] Fix docker-compose config --- docker-compose.yml | 19 ++++++++++++------- task_queue/Dockerfile | 3 ++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index a88e460..ddaddc1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,16 +1,17 @@ -version: "3" services: web: environment: - MVS_DEV_VERSION=${MVS_DEV_VERSION} - MVS_OPEN_PLAN_VERSION=${MVS_OPEN_PLAN_VERSION} + - CELERY_BROKER_URL=redis://redis:6379 + - CELERY_RESULT_BACKEND=redis://redis:6379 build: args: # this should be in a .env file in the root of the repository mvs_version: ${MVS_DEV_VERSION} # `context` should be a path to a directory containing a Dockerfile - context: ./fastapi_app - dockerfile: Dockerfile + context: . + dockerfile: ./fastapi_app/Dockerfile restart: unless-stopped ports: - "5001:5001" @@ -22,13 +23,15 @@ services: worker-dev: environment: - CELERY_TASK_NAME=dev + - CELERY_BROKER_URL=redis://redis:6379 + - CELERY_RESULT_BACKEND=redis://redis:6379 build: args: # this should be in a .env file in the root of the repository mvs_version: ${MVS_DEV_VERSION} # context should be the name of the folder which define the tasks - context: task_queue - dockerfile: Dockerfile_dev + context: . + dockerfile: ./task_queue/Dockerfile depends_on: - redis networks: @@ -36,13 +39,15 @@ services: worker-open-plan: environment: - CELERY_TASK_NAME=open_plan + - CELERY_BROKER_URL=redis://redis:6379 + - CELERY_RESULT_BACKEND=redis://redis:6379 build: args: # this should be in a .env file in the root of the repository mvs_version: ${MVS_OPEN_PLAN_VERSION} # context should be the name of the folder which define the tasks - context: task_queue - dockerfile: Dockerfile + context: . + dockerfile: ./task_queue/Dockerfile depends_on: - redis networks: diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 5b7e0eb..118810b 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -3,7 +3,8 @@ FROM python:3.12-slim RUN apt-get update && \ apt-get install -y git && \ apt-get install coinor-cbc -y && \ - apt-get install graphviz -y + apt-get install graphviz -y && \ + apt-get install tk -y COPY task_queue/requirements.txt /tmp/ From 8dfb6ab284ffe42bf661d3384cef7f1e90f2f864 Mon Sep 17 00:00:00 2001 From: paulapreuss Date: Tue, 23 Jun 2026 15:27:29 +0200 Subject: [PATCH 24/28] Add oemof-visio requirements Currently breaks build otherwise because of wonky eesyplan settings --- task_queue/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/task_queue/requirements.txt b/task_queue/requirements.txt index 9fc707f..8a2f582 100644 --- a/task_queue/requirements.txt +++ b/task_queue/requirements.txt @@ -2,3 +2,4 @@ celery flower redis python-multipart +oemof-visio \ No newline at end of file From c459b7e5032b0b2688856f1a72b2b9253607b820 Mon Sep 17 00:00:00 2001 From: paulapreuss Date: Tue, 23 Jun 2026 15:27:58 +0200 Subject: [PATCH 25/28] Update TemplateResponse to new starlette function signature --- fastapi_app/webapp.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fastapi_app/webapp.py b/fastapi_app/webapp.py index 42e14dd..ac9343a 100644 --- a/fastapi_app/webapp.py +++ b/fastapi_app/webapp.py @@ -70,9 +70,9 @@ async def debug_ping(): @app.get("/") def index(request: Request) -> Response: return templates.TemplateResponse( - "index.html", - { - "request": request, + request=request, + name="index.html", + context={ "dev_version": get_worker_version("dev"), "prod_version": get_worker_version("prod"), }, @@ -189,7 +189,9 @@ def run_simulation(request: Request, input_json=None, queue="dev") -> Response: ) return templates.TemplateResponse( - "submitted_task.html", {"request": request, "task_id": task.id} + request=request, + name="submitted_task.html", + context={"task_id": task.id}, ) From 1224e13fd64684ff35caaad6a6593d331d730f74 Mon Sep 17 00:00:00 2001 From: MaaJoo13 <148241644+MaaJoo13@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:53:14 +0200 Subject: [PATCH 26/28] Update dockerfile requirements --- fastapi_app/Dockerfile | 2 +- task_queue/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fastapi_app/Dockerfile b/fastapi_app/Dockerfile index 33ba246..3f5f5fb 100644 --- a/fastapi_app/Dockerfile +++ b/fastapi_app/Dockerfile @@ -7,7 +7,7 @@ RUN python -m pip install --upgrade pip RUN pip install -r /tmp/requirements.txt # install multi-vector-simulator's version pinned in docker-compose.yml file RUN pip install gunicorn -RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@feature/export_dp_to_json_and_reverse" --no-cache-dir +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git" --no-cache-dir diff --git a/task_queue/Dockerfile b/task_queue/Dockerfile index 118810b..af4a200 100644 --- a/task_queue/Dockerfile +++ b/task_queue/Dockerfile @@ -14,7 +14,7 @@ RUN pip install -r /tmp/requirements.txt #RUN pip install "oemof-eesyplan==$SIMULATION_VERSION" gunicorn RUN pip install "git+https://github.com/oemof/oemof-eesyplan.git@main" --no-cache-dir RUN pip install gunicorn -RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git@fix/multilevel-columns-resources" +RUN pip install "oemof-datapackage @ git+https://github.com/oemof/oemof-datapackage.git" run echo $(pip freeze) From 2819f76ded63303c4e18c1c6a8d66a02ef939c3f Mon Sep 17 00:00:00 2001 From: MaaJoo13 <148241644+MaaJoo13@users.noreply.github.com> Date: Tue, 23 Jun 2026 17:40:46 +0200 Subject: [PATCH 27/28] Enable local script execution --- task_queue/tasks.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index e9319cd..978d189 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -87,3 +87,20 @@ def ping(self): "pid": os.getpid(), "timestamp": time.time(), } + +if __name__ == "__main__": + with open('sim_data_debug.json', 'r') as file: + dp = json.load(file) + + # Run simulation locally + result = run_simulation(dp) + + # If Celery decorator wraps the output inside AsyncResult, unwrap it + if hasattr(result, "get"): + result = result.get() + + # Store the exact server output + out_path = Path("debug_simulation_output.json") + out_path.write_text(json.dumps(result, indent=2)) + + print("Simulation results saved to:", out_path.resolve()) \ No newline at end of file From 9e5c2d5c489e2045bacb34b6e23cd2e3e3908023 Mon Sep 17 00:00:00 2001 From: MaaJoo13 <148241644+MaaJoo13@users.noreply.github.com> Date: Tue, 7 Jul 2026 17:47:09 +0200 Subject: [PATCH 28/28] Include sankey figure in server response --- task_queue/tasks.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/task_queue/tasks.py b/task_queue/tasks.py index 978d189..6529f9c 100644 --- a/task_queue/tasks.py +++ b/task_queue/tasks.py @@ -11,10 +11,12 @@ from oemof.datapackage import datapackage # noqa from oemof.datapackage import __version__ as dp_version -from oemof.eesyplan import export_results +from oemof.eesyplan import export_results, import_results from oemof.eesyplan.datapackage.energy_system import create_energy_system_from_dp from oemof.eesyplan.model import optimise +import oemof.eesyplan.postprocessing.graphs as eesyplan_graphs + SIMULATION_VERSION = os.environ.get("SIMULATION_VERSION", "no_version") @@ -48,7 +50,10 @@ def __run_simulation( export_results(results, path=results_path) json_export = datapackage.export_dp_to_json(results_path) simulation_output["raw_results"] = json.loads(json_export) - # imported_results = import_results(path=results_path, es=es) + + imported_results = import_results(path=results_path, es=es) + fig, links_df = eesyplan_graphs.sankey(imported_results["flow"], title="Test Sankey") + simulation_output["figures"] = {"sankey": fig.to_dict()} except Exception as e: logger.error(