概述
在阿里云IoT平台中,MQTT协议是一种重要的连接方式,可以用于设备与平台之间的通信。通过配置设备的Topic和订阅规则,设备可以在平台上发布/订阅消息,实现设备状态的监控、控制和数据的传输。同时,阿里云IoT平台还提供了MQTT SDK和API,方便开发者快速接入平台,实现物联网应用的开发和部署。
我们可以基于Mqtt接口,将自己的设备接入阿里云的IOT平台,这里主要记录实现方法,具体阿里云上的产品、设备创建不再记录,阿里云文档上比较详细了。
下载阿里云的LinkSdk
地址:https://help.aliyun.com/zh/iot/user-guide/download-device-sdks
选择C LinkSdk:
我这里没有使用LinkSdk里的mqtt,而是使用上次移植的mosquito,这里下载这个LinkSdk主要是用里面的认证部分(aiot_mqtt_sign.c)。
示例代码
下面代码中,利用aiotMqttSign函数生成clientId,用户名和密码。
aliy.cpp
#include "mosquittopp.h" #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <iostream> extern int aiotMqttSign(const char *productKey, const char *deviceName, const char *deviceSecret, char clientId[150], char username[65], char password[65]); using namespace std; #define EXAMPLE_PRODUCT_KEY "hj1skja****" #define EXAMPLE_DEVICE_NAME "FZ00**" #define EXAMPLE_DEVICE_SECRET "7bb8c2cfb69***************************" class MyMqtt : public mosqpp::mosquittopp { public: MyMqtt(const char *id, const char *host, int port, const char *username, const char *password) : mosquittopp(id) { mosqpp::lib_init(); // 初始化mosquitto库 username_pw_set(username, password); // 设置用户名和密码 connect(host, port, 60); // 连接到MQTT服务器 } ~MyMqtt() { disconnect(); // 断开连接 mosqpp::lib_cleanup(); // 清理mosquitto库 } void on_connect(int rc) { if (rc == 0) { std::cout << "连接成功" << std::endl; subscribe(NULL, "/sys/hj1skj****/FZ00**/thing/event/property/post_reply", 0); // 订阅主题 subscribe(NULL, "/sys/hj1skj****/FZ00**/thing/event/property/set", 0); // 订阅主题 } else { std::cout << "连接失败" << std::endl; } } void on_message(const struct mosquitto_message *message) { std::cout << "收到消息:" << (char *)message->payload << std::endl; } }; int main(int argc, char *argv[]) { const char *mqtt_host = "hj1skja****.iot-as-mqtt.cn-shanghai.aliyuncs.com"; int mqtt_port = 1883; char clientId[256] = {0}; char username[65] = {0}; char password[65] = {0}; if (aiotMqttSign(EXAMPLE_PRODUCT_KEY, EXAMPLE_DEVICE_NAME, EXAMPLE_DEVICE_SECRET, clientId, username, password) < 0) { printf("aiotMqttSign error\n"); return -1; } printf("clientId: %s\n", clientId); printf("username: %s\n", username); printf("password: %s\n", password); MyMqtt mqtt(clientId, mqtt_host, mqtt_port, username, password); mqtt.loop_start(); // 开始循环 string msg="{\"params\":{\"CurrentTemperature\":27.37,\"CurrentHumidity\":56.8,\"version\":\"ver1.0.1\",\"GeoLocation\":{\"Longitude\":113.987817,\"Latitude\":34.987895,\"Altitude\":123.1,\"CoordinateSystem\":1}}}"; while (1) { // 发布消息 mqtt.publish(NULL, "/sys/hj1skj****/FZ00**/thing/event/property/post", msg.size(), msg.c_str()); sleep(5); } mqtt.loop_stop(); // 停止循环 return 0; }
这个代码中是定时上传一串模拟的温湿度数据,这个Json的字段名称和阿里云IOT平台上的设备模型字段保持一致,这样平台才能够正常解析。
{ "params":{ "CurrentTemperature":27.37, "CurrentHumidity":56.8, "version":"ver1.0.1", "GeoLocation":{ "Longitude":113.987817, "Latitude":34.987895, "Altitude":123.1, "CoordinateSystem":1 } }, "time":"2022-03-05_00:45:26" }
测试效果
将代码编译测试后,放在板子上运行,需要注意的时候,板子上的系统要支持域名解析,配置好DNS。订阅与发布的消息主题与平台上也要保持一致。
运行:
./aliy_mqtt macSrc: clientIdFZ0***&hj1skja****deviceNameFZ0001productKeyhj1s****timestamp2524608000000 clientId: FZ00***&hj1skja****|timestamp=2524608000000,_v=paho-c-1.0.0,securemode=3,signmethod=hmacsha256,lan=C| username: FZ0***&hj1skjaDSpk password: 6CC4F399F59A1CDB2D355DB449BB741AF5C3713C9F9B************** 连接成功 收到消息:{"params":{"CurrentTemperature":27.37,"CurrentHumidity":56.8,"version":"ver1.0.1","GeoLocation":{"Longitude":113.987817,"Latitude":34.987895,"Altitude":123.1,"CoordinateSystem":1}},"time":"2022-03-05_00:45:26"} 收到消息:{"code":200,"data":{},"id":"null","message":"success","method":"thing.event.property.post","version":"1.0"} 收到消息:{"params":{"CurrentTemperature":27.37,"CurrentHumidity":56.8,"version":"ver1.0.1","GeoLocation":{"Longitude":113.987817,"Latitude":34.987895,"Altitude":123.1,"CoordinateSystem":1}},"time":"2022-03-05_00:45:26"} 收到消息:{"code":200,"data":{},"id":"null","message":"success","method":"thing.event.property.post","version":"1.0"}
平台上显示设备已经在线:
查看一下设备数据日志:
设备物理模型数据: