Reputation: 172
WiFiClientSecure net;
PubSubClient client(net);
char lwtMessage[256];
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
connectWiFi();
// Prepare JSON for Last Will Testament (LWT)
StaticJsonDocument<512> doc;
doc["state"]["reported"]["deviceStatus"] = "OFFLINE";
serializeJson(doc, lwtMessage, sizeof(lwtMessage));
connectAWSIoT();
}
void connectAWSIoT() {
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
client.setServer(AWS_IOT_ENDPOINT, AWS_IOT_PORT);
client.setCallback(messageHandler);
Serial.print("Connecting to AWS IoT...");
while (!client.connect(CLIENT_ID, "", "", SHADOW_UPDATE_TOPIC, 1, true, lwtMessage)) {
Serial.print(client.state());
delay(1000);
}
Serial.println("Connected to AWS!");
client.subscribe(AWS_IOT_TOPIC_SUB);
publishDeviceStatus("ONLINE");
}
I am not able to connect to AWS when setting the client function with Last Will Testimony. Basically whenever the ESP-32 goes offline, the shadow must be updated to reflect that the device is offline. But its not able to connect to AWS in the first place, and client.state()
outputs -4
, which is connection timeout I guess.
Complete code
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <WiFi.h>
#include <ArduinoJson.h>
#include "secrets.h" // Include credentials
#include "DHT.h"
// Relay Pin
#define RELAY_PIN 5 // GPIO5
#define DHTPIN 4 //GPIO4
#define DHTTYPE DHT11 // DHT 11
DHT dht = DHT(DHTPIN, DHTTYPE);
float h;
float t;
unsigned long turnOffTime = 0; // Store turn-off time
unsigned long lastOnlineUpdate = 0;
// Create JSON buffer for Last Will Testament
char lwtMessage[256];
WiFiClientSecure net;
PubSubClient client(net);
// Connect to WiFi
void connectWiFi() {
Serial.print("Connecting to WiFi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected!");
}
// Connect to AWS IoT
void connectAWSIoT() {
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
client.setServer(AWS_IOT_ENDPOINT, AWS_IOT_PORT);
client.setCallback(messageHandler);
Serial.print("Connecting to AWS IoT...");
while (!client.connect(CLIENT_ID, "", "", SHADOW_UPDATE_TOPIC, 1, true, lwtMessage)) {
Serial.print(client.state());
delay(1000);
}
Serial.println("Connected to AWS!");
client.subscribe(AWS_IOT_TOPIC_SUB);
publishDeviceStatus("ONLINE");
}
void publishDeviceStatus(String status) {
StaticJsonDocument<256> doc;
doc["state"]["reported"]["status"] = status;
char jsonBuffer[256];
serializeJson(doc, jsonBuffer);
client.publish(SHADOW_UPDATE_TOPIC, jsonBuffer);
}
// Message handler to turn relay ON/OFF
void messageHandler(char* topic, byte* payload, unsigned int length) {
Serial.print("Message received");
String msg = "";
for (int i = 0; i < length; i++) {
msg += (char)payload[i];
}
Serial.print("Received: ");
Serial.println(msg);
int duration = msg.toInt(); // Convert MQTT message to integer
if (duration > 0) {
Serial.println("Turning ON the motor for " + String(duration) + " minutes.");
digitalWrite(RELAY_PIN, HIGH); // Turn ON motor
turnOffTime = millis() + (duration * 60000); // Set turn-off time
}
}
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
connectWiFi();
// Prepare JSON for Last Will Testament (LWT)
StaticJsonDocument<512> doc;
doc["state"]["reported"]["deviceStatus"] = "OFFLINE";
serializeJson(doc, lwtMessage, sizeof(lwtMessage));
connectAWSIoT();
}
void sendOnlineStatus() {
StaticJsonDocument<200> doc;
doc["state"]["reported"]["deviceStatus"] = "ONLINE";
char buffer[256];
serializeJson(doc, buffer);
client.publish(SHADOW_UPDATE_TOPIC, buffer);
}
void loop() {
if (!client.connected()) {
connectAWSIoT();
}
h = dht.readHumidity();
t = dht.readTemperature();
client.loop(); // Keep MQTT connection alive
// ✅ Send "ONLINE" status every 30 seconds, NOT on every loop iteration
if (millis() - lastOnlineUpdate > 30000) {
sendOnlineStatus();
lastOnlineUpdate = millis();
}
// Check if it's time to turn OFF the motor
if (turnOffTime > 0 && millis() >= turnOffTime) {
Serial.println("Turning OFF the motor.");
digitalWrite(RELAY_PIN, LOW); // Turn OFF motor
turnOffTime = 0; // Reset timer
}
}
Upvotes: 0
Views: 24