initial commit
This commit is contained in:
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
45
public/index.css
Normal file
45
public/index.css
Normal file
@@ -0,0 +1,45 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 1rem;
|
||||
margin: 0 auto;
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
.select-form {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
border: 1px lightgray solid;
|
||||
gap: 2rem;
|
||||
margin: 1rem 0;
|
||||
padding: 1rem;
|
||||
|
||||
& > .pickers {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1rem;
|
||||
& > label {
|
||||
padding: 0.5rem 0rem;
|
||||
& > select {
|
||||
padding: 0.5rem 1rem;
|
||||
margin: 0.5rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
& > input {
|
||||
padding: 0.5rem 1rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
}
|
||||
73
public/index.html
Normal file
73
public/index.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello</title>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/moment"></script>
|
||||
<!-- <script src="https://cdn.jsdelivr.net/npm/moment-timezone@0.6.0/moment-timezone.min.js"></script>-->
|
||||
<script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>
|
||||
|
||||
<script defer src="index.js"></script>
|
||||
<!-- <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>-->
|
||||
|
||||
<!-- <script defer src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>-->
|
||||
<!-- <script defer src="https://cdn.jsdelivr.net/npm/chartjs-plugin-colorschemes"></script>-->
|
||||
<link rel="stylesheet" href="index.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<h1>Luftfeuchtigkeitsdaten</h1>
|
||||
|
||||
|
||||
<form class="select-form">
|
||||
|
||||
<div class="pickers">
|
||||
|
||||
<label for="tag-select">Daten von
|
||||
<select name="tag-select" id="tag-select">
|
||||
<option value="">--Lade--</option>
|
||||
</select>
|
||||
</label>
|
||||
<label for="range-select">Wie lange?
|
||||
|
||||
<select name="range-select" id="range-select">
|
||||
<option value="3" selected>3 Stunden</option>
|
||||
<option value="6">6 Stunden</option>
|
||||
<option value="12">12 Stunden</option>
|
||||
<option value="24">1 Tag</option>
|
||||
<option value="72">3 Tage</option>
|
||||
<option value="72">3 Tage</option>
|
||||
<option value="168">1 Woche</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</label>
|
||||
<input type="submit" value="Anwenden" id="submit-select">
|
||||
</form>
|
||||
|
||||
<div class="chart-container">
|
||||
<canvas id="humChart" class="chart"> Lade...</canvas>
|
||||
<canvas id="pwrChart" class="chart"> Lade...</canvas>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!--<form>-->
|
||||
|
||||
<!-- <label for="range-select">Choose a range:</label>-->
|
||||
|
||||
<!-- <select name="range-select" id="table-select">-->
|
||||
<!-- <option value="">--Please choose an option--</option>-->
|
||||
<!-- <option value="humidity">Luftfeuchtigkeit</option>-->
|
||||
<!-- <option value="power">Stromverbrauch</option>-->
|
||||
<!-- </select>-->
|
||||
|
||||
<!-- <input type="submit" value="Submit" id="submit-table-select">-->
|
||||
<!--</form>-->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
244
public/index.js
Normal file
244
public/index.js
Normal file
@@ -0,0 +1,244 @@
|
||||
|
||||
moment.tz('Europe/Berlin')
|
||||
Chart.defaults.font.size = 24;
|
||||
|
||||
let humChart, pwrChart
|
||||
|
||||
function toMoment(time) {
|
||||
|
||||
|
||||
let m = moment(time);
|
||||
m = m.subtract({hours: 1});
|
||||
return m
|
||||
}
|
||||
|
||||
async function fetchTags() {
|
||||
let res = await fetch("/tags");
|
||||
let tags = await res.json();
|
||||
return tags;
|
||||
}
|
||||
|
||||
async function fetchChartData(series, tag, from) {
|
||||
|
||||
const queryParams = new URLSearchParams({tag, from});
|
||||
const url = `/${series}?${queryParams.toString()}`
|
||||
let res = await fetch(url);
|
||||
let data = await res.json();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
async function fetchTagData(tag, from) {
|
||||
|
||||
let humidityDataPromise = fetchChartData("humidity",tag, from);
|
||||
let powerDataPromise = fetchChartData("power",tag, from);
|
||||
let stateDataPromise = fetchChartData("state",tag, from);
|
||||
|
||||
let [humidityData, powerData, stateData] = await Promise.all([humidityDataPromise, powerDataPromise,stateDataPromise])
|
||||
return {
|
||||
humidityData, powerData, stateData
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function initHumChart({humidityData, powerData, stateData}) {
|
||||
|
||||
// let humidityData = await fetchChartData("humidity",tag, new Date().getTime());
|
||||
// let powerData = await fetchChartData("power",tag, new Date().getTime());
|
||||
// let stateData = await fetchChartData("state",tag, new Date().getTime());
|
||||
|
||||
let humidityDataSet = {
|
||||
label: 'Luftfeuchtigkeit',
|
||||
yAxisID: 'humidity',
|
||||
data: humidityData.map(v => ({x: toMoment(v.Time), y: v.Humidity})),
|
||||
backgroundColor: 'rgba(8,62,236,0.2)',
|
||||
borderColor: 'rgb(101,119,234)',
|
||||
borderWidth: 1
|
||||
}
|
||||
|
||||
|
||||
let powerDataSet = {
|
||||
label: 'Apparent Power',
|
||||
yAxisID: 'power',
|
||||
data: powerData.map(v => ({x: toMoment(v.Time), y: v.ApparentPower})),
|
||||
backgroundColor: 'rgba(193,151,91,0.2)',
|
||||
borderColor: 'rgb(207,179,106)',
|
||||
borderWidth: 1
|
||||
}
|
||||
|
||||
// let stateDataSet = {
|
||||
// label: 'An/Aus',
|
||||
// data: stateData.map(v => ({x: v.Time, y: v.SwitchState})),
|
||||
// backgroundColor: 'rgba(125,158,124,0.2)',
|
||||
// borderColor: 'rgb(8,255,0)',
|
||||
// borderWidth: 1
|
||||
// }
|
||||
|
||||
chart = new Chart(document.getElementById('humChart').getContext('2d'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [humidityDataSet, powerDataSet]
|
||||
},
|
||||
options: {
|
||||
scales:{
|
||||
x:{
|
||||
type: 'time',
|
||||
ticks: {
|
||||
autoSkip: true,
|
||||
maxTicksLimit: 20
|
||||
},
|
||||
time: {
|
||||
displayFormats: {minute: 'HH:mm'}
|
||||
}
|
||||
},
|
||||
|
||||
humidity: {
|
||||
type: 'linear',
|
||||
position: 'left',
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: true,
|
||||
},
|
||||
grid: { display: false }
|
||||
},
|
||||
power: {
|
||||
type: 'linear',
|
||||
position: 'right',
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: true,
|
||||
},
|
||||
grid: { display: false }
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
return chart
|
||||
}
|
||||
|
||||
function initPwrChart({humidityData, powerData, stateData}) {
|
||||
|
||||
//
|
||||
// let humidityDataSet = {
|
||||
// label: 'Luftfeuchtigkeit',
|
||||
// yAxisID: 'humidity',
|
||||
// data: humidityData.map(v => ({x: toMoment(v.Time), y: v.Humidity})),
|
||||
// backgroundColor: 'rgba(8,62,236,0.2)',
|
||||
// borderColor: 'rgb(101,119,234)',
|
||||
// borderWidth: 1
|
||||
// }
|
||||
|
||||
|
||||
let totalDataset = {
|
||||
label: 'Total KWh',
|
||||
yAxisID: 'total',
|
||||
data: powerData.map(v => ({x: toMoment(v.Time), y: v.Total})),
|
||||
backgroundColor: 'rgba(193,151,91,0.2)',
|
||||
borderColor: 'rgb(207,179,106)',
|
||||
borderWidth: 1
|
||||
}
|
||||
|
||||
let yesterdayDataset = {
|
||||
label: 'Gestern KWh',
|
||||
yAxisID: 'yesterday',
|
||||
data: powerData.map(v => ({x: toMoment(v.Time), y: v.Yesterday})),
|
||||
backgroundColor: 'rgba(110,70,70,0.2)',
|
||||
borderColor: 'rgb(207,106,114)',
|
||||
borderWidth: 1
|
||||
}
|
||||
|
||||
|
||||
|
||||
chart = new Chart(document.getElementById('pwrChart').getContext('2d'), {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [totalDataset, yesterdayDataset]
|
||||
},
|
||||
options: {
|
||||
scales:{
|
||||
x:{
|
||||
type: 'time',
|
||||
ticks: {
|
||||
autoSkip: true,
|
||||
maxTicksLimit: 20
|
||||
},
|
||||
time: {
|
||||
displayFormats: {minute: 'HH:mm'}
|
||||
}
|
||||
},
|
||||
|
||||
total: {
|
||||
type: 'linear',
|
||||
position: 'left',
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: true,
|
||||
},
|
||||
grid: { display: false }
|
||||
},
|
||||
yesterday: {
|
||||
type: 'linear',
|
||||
position: 'right',
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: true,
|
||||
},
|
||||
grid: { display: false }
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
return chart
|
||||
}
|
||||
|
||||
async function loadChartData(tag, date) {
|
||||
console.log(date)
|
||||
let data = await fetchTagData(tag, date);
|
||||
|
||||
humChart = initHumChart(data);
|
||||
pwrChart = initPwrChart(data);
|
||||
}
|
||||
|
||||
|
||||
async function populateOptions() {
|
||||
|
||||
let tagSelectElement = document.getElementById("tag-select")
|
||||
tagSelectElement.active = false
|
||||
let tags = await fetchTags();
|
||||
tagSelectElement.innerHTML = '';
|
||||
for (let tag of tags) {
|
||||
let option = document.createElement("option");
|
||||
option.value = tag;
|
||||
option.text = tag;
|
||||
tagSelectElement.appendChild(option);
|
||||
}
|
||||
tagSelectElement.active = true
|
||||
let rangeSelectElement = document.getElementById("range-select")
|
||||
document.getElementById("submit-select").addEventListener("click", function(event){
|
||||
event.preventDefault();
|
||||
console.log("submit clicked", rangeSelectElement.value, tagSelectElement.value);
|
||||
let m = moment().subtract({hours: rangeSelectElement.value});
|
||||
console.log(m);
|
||||
var fromDate = m.toDate();
|
||||
console.log(fromDate.toISOString());
|
||||
if (humChart !== undefined) {
|
||||
humChart.destroy();
|
||||
}
|
||||
if (pwrChart !== undefined) {
|
||||
pwrChart.destroy();
|
||||
}
|
||||
|
||||
loadChartData(tagSelectElement.value, fromDate.toISOString());
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
populateOptions();
|
||||
|
||||
let m = moment().subtract({hours: 3});
|
||||
var fromDate = m.toDate();
|
||||
|
||||
loadChartData("Bad Unten", fromDate.toISOString());
|
||||
Reference in New Issue
Block a user