diff --git a/server/Flask/main.py b/server/Flask/main.py index c185937..7232c81 100644 --- a/server/Flask/main.py +++ b/server/Flask/main.py @@ -22,9 +22,13 @@ def getNodeInfoIndex(): macAdress = request.args.get('macAdress', None) return getNodeInfo(macAdress) +@app.route('/getQuestionData') +def getQuestionDataIndex(): + return getQuestionData() + def updateData(node, name, location): mydb = loginDB() - query = update_query(node, name, location) + query = update_query(node, name, location, False, False) cursor = mydb.cursor(dictionary=True) # Enable dictionary output cursor.execute(query) mydb.commit() @@ -45,7 +49,7 @@ def loginDB(): def getData(node, dataType, MAC): mydb = loginDB() - query = get_query(node, dataType, MAC) + query = get_query(node, dataType, MAC, False, False) cursor = mydb.cursor(dictionary=True) # Enable dictionary output cursor.execute(query) result = cursor.fetchall() # Fetch the results @@ -56,7 +60,18 @@ def getData(node, dataType, MAC): def getNodeInfo(macAdress): mydb = loginDB() - query = get_query(False, False, macAdress) + query = get_query(False, False, macAdress, False, False) + cursor = mydb.cursor(dictionary=True) # Enable dictionary output + cursor.execute(query) + result = cursor.fetchall() # Fetch the results + cursor.close() + mydb.close() + + return result + +def getQuestionData(): + mydb = loginDB() + query = get_query(False, False, False, True, False) cursor = mydb.cursor(dictionary=True) # Enable dictionary output cursor.execute(query) result = cursor.fetchall() # Fetch the results diff --git a/server/Flask/queries.py b/server/Flask/queries.py index e2da308..cd85146 100644 --- a/server/Flask/queries.py +++ b/server/Flask/queries.py @@ -1,4 +1,4 @@ -def get_query(node, dataType, MAC): +def get_query(node, dataType, MAC, questionID, replies): if node and dataType: query = f"SELECT * FROM Measurement WHERE NodeID = {node} AND Type = '{dataType}'" elif node: @@ -7,12 +7,15 @@ def get_query(node, dataType, MAC): query = f"SELECT * FROM Measurement WHERE Type = '{dataType}'" elif MAC: query = f"SELECT * FROM Node WHERE MAC = '{MAC}'" + elif replies and questionID: + query = f"SELECT * FROM Reply WHERE QuestionID = '{questionID}'" + elif questionID: + query = f"SELECT * FROM Question" else: query = "SELECT * FROM `Measurement`" return query - def update_query(node, name, location): if node and name and location: query = f""" diff --git a/web/newWebsite/graph-classes.js b/web/newWebsite/graph-classes.js new file mode 100644 index 0000000..200b0f0 --- /dev/null +++ b/web/newWebsite/graph-classes.js @@ -0,0 +1,79 @@ +class Graph{ + constructor(id) { + this.id = "graph" + id; + this.timeArray = []; + } + + // Function to create a graph + makeGraph(line, lineColor, name) { + let lineArray; + switch (line) { + case "temp": + lineArray = this.tempArray; + break; + case "humi": + lineArray = this.humiArray; + break; + case "eco2": + lineArray = this.eco2Array; + break; + case "tvoc": + lineArray = this.tvocArray; + break; + default: + console.error("Invalid line"); + } + this.timeArray.push(new Date()); + Plotly.plot(this.id, [ + { + x: this.timeArray, + y: lineArray, + mode: "lines", + line: { color: lineColor }, + name: name, + }, + ]); + } +} + +class LiveGraph extends Graph{ + // Constructor to initialize the graph + constructor(id){ + super(id); + this.tempArray = []; + this.humiArray = []; + this.eco2Array = []; + this.tvocArray = []; + this.cnt = 0; + } + // Function to update the graph with new values got from updateData function + updateGraph() { + let time = new Date(); + this.timeArray.push(new Date()); + + let update = { + x: [[this.timeArray]], + y: [[this.tempArray], [this.humiArray], [this.eco2Array], [this.tvocArray]] + }; + + let olderTime = time.setMinutes(time.getMinutes() - 1); + let futureTime = time.setMinutes(time.getMinutes() + 1); + let minuteView = { + xaxis: { + type: "date", + range: [olderTime, futureTime], + }, + }; + Plotly.relayout(this.id, minuteView); + if (this.cnt === 10) clearInterval(interval); + } + // function to get the new data for graph + updateData(temperature, humidity, eCO2, TVOC) { + // Update the graph + this.tempArray.push(temperature); + this.humiArray.push(humidity); + this.eco2Array.push(eCO2 / 10); + this.tvocArray.push(TVOC / 10); + } + } + diff --git a/web/newWebsite/graph-main.js b/web/newWebsite/graph-main.js new file mode 100644 index 0000000..3eb71ae --- /dev/null +++ b/web/newWebsite/graph-main.js @@ -0,0 +1,95 @@ +// Sample data - you can replace this with your actual dataset +const data = [ + { node: 'A', timestamp: '2022-01-01 08:00:00', temperature: 25, humidity: 50, eco2: 400, tvoc: 1 }, + { node: 'B', timestamp: '2022-01-01 09:00:00', temperature: 26, humidity: 45, eco2: 450, tvoc: 2 }, + { node: 'A', timestamp: '2022-01-01 08:00:00', temperature: 24, humidity: 55, eco2: 500, tvoc: 3 }, + { node: 'B', timestamp: '2022-01-01 09:00:00', temperature: 27, humidity: 40, eco2: 550, tvoc: 4 }, + { node: 'A', timestamp: '2022-01-01 08:00:00', temperature: 23, humidity: 60, eco2: 600, tvoc: 5 }, + { node: 'B', timestamp: '2022-01-01 09:00:00', temperature: 25, humidity: 50, eco2: 650, tvoc: 6 } + ]; + + // Function to filter data based on user input + function filterData(data, startDate, endDate, nodes, selectedFields) { + const filteredData = data.filter(item => { + const timestamp = new Date(item.timestamp); + return timestamp >= startDate && timestamp <= endDate && nodes.includes(item.node); + }).map(item => { + const filteredItem = { node: item.node, timestamp: item.timestamp }; + selectedFields.forEach(field => { + filteredItem[field] = item[field]; + }); + return filteredItem; + }); + return filteredData; + } + + // Create HTML input elements for user input + // Include checkboxes for each data field + const temperatureCheckbox = createCheckBox('temperature', 'Temperature'); + const humidityCheckbox = createCheckBox('humidity', 'Humidity'); + const eco2Checkbox = createCheckBox('eco2', 'eCO2'); + const tvocCheckbox = createCheckBox('tvoc', 'TVOC'); + + // Create a checkbox element with label + function createCheckBox(id, label) { + const checkbox = document.createElement('input'); + checkbox.setAttribute('type', 'checkbox'); + checkbox.setAttribute('id', id); + checkbox.setAttribute('class', 'checkbox'); + + const checkboxLabel = document.createElement('label'); + checkboxLabel.setAttribute('for', id); + checkboxLabel.textContent = label; + + return { checkbox, checkboxLabel }; + } + + const startDateInput = document.createElement('input'); + startDateInput.setAttribute('type', 'datetime-local'); + startDateInput.setAttribute('id', 'start-date'); + startDateInput.setAttribute('class', 'input-field'); + + const endDateInput = document.createElement('input'); + endDateInput.setAttribute('type', 'datetime-local'); + endDateInput.setAttribute('id', 'end-date'); + endDateInput.setAttribute('class', 'input-field'); + + const nodeInput = document.createElement('input'); + nodeInput.setAttribute('type', 'text'); + nodeInput.setAttribute('placeholder', 'Enter node (A, B, etc.)'); + nodeInput.setAttribute('id', 'node-input'); + nodeInput.setAttribute('class', 'input-field'); + + const filterButton = document.createElement('button'); + filterButton.textContent = 'Filter Data'; + filterButton.setAttribute('class', 'filter-button'); + filterButton.addEventListener('click', () => { + const startDate = new Date(document.getElementById('start-date').value); + const endDate = new Date(document.getElementById('end-date').value); + const selectedNodes = document.getElementById('node-input').value.split(',').map(node => node.trim()); + + const selectedFields = []; + const checkboxes = [temperatureCheckbox, humidityCheckbox, eco2Checkbox, tvocCheckbox]; + checkboxes.forEach(checkbox => { + if (checkbox.checkbox.checked) { + selectedFields.push(checkbox.checkbox.id); + } + }); + + const filteredData = filterData(data, startDate, endDate, selectedNodes, selectedFields); + console.log(filteredData); + }); + + // Append input elements to the document body + document.body.appendChild(startDateInput); + document.body.appendChild(endDateInput); + document.body.appendChild(nodeInput); + document.body.appendChild(temperatureCheckbox.checkbox); + document.body.appendChild(temperatureCheckbox.checkboxLabel); + document.body.appendChild(humidityCheckbox.checkbox); + document.body.appendChild(humidityCheckbox.checkboxLabel); + document.body.appendChild(eco2Checkbox.checkbox); + document.body.appendChild(eco2Checkbox.checkboxLabel); + document.body.appendChild(tvocCheckbox.checkbox); + document.body.appendChild(tvocCheckbox.checkboxLabel); + document.body.appendChild(filterButton); \ No newline at end of file diff --git a/web/newWebsite/graphs.html b/web/newWebsite/graphs.html index 975f041..0629172 100644 --- a/web/newWebsite/graphs.html +++ b/web/newWebsite/graphs.html @@ -6,6 +6,7 @@ Graphs + @@ -25,9 +26,10 @@ - - +
+ + \ No newline at end of file diff --git a/web/newWebsite/index.html b/web/newWebsite/index.html index 854fcd6..dfe847a 100644 --- a/web/newWebsite/index.html +++ b/web/newWebsite/index.html @@ -6,6 +6,7 @@ Gauges + @@ -30,6 +31,7 @@ + diff --git a/web/newWebsite/styles/graph-styles.css b/web/newWebsite/styles/graph-styles.css index 8ad355d..ec79d48 100644 --- a/web/newWebsite/styles/graph-styles.css +++ b/web/newWebsite/styles/graph-styles.css @@ -165,4 +165,29 @@ body { color: #fff; text-decoration: none; font-size: 18px; -} \ No newline at end of file +} + +.input-field { + margin: 10px; + padding: 5px; + border: 1px solid #ccc; + border-radius: 5px; + } + + .checkbox { + margin-right: 5px; + } + + .filter-button { + margin: 10px; + padding: 5px 10px; + background-color: #007bff; + color: #fff; + border: none; + border-radius: 5px; + cursor: pointer; + } + + .filter-button:hover { + background-color: #0056b3; + } \ No newline at end of file