From 08c9bedb44ea459e8a32632bae46e10c30408cbe Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Fri, 8 Mar 2024 11:38:31 +0100 Subject: [PATCH 01/14] adds mac adress code to arduino folder --- arduino/mac_adress.ino | 13 +++++++++++++ web/index.html | 4 ---- 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 arduino/mac_adress.ino diff --git a/arduino/mac_adress.ino b/arduino/mac_adress.ino new file mode 100644 index 0000000..67dff28 --- /dev/null +++ b/arduino/mac_adress.ino @@ -0,0 +1,13 @@ +// Complete Instructions to Get and Change ESP MAC Address: https://RandomNerdTutorials.com/get-change-esp32-esp8266-mac-address-arduino/ +#include + +void setup(){ + Serial.begin(115200); + Serial.println(); + Serial.print("ESP Board MAC Address: "); + Serial.println(WiFi.macAddress()); +} + +void loop(){ + +} \ No newline at end of file diff --git a/web/index.html b/web/index.html index 1d30d1d..2bb052a 100644 --- a/web/index.html +++ b/web/index.html @@ -8,7 +8,6 @@ Node dev page - @@ -24,11 +23,8 @@ -
- - From 3886292110e6cbe9b98d1cda9c0a6683fb8a4d8b Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Fri, 8 Mar 2024 12:58:33 +0100 Subject: [PATCH 02/14] Refactor code and update websocket connection --- .../node-code-final/node-code-final.ino | 80 +++++++++---------- web/main.js | 10 ++- 2 files changed, 43 insertions(+), 47 deletions(-) diff --git a/arduino/node-code/node-code-final/node-code-final.ino b/arduino/node-code/node-code-final/node-code-final.ino index cb78a60..3e21be5 100644 --- a/arduino/node-code/node-code-final/node-code-final.ino +++ b/arduino/node-code/node-code-final/node-code-final.ino @@ -1,6 +1,3 @@ -// Sietse Jonker & Dano Bosch -// 28/02/2024 - // include these libraries #include #include @@ -21,9 +18,6 @@ #define i2c_adress 0x3c #define USE_SERIAL Serial -// define node identification number -#define nodeIdentificationNumber 1 - // make new objects Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); DHT dht(DHTPIN, DHTTYPE); @@ -45,6 +39,41 @@ bool errorSGP30 = false; bool errorDHT11 = false; bool noise = false; +// setup function +void setup() { + // make serial connection at 115200 baud + Serial.begin(115200); + + // tell display what settings to use + display.begin(i2c_adress, true); + display.clearDisplay(); + + // tell sensors to start reading + dht.begin(); + sgp.begin(); + + pinMode(MICPIN, INPUT); + pinMode(DHTPIN, INPUT); + + websocketSetup(); + resetValues(); +} + +// loop function +void loop() { + // loop the websocket connection so it stays alive + webSocket.loop(); + + // update when interval is met + if (currentMillis - lastMillis >= interval){ + lastMillis = millis(); + update(); + } + + // update the counter + currentMillis = millis(); +} + // hexdump function for websockets binary handler void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { const uint8_t* src = (const uint8_t*) mem; @@ -112,7 +141,7 @@ void websocketSetup(){ webSocket.setReconnectInterval(500); } -// fucntion to reset the values if needed +// function to reset the values if needed void resetValues() { TVOC_base; eCO2_base; @@ -153,7 +182,7 @@ void update(){ displayData(); // webSocket.sendTXT("{\"Temp\":\"" + String(temperature) + "\",\"Humi\":\"" + String(humidity) + "\",\"eCO2\":\"" + String(sgp.eCO2) + "\",\"TVOC\":\"" + String(sgp.TVOC) + "\"}"); - webSocket.sendTXT("{\"node\": \"" + String(nodeIdentificationNumber) + "\", \"Temp\":\"" + String(temperature) + "\",\"Humi\":\"" + String(humidity) + "\",\"eCO2\":\"" + String(sgp.eCO2) + "\",\"TVOC\":\"" + String(sgp.TVOC) + "\"}"); + webSocket.sendTXT("{\"node\": \"" + String(WiFi.macAddress()) + "\", \"Temp\":\"" + String(temperature) + "\",\"Humi\":\"" + String(humidity) + "\",\"eCO2\":\"" + String(sgp.eCO2) + "\",\"TVOC\":\"" + String(sgp.TVOC) + "\"}"); sgp.getIAQBaseline(&eCO2_base, &TVOC_base); @@ -183,39 +212,4 @@ void displayData() { // display the screen display.display(); -} - -// setup function -void setup() { - // make serial connection at 115200 baud - Serial.begin(115200); - - // tell display what settings to use - display.begin(i2c_adress, true); - display.clearDisplay(); - - // tell sensors to start reading - dht.begin(); - sgp.begin(); - - pinMode(MICPIN, INPUT); - pinMode(DHTPIN, INPUT); - - websocketSetup(); - resetValues(); -} - -// loop function -void loop() { - // loop the websocket connection so it stays alive - webSocket.loop(); - - // update when interval is met - if (currentMillis - lastMillis >= interval){ - lastMillis = millis(); - update(); - } - - // update the counter - currentMillis = millis(); } \ No newline at end of file diff --git a/web/main.js b/web/main.js index 0cd4aad..7a254cc 100644 --- a/web/main.js +++ b/web/main.js @@ -56,7 +56,7 @@ function handleIncomingData(data) { function processNodeData(nodeNumber, temperature, humidity, CO2, TVOC) { // Initialize the array for this node if it doesn't exist yet - if (!sensorData[nodeNumber]) { + if (!nodeNumber[nodeNumber]) { sensorData[nodeNumber] = []; } @@ -191,14 +191,16 @@ function updateNodeData(node, temperature, humidity, eCO2, TVOC) { document.getElementById("TVOCStatus").textContent = "Connected"; // Update the graph - liveGraphs[node - 1].updateData(temperature, humidity, eCO2, TVOC); - liveGraphs[node - 1].updateGraph(); + liveGraphs[0].updateData(temperature, humidity, eCO2, TVOC); + liveGraphs[0].updateGraph(); } +createNodeData("34:85:18:B5:CF:20"); + liveGraphs.push(new liveGraph("34:85:18:B5:CF:20")); // Call the function to create the HTML structure for (let i = 1; i <= amountOfNodes; i++) { createNodeData(i); - liveGraphs.push(new liveGraph(i)); + } // make the graphs From 9acd2b44a8556d224ffac2bb61bdb65dc7127ffa Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Fri, 8 Mar 2024 13:26:23 +0100 Subject: [PATCH 03/14] Add header file and refactor code --- .../node-code/node-code-final/headerFile.h | 40 ++++++++++++++++++ .../node-code-final/node-code-final.ino | 42 +------------------ 2 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 arduino/node-code/node-code-final/headerFile.h diff --git a/arduino/node-code/node-code-final/headerFile.h b/arduino/node-code/node-code-final/headerFile.h new file mode 100644 index 0000000..d7f2e9e --- /dev/null +++ b/arduino/node-code/node-code-final/headerFile.h @@ -0,0 +1,40 @@ +// include these libraries +#include +#include +#include +#include +#include +#include +#include + +// define pins on esp32 +#define MICPIN 6 +#define DHTPIN 7 +#define SCL 9 +#define SDA 8 +#define DHTTYPE DHT11 +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define i2c_adress 0x3c +#define USE_SERIAL Serial + +// make new objects +Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); +DHT dht(DHTPIN, DHTTYPE); +WiFiMulti WiFiMulti; +Adafruit_SGP30 sgp; +WebSocketsClient webSocket; + +// define variables +uint16_t TVOC_base, eCO2_base; +uint16_t counter = 0; +uint16_t eCO2 = 0; +uint16_t TVOC = 0; +uint16_t interval = 5000; +float temperature = 0; +float humidity = 0; +unsigned long currentMillis; +unsigned long lastMillis; +bool errorSGP30 = false; +bool errorDHT11 = false; +bool noise = false; \ No newline at end of file diff --git a/arduino/node-code/node-code-final/node-code-final.ino b/arduino/node-code/node-code-final/node-code-final.ino index 3e21be5..fcc93cd 100644 --- a/arduino/node-code/node-code-final/node-code-final.ino +++ b/arduino/node-code/node-code-final/node-code-final.ino @@ -1,43 +1,5 @@ -// include these libraries -#include -#include -#include -#include -#include -#include -#include - -// define pins on esp32 -#define MICPIN 6 -#define DHTPIN 7 -#define SCL 9 -#define SDA 8 -#define DHTTYPE DHT11 -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 -#define i2c_adress 0x3c -#define USE_SERIAL Serial - -// make new objects -Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); -DHT dht(DHTPIN, DHTTYPE); -WiFiMulti WiFiMulti; -Adafruit_SGP30 sgp; -WebSocketsClient webSocket; - -// define variables -uint16_t TVOC_base, eCO2_base; -uint16_t counter = 0; -uint16_t eCO2 = 0; -uint16_t TVOC = 0; -uint16_t interval = 5000; -float temperature = 0; -float humidity = 0; -unsigned long currentMillis; -unsigned long lastMillis; -bool errorSGP30 = false; -bool errorDHT11 = false; -bool noise = false; +// include header file into code +#include // setup function void setup() { From 856775c2a87398c96f33a60e392445a1ec670bea Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Fri, 8 Mar 2024 16:46:02 +0100 Subject: [PATCH 04/14] Update WiFi password and handle node addresses --- .../node-code-final/node-code-final.ino | 2 +- web/main.js | 43 ++++++------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/arduino/node-code/node-code-final/node-code-final.ino b/arduino/node-code/node-code-final/node-code-final.ino index fcc93cd..ff9485a 100644 --- a/arduino/node-code/node-code-final/node-code-final.ino +++ b/arduino/node-code/node-code-final/node-code-final.ino @@ -86,7 +86,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { // special function to setup websocket void websocketSetup(){ - WiFiMulti.addAP("iotroam", "vbK9gbDBIB"); + WiFiMulti.addAP("iotroam", "WFXRLtSwN2"); WiFiMulti.addAP("LansanKPN-boven", "19sander71vlieland14"); while(WiFiMulti.run() != WL_CONNECTED) { diff --git a/web/main.js b/web/main.js index 7a254cc..aa8568b 100644 --- a/web/main.js +++ b/web/main.js @@ -2,6 +2,8 @@ // arrays and stuff const sensorData = {}; let liveGraphs = []; +let nodeArray = []; +let nodeDict = {}; // letiables let intervalDelay = 5000; @@ -45,39 +47,21 @@ function openConnection() { openConnection(); function handleIncomingData(data) { - nodeNumber = data.node; + nodeAdressHandler(data.Node); + + nodeNumber = nodeDict[data.Node]; temperature = data.Temp; humidity = data.Humi; CO2 = data.eCO2; TVOC = data.TVOC; - processNodeData(nodeNumber, temperature, humidity, CO2, TVOC); + updateNodeData(nodeNumber, temperature, humidity, CO2, TVOC); } -function processNodeData(nodeNumber, temperature, humidity, CO2, TVOC) { - // Initialize the array for this node if it doesn't exist yet - if (!nodeNumber[nodeNumber]) { - sensorData[nodeNumber] = []; - } - - // Push the new data onto the array for this node - sensorData[nodeNumber].push({ - 'node': nodeNumber, - 'temp': temperature, - 'humi': humidity, - 'CO2': CO2, - 'TVOC': TVOC, - }); - - // updateNodeData(node, temperature, humidity, lightIntensity) - updateNodeData(nodeNumber, temperature, humidity, CO2, TVOC); - - // Log the array for this node - console.log(sensorData[nodeNumber]); - - // If the array for this node has more than 10 elements, remove the oldest one - if (sensorData[nodeNumber].length >= 10) { - sensorData[nodeNumber].shift(); +function nodeAdressHandler(node) { + if (!nodeArray.includes(node)) { + nodeArray.push(node); + nodeDict[node] = nodeArray.length; } } @@ -193,14 +177,15 @@ function updateNodeData(node, temperature, humidity, eCO2, TVOC) { // Update the graph liveGraphs[0].updateData(temperature, humidity, eCO2, TVOC); liveGraphs[0].updateGraph(); + + console.log(nodeDict[node]); + console.log(nodeArray); } -createNodeData("34:85:18:B5:CF:20"); - liveGraphs.push(new liveGraph("34:85:18:B5:CF:20")); // Call the function to create the HTML structure for (let i = 1; i <= amountOfNodes; i++) { createNodeData(i); - + liveGraphs.push(new liveGraph(i)); } // make the graphs From 6c3b523208ad6d22a17d664f10712f309f19511f Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Wed, 13 Mar 2024 14:44:32 +0100 Subject: [PATCH 05/14] Update webSocket message format and add classes for websockets --- .../node-code-final/node-code-final.ino | 4 +- docs/rpi-documentation/websockets.md | 38 ++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/arduino/node-code/node-code-final/node-code-final.ino b/arduino/node-code/node-code-final/node-code-final.ino index ff9485a..682b509 100644 --- a/arduino/node-code/node-code-final/node-code-final.ino +++ b/arduino/node-code/node-code-final/node-code-final.ino @@ -60,7 +60,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); // send message to server when Connected - webSocket.sendTXT("Connected"); + webSocket.sendTXT("{\"message\": \"Connected\"}"); break; case WStype_TEXT: // USE_SERIAL.printf("[WSc] get text: %s\n", payload); @@ -86,7 +86,7 @@ void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { // special function to setup websocket void websocketSetup(){ - WiFiMulti.addAP("iotroam", "WFXRLtSwN2"); + WiFiMulti.addAP("iotroam", "vbK9gbDBIB"); WiFiMulti.addAP("LansanKPN-boven", "19sander71vlieland14"); while(WiFiMulti.run() != WL_CONNECTED) { diff --git a/docs/rpi-documentation/websockets.md b/docs/rpi-documentation/websockets.md index e69d2b8..96cc060 100644 --- a/docs/rpi-documentation/websockets.md +++ b/docs/rpi-documentation/websockets.md @@ -14,7 +14,43 @@ We can only use certain ports like 113, 80, 443. These are common ports and are A solution for this is to use a reverse proxy. (See [Reverse Proxy](./Reverse-Proxy.md)) +## Classes + +For the websockets we are going to use 2 classes. One for the nodes and one for the websites. The nodes are going to send data to the website and have multiple variables like temperature, humidity, eCO2, TVOC and sound. The website is going to send data to the nodes like names and settings. For this they have to use a userName and password. + +``` mermaid +classDiagram + +client --> Website : website client +client --> Node : esp32 client +Website --> Node : settings + +namespace raspberry pi clients { + class client { + +MacAdress + sendData() + } + + class Node { + +eCO2 + +Temperature + +Humidity + +TVOC + +Sound + +Settings + changeNodeName(name) + updateData(data) + } + + class Website { + +userName + +password + changeNodeName(data) + } +} +``` + #### Sources: * https://websockets.readthedocs.io/en/stable/index.html -**Written by Sam** \ No newline at end of file +**Written by Sam & Sietse** \ No newline at end of file From 023a1b07813758906c4adf287d6e707d10037520 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 13 Mar 2024 14:45:13 +0100 Subject: [PATCH 06/14] Moved files --- server/{ => Database}/Database.sql | 0 server/{ => Database}/DatabasewithMAC.sql | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename server/{ => Database}/Database.sql (100%) rename server/{ => Database}/DatabasewithMAC.sql (100%) diff --git a/server/Database.sql b/server/Database/Database.sql similarity index 100% rename from server/Database.sql rename to server/Database/Database.sql diff --git a/server/DatabasewithMAC.sql b/server/Database/DatabasewithMAC.sql similarity index 100% rename from server/DatabasewithMAC.sql rename to server/Database/DatabasewithMAC.sql From 6efac7b179ed8fdcfac179c27aa0a917b02cdef5 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 13 Mar 2024 14:45:23 +0100 Subject: [PATCH 07/14] New Flask documentation --- docs/rpi-documentation/Flask.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/rpi-documentation/Flask.md diff --git a/docs/rpi-documentation/Flask.md b/docs/rpi-documentation/Flask.md new file mode 100644 index 0000000..a25412f --- /dev/null +++ b/docs/rpi-documentation/Flask.md @@ -0,0 +1,16 @@ +# Flask + + +## Introduction +Flask is a micro web framework written in Python. It is easy to use and has a lot of documentation. We are going to use Flask to serve our REST api. + +## Cheatsheet +```python +print(f"Hello world have a nice {args}!") +``` +This way you can put variables in a string. This is called f-strings. + + + +## Rules for python +* You can only use one return statement in a function. \ No newline at end of file From b8f8f5ea7ea0610856e4d5c292ce3f85cb2cd700 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 13 Mar 2024 14:45:29 +0100 Subject: [PATCH 08/14] Added flask script --- server/Flask/main.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 server/Flask/main.py diff --git a/server/Flask/main.py b/server/Flask/main.py new file mode 100644 index 0000000..a19a087 --- /dev/null +++ b/server/Flask/main.py @@ -0,0 +1,41 @@ +from flask import Flask, request +import mysql.connector + +app = Flask(__name__) + +@app.route('/') +def index(): +# return getData() + nodeNumber = request.args.get('nodenumber', default = None) + nodeList = request.args.get('nodeList', default = None) +# return nodeNumber + return nodeList + + +def getData(): + try: + mydb = mysql.connector.connect( + host="localhost", + user="root", + password="Dingleberries69!", + database="NodeData" + ) + + cursor = mydb.cursor() + query = "SELECT * FROM `Measurement`" + cursor.execute(query) + result = cursor.fetchall() # Fetch the results + + # Convert the results to a string for display + result_str = ', '.join([str(row) for row in result]) + + cursor.close() + mydb.close() + + return result + except mysql.connector.Error as err: + print("MySQL Error:", err) + return "MySQL Error: " + str(err) + +if __name__ == '__main__': + app.run(debug=True, host='localhost') \ No newline at end of file From 25de52c54b49f8dea6e1a3c7665f038dd13d2c0e Mon Sep 17 00:00:00 2001 From: Sietse Jonker Date: Wed, 13 Mar 2024 14:53:40 +0100 Subject: [PATCH 09/14] Refactor classes and update documentation --- docs/rpi-documentation/websockets.md | 37 +++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/docs/rpi-documentation/websockets.md b/docs/rpi-documentation/websockets.md index 96cc060..d6636f6 100644 --- a/docs/rpi-documentation/websockets.md +++ b/docs/rpi-documentation/websockets.md @@ -21,9 +21,8 @@ For the websockets we are going to use 2 classes. One for the nodes and one for ``` mermaid classDiagram -client --> Website : website client +client --> User : website client client --> Node : esp32 client -Website --> Node : settings namespace raspberry pi clients { class client { @@ -42,7 +41,7 @@ namespace raspberry pi clients { updateData(data) } - class Website { + class User { +userName +password changeNodeName(data) @@ -50,6 +49,38 @@ namespace raspberry pi clients { } ``` +Code of the classes: + +``` python +class client: + def __init__(self, macAdress): + self.macAdress = macAdress + +class node(client): + def __init__(self, name, node, temperature, humidity, eCO2, TVOC, sound): + super().__init__(macAdress) + self.nodeNumber = node + self.temperature = temperature + self.humidity = humidity + self.eCO2 = eCO2 + self.TVOC = TVOC + self.sound = sound + self.name = name + + def updateData(self, temperature, humidity, eCO2, TVOC, sound): + self.temperature = temperature + self.humidity = humidity + self.eCO2 = eCO2 + self.TVOC = TVOC + self.sound = sound + +class Website(client): + def __init__(self, macAdress, user, password): + super().__init__(macAdress) + self.passWord = passWord + self.userName = userName +``` + #### Sources: * https://websockets.readthedocs.io/en/stable/index.html From 3801b074f681e95da0d2206e4c5e652a2b38915b Mon Sep 17 00:00:00 2001 From: Dano van den Bosch Date: Wed, 13 Mar 2024 15:03:11 +0100 Subject: [PATCH 10/14] Arduino oop --- .../node-code/node-code-final/nodeCode.cpp | 18 ++ .../node-code-final/nodeCodeFinal.ino | 227 ++++++++++++++++++ .../node-code-final/nodeCodeHeader.h | 13 +- 3 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 arduino/node-code/node-code-final/nodeCode.cpp create mode 100644 arduino/node-code/node-code-final/nodeCodeFinal.ino diff --git a/arduino/node-code/node-code-final/nodeCode.cpp b/arduino/node-code/node-code-final/nodeCode.cpp new file mode 100644 index 0000000..c21bd92 --- /dev/null +++ b/arduino/node-code/node-code-final/nodeCode.cpp @@ -0,0 +1,18 @@ +#include "arduino.h" +#include "nodeCodeHeader.h" + +nodeReadings::nodeReadings() { +} + +void nodeReadings::resetValues() { + counter = 0; + eCO2 = 0; + TVOC = 0; + temperature = 0; + humidity = 0; + currentMillis = 0; + lastMillis = 0; + errorSGP30 = false; + errorDHT11 = false; + noise = false; +} diff --git a/arduino/node-code/node-code-final/nodeCodeFinal.ino b/arduino/node-code/node-code-final/nodeCodeFinal.ino new file mode 100644 index 0000000..b3f50ee --- /dev/null +++ b/arduino/node-code/node-code-final/nodeCodeFinal.ino @@ -0,0 +1,227 @@ +#include + +nodeReadings esp32Node(); + + + + + + + + + +////////////////////////////////// + + +// Sietse Jonker & Dano van den Bosch +// 28/02/2024 + +// define pins on esp32 +#define MICPIN 6 +#define DHTPIN 7 +#define SCL 9 +#define SDA 8 +#define DHTTYPE DHT11 +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define i2c_adress 0x3c +#define USE_SERIAL Serial + +// define node identification number +#define nodeIdentificationNumber 1 + +// make new objects +Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); +DHT dht(DHTPIN, DHTTYPE); +WiFiMulti WiFiMulti; +Adafruit_SGP30 sgp; +WebSocketsClient webSocket; + +// define variables +uint16_t TVOC_base, eCO2_base; +uint16_t counter = 0; +uint16_t eCO2 = 0; +uint16_t TVOC = 0; +uint16_t interval = 5000; +float temperature = 0; +float humidity = 0; +unsigned long currentMillis; +unsigned long lastMillis; +bool errorSGP30 = false; +bool errorDHT11 = false; +bool noise = false; + +// hexdump function for websockets binary handler +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); +} + +// handler for websocket events +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("{\"message\": \"Connected\"}"); + break; + case WStype_TEXT: + // USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + // USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + case WStype_ERROR: + case WStype_FRAGMENT_TEXT_START: + case WStype_FRAGMENT_BIN_START: + case WStype_FRAGMENT: + case WStype_FRAGMENT_FIN: + break; + } +} + +// special function to setup websocket +void websocketSetup(){ + WiFiMulti.addAP("iotroam", "vbK9gbDBIB"); + WiFiMulti.addAP("LansanKPN-boven", "19sander71vlieland14"); + + while(WiFiMulti.run() != WL_CONNECTED) { + delay(100); + } + + // server address, port and URL + webSocket.begin("145.92.8.114", 80, "/ws"); + + // event handler + webSocket.onEvent(webSocketEvent); + + // try ever 500 again if connection has failed + webSocket.setReconnectInterval(500); +} + +// fucntion to reset the values if needed +void resetValues() { + TVOC_base; + eCO2_base; + counter = 0; + temperature = 0; + humidity = 0; + eCO2 = 0; + TVOC = 0; + noise = false; + lastMillis = 0; + currentMillis = 0; +} + +// function to check for errors in sensors +bool checkForError(){ + if (!sgp.IAQmeasure()) { + Serial.println("SGP30: BAD"); + errorSGP30 = true; + } else { + Serial.println("SGP30: OK"); + errorSGP30 = false; + } + + if (isnan(temperature) || isnan(humidity)){ + Serial.println("DHT11: BAD"); + errorDHT11 = true; + } else { + Serial.println("DHT11: OK"); + errorDHT11 = false; + } + + return false; +} + +// function to update when interval is met (see intervalCounter variable) +void update(){ + // display sensordata on oled screen + displayData(); + + // webSocket.sendTXT("{\"Temp\":\"" + String(temperature) + "\",\"Humi\":\"" + String(humidity) + "\",\"eCO2\":\"" + String(sgp.eCO2) + "\",\"TVOC\":\"" + String(sgp.TVOC) + "\"}"); + webSocket.sendTXT("{\"node\": \"" + String(nodeIdentificationNumber) + "\", \"Temp\":\"" + String(temperature) + "\",\"Humi\":\"" + String(humidity) + "\",\"eCO2\":\"" + String(sgp.eCO2) + "\",\"TVOC\":\"" + String(sgp.TVOC) + "\"}"); + + sgp.getIAQBaseline(&eCO2_base, &TVOC_base); + + // read dht11 sensor + temperature = float(dht.readTemperature()); + humidity = float(dht.readHumidity()); + + // check if any errors occured when reading sensors + checkForError(); +} + +// function to display data on oled screen +void displayData() { + // clear display for new info + display.clearDisplay(); + + // set custom text properties + display.setTextSize(2); + display.setTextColor(SH110X_WHITE); + display.setCursor(0, 0); + + // display info on oled screen + display.println((String) "Temp: " + int(temperature) + "C" + '\n' + + "Humi: " + int(humidity) + "%" + '\n' + + "eCO2: " + int(sgp.eCO2) + '\n' + + "TVOC: " + int(sgp.TVOC)); + + // display the screen + display.display(); +} + +// setup function +void setup() { + // make serial connection at 115200 baud + Serial.begin(115200); + + // tell display what settings to use + display.begin(i2c_adress, true); + display.clearDisplay(); + + // tell sensors to start reading + dht.begin(); + sgp.begin(); + + pinMode(MICPIN, INPUT); + pinMode(DHTPIN, INPUT); + + websocketSetup(); + resetValues(); +} + +// loop function +void loop() { + // loop the websocket connection so it stays alive + webSocket.loop(); + + // update when interval is met + if (currentMillis - lastMillis >= interval){ + lastMillis = millis(); + update(); + } + + // update the counter + currentMillis = millis(); +} diff --git a/arduino/node-code/node-code-final/nodeCodeHeader.h b/arduino/node-code/node-code-final/nodeCodeHeader.h index 7bfeb88..62d17de 100644 --- a/arduino/node-code/node-code-final/nodeCodeHeader.h +++ b/arduino/node-code/node-code-final/nodeCodeHeader.h @@ -1,13 +1,22 @@ #ifndef nodeClass_h #define nodeClass_h + +// include these libraries +#include +#include +#include +#include +#include +#include +#include #include "Arduino.h" + class nodeReadings { private: public: nodeReadings(); - void readDht(); - void printNode(); + void resetValues(); // class code goes here }; #endif \ No newline at end of file From c4880ce0e2cc7478a3a51d81159fa5f6d4d13cd1 Mon Sep 17 00:00:00 2001 From: Dano van den Bosch Date: Wed, 13 Mar 2024 15:47:42 +0100 Subject: [PATCH 11/14] Added the header files to for changing the arduino code to OOP --- .../node-code/node-code-final/headerFile.h | 1 + .../node-code-final/nodeCodeFinal.ino | 14 +++++ .../node-code-final/nodeCodeHeader.cpp | 54 +++++++++++++++++++ .../node-code-final/nodeCodeHeader.h | 16 ++++++ 4 files changed, 85 insertions(+) create mode 100644 arduino/node-code/node-code-final/nodeCodeFinal.ino create mode 100644 arduino/node-code/node-code-final/nodeCodeHeader.cpp create mode 100644 arduino/node-code/node-code-final/nodeCodeHeader.h diff --git a/arduino/node-code/node-code-final/headerFile.h b/arduino/node-code/node-code-final/headerFile.h index d7f2e9e..b7e72e4 100644 --- a/arduino/node-code/node-code-final/headerFile.h +++ b/arduino/node-code/node-code-final/headerFile.h @@ -6,6 +6,7 @@ #include #include #include +#include // define pins on esp32 #define MICPIN 6 diff --git a/arduino/node-code/node-code-final/nodeCodeFinal.ino b/arduino/node-code/node-code-final/nodeCodeFinal.ino new file mode 100644 index 0000000..261048e --- /dev/null +++ b/arduino/node-code/node-code-final/nodeCodeFinal.ino @@ -0,0 +1,14 @@ +#include + +nodeReadings esp32Node(); + + +void setup() { + // put your setup code here, to run once: + esp32Node.setup(); +} + +void loop() { + // put your main code here, to run repeatedly: + esp32Node.loop(); +} diff --git a/arduino/node-code/node-code-final/nodeCodeHeader.cpp b/arduino/node-code/node-code-final/nodeCodeHeader.cpp new file mode 100644 index 0000000..54a3008 --- /dev/null +++ b/arduino/node-code/node-code-final/nodeCodeHeader.cpp @@ -0,0 +1,54 @@ +#include "arduino.h" +#include "nodeCodeHeader.h" + +nodeReadings::nodeReadings() { +} + +void nodeReadings::setup(){ + // make serial connection at 115200 baud + Serial.begin(115200); + + // tell display what settings to use + display.begin(i2c_adress, true); + display.clearDisplay(); + + // tell sensors to start reading + dht.begin(); + sgp.begin(); + + pinMode(MICPIN, INPUT); + pinMode(DHTPIN, INPUT); + + websocketSetup(); + resetValues(); + +} + +void nodeReadings::loop() { + // loop the websocket connection so it stays alive + webSocket.loop(); + + // update when interval is met + if (currentMillis - lastMillis >= interval){ + lastMillis = millis(); + update(); + } + + // update the counter + currentMillis = millis(); +} + + + +void nodeReadings::resetValues() { + counter = 0; + eCO2 = 0; + TVOC = 0; + temperature = 0; + humidity = 0; + currentMillis = 0; + lastMillis = 0; + errorSGP30 = false; + errorDHT11 = false; + noise = false; +} \ No newline at end of file diff --git a/arduino/node-code/node-code-final/nodeCodeHeader.h b/arduino/node-code/node-code-final/nodeCodeHeader.h new file mode 100644 index 0000000..82644cf --- /dev/null +++ b/arduino/node-code/node-code-final/nodeCodeHeader.h @@ -0,0 +1,16 @@ +#ifndef nodeReading_h +#define nodeReading_h + +#include "Arduino.h" +# + +class nodeReadings() { + + public: + nodeReadings(); + void setup(); + void resetValues(); + private: +}; + +#endif \ No newline at end of file From 10eee1218930c84e7e5089ad285adfc046c5c83f Mon Sep 17 00:00:00 2001 From: Dano van den Bosch Date: Wed, 13 Mar 2024 16:06:10 +0100 Subject: [PATCH 12/14] Arduino oop adding functions from the original aduino code --- .../node-code/node-code-final/headerFile.h | 3 ++- .../node-code-final/nodeCodeFinal.ino | 17 ++++++++++------- .../node-code-final/nodeCodeHeader.cpp | 19 ++++++++++++++----- .../node-code-final/nodeCodeHeader.h | 6 ++++-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/arduino/node-code/node-code-final/headerFile.h b/arduino/node-code/node-code-final/headerFile.h index b7e72e4..1ef0ea7 100644 --- a/arduino/node-code/node-code-final/headerFile.h +++ b/arduino/node-code/node-code-final/headerFile.h @@ -17,10 +17,11 @@ #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define i2c_adress 0x3c +#define OLED_RESET -1 // QT-PY / XIAO #define USE_SERIAL Serial // make new objects -Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); +Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); DHT dht(DHTPIN, DHTTYPE); WiFiMulti WiFiMulti; Adafruit_SGP30 sgp; diff --git a/arduino/node-code/node-code-final/nodeCodeFinal.ino b/arduino/node-code/node-code-final/nodeCodeFinal.ino index 261048e..eb3c086 100644 --- a/arduino/node-code/node-code-final/nodeCodeFinal.ino +++ b/arduino/node-code/node-code-final/nodeCodeFinal.ino @@ -2,13 +2,16 @@ nodeReadings esp32Node(); - -void setup() { - // put your setup code here, to run once: - esp32Node.setup(); +void setup() +{ + // put your setup code here, to run once: + esp32Node.setup(); + esp32Node.websocketSetup(); + esp32Node.resetValues(); } -void loop() { - // put your main code here, to run repeatedly: - esp32Node.loop(); +void loop() +{ + // put your main code here, to run repeatedly: + esp32Node.loop(); } diff --git a/arduino/node-code/node-code-final/nodeCodeHeader.cpp b/arduino/node-code/node-code-final/nodeCodeHeader.cpp index 54a3008..d2a2ec5 100644 --- a/arduino/node-code/node-code-final/nodeCodeHeader.cpp +++ b/arduino/node-code/node-code-final/nodeCodeHeader.cpp @@ -18,9 +18,6 @@ void nodeReadings::setup(){ pinMode(MICPIN, INPUT); pinMode(DHTPIN, INPUT); - - websocketSetup(); - resetValues(); } @@ -38,8 +35,6 @@ void nodeReadings::loop() { currentMillis = millis(); } - - void nodeReadings::resetValues() { counter = 0; eCO2 = 0; @@ -51,4 +46,18 @@ void nodeReadings::resetValues() { errorSGP30 = false; errorDHT11 = false; noise = false; +} + +// hexdump function for websockets binary handler +void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { + const uint8_t* src = (const uint8_t*) mem; + USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); + for(uint32_t i = 0; i < len; i++) { + if(i % cols == 0) { + USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); + } + USE_SERIAL.printf("%02X ", *src); + src++; + } + USE_SERIAL.printf("\n"); } \ No newline at end of file diff --git a/arduino/node-code/node-code-final/nodeCodeHeader.h b/arduino/node-code/node-code-final/nodeCodeHeader.h index 82644cf..20ed3e4 100644 --- a/arduino/node-code/node-code-final/nodeCodeHeader.h +++ b/arduino/node-code/node-code-final/nodeCodeHeader.h @@ -2,13 +2,15 @@ #define nodeReading_h #include "Arduino.h" -# +#include "headerFile.h" -class nodeReadings() { + +class nodeReadings { public: nodeReadings(); void setup(); + void loop(); void resetValues(); private: }; From 47f1f393da6a71d2386114943ce78239d0c3e62d Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 13 Mar 2024 17:55:50 +0100 Subject: [PATCH 13/14] Added parameters --- server/Flask/main.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/server/Flask/main.py b/server/Flask/main.py index a19a087..d2951f0 100644 --- a/server/Flask/main.py +++ b/server/Flask/main.py @@ -5,14 +5,11 @@ app = Flask(__name__) @app.route('/') def index(): -# return getData() - nodeNumber = request.args.get('nodenumber', default = None) - nodeList = request.args.get('nodeList', default = None) -# return nodeNumber - return nodeList + node = request.args.get('node', default = None) + dataType = request.args.get('dataType', default = None) + return getData(node, dataType) - -def getData(): +def getData(node, dataType): try: mydb = mysql.connector.connect( host="localhost", @@ -20,9 +17,14 @@ def getData(): password="Dingleberries69!", database="NodeData" ) - +#turn this into a switch statement cursor = mydb.cursor() - query = "SELECT * FROM `Measurement`" + if node: + query = f"SELECT * FROM Measurement WHERE NodeID = {node}" + elif dataType: + query = f"SELECT * FROM Measurement WHERE Type = '{dataType}'" + else: + query = "SELECT * FROM `Measurement`" cursor.execute(query) result = cursor.fetchall() # Fetch the results From 23bfbdada52200953372f0b365f05f51fd34f478 Mon Sep 17 00:00:00 2001 From: Sam Hos Date: Wed, 13 Mar 2024 17:56:05 +0100 Subject: [PATCH 14/14] Removed PK nodeID at measurement --- server/Database/DatabasewithMAC.sql | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/server/Database/DatabasewithMAC.sql b/server/Database/DatabasewithMAC.sql index 32c3c8a..131cdb7 100644 --- a/server/Database/DatabasewithMAC.sql +++ b/server/Database/DatabasewithMAC.sql @@ -1,5 +1,5 @@ -- MySQL Script generated by MySQL Workbench --- Fri Mar 8 12:25:17 2024 +-- Wed Mar 13 16:04:58 2024 -- Model: New Model Version: 1.0 -- MySQL Workbench Forward Engineering @@ -44,14 +44,11 @@ ENGINE = InnoDB; -- ----------------------------------------------------- CREATE TABLE IF NOT EXISTS `NodeData`.`Measurement` ( `NodeID` INT NOT NULL, + `TimeStamp` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `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`) + FOREIGN KEY (`NodeID`) REFERENCES `NodeData`.`Node` (`NodeID`) ON DELETE NO ACTION ON UPDATE NO ACTION)