v#include <WiFi.h>
#include <HTTPClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// === CONFIGURE THESE ===
const char* ssid = "Room wifi";
const char* password = "4c617b32d0";
const char* mqtt_server = "mqtt.eclipseprojects.io";
const int mqtt_port = 1883;
const char* apiKey = "ea560a5d49c911b62926a27679617854"; // OpenWeatherMap API key
// MQTT Topics
const char* cityTopic = "weather/city23";
const char* weatherTopic = "weather/data23";
const char* coordsTopic = "weather/coords23"; // Topic for lat/lon/temp/desc
// WiFi & MQTT clients
WiFiClient espClient;
PubSubClient client(espClient);
// Global variable to store the city name
String city = "Cape Town";
void setup() {
Serial.begin(115200);
delay(1000);
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi Connected!");
// MQTT setup
client.setServer(mqtt_server, mqtt_port);
client.setCallback(mqttCallback);
connectMQTT();
}
void loop() {
if (!client.connected()) {
connectMQTT();
}
client.loop();
// Fetch and send weather data every 10 seconds
fetchAndSendWeatherData();
delay(10000);
}
void connectMQTT() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32WeatherClient")) {
Serial.println("connected.");
client.subscribe(cityTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5 seconds...");
delay(5000);
}
}
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
if (String(topic) == cityTopic) {
payload[length] = '\0';
city = String((char*)payload);
Serial.print("City updated to: ");
Serial.println(city);
}
}
void fetchAndSendWeatherData() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String cityEncoded = city;
cityEncoded.replace(" ", "%20");
String url = "http://api.openweathermap.org/data/2.5/weather?q=" + cityEncoded + "&units=metric&appid=" + String(apiKey);
Serial.print("Requesting URL: ");
Serial.println(url);
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
Serial.println("Raw weather JSON:");
Serial.println(payload);
DynamicJsonDocument doc(2048);
DeserializationError error = deserializeJson(doc, payload);
if (!error) {
String description = doc["weather"][0]["description"];
float temp = doc["main"]["temp"];
float feels_like = doc["main"]["feels_like"];
int humidity = doc["main"]["humidity"];
int pressure = doc["main"]["pressure"];
float wind_speed = doc["wind"]["speed"];
int wind_deg = doc["wind"]["deg"];
int clouds = doc["clouds"]["all"];
long sunrise = doc["sys"]["sunrise"];
long sunset = doc["sys"]["sunset"];
float latitude = doc["coord"]["lat"];
float longitude = doc["coord"]["lon"];
// ========== Full Weather JSON ==========
DynamicJsonDocument jsonToSend(1024);
jsonToSend["city"] = city;
jsonToSend["temperature"] = temp;
jsonToSend["description"] = description;
jsonToSend["feels_like"] = feels_like;
jsonToSend["humidity"] = humidity;
jsonToSend["pressure"] = pressure;
jsonToSend["wind_speed"] = wind_speed;
jsonToSend["wind_deg"] = wind_deg;
jsonToSend["clouds"] = clouds;
jsonToSend["sunrise"] = sunrise;
jsonToSend["sunset"] = sunset;
char weatherBuffer[1024];
serializeJson(jsonToSend, weatherBuffer);
Serial.println("Publishing weather data:");
Serial.println(weatherBuffer);
client.publish(weatherTopic, weatherBuffer);
// ========== Coordinates JSON (with temp + desc) ==========
DynamicJsonDocument coordJson(512);
coordJson["city"] = city;
coordJson["latitude"] = latitude;
coordJson["longitude"] = longitude;
coordJson["temperature"] = temp;
coordJson["description"] = description;
char coordBuffer[512];
serializeJson(coordJson, coordBuffer);
Serial.println("Publishing coordinates:");
Serial.println(coordBuffer);
client.publish(coordsTopic, coordBuffer);
} else {
Serial.print("JSON parsing error: ");
Serial.println(error.c_str());
}
} else {
Serial.print("HTTP request failed. Code: ");
Serial.println(httpCode);
}
http.end();
} else {
Serial.println("WiFi not connected");
}
}