#include "WiFi.h"
#include <PubSubClient.h>
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT broker details
const char* mqtt_server = "192.168.29.98"; // Replace with your laptop's IP address
const int mqtt_port = 1883;
// MQTT client setup
WiFiClient espClient;
PubSubClient client(espClient);
// Device details
String device_id;
// Function to connect to WiFi
void connectToWiFi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// Generate device ID from MAC address
device_id = "device_" + WiFi.macAddress();
Serial.println("Device ID: " + device_id);
}
// Function to connect to MQTT broker
void connectToMQTT() {
while (!client.connected()) {
Serial.println("Connecting to MQTT broker...");
if (client.connect(device_id.c_str())) {
Serial.println("MQTT connected");
// Publish availability status
client.publish((device_id + "/status").c_str(), "{\"status\":\"online\"}", true);
// Send discovery information
sendDeviceDiscovery();
// Subscribe to device-specific command topic
client.subscribe((device_id + "/commands").c_str());
Serial.println("Subscribed to: " + device_id + "/commands");
} else {
Serial.print("Failed to connect. State: ");
Serial.println(client.state());
delay(5000);
}
}
}
// Function to send device discovery data
void sendDeviceDiscovery() {
String discoveryPayload = "{";
discoveryPayload += "\"id\":\"" + device_id + "\",";
discoveryPayload += "\"firmware\":\"1.0.0\",";
discoveryPayload += "\"capabilities\":[\"temperature\",\"battery\",\"humidity\"]";
discoveryPayload += "}";
client.publish("global/discovery", discoveryPayload.c_str());
Serial.println("Published discovery data: " + discoveryPayload);
}
// Function to send telemetry data
void sendTelemetry() {
// Simulate sensor data
float temperature = random(20, 30) + random(0, 100) / 100.0;
float battery = random(30, 100) / 10.0;
float humidity = random(30, 70) + random(0, 100) / 100.0;
unsigned long timestamp = millis(); // Placeholder timestamp
String telemetryPayload = "{";
telemetryPayload += "\"temperature\":" + String(temperature, 2) + ",";
telemetryPayload += "\"battery\":" + String(battery, 2) + ",";
telemetryPayload += "\"humidity\":" + String(humidity, 2) + ",";
telemetryPayload += "\"timestamp\":" + String(timestamp);
telemetryPayload += "}";
client.publish((device_id + "/telemetry").c_str(), telemetryPayload.c_str());
Serial.println("Published telemetry to " + device_id + "/telemetry: " + telemetryPayload);
}
// Callback function to handle incoming MQTT messages
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.println(topic);
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println("Message: " + message);
// Handle reboot command
if (String(topic).endsWith("/commands") && message == "{\"action\":\"reboot\"}") {
Serial.println("Reboot command received!");
ESP.restart();
}
}
void setup() {
Serial.begin(115200);
// Connect to WiFi
connectToWiFi();
// Set MQTT server and callback
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
// Connect to MQTT broker
connectToMQTT();
}
void loop() {
if (!client.connected()) {
connectToMQTT();
}
client.loop();
// Send telemetry every 5 seconds
static unsigned long lastTelemetry = 0;
if (millis() - lastTelemetry >= 5000) {
sendTelemetry();
lastTelemetry = millis();
}
}