WIP routes data

This commit is contained in:
newtbot 2024-01-09 02:01:59 +08:00
parent c2dc608d5b
commit ce2b776920
4 changed files with 212 additions and 77 deletions

View File

@ -1,12 +1,19 @@
{
psi: '34', {
humidity: '11%', "id": 1,
o3: '326ppm', "sensorid": 1,
no2: '445ppm', "locationid": 1,
so2: '511ppm', "measurement": {
co: '16ppm', "co": 8,
temperature: '25°C', "o3": 89,
windspeed: '2km/h', "no2": 31,
time: '2023-12-21 14:24:44', "psi": 34,
region: 'east' "so2": 17,
} "humidity": 86,
"windspeed": 10,
"temperature": 26
},
"createdAt": "2023-01-01T16:00:00.000Z",
"updatedAt": "2024-01-05T11:34:10.000Z"
},

View File

@ -2,7 +2,7 @@ const { sequelize } = require("../../Database/mySql.js");
const { locationModel } = require("../../Database/model/locationModel.js"); const { locationModel } = require("../../Database/model/locationModel.js");
const { sensorModel } = require("../../Database/model/sensorModel.js"); const { sensorModel } = require("../../Database/model/sensorModel.js");
const { sensorDataModel } = require("../../Database/model/sensorDataModel.js"); const { sensorDataModel } = require("../../Database/model/sensorDataModel.js");
const { Op } = require("sequelize"); const { Op, where, or } = require("sequelize");
//helper function to convert month name to month number //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 //https://stackoverflow.com/questions/13566552/easiest-way-to-convert-month-name-to-month-number-in-js-jan-01
@ -175,6 +175,7 @@ async function getData(query) {
let ormQuery = {}; let ormQuery = {};
let whereClause = {}; let whereClause = {};
let whereNest = {}; let whereNest = {};
let whereDate = {};
if (query.limit !== undefined && query.order !== undefined) if (query.limit !== undefined && query.order !== undefined)
ormQuery = { ormQuery = {
@ -194,7 +195,11 @@ async function getData(query) {
query.hour || query.hour ||
query.minute || query.minute ||
query.sensorid || query.sensorid ||
query.locationid query.locationid ||
query.startdate ||
query.enddate
//get specific data like psi or wtv
) { ) {
if (query.limit !== undefined && query.order !== undefined) if (query.limit !== undefined && query.order !== undefined)
ormQuery = { ormQuery = {
@ -266,6 +271,15 @@ async function getData(query) {
query.minute query.minute
); );
} }
if (query.startdate) {
let startdate = new Date(query.startdate);
whereDate.startdate = startdate;
}
if (query.enddate) {
let enddate = new Date(query.enddate);
whereDate.enddate = enddate;
}
if (query.sensorid) { if (query.sensorid) {
whereNest.sensorid = sequelize.where( whereNest.sensorid = sequelize.where(
sequelize.col("sensorid"), sequelize.col("sensorid"),
@ -380,32 +394,84 @@ async function getData(query) {
}; };
} }
//get specific data like psi or wtv
//range of date values
if (!whereClause) { if (!whereClause) {
return await sensorDataModel.findAll(ormQuery); return await sensorDataModel.findAll(ormQuery);
} else { } else if (whereClause && whereNest) {
console.log(whereClause); console.log(whereClause);
console.log(whereNest); console.log(whereNest);
console.log(whereDate);
console.log(query); console.log(query);
console.log(ormQuery); console.log(ormQuery);
return await sensorDataModel.findAll({ return await sensorDataModel.findAll({
//The operators Op.and, Op.or and Op.not can be used to create arbitrarily complex nested logical comparisons. //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 //https://sequelize.org/docs/v6/core-concepts/model-querying-basics/#examples-with-opand-and-opor
where: { where: {
[Op.and]: [whereNest, whereClause], [Op.and]: [whereNest, whereClause],
createdAt: {
//https://stackoverflow.com/questions/43115151/sequelize-query-to-find-all-records-that-falls-in-between-date-range
[Op.between]: [whereDate.startdate, whereDate.enddate],
},
}, },
//only use where clause to lookup based on condition that i put into whereClause //only use where clause to lookup based on condition that i put into whereClause
//where: whereClause,
...ormQuery, ...ormQuery,
}); });
} }
} }
/*
async function getdataFilter(query) {
let ormQuery = {};
//get highest and lowest data of measurement from all data
if (query.psi !== undefined && query.psi === "highest") {
ormQuery = {
where: sequelize.where(
sequelize.fn("JSON_EXTRACT", sequelize.col("measurement"), "$.psi"),
//sequelize.fn('JSON_EXTRACT', sequelize.col('aa.bb.field'), sequelize.literal(`'$.attr'`))
sequelize.literal(`'$$.type'`),
//max value of psi
sequelize.fn("MAX", sequelize.col("measurement.psi"))
),
};
}
console.log(ormQuery);
return await sensorDataModel.findAll(ormQuery);
}
/*
sequelize.fn('JSON_EXTRACT', sequelize.col('aa.bb.field'), sequelize.literal(`'$.attr'`))
else if (query.hour !== undefined) {
ormQuery = {
where: sequelize.where(
sequelize.fn("HOUR", sequelize.col("createdAt")),
query.hour
),
...ormQuery,
};
}
*/
/*' ormQuery = {
order: [sequelize.fn("max", sequelize.col("measurement.psi::int"))],
limit: 1,
};
sequelize.literal('(SELECT MAX(`measurement`->>"$.psi") FROM `sensorData`)'),
'max_psi'
if (query.highest) {
//[sequelize.fn("max", sequelize.col("measurement.psi")), "max_psi"],
ormQuery = {
attributes: [
[sequelize.fn("max", sequelize.col("measurement")), "max"],
],
};
}
*/ */
@ -426,4 +492,5 @@ module.exports = {
deleteSensorData, deleteSensorData,
getSensorDataById, getSensorDataById,
getData, getData,
getdataFilter,
}; };

View File

@ -7,7 +7,7 @@ const {
deleteSensorData, deleteSensorData,
getSensorDataById, getSensorDataById,
getData, getData,
getdataFilter,
} = require("../functions/apiDatabase.js"); } = require("../functions/apiDatabase.js");
const express = require("express"); const express = require("express");
@ -27,8 +27,8 @@ router.get("/", async (req, res, next) => {
router.post("/new", async (req, res, next) => { router.post("/new", async (req, res, next) => {
try { try {
const { id, id_sensor, id_location, sensordata } = req.body; const { id, id_sensor, id_location, sensordata } = req.body;
await addSensorData(id , id_sensor , id_location , sensordata); await addSensorData(id, id_sensor, id_location, sensordata);
res.sendStatus(200).json({message: "SensorData " + id + " added" }); res.sendStatus(200).json({ message: "SensorData " + id + " added" });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
next(error); next(error);
@ -37,8 +37,8 @@ router.post("/new", async (req, res, next) => {
router.put("/update", async (req, res, next) => { router.put("/update", async (req, res, next) => {
try { try {
const { id , id_sensor , id_location , sensordata } = req.body; const { id, id_sensor, id_location, sensordata } = req.body;
await updateSensorData( id , id_sensor , id_location , sensordata ); await updateSensorData(id, id_sensor, id_location, sensordata);
res.status(200).json({ message: "SensorData " + id + " updated" }); res.status(200).json({ message: "SensorData " + id + " updated" });
} catch (error) { } catch (error) {
console.error(error); console.error(error);
@ -57,7 +57,6 @@ router.delete("/delete", async (req, res, next) => {
} }
}); });
router.get("/data", async (req, res, next) => { router.get("/data", async (req, res, next) => {
try { try {
let query = { let query = {
@ -90,12 +89,23 @@ router.get("/data", async (req, res, next) => {
//minute //minute
minute: req.query.minute, minute: req.query.minute,
//start date
startdate: req.query.startdate,
//end date
enddate: req.query.enddate,
/*
//highest or lowest of psi, co, o3, no2, so2, humidity, windspeed, temperature
highest: req.query.highest,
//highest or lowest of psi, co, o3, no2, so2, humidity, windspeed, temperature
lowest: req.query.lowest,
*/
}; };
const data = await getData(query); const data = await getData(query);
res.status(200).json(data); res.status(200).json(data);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
next(error); next(error);
@ -103,6 +113,28 @@ router.get("/data", async (req, res, next) => {
}); });
router.get("/filter", async (req, res, next) => {
try {
const query = {
psi: req.query.psi,
co: req.query.co,
o3: req.query.o3,
no2: req.query.no2,
so2: req.query.so2,
humidity: req.query.humidity,
windspeed: req.query.windspeed,
temperature: req.query.temperature,
};
const data = await getdataFilter(query);
res.status(200).json(data);
} catch (error) {
console.error(error);
next(error);
}
});
router.get("/:id", async (req, res, next) => { router.get("/:id", async (req, res, next) => {
try { try {
const sensor = await getSensorDataById(req.params.id); const sensor = await getSensorDataById(req.params.id);
@ -114,3 +146,30 @@ router.get("/:id", async (req, res, next) => {
}); });
module.exports = router; module.exports = router;
/*
**Aggregate Sensor Data (e.g., Average PSI):**
- **Route:** `GET /api/v0/sensor-data/aggregate`
- **Query Parameter:** `metric` (e.g., `psi`, `co`, `o3`)
- **Description:** Calculate aggregate metrics for the specified parameter.
**Filter Sensor Data by Measurement Values:**
- **Route:** `GET /api/v0/sensor-data/filter`
- **Query Parameters:** `min_psi`, `max_psi`, `min_co`, `max_co`, etc. temp and humidity too
- **Description:** Retrieve sensor data entries within specified measurement value ranges.
*/
/*
"measurement": {
"co": 8,
"o3": 89,
"no2": 31,
"psi": 34,
"so2": 17,
"humidity": 86,
"windspeed": 10,
"temperature": 26
},
*/

2
api.MD
View File

@ -153,4 +153,6 @@ Hour = 1 or wtv
//strong optional chaining //strong optional chaining
curl 'http://localhost/api/v0/sensor-data/data?year=2023&month=1&week=1&day=1&sensorid=1&locationid=1' curl 'http://localhost/api/v0/sensor-data/data?year=2023&month=1&week=1&day=1&sensorid=1&locationid=1'
http://localhost/api/v0/sensor-data/data?startdate=2023-01-01T00:00:00.000&enddate=2023-01-03T&sensorid=1&locationid=1
//get specific data //get specific data