之前的 例子 是使用username,password,clientid连接物联网平台的,但是阿里云物联网平台提供productKey,deviceName,deviceSerect来连接平台的,下面的例子是使用设备三元组计算出userName,passWord,clientId后再连接平台的,这样只要替换设备三元组信息就可以了。使用到的库是:PubSubClient,Crypto。
#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <SHA256.h> #define MQTT_PORT (1883) #define SHA256HMAC_SIZE (32) #define ALINK_CLIENTID_FORMAT "%s.%s|securemode=2,signmethod=hmacsha256,timestamp=%s|" // Update these with values suitable for your network. const char* ssid = "***"; const char* password = "***"; const char *mqtt_server = "***.iot-as-mqtt.cn-shanghai.aliyuncs.com"; const char *productKey = "***"; const char *deviceName = "***"; const char *deviceSecret = "***"; WiFiClient espClient; PubSubClient client(espClient); unsigned long lastMsg = 0; int value = 0; void setup_wifi() { delay(10); //We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } randomSeed(micros()); Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char* topic, byte* payload, unsigned int length) { Serial.print("Message arrived ["); Serial.print(topic); Serial.print("] "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); } String hmac256(const String &signcontent, const String &ds) { byte hashCode[SHA256HMAC_SIZE]; SHA256 sha256; const char *key = ds.c_str(); size_t keySize = ds.length(); sha256.resetHMAC(key, keySize); sha256.update((const byte *)signcontent.c_str(), signcontent.length()); sha256.finalizeHMAC(key, keySize, hashCode, sizeof(hashCode)); String sign = ""; for (byte i = 0; i < SHA256HMAC_SIZE; ++i) { sign += "0123456789ABCDEF"[hashCode[i] >> 4]; sign += "0123456789ABCDEF"[hashCode[i] & 0xf]; } return sign; } void reconnect() { //Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Create a random client ID long times = millis(); String timestamp = String(times); char mqtt_clientId[256] = ""; sprintf(mqtt_clientId, ALINK_CLIENTID_FORMAT, productKey, deviceName, timestamp.c_str()); char mqtt_user[100] = ""; sprintf(mqtt_user, "%s&%s", deviceName, productKey); String signcontent = "clientId"; signcontent += productKey; signcontent += "."; signcontent += deviceName; signcontent += "deviceName"; signcontent += deviceName; signcontent += "productKey"; signcontent += productKey; signcontent += "timestamp"; signcontent += timestamp; String pwd = hmac256(signcontent, deviceSecret); char mqtt_pwd[100] = ""; strcpy(mqtt_pwd, pwd.c_str()); // Attempt to connect if (client.connect(mqtt_clientId, mqtt_user, mqtt_pwd)) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(12000); } } } void setup() { //pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output Serial.begin(115200); setup_wifi(); client.setServer(mqtt_server, MQTT_PORT); client.setCallback(callback); } void loop() { if (!client.connected()) { reconnect(); } client.loop(); unsigned long now = millis(); if (now - lastMsg > 5000) { lastMsg = now; ++value; char topic[50] = ""; char msg[100] = ""; sprintf(topic, "/%s/%s/user/update", productKey, deviceName); sprintf(msg, "hello world #%ld", value); Serial.print("Publish message: "); Serial.println(msg); client.publish(topic, msg); } }