-
-
-
Set fan speed
-
-
+
+
+
+
+
+
+
Set pressure value
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/WebUI/index.js b/WebUI/index.js
index 8cb9992..d15e1dc 100644
--- a/WebUI/index.js
+++ b/WebUI/index.js
@@ -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);
+ socket.on('setting', (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');
@@ -90,7 +90,8 @@ client.on('message', async (topic, message) =>{
let now = getTime();
newData['ts'] = now;
info.push(newData);
- write(info, 'data.json');
+ 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(`
Register
@@ -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'));
\ No newline at end of file
diff --git a/WebUI/main.js b/WebUI/main.js
index cb14330..c52753e 100644
--- a/WebUI/main.js
+++ b/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', () =>{
- document.getElementById('login-form').style.display = "none";
+ 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_pressure.disabled = false;
- document.getElementById('pr_div').style.opacity = 1;
-
- s_speed.disabled = true;
- document.getElementById('sp_div').style.opacity = 0.4;
+ 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('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{
+ 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,34 +226,65 @@ 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;
- s_pressure.disabled = true;
- document.getElementById('pr_div').style.opacity = 0.4;
- s_speed.disabled = false;
+ if(manmode.checked = true){
+ s_pressure.disabled = true;
+ document.getElementById('pr_div').style.opacity = 0.4;
+ s_speed.disabled = false;
+ }
+ if(automode.checked = true){
+ s_speed.disabled = true;
+ document.getElementById('sp_div').style.opacity = 0.4;
+ s_pressure.disabled = false;
+ }
}
else{
- 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";
+ 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;
+ }
+ 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";
}
- if(!data_miss){
- document.getElementById('chart_warning').style.display = "none";
- }
}
function sendPressure(){
@@ -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();
})
diff --git a/WebUI/style.css b/WebUI/style.css
index 8831f61..1011cfe 100644
--- a/WebUI/style.css
+++ b/WebUI/style.css
@@ -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"] {
diff --git a/WebUI/user_log.json b/WebUI/user_log.json
index 9104869..fefcb64 100644
--- a/WebUI/user_log.json
+++ b/WebUI/user_log.json
@@ -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,