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:
@@ -6,8 +6,13 @@ nav:
|
|||||||
- Criteria: opdracht/criteria
|
- Criteria: opdracht/criteria
|
||||||
- User Stories: opdracht/user_stories
|
- User Stories: opdracht/user_stories
|
||||||
- Links: opdracht/links
|
- Links: opdracht/links
|
||||||
- 📚 Documentatie:
|
- 🎮 Arduino documentation:
|
||||||
- I2C: arduino-documentation/i2c-ESP32
|
- I2C: arduino-documentation/i2c-ESP32
|
||||||
|
- 🍓 RPi Documentation:
|
||||||
|
- Raspberry pi: Sp1SchetsProject/InfrastructuurDocumentatie/raspberryPi
|
||||||
|
- MariaDB: rpi-documentation/mariadb-installation
|
||||||
|
- phpMyAdmin: rpi-documentation/phpmyadmin-installation
|
||||||
|
- Websockets: rpi-documentation/websockets
|
||||||
- 🧠 Brainstorm:
|
- 🧠 Brainstorm:
|
||||||
- Ideeën: brainstorm/ideeën
|
- Ideeën: brainstorm/ideeën
|
||||||
- Database design: brainstorm/Database
|
- Database design: brainstorm/Database
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
#Rasberry Pi
|
||||||
|
|
||||||
|
##Table of contents
|
||||||
|
1. [Introduction](##introduction)
|
||||||
|
2. [Rasberry Pi](##Rasberry-Pi)
|
||||||
|
3. [Dev-Page](###Dev-Page)
|
||||||
|
4. [Database](##Database)
|
||||||
|
5. [Database software](###Database-software)
|
||||||
|
6. [Esp to database](###Esp-to-database)
|
||||||
|
|
||||||
|
##Introduction
|
||||||
|
|
||||||
|
The backend of this project there is a raspberry pi 3 for handeling the dev page (more on this later) and the database. The Esp nodes are going to send a api request to the dev page wich is going to make a POST request to the database.
|
||||||
|
|
||||||
|
##Rasberry Pi
|
||||||
|
|
||||||
|
The Raspberry 3 can be descriped as a "little" computer running a quad-code 64-bit prossesor, the previus Raspberry witch is 50% slower than this one
|
||||||
|
|
||||||
|
The Raspberry Pi 3 is equipped with a quad-core 64-bit Broadcom BCM2837 ARM Cortex-A53 SoC processor running at 1.2 GHz, making it about 50% more powerful than the Pi 2.
|
||||||
|
|
||||||
|
###Dev Page
|
||||||
|
|
||||||
|
##Database
|
||||||
|
|
||||||
|
###Database software
|
||||||
|
|
||||||
|
###Esp to database
|
7
docs/brainstorm/Problem.md
Normal file
7
docs/brainstorm/Problem.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# The problem
|
||||||
|
|
||||||
|
The problem we are facing with the study area is having to walk around a lot to find a place to study. Which costs lots of valuable time to work on your project.
|
||||||
|
|
||||||
|
|
||||||
|
## The solution
|
||||||
|
Thats why we are going to make a system that can show how loud it is in the study area, so you have a better chance of walking to a spot where you can sit and work in peace. There are going to be 3 nodes in different study areas that are going to measure the sound level. These nodes are going to send the data to a server, which is going to process the data and send it to the main node that is located at the coffee machine. This node is going to show the data on a display.
|
5
docs/brainstorm/Questions Enquete.md
Normal file
5
docs/brainstorm/Questions Enquete.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Questions
|
||||||
|
|
||||||
|
How clean are the toilets (clean, normal, disgusting)
|
||||||
|
How clean is the study area (clean, normal, disgusting)
|
||||||
|
What do you think of the temparature in the study area (hot, perfect, cold)
|
@@ -5,14 +5,15 @@
|
|||||||
``` mermaid
|
``` mermaid
|
||||||
classDiagram
|
classDiagram
|
||||||
|
|
||||||
Node --> Raspberry pi : postData
|
Node --> Raspberry pi : Websocket
|
||||||
|
Raspberry pi --> Website : getData
|
||||||
|
Raspberry pi <--> EnqueteNode : Websocket
|
||||||
|
|
||||||
namespace Server {
|
namespace Server {
|
||||||
class Raspberry pi {
|
class Raspberry pi {
|
||||||
Database()
|
Database()
|
||||||
Webserver()
|
Webserver()
|
||||||
|
Websocket()
|
||||||
|
|
||||||
}
|
}
|
||||||
class Node {
|
class Node {
|
||||||
@@ -22,7 +23,39 @@ namespace Server {
|
|||||||
+Tfok
|
+Tfok
|
||||||
+Sound
|
+Sound
|
||||||
collectData()
|
collectData()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace User {
|
||||||
|
class Website {
|
||||||
|
+Co2
|
||||||
|
+Temperature
|
||||||
|
+Humidity
|
||||||
|
+Tfok
|
||||||
|
+Sound
|
||||||
|
+Graph
|
||||||
|
+Map
|
||||||
|
+Settings
|
||||||
|
GetData()
|
||||||
|
}
|
||||||
|
class EnqueteNode {
|
||||||
|
+Co2
|
||||||
|
+Temperature
|
||||||
|
+Humidity
|
||||||
|
+Tfok
|
||||||
|
+Sound
|
||||||
|
+Graph
|
||||||
|
+Map
|
||||||
|
+QuestionResponse
|
||||||
|
EnqueteDisplay()
|
||||||
|
EnqueteButtons()
|
||||||
|
GetData()
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
26
docs/node-documentation/node-sensors.md
Normal file
26
docs/node-documentation/node-sensors.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Node sensor documentation
|
||||||
|
|
||||||
|
## How does it work?
|
||||||
|
|
||||||
|
The nodes are used to collect data about the environment. They are connected to the database using post requests, every node sends a post request to the database with the sensordata it has collected. The database then stores this data in the right table. Every node is also connected to a websocket server, this server is used to send the data to the frontend. The frontend then uses this data to display the current situation in the environment.
|
||||||
|
|
||||||
|
Every node has the same sensors, this makes it easy to create more and ensures that you get as many equal measurements as possible everywhere. There is 1 node that will be different. This is the one with the screen. This will have some other functions.
|
||||||
|
|
||||||
|
The goal is to put every node on a populated area or in every room, this way we can get a good overview of the environment and react on it to make it more comfortable for everyone.
|
||||||
|
|
||||||
|
## What sensors will we use?
|
||||||
|
|
||||||
|
We will use the following sensors in the nodes:
|
||||||
|
* SGP30 for eCO2 and TVOC
|
||||||
|
* DHT11 for temperature and humidity
|
||||||
|
* Sound sensor for sound level
|
||||||
|
|
||||||
|
We chose these sensors because they are cheap to buy and don't require a lot of power to run. This makes it easy to create more nodes and to put them everywhere. These sensors aren't the most accurate, but they are good enough for our use case. Since we will only use them to get an overview of the environment and not for scientific research.
|
||||||
|
|
||||||
|
## Appearance of the nodes
|
||||||
|
|
||||||
|
Every node has the sensors listed above. The also have a little oled screen to display the current situation in the environment. This is used to show the current temperature, humidity, eCO2, TVOC. Next to it is also a little led matrix which will show the current sound level.
|
||||||
|
|
||||||
|
## Power
|
||||||
|
|
||||||
|
The nodes are powered by 2 lithium batteries. They will be removable to charge them. We might consider using double A batteries, but we are not sure yet, since lithium batteries are more powerful, last longer and AA batteries are not rechargeable, and we want to make the nodes as sustainable as possible.
|
39
docs/rpi-documentation/mariadb-installation.md
Normal file
39
docs/rpi-documentation/mariadb-installation.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Mariadb
|
||||||
|
|
||||||
|
First we have to install the package. This is done by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo apt install mariadb-server
|
||||||
|
```
|
||||||
|
|
||||||
|
Now the raspberry pi will download the package and install it. After the installation is done, we have to secure the installation. This is done by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo mysql_secure_installation
|
||||||
|
```
|
||||||
|
|
||||||
|
This will ask you a couple of questions. The first question is if you want to set a password for the root user. We chose not to because we are the only ones that have access to the raspberry pi. The second question is if you want to remove the anonymous user. We chose to remove the anonymous user. The third question is if you want to disallow root login remotely. We chose NOT to disallow root login remotely, otherwise we wouldn't be able to login to the database remotely anymore. The fourth question is if you want to remove the test database. We chose yes because we made our own database. The fifth question is if you want to reload the privilege tables now. We chose yes, because we want to apply the changes we made.
|
||||||
|
|
||||||
|
Now the installation is done and the database is secured. Now we can start using the database.
|
||||||
|
|
||||||
|
# Create a database
|
||||||
|
|
||||||
|
First we have to login to the database. This is done by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo mysql -u root
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we are logged in to the database. We have created our database by using the forward engineer function of MySQL workbench and then exporting the sql file to the raspberry pi.
|
||||||
|
|
||||||
|
# Create a user
|
||||||
|
|
||||||
|
We have to create a user for the database. This is done by running the following command:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace username with the username you want to use and password with the password you want to use. This will create a user with all privileges on all databases. If you want to create a user with less privileges you can change the ALL PRIVILEGES to the privileges you want to give the user. We chose to give the user all privileges to make it easy for us to use the database.
|
||||||
|
|
||||||
|
**Written by Sietse**
|
22
docs/rpi-documentation/phpmyadmin-installation.md
Normal file
22
docs/rpi-documentation/phpmyadmin-installation.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# PHPMyAdmin
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo apt install phpmyadmin
|
||||||
|
```
|
||||||
|
|
||||||
|
The raspberry pi will download the package and install it. It will also ask a few questions. For the first question we selected the “apache2” option by pressing SPACE and then ENTER. Then it will ask us to configure the database using dbconfig-common, we selected “yes” and then pressed ENTER. Then it will ask us for the password of the root user of the database, we entered the password and then pressed ENTER. Then it will ask us to enter a password for the phpmyadmin application, we entered the password and then pressed ENTER. Then it will ask us to confirm the password, we entered the password again and then pressed ENTER. After this the installation is done and we can start using phpmyadmin.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To use phpmyadmin we have to go to the following url in our browser: http://(ip adress of your pi)/phpmyadmin. This will open the phpmyadmin login page. We can login using the root user and the password we entered during the installation. After we have logged in we can start using the database.
|
||||||
|
|
||||||
|
This didnt work for us, we first had to run this command on hte raspberry pi:
|
||||||
|
```bash
|
||||||
|
$ sudo apt install php
|
||||||
|
```
|
||||||
|
|
||||||
|
After this we could use phpmyadmin, access the database we've created and start using it.
|
||||||
|
|
||||||
|
**Written by Sietse**
|
14
docs/rpi-documentation/websockets.md
Normal file
14
docs/rpi-documentation/websockets.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Websockets
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
### Why are we going to use websockets?
|
||||||
|
With websockets you can establish a connection between the client and the server, and both can send data fast to each other. This is useful for real-time applications like for our project to plot live graphs of the data we are collecting from the sensors.
|
||||||
|
|
||||||
|
### How to use websockets
|
||||||
|
There are different languages to serve websockets with, but we are going to use Python with the library `websockets`. This library is easy to use and has a lot of documentation.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Sources:
|
||||||
|
* https://websockets.readthedocs.io/en/stable/index.html
|
133
server/Database.sql
Normal file
133
server/Database.sql
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
-- MySQL Script generated by MySQL Workbench
|
||||||
|
-- Tue Feb 13 15:17:23 2024
|
||||||
|
-- Model: New Model Version: 1.0
|
||||||
|
-- MySQL Workbench Forward Engineering
|
||||||
|
|
||||||
|
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||||
|
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||||
|
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Schema NodeData
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Schema NodeData
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE SCHEMA IF NOT EXISTS `NodeData` DEFAULT CHARACTER SET utf8 ;
|
||||||
|
USE `NodeData` ;
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`enqueteAnswer`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`enqueteAnswer` (
|
||||||
|
`AnswerID` INT NOT NULL,
|
||||||
|
`NodeID` INT NOT NULL,
|
||||||
|
`Result` VARCHAR(45) NULL,
|
||||||
|
`enqueteDatacol` VARCHAR(45) NULL,
|
||||||
|
`enqueteAnswerscol` VARCHAR(45) NULL,
|
||||||
|
`Question_QuestionID` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`AnswerID`, `Question_QuestionID`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`Question`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`Question` (
|
||||||
|
`QuestionID` INT NOT NULL,
|
||||||
|
`Question` VARCHAR(45) NULL,
|
||||||
|
PRIMARY KEY (`QuestionID`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`Node`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`Node` (
|
||||||
|
`NodeID` INT NOT NULL,
|
||||||
|
`Name` VARCHAR(45) NULL,
|
||||||
|
`Location` VARCHAR(45) NULL,
|
||||||
|
PRIMARY KEY (`NodeID`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`Measurement`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`Measurement` (
|
||||||
|
`NodeID` INT NOT NULL,
|
||||||
|
`Type` VARCHAR(45) NULL,
|
||||||
|
`Value` FLOAT NULL,
|
||||||
|
`TimeStamp` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`Node_NodeID` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`NodeID`, `Node_NodeID`),
|
||||||
|
INDEX `fk_Measurement_Node1_idx` (`Node_NodeID` ASC) VISIBLE,
|
||||||
|
CONSTRAINT `fk_Measurement_Node1`
|
||||||
|
FOREIGN KEY (`Node_NodeID`)
|
||||||
|
REFERENCES `NodeData`.`Node` (`NodeID`)
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
ON UPDATE NO ACTION)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`Enquete`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`Enquete` (
|
||||||
|
`EnqueteID` INT NOT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`EnqueteID`))
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`enqueteQuestion`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`enqueteQuestion` (
|
||||||
|
`Enquete_EnqueteID` INT NOT NULL,
|
||||||
|
`Question_QuestionID` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`Enquete_EnqueteID`, `Question_QuestionID`),
|
||||||
|
INDEX `fk_Enquete_has_Question_Question1_idx` (`Question_QuestionID` ASC) VISIBLE,
|
||||||
|
INDEX `fk_Enquete_has_Question_Enquete1_idx` (`Enquete_EnqueteID` ASC) VISIBLE,
|
||||||
|
CONSTRAINT `fk_Enquete_has_Question_Enquete1`
|
||||||
|
FOREIGN KEY (`Enquete_EnqueteID`)
|
||||||
|
REFERENCES `NodeData`.`Enquete` (`EnqueteID`)
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
ON UPDATE NO ACTION,
|
||||||
|
CONSTRAINT `fk_Enquete_has_Question_Question1`
|
||||||
|
FOREIGN KEY (`Question_QuestionID`)
|
||||||
|
REFERENCES `NodeData`.`Question` (`QuestionID`)
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
ON UPDATE NO ACTION)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
-- Table `NodeData`.`Reply`
|
||||||
|
-- -----------------------------------------------------
|
||||||
|
CREATE TABLE IF NOT EXISTS `NodeData`.`Reply` (
|
||||||
|
`Node_NodeID` INT NOT NULL,
|
||||||
|
`enqueteQuestion_Enquete_EnqueteID` INT NOT NULL,
|
||||||
|
`enqueteQuestion_Question_QuestionID` INT NOT NULL,
|
||||||
|
`Result` INT NULL,
|
||||||
|
`Time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`AnswerID` INT NULL AUTO_INCREMENT,
|
||||||
|
PRIMARY KEY (`Node_NodeID`, `enqueteQuestion_Enquete_EnqueteID`, `enqueteQuestion_Question_QuestionID`),
|
||||||
|
INDEX `fk_Node_has_enqueteQuestion_enqueteQuestion1_idx` (`enqueteQuestion_Enquete_EnqueteID` ASC, `enqueteQuestion_Question_QuestionID` ASC) VISIBLE,
|
||||||
|
INDEX `fk_Node_has_enqueteQuestion_Node1_idx` (`Node_NodeID` ASC) VISIBLE,
|
||||||
|
CONSTRAINT `fk_Node_has_enqueteQuestion_Node1`
|
||||||
|
FOREIGN KEY (`Node_NodeID`)
|
||||||
|
REFERENCES `NodeData`.`Node` (`NodeID`)
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
ON UPDATE NO ACTION,
|
||||||
|
CONSTRAINT `fk_Node_has_enqueteQuestion_enqueteQuestion1`
|
||||||
|
FOREIGN KEY (`enqueteQuestion_Enquete_EnqueteID` , `enqueteQuestion_Question_QuestionID`)
|
||||||
|
REFERENCES `NodeData`.`enqueteQuestion` (`Enquete_EnqueteID` , `Question_QuestionID`)
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
ON UPDATE NO ACTION)
|
||||||
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
SET SQL_MODE=@OLD_SQL_MODE;
|
||||||
|
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||||
|
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
21
server/Websocket.py
Normal file
21
server/Websocket.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import websockets;
|
||||||
|
import asyncio;
|
||||||
|
|
||||||
|
|
||||||
|
async def handler(websocket):
|
||||||
|
while True:
|
||||||
|
#Save the incoming message in variable message.
|
||||||
|
message = await websocket.recv()
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
async with websockets.serve(handler, "145.92.8.114" , 8001):
|
||||||
|
await asyncio.Future() # run forever
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(main())
|
||||||
|
|
||||||
|
|
||||||
|
#https://websockets.readthedocs.io/en/stable/reference/sync/server.html#websockets.sync.server.serve
|
Reference in New Issue
Block a user