How was the room app created

Getting the data

Firstly, I've bought the ESP8266 microcontroller with a WiFi module NodeMCU v3, and a temperature and humidity sensor.

my esp8266

I've installed the firmware, using a NodeMCU flasher, connected the sensor, and written the code (in Arduino IDE) that connects the controller to the Internet (via WiFi), reads the data, and sends it to my database.

#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include "DHT.h" // Settings for the sensor #define DHT11PIN 2 #define DHTPIN 14 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); // Settings for the WiFi const char* ssid = "ssid"; const char* password = "password"; // wifi WiFiClientSecure wifiClient; // Where to send the data const char* serverUrl = "https://url_to_script.php"; void setup() { // Connect to the network WiFi.begin(ssid, password); // Wait for the Wi-Fi to connect while (WiFi.status() != WL_CONNECTED) { delay(1000); dht.begin(); } wifiClient.setFingerprint("AA:AA:AA:AA:AA..."); // Turning off the certificate validation: // wifiClient.setInsecure(); } void loop() { // Reading temperature or humidity takes about 250 milliseconds float h = dht.readHumidity(); // Read temperature as Celsius float t = dht.readTemperature(); // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { // || isnan(f) Serial.println(F("Failed to read from DHT sensor!")); return; } if (WiFi.status() == WL_CONNECTED) { HTTPClient http; // Open the connection http.begin(wifiClient, serverUrl); // Specify content type for JSON http.addHeader("Content-Type", "application/json"); // Prepare the payload int valueToSend = changing; String payload = "{\"pHumidity\":" + String(h) + ",\"cTemperature\":" + String(t) + "}"; // Send POST request int httpResponseCode = http.POST(payload); // Print response if (httpResponseCode > 0) { Serial.println("POST Success"); Serial.print("Response Code: "); Serial.println(httpResponseCode); Serial.println("Response: "); Serial.println(http.getString()); } else { Serial.println("POST Failed"); Serial.print("Error Code: "); Serial.println(httpResponseCode); } // Close connection http.end(); } else { Serial.println("WiFi not connected"); } // Send the data every minute or so delay(59500); }

There was a problem with sending the data, because of the strict HTTPS setting on my server. I've used http requests sending via curl in order to find the problem.

It turned out that the SSL/TLS verification didn't work, because NodeMCU doesn't have (unlike browsers) built in verification via CA. The fingerprint for the SSL certificate had to be entered manually.

Code of the script to read the data:

<?php $servername = "sql server"; $username = "user"; $password = "pass"; $dbname = "db"; // Set the content type to JSON header('Content-Type: application/json'); // Read the incoming JSON payload $data = json_decode(file_get_contents('php://input'), true); // Extract the integer value from the payload if (isset($data['cTemperature'])) { try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $query = $conn->prepare("INSERT INTO data (date, humidity, temperature) VALUES (:date, :humidity, :temperature)"); $query->bindParam(':date', date("Y-m-d H:i:s")); $query->bindParam(':humidity', $data['pHumidity']); $query->bindParam(':temperature', $data['cTemperature']); $query->execute(); } catch(PDOException $e) { echo $e->getMessage(); } } else { // Handle missing value echo json_encode(["error" => "Invalid data received"]); } ?>

Database

The table looks like this:

id date humidity temperature
2 2024-12-11 13:01:16 64 22.3
3 2024-12-11 13:00:15 64 22.4

Web app

It's a Python Flask application. It retrieves data from DB, creates plots as a base64 data stream and displays them.

The form to select dates sends a POST request to regenerate the plots with data within the dates. AJAX refreshes the plots.