#include <WiFi.h>
#include <HTTPClient.h>
#include <PubSubClient.h>
// Wi-Fi Credentials
const char* ssid = "Wokwi-GUEST"; // Use your real WiFi if not using Wokwi sim
const char* password = "";
// MQTT Settings
const char* mqtt_server = "mqtt.eclipseprojects.io"; // <-- Your Node-RED/MQTT broker IP
const char* mqtt_topic = "ESP32"; // <-- Must match topic in Node-RED
// OpenWeatherMap API
const char* weather_url = "http://api.openweathermap.org/data/2.5/weather?q=Cape%20Town&appid=36e6822e65b17aac7b918af60ee321db&units=metric";
WiFiClient espClient;
PubSubClient client(espClient);
void connectWiFi() {
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
void connectMQTT() {
while (!client.connected()) {
Serial.print("Connecting to MQTT...");
String clientId = "ESP32Client-" + String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" trying again in 5 seconds");
delay(5000);
}
}
}
void fetchWeatherAndPublish() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(weather_url);
http.setTimeout(10000); // 10s timeout
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println("Weather data received:");
Serial.println(payload);
if (client.connected()) {
// Safely copy string to C-style buffer
size_t len = payload.length() + 1;
char mqttPayload[len];
payload.toCharArray(mqttPayload, len);
client.publish(mqtt_topic, mqttPayload);
Serial.println("Published to Node-RED via MQTT");
} else {
Serial.println("MQTT not connected");
}
} else {
Serial.print("HTTP Error: ");
Serial.println(httpCode);
}
http.end();
} else {
Serial.println("WiFi not connected");
}
}
void setup() {
Serial.begin(115200);
connectWiFi();
client.setServer(mqtt_server, 1883);
client.setBufferSize(2048); // To fit full JSON response
connectMQTT();
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
fetchWeatherAndPublish();
delay(60000); // every 60 seconds
}