Skip to content

Commit 109247a

Browse files
authored
Merge pull request #13 from maexled/feature/detailed-shelly-result
- add total returned power in shelly results - compute variable results on server side with database - add gzip middleware - add debug_toolbar
2 parents bf208be + ef43a2b commit 109247a

File tree

13 files changed

+288
-169
lines changed

13 files changed

+288
-169
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ jobs:
2828
pip install -r requirements.txt
2929
- name: Run Tests
3030
run: |
31+
python manage.py collectstatic --noinput
3132
python manage.py test

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ RUN pip install --no-cache-dir --upgrade pip && \
1313
pip install --no-cache-dir -r requirements.txt
1414

1515
COPY . .
16-
CMD python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput && gunicorn --bind=0.0.0.0:8000 --timeout 600 --workers=3 --threads=3 pim.wsgi:application
16+
CMD python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput && gunicorn --bind=0.0.0.0:8000 --timeout 300 --workers=3 --threads=3 --max-requests 5 --max-requests-jitter 2 pim.wsgi:application
1717
EXPOSE 8000/tcp

interface/templates/mystrom_chart.html

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@
2626
startQuery +
2727
endQuery,
2828
data => {
29+
const results = data.results;
2930
const chartElement = document.getElementById(elementId + "-chart");
3031
const informationElement = document.getElementById(
3132
elementId + "-information"
3233
);
3334

34-
if (data.length == 0) {
35+
if (results.length == 0) {
3536
informationElement.innerHTML =
3637
'<h3 class="text-danger">Query of device ' +
3738
id +
@@ -40,41 +41,43 @@
4041
resolve();
4142
return;
4243
}
43-
const firstDate = new Date(data[0].date);
44-
const lastDate = new Date(data[data.length - 1].date);
44+
const firstDate = new Date(results[0].date);
45+
const lastDate = new Date(results[results.length - 1].date);
46+
4547
const differenceBetweenDates = lastDate - firstDate;
4648
const hoursDifferenceBetweedDates =
4749
differenceBetweenDates / 1000 / 60 / 60;
4850

49-
const powerList = data.map((entry) => entry.power);
50-
const wsList = data.map((entry) => entry.ws);
51-
const temperatureList = data.map((entry) => entry.temperature);
52-
let total = 0;
53-
for (let power of powerList) {
54-
total += power;
55-
}
56-
const average = total / powerList.length;
57-
const totalProducedkWh =
58-
(average * hoursDifferenceBetweedDates) / 1000;
51+
const powerList = results.map((entry) => entry.power);
52+
const wsList = results.map((entry) => entry.ws);
53+
const temperatureList = results.map((entry) => entry.temperature);
54+
const totalPowerkWh = data.total_power / 1000;
5955

6056
informationElement.innerHTML =
61-
"<h5>Average of " +
62-
hoursDifferenceBetweedDates.toFixed(2) +
63-
" hours: " +
64-
average.toFixed(2) +
65-
"Wh</h5>";
66-
informationElement.innerHTML +=
6757
"<h5>Leads to <b>" +
68-
totalProducedkWh.toFixed(2) +
58+
totalPowerkWh.toFixed(2) +
6959
"kWh</b> produced in " +
7060
hoursDifferenceBetweedDates.toFixed(2) +
7161
" hours</h5>";
7262

73-
const xAxisList = data.map((entry) => entry.date);
63+
const xAxisList = results.map((entry) => entry.date);
7464
renderMystromChart(powerList, wsList, temperatureList, xAxisList, chartElement);
75-
resolve();
7665
}
77-
);
66+
).fail((jqXHR, textStatus, errorThrown) => {
67+
console.log("Error: " + errorThrown);
68+
console.log("Status: " + textStatus);
69+
const informationElement = document.getElementById(
70+
elementId + "-information"
71+
);
72+
if (informationElement)
73+
informationElement.innerHTML =
74+
'<h3 class="text-danger">Error while requesting data of device ' +
75+
id +
76+
"</h3>";
77+
}).always(() => {
78+
console.log("Request finished");
79+
resolve();
80+
});
7881
});
7982
}
8083

@@ -175,7 +178,7 @@
175178
*/
176179
function renderMystromChart(powerList, wsList, temperatureList, xAxisList, chartElement) {
177180
let data = [
178-
xAxisList.map((date) => new Date(date)/1000),
181+
xAxisList.map((date) => new Date(date) / 1000),
179182
powerList,
180183
wsList,
181184
temperatureList
@@ -190,7 +193,7 @@
190193
axes: [
191194
{
192195
label: "Time",
193-
values: (u, vals, space) => vals.map(v => new Date(v*1000).toLocaleTimeString().substring(0, 5) + "h"),
196+
values: (u, vals, space) => vals.map(v => new Date(v * 1000).toLocaleTimeString().substring(0, 5) + "h"),
194197
},
195198
{
196199
values: (u, vals, space) => vals.map(v => v.toFixed(1) + "W/h"),

interface/templates/results.html

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ <h1>Device Results</h1>
2929
<div class="form-row">
3030
<div class="form-group col-md-4">
3131
<label for="start-date-{{ device.id }}">Start date</label>
32-
<input placeholder="Select date" type="date" id="start-date-mystrom-{{ device.id }}" class="form-control">
32+
<input placeholder="Select date" type="date" id="start-date-mystrom-{{ device.id }}"
33+
class="form-control">
3334
</div>
3435

3536
<div class="form-group col-md-4">
@@ -44,7 +45,8 @@ <h1>Device Results</h1>
4445
</div>
4546
<div class="form-row">
4647
<div class="form-group col-md-9">
47-
<button class="btn btn-info" id="mystrom-{{ device.id }}" onclick="toggleChart(this.id), 'mystrom'">
48+
<button class="btn btn-info" id="mystrom-{{ device.id }}"
49+
onclick="toggleChart(this.id, '{{ device.name }}', 'mystrom')">
4850
Show Chart for Device {{ device.id }}
4951
</button>
5052
</div>
@@ -66,7 +68,8 @@ <h1>Device Results</h1>
6668
<div class="form-row">
6769
<div class="form-group col-md-4">
6870
<label for="start-date-{{ device.id }}">Start date</label>
69-
<input placeholder="Select date" type="date" id="start-date-shelly-{{ device.id }}" class="form-control">
71+
<input placeholder="Select date" type="date" id="start-date-shelly-{{ device.id }}"
72+
class="form-control">
7073
</div>
7174

7275
<div class="form-group col-md-4">
@@ -81,7 +84,8 @@ <h1>Device Results</h1>
8184
</div>
8285
<div class="form-row">
8386
<div class="form-group col-md-9">
84-
<button class="btn btn-info" id="shelly-{{ device.id }}" onclick="toggleChart(this.id, 'shelly')">
87+
<button class="btn btn-info" id="shelly-{{ device.id }}"
88+
onclick="toggleChart(this.id, '{{ device.name }}', 'shelly')">
8589
Show Chart for Device {{ device.id }}
8690
</button>
8791
</div>
@@ -101,8 +105,11 @@ <h1>Device Results</h1>
101105
{% endblock %}
102106

103107
{% block scripts %}
108+
{% if CHART_TYPE == 'apexcharts' %}
104109
<script src="{% static 'js/apexcharts.min.js' %}"></script>
110+
{% elif CHART_TYPE == "uplot" %}
105111
<script src="{% static 'js/uPlot.iife.min.js' %}"></script>
112+
{% endif %}
106113

107114
{% include "mystrom_chart.html" %}
108115
{% include "shelly_chart.html" %}
@@ -120,7 +127,7 @@ <h1>Device Results</h1>
120127
return date.toISOString();
121128
}
122129

123-
function toggleChart(id, device_type) {
130+
function toggleChart(id, name, device_type) {
124131
const startDateElement = document.getElementById("start-date-" + id);
125132
const endDateElement = document.getElementById("end-date-" + id);
126133
const elementId = "chart-" + id;
@@ -153,21 +160,23 @@ <h1>Device Results</h1>
153160
let endDate = endDateElement.value;
154161
if (!startDate) {
155162
startDate = new Date();
156-
startDate.setHours(0);
157-
startDate.setMinutes(0);
158-
startDate.setSeconds(0);
159-
startDate = dateFormat(startDate);
160-
startDateElement.value = startDate;
163+
} else {
164+
startDate = new Date(startDate);
161165
}
166+
startDate.setHours(0);
167+
startDate.setMinutes(0);
168+
startDate.setSeconds(0);
169+
startDate = dateFormat(startDate);
162170
if (!endDate) {
163171
endDate = new Date();
164-
endDate.setHours(0);
165-
endDate.setMinutes(0);
166-
endDate.setSeconds(0);
167172
endDate.setDate(endDate.getDate() + 1);
168-
endDate = dateFormat(endDate);
169-
endDateElement.value = endDate;
173+
} else {
174+
endDate = new Date(endDate);
170175
}
176+
endDate.setHours(0);
177+
endDate.setMinutes(0);
178+
endDate.setSeconds(0);
179+
endDate = dateFormat(endDate);
171180

172181
setTimeout(async () => {
173182
if (device_type == "shelly") {
@@ -176,6 +185,7 @@ <h1>Device Results</h1>
176185
await loadMystromChart(id, elementId, startDate, endDate);
177186
}
178187
chartElement.removeChild(loadingAnimation);
188+
informationElement.innerHTML = "<h4>Information about device <b>" + name + "</b></h4>" + informationElement.innerHTML;
179189
})
180190

181191
document.getElementById(id).innerHTML = "Hide Chart for Device " + id;

interface/templates/shelly_chart.html

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@
2626
startQuery +
2727
endQuery,
2828
function (data) {
29+
const results = data.results;
2930
const chartElement = document.getElementById(elementId + "-chart");
3031
const informationElement = document.getElementById(
3132
elementId + "-information"
3233
);
3334

34-
if (data.length == 0) {
35+
if (results.length == 0) {
3536
informationElement.innerHTML =
3637
'<h3 class="text-danger">Query of device ' +
3738
id +
@@ -40,19 +41,19 @@
4041
resolve();
4142
return;
4243
}
43-
const firstDate = new Date(data[0].date);
44-
const lastDate = new Date(data[data.length - 1].date);
44+
const firstDate = new Date(results[0].date);
45+
const lastDate = new Date(results[results.length - 1].date);
4546
const differenceBetweenDates = lastDate - firstDate;
4647
const hoursDifferenceBetweedDates =
4748
differenceBetweenDates / 1000 / 60 / 60;
4849

49-
const powerList = data.map((entry) => entry.total_power);
50+
const powerList = results.map((entry) => entry.total_power);
5051
let emeter0List, emeter1List, emeter2List = [];
5152
let emeterSeries = [];
52-
if (data[0].emeters) {
53-
emeter0List = data.map((entry) => entry.emeters[0] ? entry.emeters[0].power : 0);
54-
emeter1List = data.map((entry) => entry.emeters[1] ? entry.emeters[1].power : 0);
55-
emeter2List = data.map((entry) => entry.emeters[2] ? entry.emeters[2].power : 0);
53+
if (results[0].emeters) {
54+
emeter0List = results.map((entry) => entry.emeters[0] ? entry.emeters[0].power : 0);
55+
emeter1List = results.map((entry) => entry.emeters[1] ? entry.emeters[1].power : 0);
56+
emeter2List = results.map((entry) => entry.emeters[2] ? entry.emeters[2].power : 0);
5657
emeterSeries = [
5758
{
5859
name: "Phase A",
@@ -68,32 +69,39 @@
6869
},
6970
];
7071
}
71-
let total = 0;
72-
for (let power of powerList) {
73-
total += power;
74-
}
72+
let total = powerList.reduce((a, b) => a + b, 0);
7573
const average = total / powerList.length;
76-
const totalProducedkWh =
77-
(average * hoursDifferenceBetweedDates) / 1000;
74+
const totalProducedkWh = data.total_power / 1000;
75+
const totalReturnedkWh = data.total_returned_power / 1000;
7876

7977
informationElement.innerHTML =
80-
"<h5>Average of " +
81-
hoursDifferenceBetweedDates.toFixed(2) +
82-
" hours: " +
83-
average.toFixed(2) +
84-
"Wh</h5>";
85-
informationElement.innerHTML +=
8678
"<h5>Leads to <b>" +
8779
totalProducedkWh.toFixed(2) +
8880
"kWh</b> produced in " +
8981
hoursDifferenceBetweedDates.toFixed(2) +
9082
" hours</h5>";
83+
informationElement.innerHTML +=
84+
"Total returned power: <b>" +
85+
totalReturnedkWh.toFixed(2) +
86+
"kWh</b><br>";
9187

92-
const xAxisList = data.map((entry) => entry.date);
88+
const xAxisList = results.map((entry) => entry.date);
9389
renderShellyChart(powerList, emeterSeries, xAxisList, chartElement);
94-
resolve();
9590
}
96-
);
91+
).fail((jqXHR, textStatus, errorThrown) => {
92+
console.log("Error: " + errorThrown);
93+
console.log("Status: " + textStatus);
94+
const informationElement = document.getElementById(
95+
elementId + "-information"
96+
);
97+
if (informationElement)
98+
informationElement.innerHTML =
99+
'<h3 class="text-danger">Error while requesting data of device ' +
100+
id +
101+
"</h3>";
102+
}).always(() => {
103+
resolve();
104+
});
97105
});
98106
}
99107

@@ -185,9 +193,9 @@
185193
* @param {Array} xAxisList the x axis list
186194
* @param {HTMLElement} chartElement the chart element to render the chart in
187195
*/
188-
function renderShellyChart(powerList, emeterSeries, xAxisList, chartElement) {
196+
function renderShellyChart(powerList, emeterSeries, xAxisList, chartElement) {
189197
let data = [
190-
xAxisList.map((date) => new Date(date)/1000),
198+
xAxisList.map((date) => new Date(date) / 1000),
191199
powerList,
192200
...emeterSeries.map(series => series.data)
193201
];
@@ -201,7 +209,7 @@
201209
axes: [
202210
{
203211
label: "Time",
204-
values: (u, vals, space) => vals.map(v => new Date(v*1000).toLocaleTimeString().substring(0, 5) + "h"),
212+
values: (u, vals, space) => vals.map(v => new Date(v * 1000).toLocaleTimeString().substring(0, 5) + "h"),
205213
},
206214
{
207215
values: (u, vals, space) => vals.map(v => v.toFixed(1) + "W/h"),

interface/templates/single_result.html

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,25 @@
44
{% block content %}
55
<div id="chartContainer">
66
<div id="loading" class="d-flex justify-content-center">
7-
<div
8-
class="spinner-border"
9-
style="width: 6rem; height: 6rem; margin-top: 100px"
10-
role="status"
11-
>
7+
<div class="spinner-border" style="width: 6rem; height: 6rem; margin-top: 100px" role="status">
128
<span class="sr-only">Loading...</span>
139
</div>
1410
</div>
1511
</div>
1612
{% endblock %}
1713

1814
{% block scripts %}
15+
{% if CHART_TYPE == 'apexcharts' %}
1916
<script src="{% static 'js/apexcharts.min.js' %}"></script>
17+
{% elif CHART_TYPE == "uplot" %}
2018
<script src="{% static 'js/uPlot.iife.min.js' %}"></script>
19+
{% endif %}
2120
{% with device|classname as modelclass %}
2221

2322
{% if modelclass == 'Shelly3EMDevice' %}
24-
{% include "shelly_chart.html" %}
23+
{% include "shelly_chart.html" %}
2524
{% elif modelclass == "MystromDevice" %}
26-
{% include "mystrom_chart.html" %}
25+
{% include "mystrom_chart.html" %}
2726
{% endif %}
2827
<script>
2928
const params = new URLSearchParams(window.location.search);
@@ -83,5 +82,5 @@
8382
loadingElement.remove();
8483
});
8584
</script>
86-
{% endwith %}
87-
{% endblock %}
85+
{% endwith %}
86+
{% endblock %}

0 commit comments

Comments
 (0)