Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add devcontainer and pave the way for ingress access #106

Merged
merged 4 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM mcr.microsoft.com/devcontainers/python:1-3.8-buster

COPY .devcontainer/setup.sh requirements.txt requirements_webserver.txt ./
RUN ./setup.sh
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "EMHASS",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
26 changes: 26 additions & 0 deletions .devcontainer/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -euo pipefail

main() {
set -x
apt-get update
apt-get install -y --no-install-recommends \
coinor-cbc \
coinor-libcbc-dev \
gcc \
gfortran \
libhdf5-dev \
libhdf5-serial-dev \
libnetcdf-dev \
netcdf-bin

ln -s /usr/include/hdf5/serial /usr/include/hdf5/include
export HDF5_DIR=/usr/include/hdf5
pip install netCDF4

pip install -r requirements_webserver.txt

rm -rf "$0"
}

main
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ FROM python:3.8-slim-buster
WORKDIR /app

# copy the requirements file into the image
COPY requirements.txt requirements.txt
COPY requirements_webserver.txt requirements_webserver.txt
COPY setup.py setup.py
COPY README.md README.md
Expand Down
14 changes: 1 addition & 13 deletions requirements_webserver.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
wheel
numpy==1.22.2
pandas==1.4.1
scipy<1.9.0
pvlib>=0.10.1
protobuf>=3.0.0
pytz>=2021.1
requests>=2.25.1
beautifulsoup4>=4.9.3
pulp>=2.4
pyyaml>=5.4.1
tables==3.7.0
skforecast==0.9.1
-r requirements.txt
flask>=2.0.3
waitress>=2.1.1
plotly>=5.6.0
136 changes: 20 additions & 116 deletions src/emhass/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<title>EMHASS: Energy Management Optimization for Home Assistant</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="../static/style.css">
<link rel="stylesheet" type="text/css" href="{{ basename }}/static/style.css">
</head>
<body>
<center>
Expand All @@ -14,8 +13,8 @@ <h2 style="font-family: Helvetica;color: darkblue;">EMHASS: Energy Management Op
<div align="center" class="form">
<form action="" method="get">
<h4 style="font-family: Helvetica;color: darkblue;">Use the buttons below to manually launch different optimization tasks</h4>
<button type="button" id="perfect-optimization" class="button button1" >Perfect Optimization</button>
<button type="button" id="dayahead-optimization" class="button button2" >Day-ahead Optimization</button>
<button type="button" id="perfect-optim" class="button button1" >Perfect Optimization</button>
<button type="button" id="dayahead-optim" class="button button2" >Day-ahead Optimization</button>
<h4 style="font-family: Helvetica;color: darkblue;">Use the button below to publish the optimized variables at the current timestamp</h4>
<button type="button" id="publish-data" class="button button1" >Publish Optimization Results</button>
<h4 style="font-family: Helvetica;color: darkblue;">Use the buttons below to fit, predict and tune a machine learning model for testing</h4>
Expand Down Expand Up @@ -43,118 +42,23 @@ <h4 style="font-family: Helvetica;color: darkblue;">Use the buttons below to fit
</footer>
</body>
<script>
document.getElementById('perfect-optimization').addEventListener('click', function() {
var url = "/action/perfect-optim"
var settings = {
"async": true,
"crossDomain": true,
"url": url,
"method": "POST",
"headers": {
'Content-Type':'application/json'
},
"dataType": 'json',
"data": '{}'
}
$.ajax(settings).done(function (response) {
async function performAction(action) {
await fetch(`{{ basename }}/action/${action}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: "{}",
});
});
document.getElementById('dayahead-optimization').addEventListener('click', function() {
var url = "/action/dayahead-optim"
var settings = {
"async": true,
"crossDomain": true,
"url": url,
"method": "POST",
"headers": {
'Content-Type':'application/json'
},
"dataType": 'json',
"data": '{}'
}
$.ajax(settings).done(function (response) {
});
});
document.getElementById('publish-data').addEventListener('click', function() {
var url = "/action/publish-data"
var settings = {
"async": true,
"crossDomain": true,
"url": url,
"method": "POST",
"headers": {
'Content-Type':'application/json'
},
"dataType": 'json',
"data": '{}'
}
$.ajax(settings).done(function (response) {
});
});
// document.getElementById('forecast-model-fit').addEventListener('click', function() {
// var formData = $("runtimeparams").serialize();
// // send ajax
// $.ajax({
// url: "/action/forecast-model-fit",
// type : "POST",
// contentType : "application/json;charset=UTF-8",
// dataType : 'json',
// data : formData,
// success : function(result) {
// console.log(result);
// },
// error: function(xhr, resp, text) {
// console.log(xhr, resp, text);
// }
// })
// });
document.getElementById('forecast-model-fit').addEventListener('click', function() {
var url = "/action/forecast-model-fit"
var settings = {
"async": true,
"crossDomain": true,
"url": url,
"method": "POST",
"headers": {
'Content-Type':'application/json'
},
"dataType": 'json',
"data": '{}'
}
$.ajax(settings).done(function (response) {
});
});
document.getElementById('forecast-model-predict').addEventListener('click', function() {
var url = "/action/forecast-model-predict"
var settings = {
"async": true,
"crossDomain": true,
"url": url,
"method": "POST",
"headers": {
'Content-Type':'application/json'
},
"dataType": 'json',
"data": '{}'
}
$.ajax(settings).done(function (response) {
});
});
document.getElementById('forecast-model-tune').addEventListener('click', function() {
var url = "/action/forecast-model-tune"
var settings = {
"async": true,
"crossDomain": true,
"url": url,
"method": "POST",
"headers": {
'Content-Type':'application/json'
},
"dataType": 'json',
"data": '{}'
}
$.ajax(settings).done(function (response) {
});
});
}

[
"dayahead-optim",
"forecast-model-fit",
"forecast-model-predict",
"forecast-model-tune",
"perfect-optim",
"publish-data",
].forEach((id) => document.getElementById(id).addEventListener('click', () => performAction(id)));
</script>
</html>
3 changes: 2 additions & 1 deletion src/emhass/web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ def index():
else:
app.logger.warning("The data container dictionary is empty... Please launch an optimization task")
injection_dict={}
return make_response(template.render(injection_dict=injection_dict))
basename = request.headers.get("X-Ingress-Path", "")
return make_response(template.render(injection_dict=injection_dict, basename=basename))

@app.route('/action/<action_name>', methods=['POST'])
def action_call(action_name):
Expand Down