2024-03-29 19:36:14 +01:00
7 changed files with 229 additions and 8 deletions

View File

@@ -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

View File

@@ -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"""

View 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);
}
}

View 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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -166,3 +166,28 @@ body {
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;
}