Merge branch 'main' of https://gitlab.fdmci.hva.nl/propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-3/qaajeeqiinii59
This commit is contained in:
@@ -22,9 +22,13 @@ def getNodeInfoIndex():
|
|||||||
macAdress = request.args.get('macAdress', None)
|
macAdress = request.args.get('macAdress', None)
|
||||||
return getNodeInfo(macAdress)
|
return getNodeInfo(macAdress)
|
||||||
|
|
||||||
|
@app.route('/getQuestionData')
|
||||||
|
def getQuestionDataIndex():
|
||||||
|
return getQuestionData()
|
||||||
|
|
||||||
def updateData(node, name, location):
|
def updateData(node, name, location):
|
||||||
mydb = loginDB()
|
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 = mydb.cursor(dictionary=True) # Enable dictionary output
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
mydb.commit()
|
mydb.commit()
|
||||||
@@ -45,7 +49,7 @@ def loginDB():
|
|||||||
|
|
||||||
def getData(node, dataType, MAC):
|
def getData(node, dataType, MAC):
|
||||||
mydb = loginDB()
|
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 = mydb.cursor(dictionary=True) # Enable dictionary output
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
result = cursor.fetchall() # Fetch the results
|
result = cursor.fetchall() # Fetch the results
|
||||||
@@ -56,7 +60,18 @@ def getData(node, dataType, MAC):
|
|||||||
|
|
||||||
def getNodeInfo(macAdress):
|
def getNodeInfo(macAdress):
|
||||||
mydb = loginDB()
|
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 = mydb.cursor(dictionary=True) # Enable dictionary output
|
||||||
cursor.execute(query)
|
cursor.execute(query)
|
||||||
result = cursor.fetchall() # Fetch the results
|
result = cursor.fetchall() # Fetch the results
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
def get_query(node, dataType, MAC):
|
def get_query(node, dataType, MAC, questionID, replies):
|
||||||
if node and dataType:
|
if node and dataType:
|
||||||
query = f"SELECT * FROM Measurement WHERE NodeID = {node} AND Type = '{dataType}'"
|
query = f"SELECT * FROM Measurement WHERE NodeID = {node} AND Type = '{dataType}'"
|
||||||
elif node:
|
elif node:
|
||||||
@@ -7,12 +7,15 @@ def get_query(node, dataType, MAC):
|
|||||||
query = f"SELECT * FROM Measurement WHERE Type = '{dataType}'"
|
query = f"SELECT * FROM Measurement WHERE Type = '{dataType}'"
|
||||||
elif MAC:
|
elif MAC:
|
||||||
query = f"SELECT * FROM Node WHERE MAC = '{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:
|
else:
|
||||||
query = "SELECT * FROM `Measurement`"
|
query = "SELECT * FROM `Measurement`"
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def update_query(node, name, location):
|
def update_query(node, name, location):
|
||||||
if node and name and location:
|
if node and name and location:
|
||||||
query = f"""
|
query = f"""
|
||||||
|
79
web/newWebsite/graph-classes.js
Normal file
79
web/newWebsite/graph-classes.js
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
95
web/newWebsite/graph-main.js
Normal file
95
web/newWebsite/graph-main.js
Normal file
@@ -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);
|
@@ -6,6 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="styles/graph-styles.css">
|
<link rel="stylesheet" href="styles/graph-styles.css">
|
||||||
<title>Graphs</title>
|
<title>Graphs</title>
|
||||||
|
<script src="https://cdn.plot.ly/plotly-latest.min.js" charset="utf-8"></script>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||||
@@ -25,9 +26,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<script src="graph-main.js"></script>
|
<div id="graph1"></div>
|
||||||
|
|
||||||
<script src="graph-classes.js"></script>
|
<script src="graph-classes.js"></script>
|
||||||
|
<script src="graph-main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@@ -6,6 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="styles/dashboard-styles.css">
|
<link rel="stylesheet" href="styles/dashboard-styles.css">
|
||||||
<title>Gauges</title>
|
<title>Gauges</title>
|
||||||
|
<script src="https://cdn.plot.ly/plotly-latest.min.js" charset="utf-8"></script>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
|
|
||||||
<script src="https://cdn.plot.ly/plotly-latest.min.js" charset="utf-8"></script>
|
<script src="https://cdn.plot.ly/plotly-latest.min.js" charset="utf-8"></script>
|
||||||
<script src="GaugGroup.js"></script>
|
<script src="GaugGroup.js"></script>
|
||||||
|
<script src="graph-classes.js"></script>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
<script src="liveGraph.js"></script>
|
<script src="liveGraph.js"></script>
|
||||||
|
|
||||||
|
@@ -165,4 +165,29 @@ body {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
Reference in New Issue
Block a user