Tuya MQTT standard protocol on an esp32
Sorry if this isn't the right place for this post, Just wondering if someone maybe able to help
I'm trying to connect to the Tuya IoT Developer platform using https://developer.tuya.com/en/docs/iot/ ... 5nphxrj8f1 as a reference.
I've created a product in the developer portal already but can't seem to get my esp32 to connect to the Tuya MQTT servers.
Here's what I've written
Code: Select all
#include <Seeed_mbedtls.h>
#define KEY_SIZE 32 // 256 bits for HMAC-SHA256
#define OUTPUT_SIZE 32 // SHA-256 outputs 32 bytes
// Your 256-bit secret key (32 bytes)
String str = "DeviceSecret";
const uint8_t* deviceSecret = (const uint8_t*)str.c_str();
#include <WiFi.h>
WiFiClient wifiClient;
#include <time.h> // include time library
// (utc+) TZ in hours
long timezone = 0;
byte daysavetime = 0;
#include <PubSubClient.h>
PubSubClient client(wifiClient);
// Set up wifi
#define SSID "SSID"
#define WIFI_PWD "pwd"
// MQTT set up
//MQTT server
#define MQTT_BROKER "m1.tuyacn.com"
#define MQTT_PORT (8883)
String compute_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *input, size_t input_len) {
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *md_info;
uint8_t hmac_output[32]; // SHA-256 outputs 32 bytes
mbedtls_md_init(&ctx);
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
if (md_info == NULL) {
Serial.println("Failed to get MD info for SHA256");
mbedtls_md_free(&ctx);
return String();
}
if (mbedtls_md_setup(&ctx, md_info, 1) != 0) {
Serial.println("Failed to setup MD context");
mbedtls_md_free(&ctx);
return String();
}
if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) {
Serial.println("Failed to start HMAC");
mbedtls_md_free(&ctx);
return String();
}
if (mbedtls_md_hmac_update(&ctx, input, input_len) != 0) {
Serial.println("Failed to update HMAC");
mbedtls_md_free(&ctx);
return String();
}
if (mbedtls_md_hmac_finish(&ctx, hmac_output) != 0) {
Serial.println("Failed to finish HMAC");
mbedtls_md_free(&ctx);
return String();
}
mbedtls_md_free(&ctx);
// Convert the HMAC output to a hexadecimal string
String hmac_str;
for (int i = 0; i < sizeof(hmac_output); i++) {
char buf[3];
sprintf(buf, "%02x", hmac_output[i]);
hmac_str += buf;
}
return hmac_str;
}
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
Serial.print("Connecting to " SSID);
WiFi.begin(SSID, WIFI_PWD); // attempt to connect to an existing wifi
//Wait for wifi to connect
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(" . ");
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
//Time Server Set up
Serial.println("Contacting Time Server");
configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
delay(1000);
time_t now;
time(&now);
//MQTT Credentials set up
String MQTT_USERNAME = "deviceID|signMethod=hmacSha256,timestamp=" + String(now) +",secureMode=1,accessType=1";
// Your original const char* message
const char *message = "deviceId=deviceID,timestamp=,secureMode=1,accessType=1";
// The String you want to insert
String additional = String(now);
// Convert the original message to a String
String messageString = String(message);
// Insert the additional String at the 43rd position
size_t insertPos = 42; // Position to insert
messageString = messageString.substring(0, insertPos) + additional + messageString.substring(insertPos);
// Convert the modified message back to const char*
const char* final_message = messageString.c_str();
// Compute HMAC-SHA256
String MQTT_PWD = compute_hmac_sha256(deviceSecret, KEY_SIZE, (const uint8_t *)final_message, strlen(final_message));
Serial.println(now);
Serial.print("MQTT_PWD: ");
Serial.println(MQTT_PWD);
Serial.println("init successfull");
String tuyalink = "tuyalink_DeviceId";
// Handle MQTT connection.
client.setServer(MQTT_BROKER, MQTT_PORT); // set broker settings
while (! client.connected()) { // check connected status
if ( client.connect(tuyalink.c_str(),MQTT_USERNAME.c_str(),MQTT_PWD.c_str())){ // connect with random id
Serial.println("MQTT connected."); // report success
//client.subscribe("Test/ra542");
} else {
Serial. printf (" failed , rc=%d try again in 5 seconds", client.state ()); // report error
delay(5000); // wait 5 seconds
}
}
}
// the loop function runs over and over again forever
void loop() {
Serial.println("Hello World!");
delay(5000);
}
In my final code I've replaced the deviceId and DeviceSecret with the credentials I've gotten from tuya
On Connecting to the MQTT Server I get
Code: Select all
failed , rc=-4 try again in 5 seconds failed
According to https://pubsubclient.knolleary.net/api#state rc -4 means the server didn't respond within the keepalive time.
I've tried increasing the keep alive time to 60s but that doesn't change anything
Code: Select all
uint16_t keepAlive = 60000;
client.setKeepAlive(keepAlive);
When Testing with test.mosquitto.org and port 1883 without credentials it seems to work fine.
I'm not sure where I'm going wrong here. Any ideas/pointers would be greatly appreciated