概述
其实之前就写过类似的文章,但是看过我博客的朋友就知道,我是先写微信小程序获取onenet,然后再写esp32上云到onenet。一篇是ESP32-C3通过MQTT协议把温湿度上传到OneNet平台(实际是mqtts协议,之前没细看以为没区别),一篇是微信小程序获取onenet数据显示温湿度(硬件连接上云是朋友搞的),之所以写这一篇是因为协议不同,权限不同,之前设备协议用的是mqtts协议,由于之前是作业需要,只搞了获取数据,并没有搞下发命令。这两天重新去翻阅相关文档才发现,onenet现在暂不支持mqtts协议下发命令,支持mqtt协议。部分重要代码需要修改,顺便优化了小程序界面。
需要注意的是这里用的是onenet老版的mqtt协议,多协议接入。新版和旧版数据不互通
硬件设备: 安信可的ESP32-C3
传感器: dht11
代码编译环境: Arduino ide
设备传输协议: mqtt
onenet云平台: 老版多协议接入
微信小程序: 微信开发者工具
文章目录
- 一、Onenet云平台
- 1、创建产品
- 2、创建设备
- 3、创建数据流
- 二、Arduino ide编译环境
- 三、嵌入代码撰写
- 1、设备怎么连上网
- 2、温湿度
- 3 、接入地址
- 4、数据如何发送给onenet
- 5、下发命令
- 6、led灯
- 7、嵌入源代码
- 四、微信开发者工具
- 1、微信界面
- 2、获取Onenet的API接口
- 3、查询OneNet平台多协议接入文档,这里直接查看MQTT的API使用
- 4、我用ApiPost来进行测试是否能获取数据
- 5、微信小程序获取OneNet数据
- 6、微信小程序下发命令
- 7、数据刷新
- 8、效果展示
- 结语
一、Onenet云平台
1、创建产品
控制台 —>多接入–>添加产品
关于产品名称、行业、类别那些自行选择即可,这里选用mqtt旧版协议
点击我们刚刚创建的dht11,然后点击产品概况,记住我们的产品id,后面用得上
2、创建设备
点击设备列表->点击右边的添加设备,设备名称和鉴权信息需要填写,鉴权信息设备连接onenet用的上,还有设备的id号
3、创建数据流
首先点击数据流,然后点击数据流模板管理,最后添加数据流模板
这里设置的数据流名称后面要用到,这里我创建了温度、湿度、灯的数据流。
二、Arduino ide编译环境
这里我使用的是Arduino IDE,它的库很多,大部分可以直接调用,只有少部分需要自己下载,网上资源有很多,可以自己查找下载,这里我直接跳过安装。
因为我之前使用过esp32开发板,一开始我以为环境是跟ESP32一样的,事实证明我还是太年轻了。后面我通过安信可官方给的包替换。下面的链接是官方的,里面也有Arduino IDE 的安装包
链接:https://pan.baidu.com/s/1kLPvsDpwQf1lz_e3goxpJg
提取码:1234
配置好开发板相应环境
三、嵌入代码撰写
之前用的是mqtts协议,这里是mqtt协议,只需要修改之前代码的一部分就能解决
1、设备怎么连上网
这里可以调用wifi库
#include <WiFi.h>
const char* ssid = "3671"; //wifi名称
const char* password = "05210835";//wifi密码
2、温湿度
我传感器用的是DHT11,这里也可以调用库
#include "DHT.h"
定义DHT11,数据引脚我接在IO7口
#define DHTPIN 7 // io7
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
3 、接入地址
mqtts协议的接口端号是1883,这里是6002
const char *mqtt_server = "183.230.40.96"; //onenet 的 IP地址
const int port = 6002; //端口号
4、数据如何发送给onenet
这里我们需要查阅onenet的相关文档
https://open.iot.10086.cn/doc/v5/develop/detail/463
#define mqtt_devid "884337606" //设备ID
#define mqtt_pubid "487632" //产品ID
//鉴权信息
#define mqtt_password "20222222" //鉴权信息
char msg_buf[200]; //发送信息缓冲区
char msgJson[75]; //要发送的json格式的数据
unsigned short json_len = 0; //json长度
//信息模板
char dataTemplate[] = "{"temp":%.2f,"humi":%.2f,"led":%d}"; // temp humi led要与onenet相对应
void sendTempAndHumi()
{
if (client.connected())
{
//dht.readHumidity()
snprintf(msgJson,75,dataTemplate,dht.readTemperature(),dht.readHumidity(),god);
json_len = strlen(msgJson); //msgJson的长度
msg_buf[0] = char(0x03); //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3
msg_buf[1] = char(json_len >> 8); //数据第二位是要发送的数据长度的高八位
msg_buf[2] = char(json_len & 0xff); //数据第三位是要发送数据的长度的低八位
memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson
msg_buf[3 + strlen(msgJson)] = 0; //添加一个0作为最后一位, 这样要发送的msg_buf准备好了
Serial.print("public the data:");
Serial.print(msgJson);
client.publish("$dp", (uint8_t *)msg_buf, 3+strlen(msgJson));
//发送数据到主题
delay(500);
}
}
在 setup()函数定义了每5秒发送一次数据到onenet
tim1.attach(5, sendTempAndHumi); //定时每5秒调用一次发送数据函数sendTempAndHumi
5、下发命令
在 setup()函数订阅命令下发主题
client.setCallback(callback); //订阅命令下发主题
//收到主题下发的回调, 注意这个回调要实现三个形参 1:topic 主题, 2: payload: 传递过来的信息 3: length: 长度
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
if ((char)payload[0] == '0') {
digitalWrite(led, LOW); //
god=0;
} if ((char)payload[0] == '1') {
digitalWrite(led, HIGH); //
god=1;
}
else{}
}
6、led灯
关于灯,本来想外接的,但是我在查看原理图后就想偷懒了,毕竟开发板有自带了两个灯和RGB灯。这里我选择的是18接口的灯,因为19的灯是常亮的,所以不选它。
const int led =18; //灯的接口
在setup()定义灯是输出的
pinMode(led,OUTPUT);//输出
我这里设置一个god变量,初始化是0,即灯没有开,等接收到指令再进行变化,1为灯开。
7、嵌入源代码
#include <WiFi.h>
#include "DHT.h"
#include "PubSubClient.h"
#include "Ticker.h"
#define DHTPIN 7
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
int god=0;
const int led =18; //灯的接口
const char *ssid = "3671"; //wifi名称
const char *password = "05210835";//wifi密码
const char *mqtt_server = "183.230.40.96"; //onenet 的 IP地址
const int port = 6002; //端口号
#define mqtt_devid "884337606" //设备ID
#define mqtt_pubid "487632" //产品ID
//鉴权信息
#define mqtt_password "20222222" //鉴权信息
WiFiClient espClient; //创建一个WIFI连接客户端
PubSubClient client(espClient); // 创建一个PubSub客户端, 传入创建的WIFI客户端
char msg_buf[200]; //发送信息缓冲区
char msgJson[75]; //要发送的json格式的数据
unsigned short json_len = 0; //json长度
//信息模板
char dataTemplate[] = "{"temp":%.2f,"humi":%.2f,"led":%d}"; // temp humi要与onenet相对应
Ticker tim1; //定时器,用来循环上传数据
void setupWifi(){
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print("正在连接中----n");
}
Serial.print("WIFI已连接n");
Serial.print(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
pinMode(led,OUTPUT);//输出
setupWifi(); //调用函数连接WIFI
Serial.print(F("DHT11 test!"));
dht.begin();
client.setServer(mqtt_server, port); //设置客户端连接的服务器,连接Onenet服务器, 使用6002端口
client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客户端连接到指定的产品的指定设备.同时输入鉴权信息
if (client.connected())
{
Serial.print("OneNet is connected!");//判断以下是不是连好了.
}
//client.setCallback(callback); //设置好客户端收到信息是的回调
client.setCallback(callback); //订阅命令下发主题
tim1.attach(5, sendTempAndHumi); //定时每5秒调用一次发送数据函数sendTempAndHumi
}
void loop() {
delay(5000);
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!n"));
return;
}
//可以让我们通过串口查看数据
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("℃ n "));
if (!WiFi.isConnected()) //先看WIFI是否还在连接
{
setupWifi();
}
if (!client.connected()) //如果客户端没连接ONENET, 重新连接
{
clientReconnect();
delay(100);
}
client.loop(); //客户端循环检测
}
void sendTempAndHumi()
{
if (client.connected())
{
//dht.readHumidity()
snprintf(msgJson,75,dataTemplate,dht.readTemperature(),dht.readHumidity(),god);
json_len = strlen(msgJson); //msgJson的长度
msg_buf[0] = char(0x03); //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3
msg_buf[1] = char(json_len >> 8); //数据第二位是要发送的数据长度的高八位
msg_buf[2] = char(json_len & 0xff); //数据第三位是要发送数据的长度的低八位
memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson
msg_buf[3 + strlen(msgJson)] = 0; //添加一个0作为最后一位, 这样要发送的msg_buf准备好了
Serial.print("public the data:");
Serial.print(msgJson);
client.publish("$dp", (uint8_t *)msg_buf, 3+strlen(msgJson));
//发送数据到主题
delay(500);
}
}
//收到主题下发的回调, 注意这个回调要实现三个形参 1:topic 主题, 2: payload: 传递过来的信息 3: length: 长度
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
if ((char)payload[0] == '0') {
digitalWrite(led, LOW); //
god=0;
} if ((char)payload[0] == '1') {
digitalWrite(led, HIGH); //
god=1;
}
else{}
}
void clientReconnect()
{
while (!client.connected()) //再重连客户端
{
Serial.print("reconnect MQTT...");
if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password))
{
Serial.print("connected");
}
else
{
Serial.print("failed");
Serial.print(client.state());
Serial.print("try again in 5 sec");
delay(5000);
}
}
}
四、微信开发者工具
这个是微信提供的一个开发工具,有框架,也方便我们把项目部署到线上。这里我着重讲述怎么获取onene数据和发送指令
1、微信界面
2、获取Onenet的API接口
回到onenet的设备列表,然后在点击右边的详情就可以看到设备的详细信息,复制API地址和API-key,一个设备可以多个apikey,自行添加。
3、查询OneNet平台多协议接入文档,这里直接查看MQTT的API使用
4、我用ApiPost来进行测试是否能获取数据
5、微信小程序获取OneNet数据
这里我定义了points()函数,是用来获取Onenet平台数据的,主要放在index.js,为后面数据定时刷新做好铺垫。
points:function(e) {
},
2、参考小程序文档,我这里采用wx.request 获取数据
points:function(e) {
var that = this
wx.request({
url: 'http://api.heclouds.com/devices/xxxxxxxxxx/datapoints?', //xxz这里填写你的设备id
//设备ID
//api-key
header:{
"api-key":"xxxxxxx" //这里写你的api-key
},
data:{
limit:1 //数据流最新的一个数据 如果是5,即五个数据
},
method :"GET",
//获取成功
success:function(res){
that.setData({
wendu:res.data.data.datastreams[0].datapoints[0].value,
time:res.data.data.datastreams[0].datapoints[0].at,
shidu:res.data.data.datastreams[1].datapoints[0].value,
led:res.data.data.datastreams[2].datapoints[0].value, //这里的shidu要跟wxml{{shidu}} 名字相同
})
}
})
},
3、关于如何显示到具体数字,因人而异,下面我这两行代码是根据json数据来定位的
shidu:res.data.data.datastreams[0].datapoints[0].value,
wendu:res.data.data.datastreams[1].datapoints[0].value,
6、微信小程序下发命令
这里我也封装了两个函数,一个是发1值,一个发0值,因为我们的嵌入代码写是1代表打开灯,0代表关灯。这里以打开灯函数介绍
openled:function(e){
wx.request({
url: 'http://api.heclouds.com/cmds?device_id=*****',//*号这里写你设备id
//设备ID
//api-key
header:{
'content-type':'application/json',
"api-key":"xxxxxxx" //这里写你的api-key
},
method :"POST",
data:1,//数据1是为灯开
success(res){
console.log("控制成功,已开灯")
console.log(res)
console.log(res.data);
}
})
},
7、数据刷新
其实这些网上都有的函数例子,我试过页面刷新、定时刷新,如果页面没有点击事件的话都可以用我下面这两个方法。但是有点击事件的话还是用定时刷新
页面刷新
//生命周期函数--监听页面加载
onLoad:function(options){
this.points(); //这个是我获取onenet数据的函数
if(getCurrentPages().length !=0){
getCurrentPages()[getCurrentPages().length-1].onLoad()
}
}
定时刷新
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.points() //这个是我获取onenet数据的函数
var that=this
setInterval(function(){
that.points();
},3000 //这里我设置3秒刷新一次
)
},
8、效果展示
因为我硬件是每5秒上传一次,微信小程序数据是3秒刷新一次,可能会造成一定是时延,还有可能是因为我这边网络的原因,我手机开热点给电脑连接,电脑开热点给设备连接,我手机开的热点,设备就是连不上。但是从视频里面可以看到我们的下发指令,设备一下子就接收到了。
这里我采用的是wx:if条件来进行图片切换的。按钮的点击并不能决定图片的切换,我这里设置if条件的判断 wx:if=“{{led==1}}”,是判断onenet的led数据流,如果为1,则灯亮,其他为灯灭。虽然会有一定的时延,但能保证其一定的真实性。
onenet-iot
结语
这样一整个物联网流程算是彻底完成了,也实现了获取设备数据并控制开关,算是做了一个小小小项目。如果有兄弟需要我这微信小程序源码(附这个项目界面设计的设计和数据交互文档),可以私信找我要。整个流程都是自己一个人完成的,查阅了很多相关文档,写代码也花费了很多时间,界面设计也是自己设计出来的。经过一次又一次的失败才成功的。个人创作实属不易,还请多多谅解!
最后
以上就是欣喜八宝粥为你收集整理的微信小程序获取Onenet温湿度数据并控制灯亮灭的全部内容,希望文章能够帮你解决微信小程序获取Onenet温湿度数据并控制灯亮灭所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复