I have basically rebuilt the solution based on an example of the PubSubClient library.. (example used: ESP-MQTT-AWS-IoT-Core/PubSubClient.ino at master · debsahu/ESP-MQTT-AWS-IoT-Core · GitHub)
They are not useing the shadow logic (i.e if I publish to /get, IoT will publish to /get/accepted)
What I have noticed in the meantime is that if I subscribe directly to the topic I am publishing in, the subscription works (pub and sub to i.e /update/accepted). Only when another process (in my case AWS IOT) is publishing to the topic i don't get the message (even though i see the message when debugging in the aws console). Very strange.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <time.h>
#define emptyString String()
#include "secrets.h"
const int MQTT_PORT = 8883;
const char AWS_IOT_UPDATE[] = "$aws/things/chicken-door/shadow/name/door/update";
const char AWS_IOT_UPDATE_DELTA[] = "$aws/things/chicken-door/shadow/name/door/update/delta";
const char AWS_IOT_GET_SHADOW[] = "$aws/things/chicken-door/shadow/name/door/get";
const char AWS_IOT_SHADOW_ACCEPTED[] = "$aws/things/chicken-door/shadow/name/door/get/accepted";
WiFiClientSecure net;
PubSubClient client(net);
unsigned long lastMillis = 0;
void messageReceived(char *topic, byte *payload, unsigned int length)
{
if (strcmp(topic,AWS_IOT_SHADOW_ACCEPTED)==0){
Serial.printf("Received Message from topic : %s", AWS_IOT_SHADOW_ACCEPTED);
}
if (strcmp(topic,AWS_IOT_UPDATE_DELTA)==0){
Serial.printf("Received Message from topic : %s", AWS_IOT_SHADOW_ACCEPTED);
}
Serial.print("Received [");
Serial.print(topic);
Serial.print("]: ");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
}
void pubSubErr(int8_t MQTTErr)
{
if (MQTTErr == MQTT_CONNECTION_TIMEOUT)
Serial.print("Connection tiemout");
else if (MQTTErr == MQTT_CONNECTION_LOST)
Serial.print("Connection lost");
else if (MQTTErr == MQTT_CONNECT_FAILED)
Serial.print("Connect failed");
else if (MQTTErr == MQTT_DISCONNECTED)
Serial.print("Disconnected");
else if (MQTTErr == MQTT_CONNECTED)
Serial.print("Connected");
else if (MQTTErr == MQTT_CONNECT_BAD_PROTOCOL)
Serial.print("Connect bad protocol");
else if (MQTTErr == MQTT_CONNECT_BAD_CLIENT_ID)
Serial.print("Connect bad Client-ID");
else if (MQTTErr == MQTT_CONNECT_UNAVAILABLE)
Serial.print("Connect unavailable");
else if (MQTTErr == MQTT_CONNECT_BAD_CREDENTIALS)
Serial.print("Connect bad credentials");
else if (MQTTErr == MQTT_CONNECT_UNAUTHORIZED)
Serial.print("Connect unauthorized");
}
void connectToMqtt(bool nonBlocking = false)
{
Serial.print("MQTT connecting ");
while (!client.connected())
{
if (client.connect(THINGNAME))
{
if (!client.subscribe(AWS_IOT_SHADOW_ACCEPTED))
pubSubErr(client.state());
if (!client.subscribe(AWS_IOT_UPDATE_DELTA))
pubSubErr(client.state());
Serial.println("connected!");
}
else
{
Serial.print("failed, reason -> ");
pubSubErr(client.state());
if (!nonBlocking)
{
Serial.println(" < try again in 5 seconds");
delay(5000);
}
else
{
Serial.println(" <");
}
}
if (nonBlocking)
break;
}
}
void connectToWiFi(String init_str)
{
if (init_str != emptyString)
Serial.print(init_str);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(1000);
}
if (init_str != emptyString)
Serial.println("ok!");
}
void checkWiFiThenMQTT(void)
{
connectToWiFi("Checking WiFi");
connectToMqtt();
}
unsigned long previousMillis = 0;
const long interval = 5000;
void checkWiFiThenMQTTNonBlocking(void)
{
connectToWiFi(emptyString);
if (millis() - previousMillis >= interval && !client.connected()) {
previousMillis = millis();
connectToMqtt(true);
}
}
void checkWiFiThenReboot(void)
{
connectToWiFi("Checking WiFi");
Serial.print("Rebooting");
ESP.restart();
}
void sendData(String value)
{
DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(3) + 100);
JsonObject root = jsonBuffer.to<JsonObject>();
JsonObject state = root.createNestedObject("state");
JsonObject state_reported = state.createNestedObject("reported");
state_reported["value"] = value;
Serial.printf("Sending [%s]: ", AWS_IOT_UPDATE);
serializeJson(root, Serial);
Serial.println();
char shadow[measureJson(root) + 1];
serializeJson(root, shadow, sizeof(shadow));
if (!client.publish(AWS_IOT_UPDATE, shadow, false))
pubSubErr(client.state());
}
void getShadow(void)
{
Serial.printf("Requesting Shadow [%s]: ", AWS_IOT_GET_SHADOW);
if (!client.publish(AWS_IOT_GET_SHADOW, "", false))
pubSubErr(client.state());
}
void setup()
{
Serial.begin(115200);
delay(5000);
Serial.println();
Serial.println();
#ifdef ESP32
WiFi.setHostname(THINGNAME);
#else
WiFi.hostname(THINGNAME);
#endif
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
connectToWiFi(String("Attempting to connect to SSID: ") + String(WIFI_SSID));
net.setCACert(AWS_CERT_CA);
net.setCertificate(AWS_CERT_CRT);
net.setPrivateKey(AWS_CERT_PRIVATE);
client.setServer(AWS_IOT_ENDPOINT, MQTT_PORT);
client.setCallback(messageReceived);
connectToMqtt();
getShadow();
}
void loop()
{
if (!client.connected())
{
checkWiFiThenMQTT();
}
else
{
client.loop();
if (millis() - lastMillis > 5000)
{
lastMillis = millis();
sendData("closed");
}
}
}