esp8266接入华为云物联网平台(IOTDA)2.0
【最新版本的PubSubClient库无法正常连接,请使用PubSubClient2.7.0,或安装资源文件夹内的库文件】
第0章 简介
之前带大家实现了利用Arduino和esp8266系列完成设备接入华为云物联网平台(IOTDA)并完成设备属性上报。最近收到很多小伙伴的私信,咨询平台下发命令的接收与处理,本期就带大家实现一下,具体的产品和设备的创建就不在这里重复讲了,大家参考之前的文章。
【教你如何使用esp8266接入华为云物联网平台】教你如何使用esp8266接入华为云物联网平台(IOTDA)(Arduino IDE开发)_IoT物联网_华为云论坛
【华为云IOT的Android应用开发【详细教程】】华为云IOT的Android应用开发【详细教程】_IoT物联网_华为云论坛
本期最终效果:
第1章 整体流程概述
1. 平台命令下发
2. 设备接收命令
3. 设备返回平台命令响应
4. 设备命令处理
第2章 具体详细步骤
一、 MQTT测试
老样子,这里我们还是先用MQTT.fx进行测试,然后再写Arduino程序
1. 平台命令下发
(1) 查看相关文档:平台命令下发_设备接入 IoTDA_API参考_设备侧MQTT/MQTTS接口参考_设备命令_华为云
官方提供的文章中,我们首先需要清楚的是,平台下发命令后,需要设备及时将命令的执行结果返回给平台,如果设备没回响应,平台会认为命令执行超时,
(2) 相关topic
下行(平台到设备的命令下发): $oc/devices/{device_id}/sys/commands/request_id={request_id}
上行(设备到平台的命令响应):$oc/devices/{device_id}/sys/commands/response/request_id={request_id}
(3) 命令下发测试
首先我们先在MQTT.fx中订阅命令主题:$oc/devices/{device_id}/sys/commands/request_id={request_id}
产品服务及命令参数设置
然后再华为云IOTDA的监控运维平台进行调试
然后我们进入MQTT.fx查看
命令接收到之后,我们需要进行设备响应平台的命令,不然平台会认为命令并没有有效下发
2. 设备的响应
(1) Topic: $oc/devices/{device_id}/sys/commands/response/request_id={request_id}
需要注意的是其中的{request_id}用于唯一标识这次请求,设备侧收到下行请求的topic带该参数时,上行响应的topic需要将该参数值返回给平台,我们在接收命令时,收到了{request_id},那么上报时是需要修改topic,带上对应的{request_id}。
由上图可知,这次命令的request_id=07fc7c27-7812-446c-8e67-6e4bb1ed9fd9
那么我们现在topic:$oc/devices/{device_id}/sys/commands/response/request_id=07fc7c27-7812-446c-8e67-6e4bb1ed9fd9
(2) 响应参数
由于都是可选,我们直接用一个空的json数据,大家根据自己需求调整
(3) MQTT.fx完成响应
由于平台等待的时间比较短,大家要及时的完成响应
2、 Anrdoid编程
(1)、 硬件准备:任意esp8266的模块,我用的是esp01s
(2)、 程序编写
MQTT连接和属性上报的程序大家参考之前的帖子,这里直接讲命令的接收处理与响应
首先我们需要在初始化时设置回调函数,用于及时接收命令
client.setCallback(callback);
回调函数;void callback(char* topic, byte* payload, unsigned int length){}
简单的回调函数可以这么写:
void callback(char* topic, byte* payload, unsigned int length)
{
String recdata="";
Serial.printf("接收到订阅的消息:主题为:");
Serial.println(topic);
Serial.printf("数据内容:");
for(int i=0;i<length;i++)
{
recdata+=(char)payload;
}
Serial.println(recdata);
}
运行后我们可以得到带request id的topic,和收到的命令json数据串,然后我们解析出我们需要的信息我们在回调函数中补充:
//解析JSON数据
DynamicJsonDocument jsonBuffer(1024);
deserializeJson(jsonBuffer,recdata);
JsonObject obj = jsonBuffer.as<JsonObject>();
String com = obj["paras"];
Serial.printf("解析命令:");
Serial.println(com);
deserializeJson(jsonBuffer,com);
obj = jsonBuffer.as<JsonObject>();
String ledcom = obj["led"];
Serial.printf("解析LED命令:");
Serial.println(ledcom);
命令解析后,我们还要对平台进行命令响应,以便平台知道我们的设备收到了数据,由于我们的命令下发是包含request id,我们先提取request id然后加到我们的上行topic中,然后我们再在回调函数中补充:
//解析request id,设备响应时的topic需要包含命令的request id,且会动态变化
char *p=topic;
String request_id="";
int i=0;
while((*p++)!='\0')//获取topic长度
{
i++;
}
topic+=(i-36); //移动指针位置
for(int j=i-36;j<i;j++)//末36位为request id
request_id+=*topic++;
Serial.println("request_id:"+request_id);
Serial.println("同步命令设备响应。。。);
String param="{}";
//设备命令响应
client.publish((Iot_link_MQTT_Topic_CommandsRes+request_id).c_str(),param.c_str());
接下来我们就可以对命令进行处理了,在回调函数中最后补充一下
//处理指令
if(ledcom=="0")
{
digitalWrite(LEDPIN,HIGH); //LED低电平触发,高电平熄灭
Serial.println("关灯");
}
else if(ledcom=="1")
{
digitalWrite(LEDPIN,LOW); //LED低电平触发,高电平熄灭
Serial.println("开灯");
}
运行一下,我们查看串口数据:
由于之前已经带着大家完成了软件设计,这里我们也可以通过APP控制,如下图:
上述操作已经可以帮助大家完成本期的任务了,大家需要上述程序的项目全部源码,