阿里云MQTT与物联网设备

## 阿里云MQTT应用
* 连接前首先要新建一个实例,可以选择按量付费,很小的量基本很便宜。
* 连接PC的MQTT需要3个参数。MQTT测试软件中已经添加对阿里云的支持;
```
//实例 ID,购买后从控制台获取
String instanceId = "post-cn-";
//此处填写购买得到的 MQTT 接入点域名
String brokerUrl = "post-cn-.mqtt.aliyuncs.com";
//此处填写阿里云帐号 AccessKey
String accessKey = "";
//此处填写阿里云帐号 SecretKey
String secretKey = "";
//此处填写在 MQ 控制台创建的 Topic,作为 MQTT 的一级 Topic
String parentTopic = "lot";
//此处填写客户端 ClientId,需要保证全局唯一,oupId 需要先在 MQ 控制台创建
String clientId = "GID_XXXX@@@XXXX";
MqttClient Aliyun_client;
```
* 以上代码就可以连接到阿里云的MQTT了,这是一个PC的连接方式;
* 如果是智能硬件不是这样的。
* 需要连接阿里云的 物联网平台 。
* 首先开通一个免费的 公共实例
* 新建一个产品,选择产品的类型,或者自定义类型。(物模型)
* 类型决定了功能,功能大体分为3类:
* ### 属性
```
上传数据用的。
上行(Alink JSON):
请求Topic: /sys/{productKey}/{deviceName}/thing/event/property/post
响应Topic: /sys/{productKey}/{deviceName}/thing/event/property/post_reply
```
设备上报至平台的属性信息,可以通过服务端订阅、云产品流转转发到您的服务器或其他云产品。具体Topic和数据格式,请参见设备属性上报。
* ### 服务
```
服务端可以下发设置属性和调用服务指令。
下行(透传):
请求Topic:/sys/{productKey}/{deviceName}/thing/model/down_raw
响应Topic:/sys/{productKey}/{deviceName}/thing/model/down_raw_reply
下行(Alink JSON):
默认模块
请求Topic:/sys/{productKey}/{deviceName}/thing/service/{tsl.service.identifier}
响应Topic:/sys/{productKey}/{deviceName}/thing/service/{tsl.service.identifier}_reply
```
* ### 事件
```
上报事件信息;主要作用在于上报一些紧急信息,比如错误等
上行(Alink JSON):
默认模块
请求Topic:/sys/{productKey}/{deviceName}/thing/event/{tsl.event.identifier}/post
响应Topic:/sys/{productKey}/{deviceName}/thing/event/{tsl.event.identifier}/post_reply
```
## 8266 中的应用
```
/*
Created: 2021-01-06
Author: 创客宏万
Explain: MQTT帮助类。
*/
#include <ArduinoJson.h>
#include <aliyun_mqtt.h>
#include <SHA256.h>
#include "config.h"
#define PRODUCT_KEY "" //产品ID
#define DEVICE_NAME "" //设备名
#define DEVICE_SECRET "" //设备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" //发布 设备属性上报
#define ALINK_TOPIC_PROP_POSTRSP "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply" //订阅 云端响应属性上报
#define ALINK_TOPIC_PROP_SET "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set" //订阅 设备属性设置
#define ALINK_METHOD_PROP_POST "thing.event.property.post" //上报地址 固定
#define ALINK_TOPIC_DEV_INFO "/ota/device/inform/" PRODUCT_KEY "/" DEVICE_NAME "" //发布 设备上报固件升级信息
#define ALINK_VERSION_FROMA "{\"id\": 123,\"params\": {\"version\": \"%s\"}}"
WiFiClient espClient; // 定义wifiClient实例
PubSubClient client(espClient); // 定义PubSubClient的实例
long lastMsg = 0;
//MQTT收到消息的回调
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); //设定回调方式,当ESP8266收到订阅消息时会调用此方法
}
//MQTT连接
void Mqtt_reconnect()
{
while (!client.connected())
{
//MQTT 阿里云
if (connectAliyunMQTT(client, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET)) //三元数据 连接到阿里云
{
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();
}
```