Merge branch 'main' of gitlab.fdmci.hva.nl:propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-3/qaajeeqiinii59
This commit is contained in:
@@ -42,7 +42,7 @@ void loop() {
|
||||
}
|
||||
|
||||
void websocketSetup(){
|
||||
WiFiMulti.addAP("iotroam", "vbK9gbDBIB");
|
||||
WiFiMulti.addAP("iotroam", "BcgrFpX3kl");
|
||||
WiFiMulti.addAP("ObsidianAmstelveen", "drijversstraatmaastricht");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
@@ -67,7 +67,7 @@ void screenButtonHandler(){
|
||||
displayText.writeText(Question[i], 3, 0, 0, 0, true, false);
|
||||
displayText.writeText(Answer[i], 3, 0, 200, 0, true, true);
|
||||
}
|
||||
|
||||
// 0 is best 2 is worst
|
||||
if (redButton == HIGH){
|
||||
sendData(questionID, "0");
|
||||
}
|
||||
|
BIN
docs/assets/imagesSp3/retrosprint3.jpg
Normal file
BIN
docs/assets/imagesSp3/retrosprint3.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 MiB |
@@ -1,110 +1,138 @@
|
||||
# Original Version (by bram)
|
||||
# Original Database - Websocket connection(by bram)
|
||||
For our project, we needed to establish an efficient and functional connection between a live data collector and a database where this data would be stored.
|
||||
|
||||
The data we collected originated from live "nodes" which were small boxes equipped with various types of sensors to gather specific data from their surroundings.
|
||||
|
||||
This collected data needed to be transmitted to a database to facilitate its presentation on a website we were developing. The website would retrieve the data from the database and display it in various formats.
|
||||
|
||||
Given the critical nature of this data connection for our project, it was imperative that it functioned reliably. Bram was tasked with designing a connection in Python between the WebSocket (live server) and the database (data storage).
|
||||
|
||||
Since we had the WebSocket data on a Raspberry Pi, it made sense to implement the connection on the Pi itself. This presented an opportunity for Bram to acquire knowledge about Python, considering he initially lacked experience with this programming language.
|
||||
## Python code + explaination
|
||||
In the given Raspberry Pi, a file named "data.py" was created, from which this script could be called when needed.
|
||||
|
||||
We wanted to make a working connection between our websocket wich runs all the data gatherd by our nodes and a live feed to our database.
|
||||
So we set out to make this connection using python.
|
||||
|
||||
At first we needed to import the folowing librarys:
|
||||
|
||||
```js
|
||||
// everything is running async so the code can run together and not interfere with eachother.
|
||||
At the beginning of the file, the code starts with importing the different required libraries.
|
||||
```py
|
||||
#this library makes functions run simultaneously
|
||||
import asyncio
|
||||
#This library makes the connection to the websocket possible.
|
||||
import websockets
|
||||
// a library to connect to the database.
|
||||
#This library makes a connection with the database
|
||||
import mysql.connector
|
||||
#This library makes json data readable.
|
||||
import json
|
||||
```
|
||||
|
||||
Then we began the process of connecting with both the websocket and the database.
|
||||
|
||||
First-off, we began making a connection to the database by using a mysql library in wich we gave the log in in order to connect to our ow database.
|
||||
|
||||
```js
|
||||
//the data that has to be pushed needs to be
|
||||
Afterward, a function would be called related to the "mysql.connector" library, where you would provide the login credentials of the database you have set up to establish a solid connection. This connection will be utilized multiple times later in the code.
|
||||
```py
|
||||
#async is making use of the asyncio library.
|
||||
async def process_data(data):
|
||||
try:
|
||||
mydb = mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="*****",
|
||||
password="*********",
|
||||
database="*******"
|
||||
user="root",
|
||||
# pasword hidden for privacy
|
||||
password="********",
|
||||
database="NodeData"
|
||||
)
|
||||
cursor = mydb.cursor()
|
||||
```
|
||||
This next part has a lot of different functions, so it will be split up for clarity.
|
||||
|
||||
It begins with creating a variable to retrieve information from a specific part of the database. This information is then stored in an array later on. In this case, it is selecting the existing MAC addresses from the database.
|
||||
|
||||
Afterward, a query is made for a different part of the code and acts as a "mold" for the data to be sent to the database. The values are not inserted yet because these will be the data collected from the nodes.
|
||||
```py
|
||||
#variable to connect to the DB
|
||||
MACDataReading = mydb.cursor()
|
||||
#get data from DB
|
||||
MACDataReading.execute("SELECT MAC FROM Node")
|
||||
#make a mold for the data to get to the DB
|
||||
query = "INSERT INTO `Measurement` (NodeID, Type, Value) VALUES (%s, %s, %s)"
|
||||
```
|
||||
In the next part of the code, the data collected from the node (which is done later on) is processed here and made readable for the Python code.
|
||||
|
||||
This processed data is then split up into five different types: the temperature, the humidity, the eCO2 and TVOC values, and the MAC address from which this information was sent.
|
||||
|
||||
The MAC address is then taken and turned into a tuple. This is done because the database expects a tuple to be inserted instead of a string.
|
||||
|
||||
(for more information on tuples I suggest visiting https://www.w3schools.com/python/python_tuples.asp)
|
||||
```py
|
||||
#load the json data and make it readable.
|
||||
processedData = json.loads(data)
|
||||
#divide the data into types
|
||||
processedTemp = (processedData['Temp'])
|
||||
processedHumi = (processedData['Humi'])
|
||||
processedeCO2 = (processedData['eCO2'])
|
||||
processedTvoc = (processedData['TVOC'])
|
||||
processedMAC = (processedData['node'])
|
||||
#make a tuple of the MAC by placing a comma.
|
||||
MACTuple = (processedMAC,)
|
||||
```
|
||||
|
||||
Then after this we code in the infromation we want to put inside of the database.
|
||||
The data collected from the websocket is json data, so this has to be changed.
|
||||
Coming back to the previous lines of code, the data which was first asked for is now gathered and put into an array.
|
||||
|
||||
```js
|
||||
//Making a variable for the database connection
|
||||
cursor = mydb.cursor()
|
||||
//Making a variable for the database connection
|
||||
MACDataReading = mydb.cursor()
|
||||
//find the correct section and interact with it.
|
||||
MACDataReading.execute("SELECT MAC FROM Node")
|
||||
//the query for what needs to be inserted into the database ( atleast where it has to go).
|
||||
query = "INSERT INTO `Measurement` (NodeID, Type, Value) VALUES (%s, %s, %s)"
|
||||
//the recieved data from the websocket is json data so needs to be changed.
|
||||
processedData = json.loads(data)
|
||||
//variables about the recieved data points.
|
||||
processedTemp = (processedData['Temp'])
|
||||
processedHumi = (processedData['Humi'])
|
||||
processedECo = (processedData['eCO2'])
|
||||
processedTvoc = (processedData['TVOC'])
|
||||
processedMAC = (processedData['node'])
|
||||
//change the recieved macadress to a tuple.
|
||||
MACTuple = (processedMAC,)
|
||||
//fetch the data from the database an[d put it in an array.
|
||||
MACDataFetching = MACDataReading.fetchall()
|
||||
MACArray = list(MACDataFetching)
|
||||
This array is then examined, and all the data is compared to the newly obtained MAC address.
|
||||
|
||||
//see if the fetched data is not in the gotten array.
|
||||
//otehrwise insert it into the database directly.
|
||||
if MACTuple not in MACArray:
|
||||
addingNode = "INSERT INTO `Node` (MAC) VALUES (%s)"
|
||||
cursor.execute(addingNode, MACTuple)
|
||||
mydb.commit()
|
||||
//the websocket data that needs to be sent to the database.
|
||||
pushingDataArray = [(1, "Temp", processedTemp), (1, "Humi", processedHumi), (1, "eCO2", processedECo), (1, "TVOC", processedTvoc)]
|
||||
// forloop, go allong the array.
|
||||
for i in pushingDataArray:
|
||||
print(query ,i)
|
||||
cursor.execute(query, i)
|
||||
mydb.commit()
|
||||
// show me the error it there is one.
|
||||
If it is not found, then the new MAC address is added to the database. This makes automation much easier and makes the process of adding a new node easy.
|
||||
```py
|
||||
#fetching data and adding to an array.
|
||||
MACDataFetching = MACDataReading.fetchall()
|
||||
MACArray = list(MACDataFetching)
|
||||
#see if the given MAC is not in the array.
|
||||
if MACTuple not in MACArray:
|
||||
#a query to insert the new MAC in the DB
|
||||
addingNode = "INSERT INTO `Node` (MAC) VALUES (%s)"
|
||||
#combine the query and the data and push it.
|
||||
cursor.execute(addingNode, MACTuple)
|
||||
mydb.commit()
|
||||
```
|
||||
From here the data which was collected from the websocket gets placed in an array together with a few guidlines to propperly place it in the correct files on the database.
|
||||
|
||||
After going along all instances of the array, the data gets pushed together with the query to propperly enter the database.
|
||||
|
||||
Sadly this version of the code is only able to push the data from the one node because of some errors within the datase.
|
||||
(This is later fixed in the updated version my teammate made.)
|
||||
```py
|
||||
#making an array with the data to sort it and be able to be pushed to the database.
|
||||
pushingDataArray = [(1, "Temp", processedTemp), (1, "Humi", processedHumi), (1, "eCO2", processedeCO2), (1, "TVOC", processedTvoc)]
|
||||
#go along all instances in the array, and combine this with the query.
|
||||
for i in pushingDataArray:
|
||||
print(query ,i)
|
||||
cursor.execute(query, i)
|
||||
mydb.commit()
|
||||
#in the case of an error, show what and where, and after, close the database connection.
|
||||
except mysql.connector.Error as err:
|
||||
print("MySQL Error:", err)
|
||||
finally:
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
```
|
||||
In the next function, the connection is established with the WebSocket and collects the data sent by the nodes. This data is then stored in a variable named "data". (This data is the same data that was being processed to make it readable for Python and was split up in differnt types.)
|
||||
|
||||
After fully connecting t othe database, making statements of what to put there and telling the code what to do, we ofcourse need to write the code to connect to the weebsocket.
|
||||
We begin by telling our websocket id and what type of port we are using.
|
||||
Then we will collect live data from the conected websocket, store it in a variable, and then in the previous code
|
||||
|
||||
```js
|
||||
//here the connection to the websocked is made
|
||||
This function also verifies if the WebSocket connection can be established and provides an error message when this is not the case.
|
||||
```py
|
||||
async def receive_data():
|
||||
uri = "****************"
|
||||
uri = "ws://145.92.8.114/ws"
|
||||
|
||||
try:
|
||||
async with websockets.connect(uri) as websocket:
|
||||
while True:
|
||||
// the data collected from the websocket is.
|
||||
data = await websocket.recv()
|
||||
// data recieved: conformation.
|
||||
print(f"Received data: {data}")
|
||||
await process_data(data)
|
||||
// error sowing.
|
||||
except websockets.ConnectionClosedError as e:
|
||||
print("WebSocket connection closed:", e)
|
||||
|
||||
```
|
||||
This is one of the last functions where the file is instructed to wait for a WebSocket connection before executing the code. This is done to prevent false data from entering the database.
|
||||
```py
|
||||
async def main():
|
||||
await receive_data()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
As a summary, this code is meant to establish connections both to the database and the WebSocket to enable a data connection between them. When new data arrives, it will be pushed to the database, and if a new MAC address is encountered, it will be added to the list of addresses.
|
||||
|
||||
(The link to the code https://gitlab.fdmci.hva.nl/propedeuse-hbo-ict/onderwijs/2023-2024/out-a-se-ti/blok-3/qaajeeqiinii59/-/blob/main/server/web-data-connection/data.py?ref_type=heads)
|
||||
|
||||
# New Version (by sietse)
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 19 KiB |
@@ -11,14 +11,14 @@ class QuestionCreationClass {
|
||||
label: 'Responses',
|
||||
data: this.data,
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.2)',
|
||||
'rgba(54, 162, 235, 0.2)',
|
||||
'rgba(255, 206, 86, 0.2)'
|
||||
'rgba(255, 206, 86, 0.2)',
|
||||
'rgba(255, 99, 132, 0.2)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(255, 99, 132, 1)',
|
||||
'rgba(54, 162, 235, 1)',
|
||||
'rgba(255, 206, 86, 1)'
|
||||
'rgba(255, 206, 86, 1)',
|
||||
'rgba(255, 99, 132, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
|
Reference in New Issue
Block a user