#include <WiFi.h>
#include <MQTTPubSubClient.h>
#include <ArduinoJson.h>
#include <FirebaseESP32.h>
//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"
// Device ID
#define DEVICE_UID "1X"
// Your Firebase Project Web API Key
#define API_KEY "AIzaSyAq2JIh8irvtVUzeSm_T1_PQDEHUaXoqEs"
// Your Firebase Realtime database URL
#define DATABASE_URL "https://iot-project-c7797-default-rtdb.europe-west1.firebasedatabase.app"
// Device Location config
String device_location = "";
// Firebase Realtime Database Object
FirebaseData fbdo;
// Firebase Authentication Object
FirebaseAuth auth;
// Firebase configuration Object
FirebaseConfig config;
// Firebase database path
String databasePath = "";
// Firebase Unique Identifier
String fuid = "901831953598";
// Stores the elapsed time from device start up
// Dummy counter to test initial firebase updates
int count = 0;
// Store device authentication status
bool isAuthenticated = false;
// used values
int pirState = 0;
float lux = 0;
String lightState = "OFF";
// Wi-Fi Credentials
const char *ssid = "Wokwi-GUEST";
const char *password = "";
// MQTT Broker
const char *mqtt_server = "broker.mqttdashboard.com";
const int mqtt_port = 1883;
#define MQTT_ID "lightsub"
// MQTT Topics
const char *topic = "esp32/sensors/data";
const char *topic2 = "node/lightstate";
const int ledPin = 2; // GPIO pin connected to the LED
WiFiClient client;
MQTTPubSubClient mqtt;
// Callback function for MQTT messages (correct signature)
void onMessage(const char *payload, unsigned int length) {
Serial.println("Message received:");
Serial.print("Payload: ");
Serial.println(payload);
// Parse JSON
StaticJsonDocument<128> jsonDoc;
DeserializationError error = deserializeJson(jsonDoc, payload, length);
if (error) {
Serial.print("Failed to parse JSON: ");
Serial.println(error.c_str());
return;
}
// Check for sensor data (pir and lux)
if (jsonDoc.containsKey("pir") && jsonDoc.containsKey("lux")) {
pirState = jsonDoc["pir"];
lux = jsonDoc["lux"];
// Print extracted values
Serial.println("Parsed Data:");
Serial.print("PIR State: ");
Serial.println(pirState);
Serial.print("LDR Lux: ");
Serial.println(lux);
// Control LED
if (pirState == 1 && lux > 15) {
digitalWrite(ledPin, HIGH); // Turn LED on
lightState = "ON";
Serial.println("LED ON: Motion detected and lux > 15");
} else {
digitalWrite(ledPin, LOW); // Turn LED off
lightState = "OFF";
Serial.println("LED OFF: Conditions not met");
}
}
// Check for manual light control (lightState)
if (jsonDoc.containsKey("lightState")) {
String command = jsonDoc["lightState"];
Serial.println("Manual led control signal");
if (command == "ON") {
digitalWrite(ledPin, HIGH);
lightState = "ON";
Serial.println("LED turned ON manually");
} else if (command == "OFF") {
digitalWrite(ledPin, LOW);
lightState = "OFF";
Serial.println("LED turned OFF manually");
} else {
Serial.println("Invalid lightState command");
return;
}
}
// Specify the key value for our data and append it to our path
String pirPath = databasePath + "/pir";
String luxPath = databasePath + "/lux";
String lightStatePath = databasePath + "/lightState";
// Create JSON object
FirebaseJson dataJson;
dataJson.set("pir", pirState);
dataJson.set("lux", lux);
dataJson.set("lightState", lightState);
// Write JSON to Firebase
String jsonPath = "Light1";
if (Firebase.setJSON(fbdo, jsonPath.c_str(), dataJson)) {
Serial.println("JSON data written to Firebase:");
dataJson.toString(Serial, true); // Print JSON data to Serial
} else {
Serial.println("Failed to write JSON: " + fbdo.errorReason());
}
}
void firebase_init() {
// configure firebase API Key
config.api_key = API_KEY;
// configure firebase realtime database url
config.database_url = DATABASE_URL;
// Enable WiFi reconnection
Firebase.reconnectWiFi(true);
Serial.println("Sign up new user...");
// Sign in to firebase Anonymously
if (Firebase.signUp(&config, &auth, "", ""))
{
Serial.println("Success");
isAuthenticated = true;
// Set the database path where updates will be loaded for this device
databasePath = "/" + device_location;
fuid = auth.token.uid.c_str();
}
else
{
Serial.printf("Failed, %s\n", config.signer.signupError.message.c_str());
isAuthenticated = false;
}
// Assign the callback function for the long running token generation task, see addons/TokenHelper.h
config.token_status_callback = tokenStatusCallback;
// Initialise the firebase library
Firebase.begin(&config, &auth);
}
// Reconnect to MQTT Broker
void connect() {
connect_to_wifi:
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println(" Connected!");
connect_to_host:
Serial.print("Connecting to host...");
client.stop();
while (!client.connect("broker.mqttdashboard.com", 1883)) {
Serial.print(".");
delay(1000);
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected");
goto connect_to_wifi;
}
}
Serial.println(" Connected!");
Serial.print("Connecting to MQTT broker...");
mqtt.disconnect();
while (!mqtt.connect(MQTT_ID, "public", "public")) {
Serial.print(".");
delay(1000);
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi disconnected");
goto connect_to_wifi;
}
if (client.connected() != 1) {
Serial.println("WiFiClient disconnected");
goto connect_to_host;
}
}
Serial.println(" Connected!");
// Subscribe to topic with correct callback signature
mqtt.subscribe(topic, [](const char *payload, unsigned int length) {
onMessage(payload, length); // Forward to onMessage handler
});
// Subscribe to topic2 with correct callback signature
mqtt.subscribe(topic2, [](const char *payload, unsigned int length) {
onMessage(payload, length);
});
Serial.println("Subscribed to topics: esp32/sensors/data ; node/lightstate ");
}
void setup() {
// Initialize Serial Monitor
Serial.begin(115200);
pirState = 0;
lux = 0;
lightState = "OFF";
// Configure LED pin as output
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW); // Ensure LED is off initially
// Connect to WiFi
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
// Initialize MQTT client
mqtt.begin(client);
// Connect to WiFi, host, and MQTT broker
connect();
// Initialise firebase configuration and signup anonymously
firebase_init();
}
void loop() {
// Ensure MQTT connection is maintained
mqtt.update();
if (!mqtt.isConnected()) {
connect();
}
}