#include <WiFi.h>
#include <HTTPClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <time.h>
// Wi-Fi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT broker settings
const char* mqtt_server = "mqtt.eclipseprojects.io";
const char* mqtt_topic = "weather/data";
// OpenWeatherMap settings
const char* apiKey = "0897ec6053fd70b586341d0cc5e0d88a";
const char* city = "CapeTown";
const char* countryCode = "ZA";
// Global clients
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void reconnectMQTT() {
while (!mqttClient.connected()) {
Serial.print("Connecting to MQTT...");
if (mqttClient.connect("ESP32WeatherClient")) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.println(mqttClient.state());
delay(2000);
}
}
}
// Helper to convert UNIX timestamp to readable time
String formatTime(unsigned long unixTime) {
time_t rawTime = unixTime;
struct tm *timeinfo = localtime(&rawTime);
char buffer[16];
sprintf(buffer, "%02d:%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
return String(buffer);
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println(" connected!");
mqttClient.setServer(mqtt_server, 1883);
String cityEncoded = "Cape%20Town";
String apiUrl = "http://api.openweathermap.org/data/2.5/weather?q=" + cityEncoded + "," + countryCode + "&appid=" + apiKey + "&units=metric";
HTTPClient http;
http.begin(apiUrl);
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
Serial.println("Weather data received.");
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("JSON parse error: ");
Serial.println(error.c_str());
return;
}
// Extract fields
float temp = doc["main"]["temp"];
int humidity = doc["main"]["humidity"];
const char* desc = doc["weather"][0]["description"];
float wind = doc["wind"]["speed"];
unsigned long sunriseUnix = doc["sys"]["sunrise"];
unsigned long sunsetUnix = doc["sys"]["sunset"];
// Prepare outgoing JSON
StaticJsonDocument<512> outDoc;
outDoc["city"] = city;
outDoc["country"] = countryCode;
outDoc["temp"] = temp;
outDoc["humidity"] = humidity;
outDoc["description"] = desc;
outDoc["wind"] = wind;
outDoc["sunrise"] = formatTime(sunriseUnix);
outDoc["sunset"] = formatTime(sunsetUnix);
char buffer[512];
serializeJson(outDoc, buffer);
reconnectMQTT();
mqttClient.publish(mqtt_topic, buffer);
Serial.println("Published weather to MQTT:");
Serial.println(buffer);
} else {
Serial.print("HTTP error: ");
Serial.println(httpCode);
}
http.end();
}
void loop() {
mqttClient.loop(); // Keep MQTT alive
delay(60000); // Fetch every 60s (or adjust as needed)
}