完整工程文件(百度网盘免费下载,提取码:0625)在文章末尾,需要请移步至文章末尾。
目录
此时STM32已经能够成功将数据上传至阿里云时,接下来的关键步骤是在小程序端开发实现双向数据交互的功能。在这个过程中,利用阿里云的MQTT服务作为通信桥梁,使小程序能够实时接收来自STM32的数据,并且可以向STM32发送控制指令或其他信息。
一、基础配置
确保将以下两个文件放置在小程序项目的 utils 文件夹下:
- mqtt.min.js:实现 MQTT 协议的通信功能的文件,通过引入第三方提供的 MQTT SDK 实现在小程序中与 MQTT 服务器的连接和消息传输功能。
- hex_hmac_sha1.js:实现 SHA1 加密算法的文件,对特定字符串进行 HMAC-SHA1 加密,生成用于认证 MQTT 连接的密码或其他安全参数。
二、MQTT连接
MQTT连接时应当将连接部分代码配置在app.js中,避免因为多次初始化而导致的性能问题和程序冲突。
- 全局存储: 在 app.js 中使用 globalData 存储 MQTT 客户端实例,确保所有页面都可以访问。
- 事件监听: 在 app.js 中监听 MQTT 连接的各种事件(如 connect, error, reconnect),以便及时处理连接状态和错误。
- 页面调用: 在需要使用 MQTT 的页面中,通过 getApp().globalData 获取 MQTT 客户端实例,并进行订阅、取消订阅等操作。
此外,每个页面对于下行数据的解析应当放置在各自页面的代码中,这样有利于代码结构的清晰性和维护性,同时可以根据页面功能需求灵活处理数据。
1. 在 app.js 中初始化 MQTT 连接
var mqtt = require('utils/mqtt');
const crypto = require('utils/hex_hmac_sha1.js');
App({
data: {
pubTopic: '/sys/j07fRDwyQJM/APPD/thing/event/property/post', //发布消息的主题
subTopic: '/sys/j07fRDwyQJM/APPD/thing/service/property/set',//订阅消息的主题
},
globalData: {
client: null,
},
doConnect() {
const that = this;
const deviceConfig = {
productKey: "j07fRDwyQJM",
deviceName: "APPD",
deviceSecret: "6447a9baa9d989555c38d51b335bd6a2",
regionId: "cn-shanghai"
};
//访问服务器
const subTopic = this.data.subTopic;
const options = this.initMqttOptions(deviceConfig);
const client = mqtt.connect(`wxs://${deviceConfig.productKey}.iot-as-mqtt.${deviceConfig.regionId}.aliyuncs.com`, options);
this.globalData.client = client;
client.on('connect', function () {
console.log('连接服务器成功')
//订阅主题
client.subscribe(subTopic, function (err) {
if (!err) {
console.log('订阅成功!');
}
})
})
/*
// 发布消息
const pubTopic = this.data.pubTopic;
const message = JSON.stringify({
key: 'value' // 要发布的 JSON 消息
});
client.publish(pubTopic, message, function (err) {
if (!err) {
console.log('消息发布成功!');
}
});
*/
},
//IoT平台mqtt连接参数初始化
initMqttOptions(deviceConfig) {
const params = {
productKey: deviceConfig.productKey,
deviceName: deviceConfig.deviceName,
timestamp: Date.now(),
clientId: Math.random().toString(36).substr(2),
}
//CONNECT参数
const options = {
keepalive: 60, //60s
clean: true, //cleanSession不保持持久会话
protocolVersion: 4 //MQTT v3.1.1
}
//1.生成clientId,username,password
options.password = this.signHmacSha1(params, deviceConfig.deviceSecret);
options.clientId = `${params.clientId}|securemode=2,signmethod=hmacsha1,timestamp=${params.timestamp}|`;
options.username = `${params.deviceName}&${params.productKey}`;
return options;
},
/*
生成基于HmacSha1的password
参考文档:https://help.aliyun.com/document_detail/73742.html?#h2-url-1
*/
signHmacSha1(params, deviceSecret) {
let keys = Object.keys(params).sort();
// 按字典序排序
keys = keys.sort();
const list = [];
keys.map((key) => {
list.push(`${key}${params[key]}`);
});
const contentStr = list.join('');
return crypto.hex_hmac_sha1(deviceSecret, contentStr);
},
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
this.doConnect();
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
}
})
2. 在页面中使用 MQTT 连接
const app = getApp();
const client = app.globalData.client;
const pubTopic = '/sys/j07fRDwyQJM/APPD/thing/event/property/post'; //发布消息的主题
const subTopic = '/sys/j07fRDwyQJM/APPD/thing/service/property/set'//订阅消息的主题
Page({
data: {
temp:0,
humi:0
},
onLightChange(event) {
const sw = event.detail.value;
// console.log('开关状态:', isSwitchOn ? '打开' : '关闭');
// 根据开关状态执行相应的操作
if (sw) {
const message = JSON.stringify({
"params": {
"lighting": 1,
},
"version": "1.0.0",
"method": "thing.event.property.post"
// 要发布的 JSON 消息
});
client.publish(pubTopic, message, function (err) {
if (!err) {
console.log('开');
}
});
} if (!sw) {
const message = JSON.stringify({
"params": {
"lighting": 0,
},
"version": "1.0.0",
"method": "thing.event.property.post"// 要发布的 JSON 消息
});
client.publish(pubTopic, message, function (err) {
if (!err) {
console.log('关');
}
});
}
else {
// 执行其他逻辑(例如停止发送数据)
}
},
doConnect() {
const that = this;
//接收消息监听
client.on('message', function (topic, message) {
// 收到消息的回调函数
console.log('收到消息:', topic, message.toString());
// 解析收到的 JSON 格式消息
const data = JSON.parse(message.toString());
// console.log(data);
// 处理收到的数据
try {
that.setData({
humi: data.items.humi.value,
temp: data.items.temp.value
})
} catch (error) {
// console.log('JSON解析失败', error);
console.log("未接收到消息")
}
// ...
});
},
onLoad: function (options) {
this.doConnect();
}
})
三、总结
至此STM32+ESP8266+智能家居实战demo项目完结!!!