基于STM32的物联网环境监测与远程控制系统实训套件-淘宝网
任务3 微信小程序下发命令控制设备
一、任务描述
本任务基于OneNET 物联网平台,在任务 1(生成鉴权 Token)、任务 2(获取传感器数据)的基础上,实现微信小程序向云端下发控制指令,远程控制终端设备的 LED 灯、风扇启停。结合小程序按钮点击事件、wx.request网络请求、OneNET 设备命令下发接口,完成指令封装、鉴权请求、状态联动等功能,掌握小程序下发控制指令、云端转发指令、终端设备执行动作的完整物联网控制流程。
二、任务目标
1. 知识目标
1)掌握 OneNET 平台设备命令下发接口的地址、请求方式、请求参数规范。
2)理解设备控制指令的封装格式,了解云端指令转发、硬件执行的原理。
3)巩固小程序wx.request POST 请求用法,熟练配置鉴权请求头。
4)掌握按钮点击事件绑定、交互提示、设备状态联动刷新的实现逻辑。
5)加深理解「小程序 - OneNET 云端 - 终端硬件」三层架构的指令交互流程。
2. 能力目标
1)能够正确调用 OneNET 命令下发接口,配置接口地址、请求头、请求体参数。
2)能够根据硬件协议,封装 LED、风扇的启停控制指令。
3)能够实现按钮点击触发指令下发,并通过wx.showToast给出交互反馈。
4)能够结合数据查询接口,自动刷新设备最新状态,保证页面状态与硬件同步。
5)能够排查指令下发失败、鉴权错误、指令格式错误等常见问题。
3. 素质目标
1)养成「先鉴权、再发指令、最后刷新状态」的标准设备控制开发流程。
2)提升指令调试、跨平台交互排错、软硬件联调的综合能力。
3)树立指令标准化、状态同步化的物联网工程开发思维。
三、任务重难点
1. 任务重点
1)正确使用 POST 方式调用 OneNET 设备命令下发接口,配置Authorization鉴权头。
2)按照平台与硬件协议,规范封装 LED、风扇的启停指令内容。
3)绑定页面按钮点击事件,实现点击按钮触发指令下发。
4)指令下发完成后,主动查询设备状态,实现页面显示与硬件状态同步。
2. 任务难点
1)严格匹配硬件约定的指令格式,指令错误会导致硬件无响应。
2)区分 OneNET 查询接口(GET)与控制接口(POST)的配置差异。
3)处理指令下发超时、云端转发失败、硬件离线等异常场景。
4)保证 Token 有效性,避免因鉴权问题导致指令下发失败。
四、知识准备
1.OneNET设备命令下发接口说明
- 接口基础地址:
https://iot-api.heclouds.com/thingmodel/set-device-property
- 请求方式:POST
- 鉴权规则:请求头携带 authorization(值为 MD5 生成的 Token)
- 必传请求参数(data):
product_id:产品 ID
device_name:设备名称
params:属性键值对(控制指令)
- 控制参数约定(见表1):
表1控制参数约定
设备动作 | params 内容 |
开启 LED | {"LED": true} |
关闭 LED | {"LED": false} |
开启风扇 | {"fan": true} |
关闭风扇 | {"fan": false} |
2.GET与POST请求区别
1)任务2 数据查询使用GET:仅向平台获取数据,参数拼接在 URL 中;
2)本任务设备控制使用POST:向平台提交控制指令,指令内容放在请求体data中;
3)两种请求均需携带Authorization鉴权头,字段名、大小写保持一致。
3.交互与状态同步逻辑
1)按钮点击 → 下发控制指令 → 弹出操作成功 / 失败提示;
2)指令下发完成后,主动调用数据查询接口,刷新 LED、风扇状态;
3)定时器定时轮询设备状态,保证页面长期与硬件状态同步。
4.前置依赖
1)已完成任务 1、任务 2,key.js、crypto-js正常工作,可稳定生成 Token;
2)小程序基础库固定为2.29.2,本地调试已勾选不校验合法域名、TLS 证书;
3)OneNET 平台设备在线,终端硬件正常接收并解析云端转发的指令。
五、任务实现
任务3.1业务逻辑代码 index.js
新增指令下发通用函数,改造按钮点击事件,实现指令下发、交互提示、状态自动刷新,完整代码:
// pages/index/index.js
const { createCommonToken } = require('../../key.js');
Page({
data: {
// 传感器数据
temp: '',
humi: '',
light: '',
// 设备状态
ledStatus: false,
fanStatus: false,
// 时间
nowDate: '',
nowTime: '',
// 鉴权与定时器
token: '',
timeInterval: null
},
onLoad() {
// 1. 生成IoT鉴权Token
const params = {
author_key: 'hkjx0f+umJ77G+vWa2VU8SNM28uii7KRuszCzGMBVK1/MdprEje4csrjcRNMMN1D',
version: '2022-05-01',
user_id: '460603',
};
this.setData({
token: createCommonToken(params)
});
// 初始化时间
this.updateTime();
},
onShow() {
// 立即查询一次设备数据
this.fetchDevData();
// 开启定时器:3秒轮询刷新数据
const timer = setInterval(() => {
this.fetchDevData();
this.updateTime();
}, 3000);
this.setData({ timer });
},
onHide() {
// 页面隐藏 清除定时器
if (this.data.timer) {
clearInterval(this.data.timer);
this.setData({ timer: null });
}
},
onUnload() {
// 页面卸载 清除定时器
if (this.data.timer) {
clearInterval(this.data.timer);
this.setData({ timer: null });
}
},
// ========== 时间格式化:日期+星期 + 时分秒 ==========
updateTime() {
const d = new Date();
const weekArr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
let y = d.getFullYear();
let m = d.getMonth() + 1;
let day = d.getDate();
let h = d.getHours();
let mi = d.getMinutes();
let s = d.getSeconds();
m = m < 10 ? '0' + m : m;
day = day < 10 ? '0' + day : day;
h = h < 10 ? '0' + h : h;
mi = mi < 10 ? '0' + mi : mi;
s = s < 10 ? '0' + s : s;
this.setData({
nowDate: `${y}年${m}月${day}日 ${weekArr[d.getDay()]}`,
nowTime: `${h}:${mi}:${s}`
});
},
// ========== 查询传感器+设备状态 ==========
fetchDevData() {
const that = this;
wx.request({
url: 'https://iot-api.heclouds.com/thingmodel/query-device-property',
method: 'GET',
data: {
product_id: 'tsK7G227aH',
device_name: 'a1'
},
header: {
'authorization': that.data.token
},
success: function (res) {
console.log("设备数据:", res.data);
const dataList = res.data.data;
// 按物模型顺序解析:温度、湿度、光照、LED、风扇
that.setData({
temp: dataList[4].value,
humi: dataList[2].value,
light: dataList[3].value,
ledStatus: dataList[0].value === 'true',
fanStatus: dataList[1].value === 'true'
});
},
fail: function (err) {
console.error("查询数据失败:", err);
}
});
},
// ========== LED 控制 ==========
ledOn() {
this.controlDevice("LED", true);
},
ledOff() {
this.controlDevice("LED", false);
},
// ========== 风扇控制 ==========
fanOn() {
this.controlDevice("fan", true);
},
fanOff() {
this.controlDevice("fan", false);
},
// ========== 通用设备控制方法 ==========
controlDevice(key, value) {
const that = this;
let params = {};
params[key] = value;
// 优先弹出提示,不用等接口返回
wx.showToast({
title: value ? '开启成功' : '关闭成功',
icon: 'success',
duration: 1500
});
// 再执行网络请求
wx.request({
url: 'https://iot-api.heclouds.com/thingmodel/set-device-property',
method: 'POST',
data: {
product_id: 'tsK7G227aH',
device_name: 'a1',
params: params
},
header: {
'authorization': that.data.token
},
success: function () {
that.fetchDevData();
},
fail: function () {
// 接口失败兜底提示
wx.showToast({
title: '操作失败',
icon: 'none'
});
}
});
}
})
任务 3.2 运行与结果验证
1.打开硬件设备电源,确认目标设备在线。
2.点击开发者工具“编译”按钮,运行小程序。
3.点击开启 LED按钮:弹出「LED 开启成功」提示,硬件 LED 点亮,页面 LED 状态同步更新。
4.点击关闭 LED按钮:弹出对应提示,硬件 LED 熄灭,页面状态同步。
5.依次测试风扇开启、关闭功能,观察硬件动作与页面状态变化,如图1所示。。
图1 运行与结果验证