Merge branch '43-als-gebruiker-wil-ik-een-grafiek-hebben-met-live-data-zodat-de-dat-van-de-laatste-paar-minuten' into 'main'
Resolve "Als gebruiker wil ik een grafiek hebben met live data, zodat de dat van de laatste paar minuten live kan terugzien en veranderingen beter zie" Closes #43 See merge request propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-3/qaajeeqiinii59!5
This commit is contained in:
56
docs/brainstorm/SoftwareDocumentatie/graph_classes.md
Normal file
56
docs/brainstorm/SoftwareDocumentatie/graph_classes.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Graphs
|
||||
|
||||
## Introduction
|
||||
|
||||
The graphs are used to display the data from the sensors. The data is collected by the raspberry pi and then displayed on the graphs. The graphs are made using the [plotly library](https://plotly.com/javascript/) .
|
||||
|
||||
## Requirements
|
||||
|
||||
### Live graphs
|
||||
- Every node has to have a live graph
|
||||
- The graphs has to be updated every 5 seconds
|
||||
- All the data from one node has to fit in one graph
|
||||
|
||||
|
||||
## Class diagrams
|
||||
|
||||
### Live graphs
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class liveGraph {
|
||||
+nodeId
|
||||
+cnt
|
||||
+timeArray
|
||||
+tempArray
|
||||
+humiArray
|
||||
+eco2Array
|
||||
+tvocArray
|
||||
makeGraph()
|
||||
updateGraph()
|
||||
updateData()
|
||||
}
|
||||
```
|
||||
|
||||
## Order of operations
|
||||
|
||||
### Live graphs
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Node
|
||||
participant Raspberry pi
|
||||
participant Website
|
||||
|
||||
Node->>Raspberry pi: sensordata via websocket every 5 seconds
|
||||
Raspberry pi->>Website: Node data via websocket if new data is received from the node
|
||||
Website->>Website: updateGraph()
|
||||
Website->>Website: updateData()
|
||||
```
|
||||
|
||||
1. Every node sends its data to the raspberry pi via websocket every 5 seconds
|
||||
2. The raspberry pi sends the data to the website via websocket if new data is received from the node
|
||||
3. The website updates the data coming from the raspberry pi on its own variables and arrays
|
||||
4. The website updates the live graphs every time new data is received from the websocket
|
||||
|
||||
|
@@ -9,9 +9,9 @@ class liveGraph {
|
||||
this.cnt = 0;
|
||||
this.nodeId = "liveGraph" + id;
|
||||
}
|
||||
|
||||
// Fuction to create a graph
|
||||
makeGraph() {
|
||||
// Create a new line for temperature
|
||||
Plotly.plot(this.nodeId, [
|
||||
{
|
||||
x: this.timeArray, // Use timeArray as x values
|
||||
@@ -21,6 +21,7 @@ class liveGraph {
|
||||
name: "Temperature",
|
||||
},
|
||||
]);
|
||||
// Create a new line for humidity
|
||||
Plotly.plot(this.nodeId, [
|
||||
{
|
||||
x: this.timeArray, // Use timeArray as x values
|
||||
@@ -30,6 +31,7 @@ class liveGraph {
|
||||
name: "Humidity",
|
||||
},
|
||||
]);
|
||||
// Create a new line for eCO2
|
||||
Plotly.plot(this.nodeId, [
|
||||
{
|
||||
x: this.timeArray, // Use timeArray as x values
|
||||
@@ -39,6 +41,7 @@ class liveGraph {
|
||||
name: "eCO2 / 10",
|
||||
},
|
||||
]);
|
||||
// Create a new line for TVOC
|
||||
Plotly.plot(this.nodeId, [
|
||||
{
|
||||
x: this.timeArray, // Use timeArray as x values
|
||||
@@ -50,7 +53,7 @@ class liveGraph {
|
||||
]);
|
||||
}
|
||||
|
||||
// Function to update the graph with new values
|
||||
// Function to update the graph with new values got from updateData function
|
||||
updateGraph() {
|
||||
let time = new Date();
|
||||
this.timeArray.push(new Date());
|
||||
@@ -71,7 +74,7 @@ class liveGraph {
|
||||
Plotly.relayout(this.nodeId, 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);
|
||||
|
89
web/main.js
89
web/main.js
@@ -1,13 +1,17 @@
|
||||
// Description: Main JavaScript file for the web application.
|
||||
// arrays and stuff
|
||||
const sensorData = {};
|
||||
let intervalDelay = 1000;
|
||||
// Create WebSocket connection.
|
||||
const socket = new WebSocket("ws://145.92.8.114/ws");
|
||||
let liveGraphs = [];
|
||||
|
||||
// letiables
|
||||
let intervalDelay = 5000;
|
||||
let amountOfNodes = 3;
|
||||
|
||||
const socket = new WebSocket("ws://145.92.8.114/ws");
|
||||
function openConnection() {
|
||||
// Open connection
|
||||
socket.addEventListener("open", (event) => {
|
||||
console.log("Connected to the WebSocket server");
|
||||
socket.send("Hello Server!");
|
||||
});
|
||||
|
||||
// Error handling
|
||||
@@ -35,14 +39,11 @@ function openConnection() {
|
||||
// Attempt to reconnect
|
||||
setTimeout(openConnection, 1000); // Retry after 1 second
|
||||
});
|
||||
console.log("Connected to the WebSocket server!!!!!!!!");
|
||||
console.log("Connected to the WebSocket server");
|
||||
}
|
||||
|
||||
// Open the connection
|
||||
openConnection();
|
||||
|
||||
|
||||
|
||||
function handleIncomingData(data) {
|
||||
nodeNumber = data.node;
|
||||
temperature = data.Temp;
|
||||
@@ -80,16 +81,7 @@ function processNodeData(nodeNumber, temperature, humidity, CO2, TVOC) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function pushArray(array) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
array.push(Math.random() * 10);
|
||||
}
|
||||
}
|
||||
|
||||
//function for making the html elements for the following html code
|
||||
|
||||
function nodeData(data, node) {
|
||||
let nodeData = document.createElement("div");
|
||||
nodeData.innerHTML = data;
|
||||
@@ -100,46 +92,46 @@ function nodeData(data, node) {
|
||||
|
||||
function createNodeData(node) {
|
||||
// Create main div
|
||||
var nodeData = document.createElement("div");
|
||||
let nodeData = document.createElement("div");
|
||||
nodeData.className = "nodeData";
|
||||
|
||||
// Create flex-NodeData div
|
||||
var flexNodeData = document.createElement("div");
|
||||
let flexNodeData = document.createElement("div");
|
||||
flexNodeData.className = "flex-NodeData";
|
||||
|
||||
// Create p element
|
||||
var pNode = document.createElement("p");
|
||||
let pNode = document.createElement("p");
|
||||
pNode.textContent = "Node " + node;
|
||||
|
||||
// Append p to flex-NodeData
|
||||
flexNodeData.appendChild(pNode);
|
||||
|
||||
// Create flex-LiveData div
|
||||
var flexLiveData = document.createElement("div");
|
||||
let flexLiveData = document.createElement("div");
|
||||
flexLiveData.className = "flex-LiveData";
|
||||
|
||||
// Create data divs (Temperature, Humidity, Light Intensity)
|
||||
var dataTypes = ["Temperatuur", "Luchtvochtigheid", "CO2", "TVOC"];
|
||||
var ids = ["temperature", "humidity", "CO2", "TVOC"];
|
||||
var statusIds = ["tempStatus", "humidStatus", "CO2Status", "TVOCStatus"];
|
||||
let dataTypes = ["Temperatuur", "Luchtvochtigheid", "CO2", "TVOC"];
|
||||
let ids = ["temperature", "humidity", "CO2", "TVOC"];
|
||||
let statusIds = ["tempStatus", "humidStatus", "CO2Status", "TVOCStatus"];
|
||||
|
||||
for (var i = 0; i < dataTypes.length; i++) {
|
||||
var dataDiv = document.createElement("div");
|
||||
for (let i = 0; i < dataTypes.length; i++) {
|
||||
let dataDiv = document.createElement("div");
|
||||
|
||||
var dataTypeDiv = document.createElement("div");
|
||||
let dataTypeDiv = document.createElement("div");
|
||||
dataTypeDiv.textContent = dataTypes[i] + ": ";
|
||||
|
||||
var pElement = document.createElement("p");
|
||||
let pElement = document.createElement("p");
|
||||
pElement.id = ids[i] + node;
|
||||
pElement.textContent = "Not connected";
|
||||
|
||||
dataTypeDiv.appendChild(pElement);
|
||||
dataDiv.appendChild(dataTypeDiv);
|
||||
|
||||
var statusElement = document.createElement("div");
|
||||
let statusElement = document.createElement("div");
|
||||
statusElement.className = "statusElement";
|
||||
|
||||
var statusText = document.createElement("p");
|
||||
let statusText = document.createElement("p");
|
||||
statusText.className = "statusText";
|
||||
statusText.id = statusIds[i];
|
||||
statusText.textContent = "Not connected";
|
||||
@@ -154,15 +146,15 @@ function createNodeData(node) {
|
||||
flexNodeData.appendChild(flexLiveData);
|
||||
|
||||
// Create flex-graph div
|
||||
var flexGraph = document.createElement("div");
|
||||
let flexGraph = document.createElement("div");
|
||||
flexGraph.className = "flex-graph";
|
||||
|
||||
var graphDiv = document.createElement("div");
|
||||
let graphDiv = document.createElement("div");
|
||||
|
||||
var graphP = document.createElement("p");
|
||||
let graphP = document.createElement("p");
|
||||
graphP.textContent = "Live graph:";
|
||||
|
||||
var liveGraph = document.createElement("div");
|
||||
let liveGraph = document.createElement("div");
|
||||
liveGraph.id = "liveGraph" + node;
|
||||
|
||||
graphDiv.appendChild(graphP);
|
||||
@@ -176,7 +168,7 @@ function createNodeData(node) {
|
||||
nodeData.appendChild(flexNodeData);
|
||||
|
||||
// Check if nodeDataLocation element exists
|
||||
var nodeDataLocation = document.getElementById("nodeDataLocation");
|
||||
let nodeDataLocation = document.getElementById("nodeDataLocation");
|
||||
if (nodeDataLocation) {
|
||||
// Append main div to nodeDataLocation
|
||||
nodeDataLocation.appendChild(nodeData);
|
||||
@@ -198,23 +190,18 @@ function updateNodeData(node, temperature, humidity, eCO2, TVOC) {
|
||||
document.getElementById("CO2Status").textContent = "Connected";
|
||||
document.getElementById("TVOCStatus").textContent = "Connected";
|
||||
|
||||
// Update the graph`
|
||||
graphNode1.updateData(temperature, humidity, eCO2, TVOC);
|
||||
graphNode1.updateGraph();
|
||||
// Update the graph
|
||||
liveGraphs[node - 1].updateData(temperature, humidity, eCO2, TVOC);
|
||||
liveGraphs[node - 1].updateGraph();
|
||||
}
|
||||
|
||||
// Call the function to create the HTML structure
|
||||
createNodeData(1);
|
||||
createNodeData(2);
|
||||
createNodeData(3);
|
||||
createNodeData(4);
|
||||
for (let i = 1; i <= amountOfNodes; i++) {
|
||||
createNodeData(i);
|
||||
liveGraphs.push(new liveGraph(i));
|
||||
}
|
||||
|
||||
// Create a new liveGraph object
|
||||
let graphNode1 = new liveGraph(1);
|
||||
|
||||
graphNode1.makeGraph();
|
||||
|
||||
let graphNode2 = new liveGraph(2);
|
||||
|
||||
graphNode2.makeGraph();
|
||||
// openConnection();
|
||||
// make the graphs
|
||||
liveGraphs.forEach((graph) => {
|
||||
graph.makeGraph();
|
||||
});
|
@@ -33,11 +33,6 @@ p1 {
|
||||
text-align: begin;
|
||||
}
|
||||
|
||||
.apiGraph{
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.statusElement{
|
||||
display:inline-block;
|
||||
border: solid #1f82d3 2px;
|
||||
@@ -50,35 +45,6 @@ p1 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* body{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-content: center;
|
||||
} */
|
||||
|
||||
#randomShit{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-content: center;
|
||||
border: 2px solid purple;
|
||||
|
||||
}
|
||||
|
||||
#nodeDataLocation{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
/* justify-content: center; */
|
||||
/* align-content: center; */
|
||||
border: 4px solid blue;
|
||||
/* padding-bottom: 50%; */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.flex-NodeData {
|
||||
display: flex;
|
||||
margin-left: 1%;
|
||||
@@ -87,21 +53,33 @@ p1 {
|
||||
/* height: 40%; */
|
||||
flex-direction: column;
|
||||
border: 3px solid #1f82d3;
|
||||
/* border-radius: 20px; */
|
||||
border-radius: 20px;
|
||||
/* width: 90%; */
|
||||
/* border: 2px solid red; */
|
||||
/* margin-right: 90%; */
|
||||
/* width: 150vh; */
|
||||
/* padding-right: 40%; */
|
||||
/* padding-left: 40%; */
|
||||
}
|
||||
|
||||
#nodeDataLocation{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
border: 4px solid rgb(0, 0, 255);
|
||||
/* padding-bottom: 50%; */
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nodeData {
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
flex-direction: row;
|
||||
margin-bottom: 2%;
|
||||
margin-top: 1%;
|
||||
|
||||
/* border: 2px solid red; */
|
||||
}
|
||||
|
||||
@@ -113,8 +91,6 @@ justify-content: left;
|
||||
justify-content: space-evenly;
|
||||
gap: 5px;
|
||||
padding: 10px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user