mp/consumerWebsite/functions/sensorData.js
newtbot c234aa3616 Add nodemailer configuration and console.log statement
Update formAJAX function to log data from the server
Add getUserByEmail and checkEmail functions
Update profile.ejs to require login
Update addSensorData function to emit new sensor data
Update api.css with styling changes
Update token route to generate and send token email
Update authChecker middleware to allow user and token routes
2024-01-27 04:52:02 +08:00

739 lines
18 KiB
JavaScript

const { Op, Sequelize } = require("sequelize");
const { sequelize } = require("../database/mySQL.js");
const { sensorDataModel } = require("../database/model/sensorDataModel.js");
const io = require('../functions/socket');
//helper function to convert month name to month number
//https://stackoverflow.com/questions/13566552/easiest-way-to-convert-month-name-to-month-number-in-js-jan-01
function getMonthFromString(mon) {
var d = Date.parse(mon + "1, 2012");
if (!isNaN(d)) {
return new Date(d).getMonth() + 1;
}
return -1;
}
async function getSensorData() {
const sensorData = await sensorDataModel.findAll();
return sensorData;
}
async function addSensorData(id_sensor, id_location, sensordata) {
const sensorData = await sensorDataModel.create({
sensorid: id_sensor,
locationid: id_location ,
measurement: sensordata.measurement,
});
//console.log("sensorData", sensorData);
//console.log("sensorData", sensordata.measurement);
io().emit('sensorData:new', sensordata)
return sensorData;
}
async function updateSensorData(id, id_sensor, id_location, sensordata) {
const sensorData = await sensorDataModel.update(
{
ensorid: id_sensor,
locationid: id_location,
measurement: sensordata,
},
{
where: {
id: id,
},
}
);
}
async function deleteSensorData(id) {
const sensorData = await sensorDataModel.destroy({
where: {
id: id,
},
});
}
async function getSensorDataById(id) {
const sensorData = await sensorDataModel.findAll({
where: {
id: id,
},
});
return sensorData;
}
async function getLatestData() {
const sensorData = await sensorDataModel.findAll({
limit: 6,
order: [["createdAt", "DESC"]],
});
return sensorData;
}
var ormQuery = {};
var whereClause = {};
var whereDate = {};
const allowedQuery = [
"limit",
"order",
"year",
"month",
"week",
"day",
"hour",
"minute",
"sensorid",
"locationid",
];
const validMonths = [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
];
//handle buildfunc for query
buildQuery = {
limit: async function (queryString) {
if (queryString.limit !== undefined) {
ormQuery.limit = parseInt(queryString.limit);
}
},
order: async function (queryString) {
if (queryString.order !== undefined) {
ormQuery = {
...ormQuery,
order: [["createdAt", queryString.order.toUpperCase()]],
};
}
},
year: async function (queryString) {
if (queryString.year !== undefined) {
//whereclause assign a value
whereClause.year = sequelize.where(
sequelize.fn("YEAR", sequelize.col("createdAt")),
queryString.year
);
}
},
month: async function (queryString) {
if (queryString.month !== undefined) {
if (validMonths.includes(queryString.month)) {
whereClause.month = sequelize.where(
sequelize.fn("MONTH", sequelize.col("createdAt")),
queryString.month
);
} else {
queryString.month = getMonthFromString(queryString.month)
whereClause.month = sequelize.where(
sequelize.fn("MONTH", sequelize.col("createdAt")),
queryString.month
);
}
}
},
week: async function (queryString) {
if (queryString.week !== undefined) {
whereClause.week = sequelize.where(
sequelize.fn("WEEK", sequelize.col("createdAt")),
queryString.week
);
}
},
day: async function (queryString) {
if (queryString.day !== undefined) {
whereClause.day = sequelize.where(
sequelize.fn("DAY", sequelize.col("createdAt")),
queryString.day
);
}
},
hour: async function (queryString) {
if (queryString.hour !== undefined) {
whereClause.hour = sequelize.where(
sequelize.fn("HOUR", sequelize.col("createdAt")),
queryString.hour
);
}
},
minute: async function (queryString) {
if (queryString.minute !== undefined) {
whereClause.minute = sequelize.where(
sequelize.fn("MINUTE", sequelize.col("createdAt")),
queryString.minute
);
}
},
sensorid: async function (queryString) {
if (queryString.sensorid !== undefined) {
whereClause.sensorid = sequelize.where(
sequelize.col("sensorid"),
queryString.sensorid
);
}
},
locationid: async function (queryString) {
if (queryString.locationid !== undefined) {
whereClause.locationid = sequelize.where(
sequelize.col("locationid"),
queryString.locationid
);
}
},
psi: async function (queryString) {
if (queryString.psi !== undefined && queryString.psi === "highest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.psi')"), "psi"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("psi"), "DESC"]],
limit: 10,
};
}
if (queryString.psi !== undefined && queryString.psi === "lowest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.psi')"), "psi"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("psi"), "ASC"]],
limit: 10,
};
}
},
co: async function (queryString) {
if (queryString.co !== undefined && queryString.co === "highest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.co')"), "co"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("co"), "DESC"]],
limit: 10,
};
}
if (queryString.co !== undefined && queryString.co === "lowest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.co')"), "co"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("co"), "ASC"]],
limit: 10,
};
}
},
o3: async function (queryString) {
if (queryString.o3 !== undefined && queryString.o3 === "highest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.o3')"), "o3"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("o3"), "DESC"]],
limit: 10,
};
}
if (queryString.o3 !== undefined && queryString.o3 === "lowest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.o3')"), "o3"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("o3"), "ASC"]],
limit: 10,
};
}
},
no2: async function (queryString) {
if (queryString.no2 !== undefined && queryString.no2 === "highest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.no2')"), "no2"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("no2"), "DESC"]],
limit: 10,
};
}
if (queryString.no2 !== undefined && queryString.no2 === "lowest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.no2')"), "no2"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("no2"), "ASC"]],
limit: 10,
};
}
},
so2: async function (queryString) {
if (queryString.so2 !== undefined && queryString.so2 === "highest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.so2')"), "so2"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("so2"), "DESC"]],
limit: 10,
};
}
if (queryString.so2 !== undefined && queryString.so2 === "lowest") {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[sequelize.literal("JSON_EXTRACT(measurement, '$.so2')"), "so2"],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("so2"), "ASC"]],
limit: 10,
};
}
},
humidity: async function (queryString) {
if (
queryString.humidity !== undefined &&
queryString.humidity === "highest"
) {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[
sequelize.literal("JSON_EXTRACT(measurement, '$.humidity')"),
"humidity",
],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("humidity"), "DESC"]],
limit: 10,
};
}
if (
queryString.humidity !== undefined &&
queryString.humidity === "lowest"
) {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[
sequelize.literal("JSON_EXTRACT(measurement, '$.humidity')"),
"humidity",
],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("humidity"), "ASC"]],
limit: 10,
};
}
},
windspeed: async function (queryString) {
if (
queryString.windspeed !== undefined &&
queryString.windspeed === "highest"
) {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[
sequelize.literal("JSON_EXTRACT(measurement, '$.windspeed')"),
"windspeed",
],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("windspeed"), "DESC"]],
limit: 10,
};
}
if (
queryString.windspeed !== undefined &&
queryString.windspeed === "lowest"
) {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[
sequelize.literal("JSON_EXTRACT(measurement, '$.windspeed')"),
"windspeed",
],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("windspeed"), "ASC"]],
limit: 10,
};
}
},
temperature: async function (queryString) {
if (
queryString.temperature !== undefined &&
queryString.temperature === "highest"
) {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[
sequelize.literal("JSON_EXTRACT(measurement, '$.temperature')"),
"temperature",
],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("temperature"), "DESC"]],
limit: 10,
};
}
if (
queryString.temperature !== undefined &&
queryString.temperature === "lowest"
) {
ormQuery = {
attributes: [
"id",
"sensorid",
"locationid",
[
sequelize.literal("JSON_EXTRACT(measurement, '$.temperature')"),
"temperature",
],
"createdAt",
],
group: ["id", "sensorid", "locationid"],
order: [[sequelize.literal("temperature"), "ASC"]],
limit: 10,
};
}
},
//average
avg: async function (queryString) {
if (queryString.avg !== undefined) {
ormQuery = {
attributes: [
//round to 2 decimal places
[
sequelize.fn(
"ROUND",
sequelize.fn(
"AVG",
Sequelize.literal(
`JSON_EXTRACT(measurement, '$.${queryString.avg}')`
)
),
2
),
"avg of " + queryString.avg,
],
],
};
}
},
sum: async function (queryString) {
if (queryString.sum !== undefined) {
ormQuery = {
attributes: [
[
sequelize.fn(
"SUM",
Sequelize.literal(
`JSON_EXTRACT(measurement, '$.${queryString.sum}')`
)
),
"sum of " + queryString.sum,
],
],
};
}
},
//total number of records
total: async function (queryString) {
if (queryString.total !== undefined) {
ormQuery = {
attributes: [
[sequelize.fn("COUNT", sequelize.col("id")), "total id / records"],
],
};
}
},
};
buildFunc = {
limit: async function (queryString) {
if (queryString.limit !== undefined) {
ormQuery.limit = parseInt(queryString.limit);
}
},
startdate: async function (queryString) {
if (queryString.startdate !== undefined) {
whereDate.startdate = new Date(queryString.startdate);
}
},
enddate: async function (queryString) {
if (queryString.enddate !== undefined) {
whereDate.enddate = new Date(queryString.enddate);
}
},
//total by startdate and enddate
total: async function (queryString) {
if (queryString.total !== undefined) {
ormQuery = {
attributes: [
[sequelize.fn("COUNT", sequelize.col("id")), "total id / records"],
],
};
}
},
//average
avg: async function (queryString) {
if (queryString.avg !== undefined) {
ormQuery = {
attributes: [
//round to 2 decimal places
[
sequelize.fn(
"ROUND",
sequelize.fn(
"AVG",
Sequelize.literal(
`JSON_EXTRACT(measurement, '$.${queryString.avg}')`
)
),
2
),
"avg of " + queryString.avg,
],
],
};
}
},
sum: async function (queryString) {
if (queryString.sum !== undefined) {
ormQuery = {
attributes: [
[
sequelize.fn(
"SUM",
Sequelize.literal(
`JSON_EXTRACT(measurement, '$.${queryString.sum}')`
)
),
"sum of " + queryString.sum,
],
],
};
}
},
//total number of records
total: async function (queryString) {
if (queryString.total !== undefined) {
ormQuery = {
attributes: [
[sequelize.fn("COUNT", sequelize.col("id")), "total id / records"],
],
};
}
},
};
async function getData(queryString) {
if (queryString.pagesize || queryString.page) {
//https://blog.bitsrc.io/pagination-with-sequelize-explained-83054df6e041
//pass pageSize taken from page=4 or default to 50
queryString.pagesize = queryString.pagesize || 50;
let offset = (queryString.page || 0) * queryString.pagesize;
queryString.limit = queryString.pagesize;
//reset keys in whereClause and ormQuery. else it will keep appending to the previous query
ormQuery = {};
whereClause = {};
whereDate = {};
for (let query in queryString) {
if (buildQuery[query]) {
await buildQuery[query](queryString);
}
}
if (!whereClause) {
return await sensorDataModel.findAll(ormQuery);
} else if (whereClause) {
console.log(whereClause);
console.log(ormQuery);
console.log(whereDate);
return await sensorDataModel.findAll({
limit: queryString.limit || 1000000,
//https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#limits-and-pagination
offset: parseInt(offset),
//The operators Op.and, Op.or and Op.not can be used to create arbitrarily complex nested logical comparisons.
//https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#examples-with-opand-and-opor
where: {
[Op.and]: [whereClause],
},
//only use where clause to lookup based on condition that i put into whereClause
...ormQuery,
});
}
} else {
//reset keys in whereClause and ormQuery. else it will keep appending to the previous query
ormQuery = {};
whereClause = {};
whereDate = {};
for (let query in queryString) {
if (buildQuery[query]) {
await buildQuery[query](queryString);
}
}
if (!whereClause) {
return await sensorDataModel.findAll(ormQuery);
} else if (whereClause) {
console.log(whereClause);
console.log(ormQuery);
console.log(whereDate);
return await sensorDataModel.findAll({
limit: queryString.limit || 1000000,
//The operators Op.and, Op.or and Op.not can be used to create arbitrarily complex nested logical comparisons.
//https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#examples-with-opand-and-opor
where: {
[Op.and]: [whereClause],
},
//only use where clause to lookup based on condition that i put into whereClause
...ormQuery,
});
}
}
}
async function getDatabyRange(queryString) {
if (queryString.pagesize || queryString.page) {
//https://blog.bitsrc.io/pagination-with-sequelize-explained-83054df6e041
//pass pageSize taken from page=4 or default to 50
queryString.pagesize = queryString.pagesize || 50;
let offset = (queryString.page || 0) * queryString.pagesize;
queryString.limit = queryString.pagesize;
whereDate = {};
for (let query in queryString) {
if (buildFunc[query]) {
await buildFunc[query](queryString);
}
}
if (whereClause) {
console.log(ormQuery);
console.log(whereDate);
return await sensorDataModel.findAll({
limit: queryString.limit || 1000000,
offset: offset,
//The operators Op.and, Op.or and Op.not can be used to create arbitrarily complex nested logical comparisons.
//https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#examples-with-opand-and-opor
where: {
createdAt: {
[Op.between]: [whereDate.startdate, whereDate.enddate],
},
},
//only use where clause to lookup based on condition that i put into whereClause
...ormQuery,
});
} else {
return "Invalid query";
}
} else {
whereDate = {};
for (let query in queryString) {
if (buildFunc[query]) {
await buildFunc[query](queryString);
}
}
if (whereClause) {
console.log(ormQuery);
console.log(whereDate);
return await sensorDataModel.findAll({
limit: queryString.limit || 1000000,
//The operators Op.and, Op.or and Op.not can be used to create arbitrarily complex nested logical comparisons.
//https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#examples-with-opand-and-opor
where: {
createdAt: {
[Op.between]: [whereDate.startdate, whereDate.enddate],
},
},
//only use where clause to lookup based on condition that i put into whereClause
...ormQuery,
});
} else {
return "Invalid query";
}
}
}
module.exports = {
getSensorData,
addSensorData,
updateSensorData,
deleteSensorData,
getSensorDataById,
getData,
getDatabyRange,
getLatestData,
};