commit
7a46f5a528
@ -9,59 +9,53 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js" defer></script>
|
||||
<script src="main.js" defer></script>
|
||||
<script src="https://cdn.socket.io/socket.io-3.0.1.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript" defer></script>
|
||||
</head>
|
||||
<body onload="updateChart(), checkMode(), getStartValues()">
|
||||
<body onload="checkUser(), checkMode(), getStartValues(), updateChart()">
|
||||
<header>
|
||||
<h1>ESP-Ventilation</h1>
|
||||
<h1>ABB Ventilation Controller</h1>
|
||||
</header>
|
||||
<div class="logout">
|
||||
<p id="user"></p>
|
||||
<form id="log_out" method="post" action="/logout">
|
||||
<input id="btn_log_out" type="submit" value="Log out">
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
<div class="upper">
|
||||
<main>
|
||||
<div class="modes">
|
||||
<br>
|
||||
<div class="buttons">
|
||||
|
||||
<input type="radio" class="custom-radio" id="m_auto" name="mode" value="Automatic" checked="true">
|
||||
|
||||
<label for="m_auto">Automatic</label><br>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
|
||||
<input type="radio" class="custom-radio" id="m_man" name="mode" value="Manual">
|
||||
|
||||
<label for="m_man">Manual</label><br><br>
|
||||
</div>
|
||||
</div>
|
||||
<div class="login">
|
||||
<form id="login-form" method="post" action="/">
|
||||
<br>
|
||||
<p id="pwd-warn">Wrong username or password</p>
|
||||
<p id="form-warn">All fields must be filled!</p>
|
||||
<p>You must log in to access manual mode<br>Please give your credentials:</p>
|
||||
<p>You must log in to change settings<br>Please give your credentials:</p>
|
||||
<input type="text" name="username" id="username" placeholder="Username" required>
|
||||
<br><br>
|
||||
<input type="password" name="password" id="password" placeholder="Password" required>
|
||||
<br><br>
|
||||
<input type="submit" name="btn_login" id="btn_login" value="Login">
|
||||
<br>
|
||||
<p id="acc" style="font-weight:normal">If you don't have account, please contact the site administrator</p>
|
||||
<br><br>
|
||||
<p id="acc" style="font-weight:normal">If you don't have an account, please contact your administrator</p>
|
||||
<br>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modes">
|
||||
<div id="buttons">
|
||||
<input type="radio" class="custom-radio" id="m_auto" name="mode" value="Automatic" checked="true">
|
||||
<label for="m_auto" id="auto_label">Automatic</label><br>
|
||||
</div>
|
||||
<div id="buttons">
|
||||
<input type="radio" class="custom-radio" id="m_man" name="mode" value="Manual">
|
||||
<label for="m_man" id="man_label">Manual</label><br><br>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<p id="mon-warn">Fan is not settled in required time!</p>
|
||||
<div class="set_values">
|
||||
<div class="field">
|
||||
<div class="ofield">
|
||||
<div id="pr_div">
|
||||
<h3>Set pressure value</h3>
|
||||
<output class="set_output" id="set_press">10 Pa</output>
|
||||
<input class="slider" id="pressure" type="range" value="10" max="120" oninput="set_press.value = this.value + ' Pa'">
|
||||
<output class="set_output" id="set_press">0 Pa</output>
|
||||
<input class="slider" id="pressure" type="range" value="0" max="120" oninput="set_press.value = this.value + ' Pa'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -75,7 +69,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br><br>
|
||||
|
||||
</main>
|
||||
<aside>
|
||||
<p id="mon-warn">Fan is not settled in required time!</p>
|
||||
<div class="get_values">
|
||||
<fieldset id="monitor">
|
||||
<legend style="font-size: 20px;"><b>Monitor</b></legend>
|
||||
@ -116,28 +113,24 @@
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
<aside>
|
||||
</aside>
|
||||
</div>
|
||||
<br>
|
||||
<div class="lower">
|
||||
<div class="chart-container" id="chart-cont">
|
||||
<h2>Data History</h2>
|
||||
<br>
|
||||
<div class="chart-container">
|
||||
<span id="chart_warning" style="display:none; color: red;">Not enough data to show the chosen period. Showing all values.</span>
|
||||
<div class="dropdown">
|
||||
<label for="data">Select period:</label>
|
||||
<select name="data" id="data">
|
||||
<option value="0">All</option>
|
||||
<option value="1">10 min</option>
|
||||
<option value="2">30 min</option>
|
||||
<option value="3">60 min</option>
|
||||
</select>
|
||||
<span id="chart_warn">No data found for selected period.</span>
|
||||
<div class="filter">
|
||||
<label>Select period:</label><br>
|
||||
<label for="start-time">Start time:</label>
|
||||
<input type="datetime-local" id="start-time" name="start-time" min="" max="" value="">
|
||||
<label for="end-time">End time:</label>
|
||||
<input type="datetime-local" id="end-time" name="end-time" min="" max="" value="">
|
||||
<button id="btn_reset">Reset</button>
|
||||
</div>
|
||||
<canvas id="dataChart" width="600px" height="300px"></canvas>
|
||||
</div>
|
||||
<br><br>
|
||||
<div class="user-table">
|
||||
<div id="user-table">
|
||||
<h2>User Log History</h2>
|
||||
<table>
|
||||
<thead>
|
||||
@ -151,7 +144,6 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br><br>
|
||||
</aside>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -12,7 +12,15 @@ const mqtt = require('mqtt');
|
||||
const session = require('express-session');
|
||||
const bcrypt = require('bcrypt')
|
||||
|
||||
const client = mqtt.connect('mqtt://127.0.0.1:1883', {clientId: 'node_server', clean: true})
|
||||
const client = mqtt.connect('mqtt://192.168.1.254:1883',
|
||||
{username: 'SmartIotMQTT',
|
||||
password: 'SmartIot',
|
||||
clientId: 'node_server',
|
||||
clean: true,
|
||||
connectTimeout: 8000,
|
||||
reconnectPeriod: 1000,
|
||||
})
|
||||
//const client = mqtt.connect('mqtt://127.0.0.1:1883', {clientId: 'node_server', clean: true})
|
||||
let newData;
|
||||
let user;
|
||||
let msg;
|
||||
@ -46,14 +54,10 @@ function write(data, filePath) {
|
||||
}
|
||||
|
||||
function getTime(){
|
||||
let today = new Date();
|
||||
let day = ("0" + today.getDate()).slice(-2);
|
||||
let month = ("0" + (today.getMonth() + 1)).slice(-2);
|
||||
let hours = ("0" + today.getHours()).slice(-2);
|
||||
let mins = ("0" + today.getMinutes()).slice(-2);
|
||||
let secs = ("0" + today.getSeconds()).slice(-2);
|
||||
let timestamp = (day + '.' + month + '.' + today.getFullYear() + ' ' + hours + '.' + mins + '.' + secs).toString();
|
||||
return timestamp;
|
||||
let day = new Date();
|
||||
day = new Date(day.getTime() - day.getTimezoneOffset()*60000);
|
||||
let today = day.toISOString().replace('T', ' ').slice(0,19);
|
||||
return today;
|
||||
}
|
||||
|
||||
client.on('connect', ()=>{
|
||||
@ -62,14 +66,13 @@ client.on('connect', ()=>{
|
||||
|
||||
client.subscribe('controller/status', (err)=>{
|
||||
if(err){
|
||||
console.log('Subscription failed')
|
||||
console.log('Subscription failed ' + err);
|
||||
}
|
||||
});
|
||||
|
||||
io.on('connection', (socket)=>{
|
||||
console.log("User " + socket.id + " connected");
|
||||
socket.on('setting', (arg)=> {
|
||||
let data = JSON.stringify(arg);
|
||||
client.publish("controller/settings", JSON.stringify(arg), { qos: 2, retain: false }, (error)=>{
|
||||
if(error){
|
||||
console.log(error);
|
||||
@ -80,9 +83,6 @@ io.on('connection', (socket)=>{
|
||||
|
||||
client.on('message', async (topic, message) =>{
|
||||
newData = JSON.parse(message);
|
||||
console.log(newData);
|
||||
io.emit('data', newData);
|
||||
|
||||
let info = [];
|
||||
try {
|
||||
info = await read('data.json');
|
||||
@ -91,6 +91,7 @@ client.on('message', async (topic, message) =>{
|
||||
newData['ts'] = now;
|
||||
info.push(newData);
|
||||
write(info, 'data.json');
|
||||
io.emit('data', newData);
|
||||
});
|
||||
|
||||
|
||||
@ -98,15 +99,6 @@ app.get('/', (req, res)=>{
|
||||
res.sendFile(path.join(__dirname + '/index.html'));
|
||||
})
|
||||
|
||||
app.get('/data', async (req, res) => {
|
||||
try {
|
||||
const data = await read('data.json');
|
||||
res.json(data);
|
||||
} catch (e) {
|
||||
res.status(404).send(e);
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/register', (req,res)=>{
|
||||
res.send(`
|
||||
<h1>Register</h1>
|
||||
@ -132,14 +124,20 @@ app.post('/', async (req,res)=>{
|
||||
|
||||
if(bcrypt.compareSync(password, pwd)){
|
||||
let now = getTime();
|
||||
let d = now.slice(8,10);
|
||||
let m = now.slice(5,7);
|
||||
let y = now.slice(0,4);
|
||||
let t = now.slice(11, 19);
|
||||
let stamp = d + '.' + m + '.' + y + ' ' + t;
|
||||
//console.log(stamp);
|
||||
req.session.userId = username;
|
||||
req.session.startTime = now;
|
||||
req.session.startTime = stamp;
|
||||
console.log('Password is correct');
|
||||
user = req.session.userId;
|
||||
io.emit('user', user);
|
||||
sesUser = user;
|
||||
sesStart = req.session.startTime;
|
||||
res.status(205);
|
||||
res.redirect('/');
|
||||
}
|
||||
else{
|
||||
msg = 'wrong';
|
||||
@ -183,7 +181,12 @@ app.post('/register', async (req,res) =>{
|
||||
|
||||
app.post('/logout',async (req, res) =>{
|
||||
let now = getTime();
|
||||
req.session.endTime = now;
|
||||
let d = now.slice(8,10);
|
||||
let m = now.slice(5,7);
|
||||
let y = now.slice(0,4);
|
||||
let t = now.slice(11, 19);
|
||||
let stamp = d + '.' + m + '.' + y + ' ' + t;
|
||||
req.session.endTime = stamp;
|
||||
let sesEnd = req.session.endTime;
|
||||
let log = [];
|
||||
try {
|
||||
@ -196,6 +199,7 @@ app.post('/logout',async (req, res) =>{
|
||||
"Login": sesStart,
|
||||
"Logout": sesEnd
|
||||
}
|
||||
console.log(newLog);
|
||||
log.unshift(newLog);
|
||||
write(log, 'user_log.json');
|
||||
|
||||
@ -208,7 +212,7 @@ app.post('/logout',async (req, res) =>{
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
app.get('/data', async (req, res) => {
|
||||
try {
|
||||
const data = await read('data.json');
|
||||
@ -217,6 +221,5 @@ app.get('/data', async (req, res) => {
|
||||
res.status(404).send(e);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
*/
|
||||
server.listen(3000, () => console.log('Server listening on port 3000'));
|
||||
266
WebUI/main.js
266
WebUI/main.js
@ -1,3 +1,4 @@
|
||||
|
||||
const automode = document.getElementById('m_auto');
|
||||
const manmode = document.getElementById('m_man');
|
||||
const s_pressure = document.getElementById('pressure'); //slider
|
||||
@ -12,7 +13,10 @@ const canvas = document.getElementById('dataChart');
|
||||
const filter = document.getElementById('data');
|
||||
const submit = document.getElementById('btn_login');
|
||||
const log_out = document.getElementById('btn_log_out');
|
||||
let data_miss = false;
|
||||
const start = document.getElementById('start-time');
|
||||
const end = document.getElementById('end-time');
|
||||
const reset = document.getElementById('btn_reset');
|
||||
|
||||
let user;
|
||||
let pointerX = -1;
|
||||
let pointerY = -1;
|
||||
@ -21,18 +25,23 @@ let lastY = 0;
|
||||
let counter = 0;
|
||||
let lastSpeed = 0;
|
||||
let notSettled = 0;
|
||||
let day = new Date();
|
||||
day = new Date(day.getTime() - day.getTimezoneOffset()*60000);
|
||||
let today = day.toISOString().slice(0,16);
|
||||
start.value = today.replace('T', ' ') + ':00';
|
||||
end.value = today.replace('T', ' ') + ':00';
|
||||
let start_time = new Date(start.value).getTime();
|
||||
let end_time = new Date(end.value).getTime();
|
||||
|
||||
const socket = io();
|
||||
|
||||
socket.on('connection');
|
||||
socket.on('data', (data) =>{
|
||||
if(data.auto === true){
|
||||
s_pressure.value = data.setpoint;
|
||||
document.getElementById('set_press').value = s_pressure.value + ' Pa';
|
||||
if(data.error === true){
|
||||
document.getElementById('mon-warn').style.display = 'block';
|
||||
}
|
||||
if(data.auto === false){
|
||||
s_speed.value = data.setpoint;
|
||||
document.getElementById('set_speed').value = s_speed.value + ' %';
|
||||
else{
|
||||
document.getElementById('mon-warn').style.display = 'none';
|
||||
}
|
||||
g_pressure.value = data.pressure;
|
||||
g_co.value = data.co2;
|
||||
@ -40,16 +49,14 @@ socket.on('data', (data) =>{
|
||||
g_speed.value = data.speed;
|
||||
g_temp.value = data.temp;
|
||||
updateChart();
|
||||
checkData();
|
||||
checkFan();
|
||||
circleColor();
|
||||
});
|
||||
|
||||
socket.on('pwd', (data) =>{
|
||||
if(data){
|
||||
automode.checked = true;
|
||||
document.getElementById('login-form').style.display = "block";
|
||||
document.getElementById('pwd-warn').style.display = "block";
|
||||
sessionStorage.setItem('reload', true);
|
||||
document.location.reload();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@ -59,6 +66,32 @@ socket.on('user', (data) =>{
|
||||
sessionStorage.setItem('loggedIn', 'true');
|
||||
});
|
||||
|
||||
reset.addEventListener('click', e =>{
|
||||
e.preventDefault();
|
||||
start.value = today.replace('T', ' ') + ':00';
|
||||
end.value = today.replace('T', ' ') + ':00';
|
||||
start_time = new Date(start.value).getTime();
|
||||
end_time = new Date(end.value).getTime();
|
||||
|
||||
//start.value = today.replace('T', ' ') + ':00';
|
||||
//end.value = today.replace('T', ' ') + ':00';
|
||||
updateChart();
|
||||
})
|
||||
|
||||
start.addEventListener('change', e =>{
|
||||
e.preventDefault();
|
||||
start_time = start.value + ':00';
|
||||
start_time = new Date(start_time).getTime();
|
||||
updateChart();
|
||||
});
|
||||
|
||||
end.addEventListener('change', e =>{
|
||||
e.preventDefault();
|
||||
end_time = end.value + ':00';
|
||||
end_time = new Date(end_time).getTime();
|
||||
updateChart();
|
||||
});
|
||||
|
||||
s_pressure.addEventListener('input', e =>{
|
||||
e.preventDefault();
|
||||
sendPressure();
|
||||
@ -70,20 +103,34 @@ s_speed.addEventListener('input', e =>{
|
||||
});
|
||||
|
||||
automode.addEventListener('click', () =>{
|
||||
if(!sessionStorage.getItem('loggedIn')){
|
||||
document.getElementById('login-form').style.display = "block";
|
||||
document.getElementsByClassName('modes').style.display = "none";
|
||||
document.getElementsByClassName('set_values').style.display = "none";
|
||||
}
|
||||
else{
|
||||
document.getElementById('login-form').style.display = "none";
|
||||
|
||||
s_pressure.disabled = false;
|
||||
document.getElementById('pr_div').style.opacity = 1;
|
||||
|
||||
s_speed.disabled = true;
|
||||
document.getElementById('sp_div').style.opacity = 0.4;
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
manmode.addEventListener('click', () =>{
|
||||
if(!sessionStorage.getItem('loggedIn')){
|
||||
document.getElementById('login-form').style.display = "block";
|
||||
document.getElementById('sp_div').style.display = "none";
|
||||
document.getElementById('pr_div').style.display = "none";
|
||||
document.getElementById('m_auto').style.display = "none";
|
||||
document.getElementById('m_man').style.display = "none";
|
||||
document.getElementById('auto_label').style.display = "none";
|
||||
document.getElementById('man_label').style.display = "none";
|
||||
}
|
||||
else{
|
||||
document.getElementById('login-form').style.display = "none";
|
||||
document.getElementById('sp_div').style.opacity = 1;
|
||||
s_speed.disabled = false;
|
||||
|
||||
@ -92,11 +139,6 @@ manmode.addEventListener('click', () =>{
|
||||
}
|
||||
})
|
||||
|
||||
filter.addEventListener('change', e =>{
|
||||
e.preventDefault();
|
||||
updateChart();
|
||||
})
|
||||
|
||||
submit.addEventListener('click', e =>{
|
||||
if(document.getElementById('username').value && document.getElementById('password').value){
|
||||
document.getElementById('login-form').style.display = "none";
|
||||
@ -111,7 +153,8 @@ document.getElementById('password').addEventListener('click', ()=>{
|
||||
document.getElementById('form-warn').style.display = "none";
|
||||
});
|
||||
|
||||
log_out.addEventListener('click', ()=>{
|
||||
log_out.addEventListener('click', () =>{
|
||||
console.log('log out clicked');
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
})
|
||||
@ -155,20 +198,6 @@ function circleColor(){
|
||||
}
|
||||
}
|
||||
|
||||
function checkFan(){
|
||||
if(lastSpeed !== g_speed.value){
|
||||
notSettled += 1;
|
||||
lastSpeed = g_speed.value;
|
||||
}
|
||||
else{
|
||||
notSettled = 0;
|
||||
document.getElementById('mon-warn').style.display = 'none';
|
||||
}
|
||||
if(notSettled > 12){
|
||||
document.getElementById('mon-warn').style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
function logOutUser(){
|
||||
if(document.cookie){
|
||||
log_out.click();
|
||||
@ -182,7 +211,7 @@ document.onmousemove = function(event) {
|
||||
setInterval(activityCheck, 1000);
|
||||
|
||||
function activityCheck() {
|
||||
if(document.cookie){
|
||||
if(sessionStorage.getItem('loggedIn')){
|
||||
if(pointerX - lastX === 0 && pointerY - lastY === 0){
|
||||
counter = counter + 1;
|
||||
}
|
||||
@ -197,33 +226,64 @@ function activityCheck() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkMode(){
|
||||
function checkUser(){
|
||||
if(sessionStorage.getItem('reload')){
|
||||
document.getElementById('login-form').style.display = "block";
|
||||
document.getElementById('pwd-warn').style.display = "block";
|
||||
sessionStorage.removeItem('reload');
|
||||
}
|
||||
if(document.cookie && sessionStorage.getItem('loggedIn')){
|
||||
document.getElementById('login-form').style.display = "none";
|
||||
document.getElementById('user').style.display = "block";
|
||||
document.getElementById('user').innerHTML = 'Signed in user: ' + localStorage.getItem('user');
|
||||
document.getElementById('btn_log_out').style.display = "block";
|
||||
document.getElementById('user').style.display = "block";
|
||||
document.getElementById('user').innerHTML = 'Signed in user: ' + localStorage.getItem('user');
|
||||
document.getElementById('btn_log_out').style.display = "block";
|
||||
document.getElementById('user-table').style.width = "45%";
|
||||
document.getElementById('chart-cont').style.width = "50%";
|
||||
|
||||
manmode.checked = true;
|
||||
if(manmode.checked = true){
|
||||
s_pressure.disabled = true;
|
||||
document.getElementById('pr_div').style.opacity = 0.4;
|
||||
s_speed.disabled = false;
|
||||
}
|
||||
else{
|
||||
automode.checked = true;
|
||||
if(automode.checked = true){
|
||||
s_speed.disabled = true;
|
||||
document.getElementById('sp_div').style.opacity = 0.4;
|
||||
s_pressure.disabled = false;
|
||||
document.getElementById('user').style.display = "none";
|
||||
document.getElementById('btn_log_out').style.display = "none";
|
||||
}
|
||||
}
|
||||
else{
|
||||
document.getElementById('login-form').style.display = "block";
|
||||
document.getElementById('sp_div').style.display = "none";
|
||||
document.getElementById('pr_div').style.display = "none";
|
||||
document.getElementById('m_auto').style.display = "none";
|
||||
document.getElementById('m_man').style.display = "none";
|
||||
document.getElementById('auto_label').style.display = "none";
|
||||
document.getElementById('man_label').style.display = "none";
|
||||
document.getElementById('user-table').style.display = "none";
|
||||
document.getElementById('chart-cont').style.width = "95%";
|
||||
}
|
||||
}
|
||||
|
||||
function checkData(){
|
||||
if(data_miss){
|
||||
document.getElementById('chart_warning').style.display = "block";
|
||||
function checkMode(){
|
||||
if(document.cookie && sessionStorage.getItem('loggedIn')){
|
||||
automode.checked = true;
|
||||
s_speed.disabled = true;
|
||||
document.getElementById('sp_div').style.opacity = 0.4;
|
||||
document.getElementById('pr_div').style.opacity = 1;
|
||||
s_pressure.disabled = false;
|
||||
}
|
||||
if(!data_miss){
|
||||
document.getElementById('chart_warning').style.display = "none";
|
||||
else{
|
||||
document.getElementById('login-form').style.display = "block";
|
||||
document.getElementById('sp_div').style.display = "none";
|
||||
document.getElementById('pr_div').style.display = "none";
|
||||
document.getElementById('m_auto').style.display = "none";
|
||||
document.getElementById('m_man').style.display = "none";
|
||||
document.getElementById('auto_label').style.display = "none";
|
||||
document.getElementById('man_label').style.display = "none";
|
||||
document.getElementById('user-table').style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,6 +297,54 @@ function sendSpeed(){
|
||||
socket.emit('setting', speed);
|
||||
}
|
||||
|
||||
function updateChart(){
|
||||
async function fetchData(){
|
||||
const response = await fetch('data.json');
|
||||
const data = await response.json();
|
||||
if(data.length !== 0){
|
||||
let min = data[0].ts;
|
||||
let max = data[data.length-1].ts;
|
||||
start.min = min.slice(0, 16);
|
||||
start.max = max.slice(0, 16);
|
||||
end.min = min.slice(0, 16);
|
||||
end.max = max.slice(0, 16);
|
||||
}
|
||||
const datapoints = data.filter(d => {
|
||||
if((end_time-start_time) !== 0){
|
||||
return (new Date(d.ts).getTime() >= start_time && new Date(d.ts).getTime() <= end_time)
|
||||
}
|
||||
else{
|
||||
return data;
|
||||
}
|
||||
})
|
||||
return datapoints;
|
||||
};
|
||||
|
||||
fetchData().then(datapoints => {
|
||||
if(datapoints.length === 0)
|
||||
{
|
||||
document.getElementById('chart_warn').style.display = "block";
|
||||
}
|
||||
const time = datapoints.map((index) => {
|
||||
return index.ts;
|
||||
});
|
||||
const co = datapoints.map((index) => {
|
||||
return index.co2;
|
||||
});
|
||||
const pressure = datapoints.map((index) => {
|
||||
return index.pressure;
|
||||
});
|
||||
const rh = datapoints.map((index) => {
|
||||
return index.rh;
|
||||
});
|
||||
myChart.config.data.labels = time;
|
||||
myChart.config.data.datasets[0].data = co;
|
||||
myChart.config.data.datasets[1].data = pressure;
|
||||
myChart.config.data.datasets[2].data = rh;
|
||||
myChart.update();
|
||||
});
|
||||
};
|
||||
|
||||
const data = {
|
||||
datasets: [{
|
||||
label: 'CO2',
|
||||
@ -318,73 +426,13 @@ const config = {
|
||||
}
|
||||
|
||||
|
||||
}//,
|
||||
//aspectRatio: 1
|
||||
},
|
||||
aspectRatio: 2
|
||||
}
|
||||
};
|
||||
|
||||
const myChart = new Chart(canvas, config);
|
||||
|
||||
function updateChart(){
|
||||
async function fetchData(){
|
||||
let datasize = 0;
|
||||
let data_per_min = 12;
|
||||
let datapoints;
|
||||
await fetch('/data')
|
||||
.then(res => res.json())
|
||||
.then(data =>{
|
||||
console.log(data.length);
|
||||
datapoints = data.filter((elem, index)=>{
|
||||
switch(parseInt(filter.value))
|
||||
{
|
||||
case 0: //all
|
||||
datasize = data.length;
|
||||
break;
|
||||
case 1: //10min
|
||||
datasize = 10*data_per_min;
|
||||
break;
|
||||
case 2: //30min
|
||||
datasize = 30*data_per_min;
|
||||
break;
|
||||
case 3: //1 hour
|
||||
datasize = 60*data_per_min;
|
||||
break;
|
||||
}
|
||||
if(datasize > data.length){
|
||||
data_miss = true;
|
||||
}
|
||||
else{
|
||||
data_miss = false;
|
||||
}
|
||||
return index >= data.length -datasize;
|
||||
});
|
||||
});
|
||||
|
||||
return datapoints;
|
||||
};
|
||||
|
||||
fetchData().then(datapoints => {
|
||||
const time = datapoints.map((time) => {
|
||||
return time.ts;
|
||||
});
|
||||
const co = datapoints.map((time) => {
|
||||
return time.co2;
|
||||
});
|
||||
const pressure = datapoints.map((time) => {
|
||||
return time.pressure;
|
||||
});
|
||||
const rh = datapoints.map((time) => {
|
||||
return time.rh;
|
||||
});
|
||||
myChart.config.data.labels = time;
|
||||
myChart.config.data.datasets[0].data = co;
|
||||
myChart.config.data.datasets[1].data = pressure;
|
||||
myChart.config.data.datasets[2].data = rh;
|
||||
myChart.update();
|
||||
checkData();
|
||||
});
|
||||
};
|
||||
|
||||
fetch('user_log.json')
|
||||
.then((res)=>{
|
||||
return res.json();
|
||||
@ -404,8 +452,8 @@ fetch('user_log.json')
|
||||
placeholder.innerHTML = out;
|
||||
});
|
||||
|
||||
function getStartValues(){
|
||||
fetch('data.json')
|
||||
async function getStartValues(){
|
||||
await fetch('data.json')
|
||||
.then((res) =>{
|
||||
return res.json();
|
||||
})
|
||||
|
||||
@ -11,7 +11,7 @@ body {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
main {
|
||||
margin-top: 100px;
|
||||
margin-top: 50px;
|
||||
padding-bottom: 20px;
|
||||
display: block;
|
||||
position: relative;
|
||||
@ -21,11 +21,27 @@ main {
|
||||
aside {
|
||||
width: 100%;
|
||||
background-color: #F6FFF8;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.upper{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.lower{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
height: 100px;
|
||||
color: black;
|
||||
}
|
||||
h1 {
|
||||
padding-top: 40px;
|
||||
@ -51,12 +67,13 @@ h4{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown{
|
||||
position: relative;
|
||||
float: right;
|
||||
.filter{
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.logout{
|
||||
margin-left: 20px;
|
||||
margin-top: 35px;
|
||||
}
|
||||
#btn_log_out{
|
||||
margin-bottom: 10px;
|
||||
@ -68,6 +85,14 @@ h4{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#btn_reset{
|
||||
position: relative;
|
||||
float: right;
|
||||
border-radius: 5px;
|
||||
background-color: #CCE3DE;
|
||||
border: 0.5px solid;
|
||||
}
|
||||
|
||||
#user{
|
||||
display: none;
|
||||
font-weight: bolder;
|
||||
@ -77,6 +102,11 @@ h4{
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.login{
|
||||
margin-top: 50px;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
#login-form:valid #btn_login{
|
||||
background-color: mediumseagreen;
|
||||
}
|
||||
@ -89,6 +119,7 @@ h4{
|
||||
font-weight: bolder;
|
||||
border-radius: 10px;
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
#acc{
|
||||
@ -96,6 +127,12 @@ h4{
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#chart_warn{
|
||||
display: none;
|
||||
text-align: center;
|
||||
color: red;
|
||||
}
|
||||
|
||||
#mon-warn{
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
@ -120,9 +157,8 @@ h4{
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
margin: 20px;
|
||||
padding: 20px;
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
@ -176,7 +212,8 @@ fieldset {
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
.buttons{
|
||||
#buttons{
|
||||
display: block;
|
||||
font-size: 25px;
|
||||
font-weight: bolder;
|
||||
width: 12ch;
|
||||
@ -186,6 +223,7 @@ fieldset {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.set_values{
|
||||
@ -195,6 +233,10 @@ fieldset {
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.sp_div{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.get_values{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -226,30 +268,32 @@ fieldset {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.chart-container{
|
||||
position: relative;
|
||||
width: 700px;
|
||||
height: 350px;
|
||||
#chart-cont{
|
||||
display: block;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
canvas{
|
||||
border-radius: 10px;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
|
||||
}
|
||||
|
||||
.user-table{
|
||||
#user-table{
|
||||
display: block;
|
||||
margin-bottom: 50px;
|
||||
width: 50%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
table{
|
||||
background-color: #CCE3DE;
|
||||
width: 700px;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
@ -274,10 +318,13 @@ output {
|
||||
width: 50%;
|
||||
}
|
||||
aside {
|
||||
margin-top: 100px;
|
||||
margin-top: 50px;
|
||||
background: #F6FFF8;
|
||||
width: 50%;
|
||||
}
|
||||
.lower{
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
|
||||
@ -1,15 +1,75 @@
|
||||
[
|
||||
{
|
||||
"id": 15,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 18:51:43",
|
||||
"Logout": "27.10.2022 18:54:01"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"UserId": "Jaakko",
|
||||
"Login": "27.10.2022 16:59:26",
|
||||
"Logout": "27.10.2022 17:00:54"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 16:56:19",
|
||||
"Logout": "27.10.2022 16:59:03"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 16:54:23",
|
||||
"Logout": "27.10.2022 16:54:33"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 14:18:53",
|
||||
"Logout": "27.10.2022 14:19:30"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 14:17:45",
|
||||
"Logout": "27.10.2022 14:18:42"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 14:15:43",
|
||||
"Logout": "27.10.2022 14:16:01"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 14:14:49",
|
||||
"Logout": "27.10.2022 14:15:06"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 14:12:33",
|
||||
"Logout": "27.10.2022 14:14:10"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"UserId": "Miisa",
|
||||
"Login": "27.10.2022 13:29:52",
|
||||
"Logout": "27.10.2022 13:30:54"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"UserId": "Miisa",
|
||||
"Login": "25.10.2022 20.19.50",
|
||||
"Logout": "25.10.2022 20.19.55"
|
||||
"Login": "27.10.2022 08:10:40",
|
||||
"Logout": "27.10.2022 08:11:42"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"UserId": "Miisa",
|
||||
"Login": "25.10.2022 20.18.27",
|
||||
"Logout": "25.10.2022 20.18.43"
|
||||
"Login": "27.10.2022 07:55:06",
|
||||
"Logout": "27.10.2022 07:56:01"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user