ESP32通过MQTT协议连接OneNet平台上报信息
创作时间:
作者:
@小白创作中心
ESP32通过MQTT协议连接OneNet平台上报信息
引用
CSDN
1.
https://blog.csdn.net/u011574457/article/details/141157655
本文将详细介绍如何使用ESP32通过MQTT协议连接OneNet平台并上报信息。文章将从OneNet平台操作和ESP32代码实现两个方面进行讲解,帮助读者快速掌握这一技术。
一、OneNet平台操作
1. 创建产品
在OneNet平台上,首先需要创建一个产品。进入"产品开发"页面,选择"创建产品",产品品类可以随意选择,智能化方式选择"设备接入"。
2. 创建设备
创建设备时,需要在"设备管理"页面选择"创建设备"。在创建设备时,需要选择之前创建的产品,并为设备命名。
3. 设置物模型
物模型相当于定义需要上报的信息。在"产品开发"页面,选择"功能定义",然后"设置物模型"。点击"新建自定义功能点",填写需要上报的数据格式及信息。完成后记得保存。
4. 制作Token
Token相当于密码,需要使用OneNet官方提供的Token计算工具。需要的数据包括产品ID、设备ID、未来时间戳和access_key。
计算Token的参数如下:
- res : products/{产品id}/devices/{设备名字}
- et : 未来时间戳(unix格式)
- key: access_key
二、ESP32代码实现
1. 头文件定义
#ifndef __MQTT_H
#define __MQTT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mqtt.h"
#include "mqtt_client.h"
#include "esp_log.h"
// 具体参数需要根据OneNet文档进行设置
#define ESP_MQTT_URI "mqtt://mqtts.heclouds.com"
#define ESP_MQTT_PORT 1883
#define ESP_CLIENT_ID "test" // 设备id
#define ESP_PRODUCT_ID "产品ID" // 产品id
#define ESP_MQTT_TOKEN "复制自己生成的Token" // TOKEN
#define ONENET_TOPIC_SUB "$sys/产品ID/设备ID/thing/property/post/reply" // 订阅主题
#define ONENET_TOPIC_PUBLISH "$sys/产品ID/设备ID/thing/property/post" // 上报主题
// MQTT状态定义
typedef enum {
MQTT_STATE_ERROR = -1,
MQTT_STATE_UNKNOWN = 0,
MQTT_STATE_INIT,
MQTT_STATE_CONNECTED,
MQTT_STATE_WAIT_TIMEOUT,
} mqtt_client_state_t;
static const char *TAG = "MQTT"; // LOG头
esp_mqtt_client_handle_t client; // MQTT句柄
bool mqtt_connect_flag=false; // 连接标志位 是否连接成功
static mqtt_client_state_t mqtt_sta = MQTT_STATE_UNKNOWN; // MQTT状态
// MQTT初始化函数声明
void mqtt_app_init(void);
// MQTT发布消息函数声明
int mqtt_data_publish(const char* theme, const char* value);
// MQTT状态获取函数声明
mqtt_client_state_t mqtt_get_sta();
#endif
2. 函数实现
2.1 初始化函数
void mqtt_app_init(void)
{
// 结构体赋值
esp_mqtt_client_config_t mqtt_cfg = {
.uri = ESP_MQTT_URI, // 域名
.port = ESP_MQTT_PORT, // 端口
.client_id = ESP_CLIENT_ID, // 设备id
.username = ESP_PRODUCT_ID, // 产品id
.password = ESP_MQTT_TOKEN, // TOKEN
};
// 初始化
client = esp_mqtt_client_init(&mqtt_cfg);
// 注册回调
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
// 启动
esp_mqtt_client_start(client);
}
2.2 回调函数
static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
{
esp_mqtt_client_handle_t client = event->client;
int msg_id;
switch (event->event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
msg_id = esp_mqtt_client_subscribe(client, ONENET_TOPIC_SUB, 0);
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
if(msg_id != -1)
{
mqtt_connect_flag=true;
mqtt_sta =MQTT_STATE_CONNECTED;
}
else
{
mqtt_connect_flag=false;
mqtt_sta =MQTT_STATE_UNKNOWN;
}
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
msg_id = mqtt_data_publish("mylog","suss");
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
mqtt_connect_flag=true;
mqtt_sta =MQTT_STATE_CONNECTED;
break;
case MQTT_EVENT_UNSUBSCRIBED:
mqtt_connect_flag=false;
mqtt_sta =MQTT_STATE_UNKNOWN;
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
break;
case MQTT_EVENT_ERROR:
mqtt_sta = MQTT_STATE_ERROR;
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
return ESP_OK;
}
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
mqtt_event_handler_cb(event_data);
}
2.3 上报函数
int mqtt_data_publish(const char* theme, const char* value)
{
char data_str[256];
int msg_id=-1;
// 使用sprintf格式化字符串 组装ONENET数据包
snprintf(data_str, sizeof(data_str), "{\"id\": \"123\",\"version\": \"1.0\",\"params\":{\"%s\":{\"value\":\"%s\"}}}", theme, value);
if(mqtt_connect_flag==true)
{
msg_id = esp_mqtt_client_publish(client, ONENET_TOPIC_PUBLISH,data_str, 0, 0, 0);
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
// 检查发布结果
if (msg_id != -1)
{
ESP_LOGI(TAG, "Sent publish successful, msg_id=%d", msg_id);
}
else
{
ESP_LOGE(TAG, "Failed to publish message");
}
}
else
{
ESP_LOGW(TAG, "MQTT client is not connected");
}
return msg_id;
}
2.4 OneNet物模型上报数据格式
参数 | 类型 | 说明 |
|---|---|---|
id | string | 消息id号,用户自定义,String类型的数字,长度限制13位。 |
version | string | 物模型版本号,可选字段,不填默认为1.0 |
params | jsonObject | 请求参数,用户自定义,标准json格式。如以上示例中,设备上报了的两个属性Power和WF。具体属性信息,包含属性上报时间(time)和上报的属性值(value)。 |
time | long | 属性值生成时间。该参数为可选字段,到毫秒级。根据您的业务场景决定消息中是否带时间戳。如果消息频繁,需根据时间戳判断消息顺序,建议消息中带有时间戳。 |
value | object | 上报的属性值 |
示例:
{
"id": "123",
"version": "1.0",
"params": {
"Power": {
"value": "12345",
"time": 1706673129818
},
"temp": {
"value": 23.6,
"time": 1706673129818
}
}
}
热门推荐
沈奕斐:如何破解爱情中的压抑情绪
中药巴戟天的功效与作用
门面房贷款指南:申请条件、所需材料及最长贷款年限
广东阳江市十大必游景点推荐
拉菲尼亚欧冠神级表现:8球2助攻,球迷热议:他还能更牛吗?
从超级杯MVP到"蝙蝠侠":拉菲尼亚的28岁生日派对
《模仿犯》:凶手的挑衅与正义的追寻
重庆桂林自驾游攻略:沿途景区及重庆贵州桂林路线详解
重庆至桂林自由行全攻略:行程规划、必游景点与实用贴士
虹口法院发布物业纠纷治理白皮书:社区和谐新举措
物业管理公司如何避免合同纠纷?
最高法最新物业合同纠纷司法解释尚未发布
血脂高也有了管理指南,看看今后该怎么吃
最熟悉的陌生人——血脂检查那些事儿
杨绛:思想不在一个高度尊重就好;三观不在一个层次微笑就好
阳江至厦门自驾游详细路线攻略
糖尿病患者为何容易抽筋?血糖与抽筋的关系及预防方法
长白山天池水怪再现江湖?专家:或为自然现象误读
八角金盘的药用价值与使用方法
男生健身应该着重锻炼哪些肌肉?
廊坊:特色产业集群成为县域高质量发展“主引擎”
家居照明风水:你家灯位对了吗?
道教斋醮法事中的神秘燃灯仪式
家居灯具设计:现代风水的阴阳平衡
“姨母笑”:从韩国饭圈到中国网络,一种独特表情的文化之旅
揭秘网络核心:三层交换机与路由器的区别
考古证明:我们所读的《道德经》,第一句话就读错了
麦冬种植攻略:时间与方法全解析
麦冬是什么?麦冬要怎么种植?
肥胖人群怎样吃?国家卫健委手把手教你科学减肥