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:
@@ -11,6 +11,8 @@ nav:
|
||||
- TFT screen : node-documentation/TFT-screen
|
||||
- Classes : arduino-documentation/classes
|
||||
- Node Documentation: node-documentation/node
|
||||
- Node Class: node-documentation/NodeClassDocumentation
|
||||
- Node Uml Diagram: node-documentation/NodeClassUml
|
||||
- 🍓 RPi Documentation:
|
||||
- Raspberry pi: Sp1SchetsProject/InfrastructuurDocumentatie/raspberryPi
|
||||
- MariaDB: rpi-documentation/mariadb-installation
|
||||
|
@@ -10,35 +10,35 @@ Then I came across a teaching site (https://www.codingkids.nl/arduino-buzzer.htm
|
||||
### Arduino Video
|
||||
I watched a video about using Arduino and took a lot of op notes along the way.
|
||||
The link is: (https://www.youtube.com/watch?v=BLrHTHUjPuw).
|
||||
```
|
||||
// $Arduino information:
|
||||
|
||||
\/\/Arduino information:
|
||||
//pinnumber(locatie, in-/output)
|
||||
|
||||
\/pinnumber(locatie, in-/output)
|
||||
//digitalwrite(locatie, high/low)
|
||||
|
||||
\/digitalwrite(locatie, high/low)
|
||||
//delay(time in millisec)
|
||||
|
||||
\/delay(time in millisec)
|
||||
//int... <- variable
|
||||
|
||||
\/int... <- variable
|
||||
//with a decimal its a double -> 1,2
|
||||
|
||||
\/with a decimal its a double -> 1,2
|
||||
//a character is a char -> "a"
|
||||
|
||||
\/a character is a char -> "a"
|
||||
// $serial communications:
|
||||
|
||||
\/\/serial communications:
|
||||
|
||||
\/setup:
|
||||
setup:
|
||||
Serial.begin(9600) -> the text speed
|
||||
Serial.sprintLn(text)
|
||||
|
||||
\/Loop:
|
||||
Loop:
|
||||
Serial.print("text")
|
||||
Serial.printLn(....) -> variable because no "
|
||||
|
||||
\/Ctrl + shift + M = serial monitor.
|
||||
//Ctrl + shift + M = serial monitor.
|
||||
The text speed needs to be the same as given.
|
||||
|
||||
\/\/If Statements:
|
||||
// $If Statements:
|
||||
|
||||
if(condition){
|
||||
|
||||
@@ -50,9 +50,9 @@ if(condition){
|
||||
|
||||
}
|
||||
|
||||
\/&& = "and"
|
||||
// && = "and"
|
||||
|
||||
\/|| = "or"
|
||||
// || = "or"
|
||||
|
||||
\/\/For loops:
|
||||
|
||||
@@ -62,20 +62,20 @@ For(int*i; i <= 10 ; i++){
|
||||
|
||||
}
|
||||
|
||||
\/The fading of led's:
|
||||
// The fading of led's:
|
||||
|
||||
examples, basics, fade
|
||||
|
||||
\/ servo's
|
||||
// servo's
|
||||
|
||||
examples, servo, sweep
|
||||
|
||||
```
|
||||
### Linux and raspberry PI.
|
||||
To gain more knowledge about Linux, I first asked my classmates if they could get me started.
|
||||
|
||||
They showed me how to gain access to a server and told me how to navigate through files.
|
||||
By doing this I got taught the following commands:
|
||||
|
||||
```
|
||||
~ $ 'ls -la' = show file / folders
|
||||
|
||||
~ $ 'top' = see currently running programs
|
||||
@@ -89,7 +89,7 @@ By doing this I got taught the following commands:
|
||||
~ $ 'ping ip addres'
|
||||
|
||||
~ $ 'ssh username@ip address' = open ssh connection.
|
||||
|
||||
```
|
||||
### Air, temperature, and all sort of stuff.
|
||||
|
||||
After the Linux coding I decided to take a step back and began gaining experience with sensors.
|
||||
@@ -101,12 +101,16 @@ I wanted to make my own spin on the original design by including a button to act
|
||||
The rest of the tutorial was clear and worked like a charm.
|
||||
the code used looks like this:
|
||||
|
||||
Begin by including a specific library for the DHT11.
|
||||
```
|
||||
#include "DHT.h"
|
||||
#define DHTPIN 4
|
||||
#define DHTTYPE DHT11
|
||||
DHT dht(DHTPIN, DHTTYPE);
|
||||
|
||||
```
|
||||
using This perticulair serial port, means that you do have to switch to it when you want to see results coming in.
|
||||
The dht.begin command starts the process.
|
||||
```
|
||||
void setup() {
|
||||
//the serial port:
|
||||
Serial.begin(9600);
|
||||
@@ -116,9 +120,11 @@ Serial.println(F("DHTxx test!"));
|
||||
//the library start
|
||||
dht.begin();
|
||||
}
|
||||
```
|
||||
It starts by making float variables, to give over the information.
|
||||
It also includes a error message in case of no feedback.
|
||||
|
||||
|
||||
|
||||
```
|
||||
void loop() {
|
||||
delay(2000);
|
||||
//a float has decimal numbers and the library reads the measurements.
|
||||
@@ -136,7 +142,7 @@ void loop() {
|
||||
float hif = dht.computeHeatIndex(f, h);
|
||||
float hic = dht.computeHeatIndex(t, h, false);
|
||||
|
||||
//all serial.ptint's send stuff to the serial board to showcase.
|
||||
//all serial.print's send stuff to the serial board to showcase.
|
||||
Serial.print(F("Humidity: "));
|
||||
Serial.print(h);
|
||||
Serial.print(F("% Temperature: "));
|
||||
@@ -158,9 +164,13 @@ And here it looks in action:
|
||||
Later on, I could expand this code and the physical product to include the rest of the sensors.
|
||||
|
||||
The wiring is shown here:
|
||||

|
||||

|
||||
The red cables are 3v, the black cables are the ground and the green cable is the echo for data.
|
||||
This version of a DHT11 has a built-in resistor otherwise this would have to be included.
|
||||
This version is using a DHT22, this is a updated version of a DHT11 but still provides the same information and still uses the same pins. So i decided to compromise for it, using it in my fritzing diagram.
|
||||
|
||||
The wire-frame is shown below:
|
||||

|
||||
This helps visualise all connections and shows what parts were used for reproductional .
|
||||
|
||||
### Buzzers .pt 2
|
||||
I found out how to make multiple buzzers go off with the press of one button and increase as Mutch as there are pins.
|
||||
@@ -174,16 +184,18 @@ The code is short and simple:
|
||||
int button = 20;
|
||||
int buzzerone = 12;
|
||||
int buzzertwo = 11;
|
||||
|
||||
```
|
||||
Now we set the pins up to either input or output a signal.
|
||||
```
|
||||
void setup() {
|
||||
//put down some pins that will output , and some that input.
|
||||
pinMode(button, INPUT);
|
||||
pinMode(buzzerone, OUTPUT);
|
||||
pinMode(buzzertwo, OUTPUT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
```
|
||||
Here the button pin will seek a signal, when it is given it will send signals to the other given pins in the if-statement.
|
||||
```
|
||||
void loop() {
|
||||
//read is there is input on the button pin, if so send output to the other pins, otherwise keep them off.
|
||||
if(digitalRead(button) == HIGH){
|
||||
@@ -201,6 +213,13 @@ Here I made the physical design but instead of buzzers I used lights in order to
|
||||
And here is the the board working:
|
||||

|
||||
|
||||
To Show my wiring more clearly, here is my fritzing board:
|
||||

|
||||
the red wires are 3v, the black wires are the ground connections.
|
||||
|
||||
Here the wireframe is shown for parts specification and possible reproduction:
|
||||

|
||||
|
||||
### Python For Dummies.
|
||||
My job was to make a connection between the WebSocket and the database we had set up, and to do this we wanted to use python.
|
||||
To give an easy picture, here is where i would come:
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 215 KiB |
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
After Width: | Height: | Size: 198 KiB |
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
@@ -33,4 +33,44 @@ We Wil use this Feedback and see what we can do to change the design in a way th
|
||||
The design will be updated to include:
|
||||
`smaller holes for less distraction.
|
||||
`ventilation at the bottom for better airflow.
|
||||
`Remove the lamps on top of the node for less distraction.
|
||||
`Remove the lamps on top of the node for less distraction.
|
||||
|
||||
### Design questions led by bram
|
||||
For the nodes we designed to be placed around the 5th floor we were stuck between two designs:
|
||||
The wooden design: takes less time to create,is more fragile, and more eco-friendly.
|
||||
The Plastic: less eco-friendly, takes a longer time, looks objectively better.
|
||||
|
||||
since we can't decide on what we should use, I (Bram) went out to asks the public for their opinion.
|
||||
|
||||
To do this i took the front of the plastic design, and the front of the wooden design.
|
||||
They lloked like this:
|
||||
|
||||
1. which design is more likable
|
||||
|
||||
/Sebas : plastic looks better and goes straight to the point.
|
||||
/Skip : plastic looks more clean.
|
||||
/Dano : plastic is more smooth.
|
||||
/Sietse : plastic is better.
|
||||
/Ishak : Wood is more ecofriendly.
|
||||
/Nailah : PLastic looks cooler
|
||||
|
||||
2. which design is more distracting.
|
||||
|
||||
/Sebas : wood is more distracting and more obvious.
|
||||
/Skip : wood, because the school walls are more darker themed.
|
||||
/Dano : wood looks off.
|
||||
/Sietse : wood would be out of place.
|
||||
/Ishak : Wood, but in a good way.
|
||||
/Nailah : plastic looks more interesting.
|
||||
|
||||
3. Any further comments about the design?
|
||||
|
||||
/Sebas : Don't do wood, plastic is more sleek.
|
||||
/Skip : plastic looks more professional.
|
||||
/Dano : no.
|
||||
/Sietse: no.
|
||||
/Ishak : in the wood you can burn in your logo.
|
||||
/Nailah : The wood can look better inside the school.
|
||||
|
||||
In conclusion, Even though the wood would atract more attention, the plastic looks better according to the students.
|
||||
So from this information we will continue to make plastic cases for the nodes.
|
@@ -1,3 +1,55 @@
|
||||
# Nodes
|
||||
|
||||
## Introduction
|
||||
|
||||
The nodes are the devices that are placed in the rooms. The nodes are used to collect the data from the sensors. Every node is connected to the websocket, and sends their data with their mac address in json format. The websocket broadcasts the node data back to all clients, and since our website functions as a client it also receives the data. Every node will, depending on what node, be made into a class.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Sensornode
|
||||
|
||||
- Every node has to have a unique nodeID
|
||||
- Every node has to have their corresponding sensorsvalues in form of arrays
|
||||
|
||||
### Feedbacknodes
|
||||
|
||||
- Every node has to have a unique nodeID
|
||||
- Every node has to have their corresponding feedback in form of a 2D array
|
||||
|
||||
## Class diagrams
|
||||
|
||||
### Node
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Node {
|
||||
+nodeID
|
||||
+processNodeData()
|
||||
+updateNodeData()
|
||||
}
|
||||
```
|
||||
|
||||
#### Sensornode
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class SensorNode extends Node {
|
||||
+tempArray
|
||||
+humiArray
|
||||
+eco2Array
|
||||
+tvocArray
|
||||
}
|
||||
```
|
||||
|
||||
#### Feedbacknode
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class FeedbackNode extends Node {
|
||||
+feedbackArray
|
||||
}
|
||||
```
|
||||
|
||||
# Graphs
|
||||
|
||||
## Introduction
|
||||
@@ -29,7 +81,6 @@ classDiagram
|
||||
```mermaid
|
||||
classDiagram
|
||||
class liveGraph extends graph {
|
||||
+nodeId
|
||||
+cnt
|
||||
+timeArray
|
||||
+tempArray
|
12
docs/brainstorm/bebouwBeheer.md
Normal file
12
docs/brainstorm/bebouwBeheer.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Talk with building management
|
||||
|
||||
## Questions for building management
|
||||
|
||||
1. Design of page? (current page, new design or own idea)
|
||||
2. What do they expect of a page made for building management?
|
||||
3. Do they think they can work with the incomming feedback from the enquete?
|
||||
4. Design of the node? (plastic or wood)
|
||||
|
||||
## Feedback:
|
||||
|
||||
building management had some good feedback points about the page itself, about the idea, and some good pointers for the execution. They would also look into making the data they are already measuring accessible for us. The things they had to say about the website are: they found the first design a bit unorganized and said that they would rather see the second design where you can select the node you want to see, maybe also a search function to specify the node that is displayed. What also was said was to try to make it idiot-proof because not all of the building management people are technically active, to put it that way. They had some things to say about the node design, like maybe make the color white to make it better with blending into the white walls of the total area. They also asked the question of does it matter at what height the node is placed. One other thing they said was to write something onto the node to make it clear to the people in the area what it was doing, something like ReaderNode™. And the last thing they said was if we thought about how to make it vandalizing students proof.
|
20
docs/node-documentation/NodeClassDocumentation.md
Normal file
20
docs/node-documentation/NodeClassDocumentation.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# OOP within Arduino
|
||||
|
||||
Object-Oriented Programming (OOP) is a way of programing that provides a means of structuring your code so the code is modular and can be used more often without making huge changes or having to copy past the same code.
|
||||
|
||||
## Abstraction
|
||||
|
||||
Abstraction in OOP is the process of exposing only the required essential variables and functions. This means hiding the complexity and only showing the essential features of the object. In Arduino, this could mean creating a class like `Sensor node` with methods such as `setUp()`, `displayData()`, and `checkForError()`.
|
||||
|
||||
## Encapsulation
|
||||
|
||||
Encapsulation is the technique used to hide the data and methods within an object and prevent outside access. In Arduino, this could mean having private variables and methods in a class that can only be accessed and modified through public methods.
|
||||
|
||||
## Which classes did we use
|
||||
|
||||
In this Arduino project, we used several classes to organize our code and manage the complexity of the project. Some of these classes include:
|
||||
|
||||
- `websockets`: This class is responsible for managing the WebSocket connections.
|
||||
- `nodeReadings`: This class is responsible for managing the sensor readings.
|
||||
|
||||
Each of these classes encapsulates the data and methods related to a specific part of the project, making the code easier to understand and maintain.
|
43
docs/node-documentation/NodeClassUml.md
Normal file
43
docs/node-documentation/NodeClassUml.md
Normal file
@@ -0,0 +1,43 @@
|
||||
### Uml diagram:
|
||||
|
||||
``` mermaid
|
||||
classDiagram
|
||||
|
||||
namespace Esp {
|
||||
class Websockets{
|
||||
+webSocket
|
||||
+_WiFiMulti
|
||||
hexdump()
|
||||
websocketSetup()
|
||||
loop()
|
||||
webSocketEvent()
|
||||
sendMyText()
|
||||
}
|
||||
|
||||
class NodeReadings{
|
||||
|
||||
+TVOC_base, eCO2_base
|
||||
+counter
|
||||
+eCO2
|
||||
+TVOC
|
||||
+interval
|
||||
+temperature
|
||||
+humidity
|
||||
+currentMillis
|
||||
+lastMillis
|
||||
+errorSGP30
|
||||
+errorDHT11
|
||||
+noise
|
||||
|
||||
setup()
|
||||
loop()
|
||||
resetValues()
|
||||
update()
|
||||
checkForError()
|
||||
displayData()
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
```
|
@@ -1,32 +1,40 @@
|
||||
# Original Version (by bram)
|
||||
|
||||
## Python code + explaination
|
||||
|
||||
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.
|
||||
import asyncio
|
||||
import websockets
|
||||
// a library to connect to the database.
|
||||
import mysql.connector
|
||||
import mysql.connector
|
||||
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
|
||||
//the data that has to be pushed needs to be
|
||||
async def process_data(data):
|
||||
try:
|
||||
mydb = mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="*****",
|
||||
password="*********",
|
||||
database="*******"
|
||||
database="*******"
|
||||
)
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```js
|
||||
//Making a variable for the database connection
|
||||
cursor = mydb.cursor()
|
||||
@@ -49,7 +57,7 @@ The data collected from the websocket is json data, so this has to be changed.
|
||||
//fetch the data from the database an[d put it in an array.
|
||||
MACDataFetching = MACDataReading.fetchall()
|
||||
MACArray = list(MACDataFetching)
|
||||
|
||||
|
||||
//see if the fetched data is not in the gotten array.
|
||||
//otehrwise insert it into the database directly.
|
||||
if MACTuple not in MACArray:
|
||||
@@ -70,9 +78,11 @@ The data collected from the websocket is json data, so this has to be changed.
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
async def receive_data():
|
||||
@@ -94,4 +104,165 @@ async def main():
|
||||
await receive_data()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
```
|
||||
|
||||
# New Version (by sietse)
|
||||
|
||||
## Changes made
|
||||
|
||||
The original code was a good start, but it had some issues. The code could only handle the data from the sensorNodes and didn't include the nodeID for measurements.
|
||||
|
||||
Since we have 2 kind of nodes (sensorNodes and enqueteNodes) we needed to make another function to commit the enqueteData in the database. I have also made a filter to know which data is from the sensorNodes and which data is from the enqueteNodes. This way we can commit the data to the right table in the database.
|
||||
|
||||
I have also added a function to get the nodeID from the MAC address. This way we can commit the data to the right node in the database.
|
||||
|
||||
## The new "filter" code
|
||||
|
||||
### Function to get a list with macAdresses from the sensorNodes and enqueteNodes
|
||||
|
||||
To filter i have made 2 lists, one with all the mac adresses of the sensorNodes and the other with the mac adresses of the enqueteNodes.
|
||||
|
||||
The function that handles that and updates the list is the following:
|
||||
|
||||
```python
|
||||
async def getNodeInfo(type):
|
||||
global sensorNodeArray
|
||||
global enqueteNodeArray
|
||||
|
||||
nodeInfoArray = []
|
||||
|
||||
id = (type,)
|
||||
mydb = dbLogin()
|
||||
cursor = mydb.cursor()
|
||||
cursor.execute("""SELECT MAC FROM Node WHERE Type = %s""", id)
|
||||
nodeInfo = cursor.fetchall()
|
||||
|
||||
for tuples in nodeInfo:
|
||||
for item in tuples:
|
||||
nodeInfoArray.append(item)
|
||||
print(nodeInfoArray)
|
||||
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
if type == 'sensor':
|
||||
sensorNodeArray = nodeInfoArray
|
||||
print(sensorNodeArray)
|
||||
return sensorNodeArray
|
||||
|
||||
elif type == 'enquete':
|
||||
enqueteNodeArray = nodeInfoArray
|
||||
return enqueteNodeArray
|
||||
```
|
||||
|
||||
As you can it works like this:
|
||||
|
||||
1. It gets the MAC adresses from the database with the type of node you want to get the data from. (sensor or enquete)
|
||||
|
||||
2. It executes the command and puts the data in a list.
|
||||
|
||||
3. It uses a nested for loop to get the data out of the tuples and puts it in the nodeInfoArray.
|
||||
|
||||
4. It updates, depending on what type, the sensorNodeArray or the enqueteNodeArray with the new data (NodeInfoArray).
|
||||
|
||||
5. It returns the array with the data.
|
||||
|
||||
### The filter code
|
||||
|
||||
Now that we have the data we can filter the data from the websocket.
|
||||
|
||||
```python
|
||||
data = await websocket.recv()
|
||||
|
||||
processedData = json.loads(data)
|
||||
macAdress = processedData['node']
|
||||
|
||||
if "Temp" in processedData:
|
||||
type = 'sensor'
|
||||
else:
|
||||
type = 'enquete'
|
||||
|
||||
await getNodeInfo('sensor')
|
||||
await getNodeInfo('enquete')
|
||||
|
||||
if macAdress in sensorNodeArray:
|
||||
nodeID = await getNodeID(macAdress)
|
||||
await processSensorNodeData(data, nodeID)
|
||||
elif macAdress in enqueteNodeArray:
|
||||
nodeID = await getNodeID(macAdress)
|
||||
await processEnqueteNodeData(data, nodeID)
|
||||
else:
|
||||
await newNode(macAdress, type)
|
||||
```
|
||||
|
||||
As you can see its alot of code to explain. So to make it easier i made a mermaid diagram to show how the code works / what it does.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Get data from websocket] --> B{Is it sensor data or enquete data?}
|
||||
B -->|sensor| C[Get sensorNodeArray]
|
||||
B -->|enquete| D[Get enqueteNodeArray]
|
||||
B -->|New node| E[Add new node to database]
|
||||
C -->|data| G[Process sensorNodeData]
|
||||
D -->|data| H[Process enqueteNodeData]
|
||||
```
|
||||
|
||||
## The function to get the nodeID
|
||||
|
||||
This function is used to get the nodeID from the MAC adress. This way we can commit the data with the right id in the database.
|
||||
|
||||
The function to get the nodeID from the MAC adress is the following:
|
||||
|
||||
```python
|
||||
async def getNodeID(macAdress):
|
||||
id = (macAdress,)
|
||||
mydb = dbLogin()
|
||||
cursor = mydb.cursor()
|
||||
cursor.execute("""SELECT nodeID FROM Node WHERE MAC = %s""", id)
|
||||
data = cursor.fetchall()
|
||||
|
||||
for tuples in data:
|
||||
for item in tuples:
|
||||
nodeID = item
|
||||
|
||||
return nodeID
|
||||
```
|
||||
|
||||
1. It gets the nodeID from the database with the MAC adress.
|
||||
2. It executes the command and puts the data in a list.
|
||||
3. It uses a nested for loop to get the data out of the tuples and puts it in the nodeID.
|
||||
4. It returns the nodeID.
|
||||
|
||||
## The function to commit the data from the sensorNodes
|
||||
|
||||
This function is alot like the original one, with the only 2 changes being that it now also commits the nodeID and that the code to make a new node is now in a different function.
|
||||
|
||||
[Link to code](server\data.py)
|
||||
|
||||
## The function to commit the data from the enqueteNodes
|
||||
|
||||
This function is alot like the sensorNode function. It just commits the data to the enqueteData table in the database. And it has another data.
|
||||
|
||||
[Link to code](server\data.py)
|
||||
|
||||
## The function to add a new node to the database
|
||||
|
||||
This function is used to add a new node to the database. This is used when a new node is connected to the websocket, but not yet in the database.
|
||||
|
||||
The function to add a new node to the database is the following:
|
||||
|
||||
```python
|
||||
async def newNode(mac, type):
|
||||
id = (mac, type)
|
||||
mydb = dbLogin()
|
||||
|
||||
cursor = mydb.cursor()
|
||||
cursor.execute("INSERT INTO `Node` (MAC, Type) VALUES (%s, %s)", id)
|
||||
print("new node assigned")
|
||||
mydb.commit()
|
||||
```
|
||||
|
||||
1. It gets the MAC adress and the type of node from the arguments.
|
||||
2. It executes the command to add the new node to the database.
|
||||
3. It prints that a new node is assigned.
|
||||
4. It commits the data to the database.
|
@@ -16,7 +16,11 @@ def updateDataIndex():
|
||||
new_name = request.args.get('name', None)
|
||||
new_location = request.args.get('location', None)
|
||||
return updateData(node_id, new_name, new_location)
|
||||
|
||||
|
||||
@app.route('/getNodeInfo')
|
||||
def getNodeInfoIndex():
|
||||
macAdress = request.args.get('macAdress', None)
|
||||
return getNodeInfo(macAdress)
|
||||
|
||||
def updateData(node, name, location):
|
||||
mydb = loginDB()
|
||||
@@ -50,5 +54,16 @@ def getData(node, dataType, MAC):
|
||||
|
||||
return result
|
||||
|
||||
def getNodeInfo(macAdress):
|
||||
mydb = loginDB()
|
||||
query = get_query(False, False, macAdress)
|
||||
cursor = mydb.cursor(dictionary=True) # Enable dictionary output
|
||||
cursor.execute(query)
|
||||
result = cursor.fetchall() # Fetch the results
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, host='localhost')
|
||||
|
65
server/brams-script.py
Normal file
65
server/brams-script.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
import mysql.connector
|
||||
import json
|
||||
|
||||
async def process_data(data):
|
||||
try:
|
||||
mydb = mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="Dingleberries69!",
|
||||
database="NodeData"
|
||||
)
|
||||
cursor = mydb.cursor()
|
||||
|
||||
MACDataReading = mydb.cursor()
|
||||
MACDataReading.execute("SELECT MAC FROM Node")
|
||||
print('some_response')
|
||||
query = "INSERT INTO `Measurement` (NodeID, Type, Value) VALUES (%s, %s, %s)"
|
||||
processedData = json.loads(data)
|
||||
processedTemp = (processedData['Temp'])
|
||||
processedHumi = (processedData['Humi'])
|
||||
processedeCO2 = (processedData['eCO2'])
|
||||
processedTvoc = (processedData['TVOC'])
|
||||
processedMAC = (processedData['node'])
|
||||
MACTuple = (processedMAC,)
|
||||
|
||||
MACDataFetching = MACDataReading.fetchall()
|
||||
MACArray = list(MACDataFetching)
|
||||
|
||||
|
||||
if MACTuple not in MACArray:
|
||||
addingNode = "INSERT INTO `Node` (MAC) VALUES (%s)"
|
||||
cursor.execute(addingNode, MACTuple)
|
||||
mydb.commit()
|
||||
|
||||
pushingDataArray = [(1, "Temp", processedTemp), (1, "Humi", processedHumi), (1, "eCO2", processedeCO2), (1, "TVOC", processedTvoc)]
|
||||
for i in pushingDataArray:
|
||||
print(query ,i)
|
||||
cursor.execute(query, i)
|
||||
mydb.commit()
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print("MySQL Error:", err)
|
||||
finally:
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
async def receive_data():
|
||||
uri = "ws://145.92.8.114/ws"
|
||||
|
||||
try:
|
||||
async with websockets.connect(uri) as websocket:
|
||||
while True:
|
||||
data = await websocket.recv()
|
||||
print(f"Received data: {data}")
|
||||
await process_data(data)
|
||||
except websockets.ConnectionClosedError as e:
|
||||
print("WebSocket connection closed:", e)
|
||||
|
||||
async def main():
|
||||
await receive_data()
|
||||
|
||||
asyncio.run(main())
|
||||
|
31
server/bullshitSenderENQUETE.py
Normal file
31
server/bullshitSenderENQUETE.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
import json
|
||||
import random
|
||||
import time
|
||||
|
||||
async def send_data(uri):
|
||||
async with websockets.connect(uri) as websocket:
|
||||
print("Connected to WebSocket server")
|
||||
|
||||
while True:
|
||||
data = {
|
||||
"node": "69:42:08:F5:00:00",
|
||||
"Response": str(round(random.uniform(0, 2))),
|
||||
"QuestionID": str(round(random.uniform(1, 2))),
|
||||
}
|
||||
await websocket.send(json.dumps(data))
|
||||
print("Data sent")
|
||||
|
||||
response = await websocket.recv()
|
||||
print("Received message:", response)
|
||||
|
||||
await asyncio.sleep(2) # Wait a bit before sending the next message
|
||||
|
||||
# Start the WebSocket connection
|
||||
while True:
|
||||
try:
|
||||
asyncio.get_event_loop().run_until_complete(send_data("ws://145.92.8.114/ws"))
|
||||
except Exception as e:
|
||||
print("Exception:", e)
|
||||
time.sleep(1) # Wait a bit before trying to reconnect
|
154
server/data.py
Normal file
154
server/data.py
Normal file
@@ -0,0 +1,154 @@
|
||||
import asyncio
|
||||
import websockets
|
||||
import mysql.connector
|
||||
import json
|
||||
|
||||
sensorNodeArray = []
|
||||
enqueteNodeArray = []
|
||||
|
||||
async def processSensorNodeData(data, nodeID):
|
||||
try:
|
||||
mydb = dbLogin()
|
||||
cursor = mydb.cursor()
|
||||
|
||||
query = "INSERT INTO `Measurement` (NodeID, Type, Value) VALUES (%s, %s, %s)"
|
||||
processedData = json.loads(data)
|
||||
|
||||
processedTemp = (processedData['Temp'])
|
||||
processedHumi = (processedData['Humi'])
|
||||
processedeCO2 = (processedData['eCO2'])
|
||||
processedTVOC = (processedData['TVOC'])
|
||||
processedMAC = (processedData['node'])
|
||||
|
||||
pushingDataArray = [(nodeID, "Temp", processedTemp), (nodeID, "Humi", processedHumi), (nodeID, "eCO2", processedeCO2), (nodeID, "TVOC", processedTVOC)]
|
||||
for i in pushingDataArray:
|
||||
print(query ,i)
|
||||
cursor.execute(query, i)
|
||||
mydb.commit()
|
||||
|
||||
except mysql.connector.Error as err:
|
||||
print("MySQL Error:", err)
|
||||
finally:
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
async def processEnqueteNodeData(data, nodeID):
|
||||
try:
|
||||
mydb = dbLogin()
|
||||
cursor = mydb.cursor()
|
||||
|
||||
query = "INSERT INTO `Reply` (Result, Node_NodeID, Question_QuestionID) VALUES (%s, %s, %s)"
|
||||
processedData = json.loads(data)
|
||||
|
||||
processedQuestionID = (processedData['QuestionID'])
|
||||
processedResponse = (processedData['Response'])
|
||||
|
||||
pushingDataArray = [(processedResponse, nodeID, processedQuestionID)]
|
||||
|
||||
for i in pushingDataArray:
|
||||
cursor.execute(query, i)
|
||||
mydb.commit()
|
||||
except mysql.connector.Error as err:
|
||||
print("MySQL Error:", err)
|
||||
finally:
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
async def receive_data():
|
||||
uri = "ws://145.92.8.114/ws"
|
||||
try:
|
||||
async with websockets.connect(uri) as websocket:
|
||||
while True:
|
||||
data = await websocket.recv()
|
||||
print(f"Received data: {data}")
|
||||
|
||||
processedData = json.loads(data)
|
||||
macAdress = processedData['node']
|
||||
|
||||
if "Temp" in processedData:
|
||||
type = 'sensor'
|
||||
else:
|
||||
type = 'enquete'
|
||||
|
||||
await getNodeInfo('sensor')
|
||||
await getNodeInfo('enquete')
|
||||
|
||||
print(sensorNodeArray)
|
||||
|
||||
if macAdress in sensorNodeArray:
|
||||
nodeID = await getNodeID(macAdress)
|
||||
await processSensorNodeData(data, nodeID)
|
||||
elif macAdress in enqueteNodeArray:
|
||||
nodeID = await getNodeID(macAdress)
|
||||
await processEnqueteNodeData(data, nodeID)
|
||||
else:
|
||||
await newNode(macAdress, type)
|
||||
except websockets.ConnectionClosedError as e:
|
||||
print("WebSocket connection closed:", e)
|
||||
|
||||
async def main():
|
||||
await receive_data()
|
||||
|
||||
def dbLogin():
|
||||
mydb = mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="Dingleberries69!",
|
||||
database="NodeData"
|
||||
)
|
||||
|
||||
return mydb
|
||||
|
||||
async def getNodeInfo(type):
|
||||
global sensorNodeArray
|
||||
global enqueteNodeArray
|
||||
|
||||
nodeInfoArray = []
|
||||
|
||||
id = (type,)
|
||||
mydb = dbLogin()
|
||||
cursor = mydb.cursor()
|
||||
cursor.execute("""SELECT MAC FROM Node WHERE Type = %s""", id)
|
||||
nodeInfo = cursor.fetchall()
|
||||
|
||||
for tuples in nodeInfo:
|
||||
for item in tuples:
|
||||
nodeInfoArray.append(item)
|
||||
print(nodeInfoArray)
|
||||
|
||||
cursor.close()
|
||||
mydb.close()
|
||||
|
||||
if type == 'sensor':
|
||||
sensorNodeArray = nodeInfoArray
|
||||
print(sensorNodeArray)
|
||||
return sensorNodeArray
|
||||
|
||||
elif type == 'enquete':
|
||||
enqueteNodeArray = nodeInfoArray
|
||||
return enqueteNodeArray
|
||||
|
||||
|
||||
async def getNodeID(macAdress):
|
||||
id = (macAdress,)
|
||||
mydb = dbLogin()
|
||||
cursor = mydb.cursor()
|
||||
cursor.execute("""SELECT nodeID FROM Node WHERE MAC = %s""", id)
|
||||
data = cursor.fetchall()
|
||||
|
||||
for tuples in data:
|
||||
for item in tuples:
|
||||
nodeID = item
|
||||
|
||||
return nodeID
|
||||
|
||||
async def newNode(mac, type):
|
||||
id = (mac, type,)
|
||||
mydb = dbLogin()
|
||||
|
||||
cursor = mydb.cursor()
|
||||
cursor.execute("INSERT INTO `Node` (MAC, Type) VALUES (%s, %s)", id)
|
||||
print("new node assigned")
|
||||
mydb.commit()
|
||||
|
||||
asyncio.run(main())
|
@@ -80,4 +80,18 @@ Sam, tft scherm, rest api ombouwen om data in node tabel te douwen
|
||||
Bram: Fritsing, documentation for code
|
||||
Sietse: Database
|
||||
Dano: Docuemtation for arduino
|
||||
Sam:
|
||||
Sam:
|
||||
|
||||
26/03/2024
|
||||
|
||||
Sam: gebouw beheer vragen, Wall mounted enquete doos
|
||||
Sietse: rest api encete vragen
|
||||
Bram: expert voorbereigen, node data updaten
|
||||
Dano: Documentatie schreiven,
|
||||
|
||||
27/03/2024
|
||||
|
||||
Bram: OOP python
|
||||
Sam: new website
|
||||
Sietse: enquete screen data sending to database and database cript better
|
||||
Dano: documentation about oop arduino
|
Reference in New Issue
Block a user