#include "secrets.h"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <NTPClient.h>
#include <Wire.h>
// WiFi network details
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASSWORD;
// AWS IoT Core endpoint
const char* aws_endpoint = AWS_IOT_ENDPOINT;
const int aws_port = 8883;
// AWS IoT Core MQTT Topics
#define AWS_IOT_PUBLISH_TOPIC "esp32/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "esp32/sub"
// DHT sensor setup (mocked, not used in this example)
#define DHTPIN 15
#define DHTTYPE 22 // Using DHT22
// Mock GPS data
float latitude = 37.2669776;
float longitude = 9.8776592;
float gpsspeed = 0;
String items[] = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
// WiFi and MQTT Client
WiFiClientSecure net;
PubSubClient client(net);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 0);
void connectToWiFi() {
Serial.print("Connecting to Wi-Fi");
WiFi.begin(ssid,password );
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected to Wi-Fi");
}
void connectToAWS() {
// Configure WiFiClientSecure to use the AWS IoT device credentials
while (!timeClient.update()) {
timeClient.forceUpdate();
}
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
// Connect to the MQTT broker on the AWS endpoint
client.setServer(aws_endpoint, aws_port);
Serial.println("Connecting to AWS IoT");
while (!client.connected()) {
Serial.print(".");
if (client.connect(THINGNAME)) { // Use a unique client ID
Serial.println("Connected to AWS IoT");
client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);
} else {
Serial.println("AWS IoT Connection Failed! Retrying...");
Serial.println(client.state());
delay(1000);
}
}
Serial.println("CONNECTED TO AWS TOO");
}
void publishMessage(const char *topic, String payload) {
if (client.publish(topic, payload.c_str()),true) {
Serial.println("Message published: " + payload);
} else {
Serial.println("Message failed to publish.");
Serial.println(client.state());
}
}
void generateMockGPSData() {
latitude += 0.001;
longitude += 0.001;
gpsspeed += 1;
if (gpsspeed > 100) {
gpsspeed = 0;
}
}
// void generateAndPublishMockData() {
// // Example mock function to update GPS data
// generateMockGPSData(); // Make sure this function exists and updates the GPS data variables
// // Use DynamicJsonDocument with a calculated capacity
// // Since we're not including items, the capacity needed is reduced
// const size_t capacity = JSON_OBJECT_SIZE(3) + 60; // Adjusted capacity for latitude, longitude, and speed
// DynamicJsonDocument doc(capacity);
// doc["latitude"] = latitude;
// doc["longitude"] = longitude;
// doc["speed"] = gpsspeed;
// String payload;
// serializeJson(doc, payload);
// publishMessage(AWS_IOT_PUBLISH_TOPIC, payload);
// }
void generateAndPublishMockData() {
// Update GPS data
generateMockGPSData();
// Calculate the length of the items array dynamically
int itemsLength = sizeof(items) / sizeof(items[0]);
// Use DynamicJsonDocument for runtime-determined size
const size_t capacity = JSON_ARRAY_SIZE(itemsLength) + JSON_OBJECT_SIZE(7) + itemsLength * JSON_OBJECT_SIZE(1);
DynamicJsonDocument doc(capacity);
// GPS data
doc["timestamp"]["S"] = THINGNAME;
doc["device_id"]["S"] = THINGNAME;
doc["latitude"]["N"] = String(latitude, 6); // More precision for coordinates
doc["longitude"]["N"] = String(longitude, 6);
doc["speed"]["N"] = String(gpsspeed);
// Items list
JsonArray itemsArray = doc.createNestedObject("items").createNestedArray("L");
for (int i = 0; i < itemsLength; i++) {
JsonObject item = itemsArray.createNestedObject();
item["S"] = items[i]; // Use actual items from the array
}
// Current time in seconds since Jan 1, 1970
long currentTime = timeClient.getEpochTime();
doc["created_at"]["N"] = String(currentTime);
// Serialize JSON to String
String payload;
serializeJson(doc, payload);
// Publish
publishMessage(AWS_IOT_PUBLISH_TOPIC, payload);
}
void setup() {
Serial.begin(115200);
connectToWiFi();
connectToAWS();
timeClient.begin();
}
void loop() {
if (!client.connected()) {
connectToAWS();
}
client.loop();
timeClient.update();
generateAndPublishMockData();
delay(2000); // Publish every 5 seconds
}