阿里云MQTT與物聯(lián)網(wǎng)設(shè)備

## 阿里云MQTT應(yīng)用
* 連接前首先要新建一個實例,可以選擇按量付費,很小的量基本很便宜。
* 連接PC的MQTT需要3個參數(shù)。MQTT測試軟件中已經(jīng)添加對阿里云的支持;
```
? ? ? ? //實例 ID,購買后從控制臺獲取
? ? ? ? String instanceId = "post-cn-";
? ? ? ? //此處填寫購買得到的 MQTT 接入點域名
? ? ? ? String brokerUrl = "post-cn-.mqtt.aliyuncs.com";
? ? ? ? //此處填寫阿里云帳號 AccessKey
? ? ? ? String accessKey = "";
? ? ? ? //此處填寫阿里云帳號 SecretKey
? ? ? ? String secretKey = "";
? ? ? ? //此處填寫在 MQ 控制臺創(chuàng)建的 Topic,作為 MQTT 的一級 Topic
? ? ? ? String parentTopic = "lot";
? ? ? ? //此處填寫客戶端 ClientId,需要保證全局唯一,oupId 需要先在 MQ 控制臺創(chuàng)建
? ? ? ? String clientId = "GID_XXXX@@@XXXX";
? ? ? ? MqttClient Aliyun_client;
```
* 以上代碼就可以連接到阿里云的MQTT了,這是一個PC的連接方式;
* 如果是智能硬件不是這樣的。
* 需要連接阿里云的 物聯(lián)網(wǎng)平臺 。
* 首先開通一個免費的 公共實例?
* 新建一個產(chǎn)品,選擇產(chǎn)品的類型,或者自定義類型。(物模型)
* 類型決定了功能,功能大體分為3類:
* ### 屬性?
```
上傳數(shù)據(jù)用的。
上行(Alink JSON):
請求Topic: /sys/{productKey}/{deviceName}/thing/event/property/post
響應(yīng)Topic: /sys/{productKey}/{deviceName}/thing/event/property/post_reply
```
設(shè)備上報至平臺的屬性信息,可以通過服務(wù)端訂閱、云產(chǎn)品流轉(zhuǎn)轉(zhuǎn)發(fā)到您的服務(wù)器或其他云產(chǎn)品。具體Topic和數(shù)據(jù)格式,請參見設(shè)備屬性上報。
* ### 服務(wù)
```
服務(wù)端可以下發(fā)設(shè)置屬性和調(diào)用服務(wù)指令。
?
下行(透傳):
請求Topic:/sys/{productKey}/{deviceName}/thing/model/down_raw
響應(yīng)Topic:/sys/{productKey}/{deviceName}/thing/model/down_raw_reply
下行(Alink JSON):
默認模塊
請求Topic:/sys/{productKey}/{deviceName}/thing/service/{tsl.service.identifier}
響應(yīng)Topic:/sys/{productKey}/{deviceName}/thing/service/{tsl.service.identifier}_reply
```
* ### 事件
```
上報事件信息;主要作用在于上報一些緊急信息,比如錯誤等
上行(Alink JSON):
默認模塊
請求Topic:/sys/{productKey}/{deviceName}/thing/event/{tsl.event.identifier}/post
響應(yīng)Topic:/sys/{productKey}/{deviceName}/thing/event/{tsl.event.identifier}/post_reply
```
## 8266 中的應(yīng)用
```
/*
? ? Created:? ? 2021-01-06
? ? Author:? ? ??創(chuàng)客宏萬
? ? Explain:? ? MQTT幫助類。
*/
#include <ArduinoJson.h>
#include <aliyun_mqtt.h>?
#include <SHA256.h>
#include "config.h"
#define PRODUCT_KEY ""? ? ? ? ? ? ? ? ? ? ? ? //產(chǎn)品ID
#define DEVICE_NAME ""? ? ? ? ? ? ? ? //設(shè)備名
#define DEVICE_SECRET "" //設(shè)備key
#define DEV_VERSION? ? ? ?"S-TH-WIFI-v1.0-"? ? ? ? //固件版本信息?
#define ALINK_BODY_FORMAT? ? ? ? ?"{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST? ? ?"/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"? ? ? ? ? //發(fā)布 設(shè)備屬性上報?
#define ALINK_TOPIC_PROP_POSTRSP? "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"? ? //訂閱 云端響應(yīng)屬性上報
#define ALINK_TOPIC_PROP_SET? ? ? "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"? ? ? ? ?//訂閱 設(shè)備屬性設(shè)置
#define ALINK_METHOD_PROP_POST? ? "thing.event.property.post"? ? ? ?//上報地址 固定
#define ALINK_TOPIC_DEV_INFO? ? ? "/ota/device/inform/" PRODUCT_KEY "/" DEVICE_NAME ""? ? ? //發(fā)布 設(shè)備上報固件升級信息
#define ALINK_VERSION_FROMA? ? ? "{\"id\": 123,\"params\": {\"version\": \"%s\"}}"
WiFiClient espClient;? ? ? ? ? ?// 定義wifiClient實例
PubSubClient client(espClient); // 定義PubSubClient的實例? ??
long lastMsg = 0;
//MQTT收到消息的回調(diào)
void callback(char* topic, byte* payload, unsigned int length)
{
? ? Serial.print("Message arrived [");
? ? Serial.print(topic);
? ? Serial.print("] ");
? ? payload[length] = '\0';
? ? Serial.println((char*)payload);
? ? if (strstr(topic, ALINK_TOPIC_PROP_SET))
? ? {
? ? ? ? StaticJsonBuffer<100> jsonBuffer;
? ? ? ? JsonObject& root = jsonBuffer.parseObject(payload);
? ? ? ? if (!root.success())
? ? ? ? {
? ? ? ? ? ? Serial.println("parseObject() failed");
? ? ? ? ? ? return;
? ? ? ? }
? ? }? ??
}
//MQTT初始化
void Mqtt_begin()
{
? ? client.setCallback(callback);? ? ? ? //設(shè)定回調(diào)方式,當ESP8266收到訂閱消息時會調(diào)用此方法
}
//MQTT連接
void Mqtt_reconnect()
{
? ? while (!client.connected())
? ? {
? ? ? ? //MQTT? 阿里云
? ? ? ? if (connectAliyunMQTT(client, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET))? ? ?//三元數(shù)據(jù) 連接到阿里云
? ? ? ? {
? ? ? ? ? ? Serial.println("connected");
? ? ? ? ? ? // 連接成功時訂閱主題
? ? ? ? ? ? //client.subscribe(ALINK_TOPIC);
? ? ? ? }
? ? ? ? Serial.print("failed, rc=");
? ? ? ? Serial.print(client.state());
? ? ? ? Serial.println(" try again in 5 seconds");
? ? ? ? // Wait 5 seconds before retrying
? ? ? ? delay(5000);
? ? }
}
void mqtt_interval_post()
{
? ? char param[512];
? ? char jsonBuf[1024];
? ? //sprintf(param, "{\"MotionAlarmState\":%d}", digitalRead(13));
? ? sprintf(param, "{\"CurrentHumidity\":11,\"CurrentTemperature\":22}");
? ? sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
? ? Serial.println(jsonBuf);
? ? client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
}
void mqtt_loop()
{
? ? if (!client.connected())
? ? {
? ? ? ? Mqtt_reconnect();
? ? }
? ? client.loop();
}
```