diff --git a/consumerWebsite/functions/location.js b/consumerWebsite/functions/location.js index 4b5baf2..7671d12 100644 --- a/consumerWebsite/functions/location.js +++ b/consumerWebsite/functions/location.js @@ -1,4 +1,5 @@ const {locationModel} = require("../database/model/locationModel"); +const {Op} = require("sequelize"); async function getLocation() { const location = await locationModel.findAll(); @@ -35,7 +36,32 @@ async function deleteLocation(id) { }, }); } +/* +const { Op } = require("sequelize"); +var options = { + where: { + [Op.or]: [ + { 'subject': { [Op.like]: '%' + query + '%' } }, + { '$Comment.body$': { [Op.like]: '%' + query + '%' } } + ] + }, + include: [{ model: Comment }] +}; +*/ + +async function getLocationByName(name) { + const location = await locationModel.findAll({ + where: { + [Op.or]: [ + {name: {[Op.like]: "%" + name + "%"}}, + {added_by: {[Op.like]: "%" + name + "%"}}, + {description: {[Op.like]: "%" + name + "%"}}, + ], + }, + }); + return location; +} async function getLocationById(id) { const location = await locationModel.findAll({ @@ -51,5 +77,6 @@ module.exports = { addLocation, updateLocation, deleteLocation, + getLocationByName, getLocationById, }; \ No newline at end of file diff --git a/consumerWebsite/functions/sensor.js b/consumerWebsite/functions/sensor.js index a72512b..45419dd 100644 --- a/consumerWebsite/functions/sensor.js +++ b/consumerWebsite/functions/sensor.js @@ -1,4 +1,5 @@ const { sensorModel } = require("../database/model/sensorModel"); +const {Op} = require("sequelize"); async function getSensor() { const sensor = await sensorModel.findAll(); @@ -55,6 +56,33 @@ async function deleteSensor(id) { }, }); } +/* +async function getLocationByName(name) { + const location = await locationModel.findAll({ + where: { + [Op.or]: [ + {name: {[Op.like]: "%" + name + "%"}}, + {added_by: {[Op.like]: "%" + name + "%"}}, + {description: {[Op.like]: "%" + name + "%"}}, + ], + }, + }); + return location; +} +*/ +async function getSensorByName(name) { + const sensor = await sensorModel.findAll({ + where: { + [Op.or]: [ + {name: {[Op.like]: "%" + name + "%"}}, + {added_by: {[Op.like]: "%" + name + "%"}}, + {mac_address: {[Op.like]: "%" + name + "%"}}, + {description: {[Op.like]: "%" + name + "%"}}, + ], + }, + }); + return sensor; +} async function getSensorById(id) { const sensor = await sensorModel.findAll({ @@ -70,5 +98,6 @@ module.exports = { addSensor, updateSensor, deleteSensor, + getSensorByName, getSensorById, }; diff --git a/consumerWebsite/public/js/data.js b/consumerWebsite/public/js/data.js index 08bae23..cc69857 100644 --- a/consumerWebsite/public/js/data.js +++ b/consumerWebsite/public/js/data.js @@ -1,7 +1,6 @@ //getting button from DOM id const buttons = document.querySelectorAll(".button-container button"); const queryButton = document.getElementById("querybutton-container"); -const ctx = document.getElementById("dataChart").getContext("2d"); $(document).ready(async function () { //https://stackoverflow.com/questions/9045868/javascript-date-getweek @@ -12,143 +11,109 @@ $(document).ready(async function () { return Math.ceil(dayOfYear / 7); }; let date = new Date(); - var week = date.getWeek(); + var week = date.getWeek() - 1; // Subtracting 1 to get the actual week number var today = date.getDate(); var month = date.getMonth() + 1; // Adding 1 to get the actual month number var year = date.getFullYear(); - //year data - app.api.get("sensor-data/data?year=" + year, function (error, data) { - //console.log(data); - }); - //monthly data - app.api.get("sensor-data/data?month=" + month, function (error, data) { - //console.log(data); - }); - //weekly data - app.api.get( - "sensor-data/data?month=" + month + "&week=" + week, - function (error, data) { - //console.log(data); - } - ); - //daily data - app.api.get( - "sensor-data/data?month=" + month + "&week=" + week + "&day=" + today, - function (error, data) { - for (let rows of data) { - console.log(rows); - getDate(rows.CreatedAt); - } - } - ); -}); + // Initialize initialData for chart + const initialData = { + labels: [], // Array to store timestamps + datasets: [ + { + label: "Average MeasurementData", + data: [], // Array to store measurements objects + backgroundColor: "green", + borderColor: "green", + }, + ], + }; -function getDate(date){ - console.log(date); - -} - -/* - -(async function() { - const data = [ - { year: 2010, count: 10 }, - { year: 2011, count: 20 }, - { year: 2012, count: 15 }, - { year: 2013, count: 25 }, - { year: 2014, count: 22 }, - { year: 2015, count: 30 }, - { year: 2016, count: 28 }, - ]; - - new Chart( - document.getElementById('acquisitions'), - { - type: 'bar', - data: { - labels: data.map(row => row.year), - datasets: [ - { - label: 'Acquisitions by year', - data: data.map(row => row.count) - } - ] - } - } - ); -})(); -*/ -// Initial dataset (AQI) -const initialData = { - //date and time - labels: [ date.map(row => row.CreatedAt)], - datasets:[ - { - //data like psi - label: "Average PSI Data", - data: [], - backgroundColor: "green", - borderColor: "green", - }, - ], -}; - -//setting chart -const chart = new Chart(ctx, { - type: "bar", - data: initialData, - options: { - responsive: true, - title: { - display: true, - text: "HISTORICAL", - }, - subtitle: { - display: true, - text: "Historic air quality graph for Singapore", - }, - legend: { - display: false, - }, - tooltips: { - mode: "index", - intersect: false, - callbacks: { - label: function (tooltipItem, data) { - const label = data.labels[tooltipItem.index]; - return label + ": " + data.datasets[0].data[tooltipItem.index]; - }, + // Create Chart.js chart + const ctx = document.getElementById("DailyDataChart").getContext("2d"); + const chart = new Chart(ctx, { + type: "bar", + data: initialData, + options: { + responsive: true, + title: { + display: true, + text: "Average measurement metric data by Hour", }, }, - scales: { - xAxes: [ - { - barPercentage: 0.6, - categoryPercentage: 0.7, - ticks: { - autoSkip: true, - }, - maxRotation: 0, - minRotation: 0, - }, - ], - yAxes: [ - { - title: { - display: true, - text: "Value", - }, - }, - ], - }, - }, + }); + + // Function to update chart data based on button clicked + function updateChart(metric) { + const queryParams = `sensor-data/data?month=${month}&week=${week}&day=${today}`; + app.api.get(queryParams, function (error, data) { + // Clear previous data + initialData.labels = []; //timestamp + initialData.datasets[0].data = []; //measurement data dependinbg on metric + + // Group data by hour and calculate average value + const hourlyData = {}; + for (let row of data) { + //each row contains a timestamp and measurement data of each sensor and location + const createdAt = new Date(row.createdAt); //set to local time + const hourString = new Date( + createdAt.getFullYear(), + createdAt.getMonth(), + createdAt.getDate(), + createdAt.getHours() + ).toISOString(); + if (!hourlyData[hourString]) { + hourlyData[hourString] = []; + } + hourlyData[hourString].push(row.measurement[metric]); //pushing measurement data into hourlyData + } + + // Calculate average value for each hour + //console.log(hourlyData); //24 values for each hour of the day + for (let hourString in hourlyData) { + const averageValue = + hourlyData[hourString].reduce((acc, val) => acc + val, 0) / + hourlyData[hourString].length; + initialData.labels.push( + new Date(hourString).toLocaleString("en-US", { + timeZone: "UTC", + hour12: false, + }) + ); + initialData.datasets[0].data.push(averageValue); + } + + // Update chart + chart.update(); + }); + } + + // Event listeners for buttons + document.getElementById("psiButton").addEventListener("click", function () { + updateChart("psi"); + }); + + document.getElementById("tempButton").addEventListener("click", function () { + updateChart("temperature"); + }); + + document.getElementById("humButton").addEventListener("click", function () { + updateChart("humidity"); + }); + + document.getElementById("o3Button").addEventListener("click", function () { + updateChart("o3"); + }); + + document.getElementById("no2Button").addEventListener("click", function () { + updateChart("no2"); + }); + + document.getElementById("so2Button").addEventListener("click", function () { + updateChart("so2"); + }); + + document.getElementById("coButton").addEventListener("click", function () { + updateChart("co"); + }); }); - -queryButton.addEventListener("click", (event) => { - const clickedButton = event.target; - //console.log(clickedButton.id); - - //make it switch bar chart based on query button -}); - diff --git a/consumerWebsite/routes/location.js b/consumerWebsite/routes/location.js index cc7ce2b..3bfd08a 100644 --- a/consumerWebsite/routes/location.js +++ b/consumerWebsite/routes/location.js @@ -2,6 +2,7 @@ const { addLocation, getLocation, getLocationById, + getLocationByName, updateLocation, deleteLocation, } = require("../functions/location"); @@ -58,6 +59,19 @@ router.delete("/delete", async (req, res, next) => { } }); +//get location by name +router.get("/name/:name", async (req, res, next) => { + try { + //get params + const { name } = req.params; + const location = await getLocationByName(name); + res.status(200).json(location); + } catch (error) { + console.error(error); + next(error); + } +}); + //get location by id diff --git a/consumerWebsite/routes/sensor.js b/consumerWebsite/routes/sensor.js index dea9ca9..de48d2d 100644 --- a/consumerWebsite/routes/sensor.js +++ b/consumerWebsite/routes/sensor.js @@ -3,6 +3,7 @@ const { addSensor, updateSensor, deleteSensor, + getSensorByName, getSensorById } = require("../functions/sensor.js"); @@ -52,6 +53,16 @@ router.delete("/delete", async (req, res, next) => { next(error); } }); + +router.get("/name/:name", async (req, res, next) => { + try { + const sensor = await getSensorByName(req.params.name); + res.status(200).json(sensor); + } catch (error) { + console.error(error); + next(error); + } +}); router.get("/:id", async (req, res, next) => { try { const sensor = await getSensorById(req.params.id); diff --git a/consumerWebsite/views/top.ejs b/consumerWebsite/views/top.ejs index 708a3b0..c13aed9 100644 --- a/consumerWebsite/views/top.ejs +++ b/consumerWebsite/views/top.ejs @@ -42,12 +42,13 @@ - + + - + @@ -99,12 +100,6 @@