物一世IoT
本示例需要使用Express云助手小程序,Express Pi设备与小程序之间通过云消息(基于mqtt协议)来通讯。
首先每个设备端通过云消息来发布和订阅主题,每个设备都有自己的唯一标识(deviceid),设备端需要订阅下面表格中的三个主题,用来接收微信小程序发布的主题消息,设备端收到这三个主题都需要做出回复
主题 | 功能 | 回复 |
---|---|---|
${deviceid}/ping | 检测设备是否在线,内容为空 | 设备端通过${deviceid}/status消息回复 |
${deviceid}/get | 获取设备当前数据,内容为空 | 设备端通过${deviceid}/detail消息回复 |
${deviceid}/set | 修改设备数据,内容为固定格式 | 设备端通过${deviceid}/post消息回复 |
另外设备端也会发布下面表格中的两个主题消息,微信小程序在添加设备后订阅这两个主题,小程序端不需要回复
主题 | 功能 | 回复 |
---|---|---|
${deviceid}/status | 上报设备状态,内容为固定格式 | 无 |
${deviceid}/post | 上报设备传感器数据,内容为固定格式 | 无 |
设备端发布**${deviceid}/status**消息,JSON格式示例:
status, 状态字符串,值为”online”或者”offline”
{
"status": "online"
}
设备端发布**${deviceid}/detail或者${deviceid}/post**消息,JSON格式示例:
字段 | 选择 | 说明 |
---|---|---|
id | 必须 | 传感器标识,可自定义,值为数字或字符串,小程序发布 ${deviceid}/set消息时会包含所要更新的传感器id值 |
icon | 必须 | 在物一世云系统中云消息-设备配置-传感器图片页面上传的图片数字编号 |
title | 必须 | 传感器名称,将在小程序中设备详情页面显示 |
value | 必须 | 传感器的当前数据值,如当前温度值,湿度值等 |
preset | 可选 | 传感器的预设值,只能是range范围内的值。比如空调的温度设定值 |
unit | 可选 | 传感器数据单位,如果没有单位,可以不添加此字段 |
state | 可选 | 传感器的状态值,可以为汉字,如继电器的“开”或”关” |
range | 可选 | 传感器值的可设置范围,如果不允许修改,可以不添加或者设置为空字符串 |
{
"items": [
{
"id": "0",
"icon": "1",
"title": "温度",
"unit": "°c",
"value": 30,
"preset": 30,
"range": "15,65"
},
{
"id": "2",
"icon": "5",
"title": "灯泡",
"value": 0,
"state": "关",
"range": "0,1"
}
]
}
小程序发布**${deviceid}/set**消息JSON格式示例,如设置id值为2的传感器的值为1
{
"id":"2",
"setvalue":"1"
}
小程序与设备端交互过程如下图:
下面详细介绍设备端如何使用WeStudio云消息控件与Express云助手微信小程序通讯:
1、登录物一世IoT云系统 https://iot.wareexpress.com,如果没有账号可以免费注册。
登录系统后选择“云消息”,点击”生成“”按钮,生成一个云标识。
2、点击“设备管理”按钮,进入图片管理页面,然后我们可以上传设备图片和传感器图片(png格式,像素48x48即可),这些图片我们将在后面的工程中使用。
3、打开WeStudio软件,新建一个工程,如IotDemo。从控件库中拖入一个云消息控件到页面中,设置云标识为步骤1中我们新生成的标识号,然后把“自动连接”的勾选去掉。
4、在页面中拖入一个二维码控件,在页面的onLoad()方法中,设置二维码对象的数据为JSON内容,包含云标识,设备ID,设备描述信息,以及设备图片种类。微信小程序可以通过扫描该二维码来添加设备。
ui.main.onLoad = function() {
// 配置二维码(JSON字符串,主要包含云消息标识以及当前设备的ID)
// 微信小程序端,扫码此二维码可以添加该设备
var obj = {cloudid: ui.main.cloudMessage.cloudId,
deviceid: util.getDeviceId(),
title: "我的房间",
icon: "2"
};
ui.main.qrcode.text = util.cast.objectToJson(obj);
}
5、设备在连接服务器的时候需要设置一下遗愿主题,以便在设备意外断线的时候,微信小程序端能接收到设备的离线状态。
ui.main.onLoad = function() {
// 设置遗愿主题,设备掉线后,订阅了该主题的一端会接收到此消息
this.cloudMessage.setWillTopic(util.getDeviceId()+'/status', '{"status": "offline"}');
// 连接云消息服务器
this.cloudMessage.connect();
// 配置二维码(JSON字符串,主要包含云消息标识以及当前设备的ID)
// 微信小程序端,扫码此二维码可以添加该设备
var obj = {cloudid: ui.main.cloudMessage.cloudId,
deviceid: util.getDeviceId(),
title: "我的房间",
icon: "2"
};
ui.main.qrcode.text = util.cast.objectToJson(obj);
}
6、在云消息对象的onReceive()方法中,需要处理微信小程序发布的消息(${deviceid}/ping, ${deviceid}/get, ${deviceid}/set)
ui.main.cloudMessage.onReceive = function(topic, payload) {
util.console.log('---->收到: ' + topic + ' ' + payload);
if (topic == util.getDeviceId()+'/ping') {
// 收到ping消息,回复status主题
util.console.log('<----回复: ' + util.getDeviceId()+'/status');
this.publish(util.getDeviceId()+'/status', '{"status": "online"}');
} else if (topic == util.getDeviceId() + '/set') {
// 收到set消息,根据id值修改相应的状态值
var obj = util.cast.jsonToJsObject(payload); {
switch (obj.id) {
case '0': // 温度设置
temperature_preset = parseInt(obj.value);
ui.main.singleLineInput.text = temperature_preset;
break;
case '2': // 灯泡开关设置
lamp_value = parseInt(obj.value);
ui.main.switch_2.checked = lamp_value;
break;
case '3': // 灯光亮度设置
brightness_value = parseInt(obj.value);
ui.main.slider.value = brightness_value;
ui.main.label_brightness.text = brightness_value;
break;
default:
break;
}
}
util.console.log('<----回复: ' + util.getDeviceId()+'/post');
// 上报设备状态数据
publishPostMessage();
} else if (topic == util.getDeviceId() + '/get') {
util.console.log('<----回复: ' + util.getDeviceId()+'/detail');
// 收到get消息,上报设备详细状态数据
publishDetailMessage();
}
};
7、在页面中拖入一个定时器控件,在onTimeout()方法中,不断调用 publishPostMessage()方法来上报消息
ui.main.timer.onTimeout = function(counter) {
// 上报设备状态数据
publishPostMessage();
};
8、在全局代码中定义 **publishDetailMessage()**和 **publishPostMessage()**方法
var temperature_preset = 30; // 温度预设值
var lamp_value = 0; // 灯泡开关的值
var brightness_value = 80; // 亮度值
var counter = 0; // 计数器,用来让温度产生微小变化
/* 发布详细数据,包含所有的配置值(如icon, title, unit等),在收到${deviceid}/get主题时回复此消息 */
function publishDetailMessage() {
var arr = [];
var temperature = {
id: '0',
icon: temperature_preset > 40 ? '7' : '1',
title: '温度',
unit: '°c',
value: temperature_preset + counter++%5,
preset: temperature_preset,
range: '15,65'
};
var humidity = {
id: '1',
icon: '2',
title: '湿度',
unit: '%',
value: '47',
range: ''
};
var lamp = {
id: '2',
icon: lamp_value ? '3' : '5',
title: '灯光',
value: lamp_value,
state: lamp_value == 1 ? '开' : '关',
range: '0,1'
};
var brightness = {
id: '3',
icon: '4',
title: '亮度',
unit: '%',
value: brightness_value,
range: '0,100'
};
arr.push(temperature);
arr.push(humidity);
arr.push(lamp);
arr.push(brightness);
var obj = { items: arr };
// util.console.log(util.cast.objectToJson(obj));
ui.main.cloudMessage.publish(util.getDeviceId()+'/detail', util.cast.objectToJson(obj));
};
/* 发布精简数据(只包含当前需要修改的值),定时上报或者在收到${deviceid}/set主题时回复此消息 */
function publishPostMessage() {
var arr = [];
var temperature = {
id: '0',
icon: temperature_preset > 40 ? '7' : '1',
value: temperature_preset + counter++%5,
preset: temperature_preset,
};
var humidity = {
id: '1',
value: '47'
};
var lamp = {
id: '2',
icon: lamp_value ? '3' : '5',
value: lamp_value,
state: lamp_value == 1 ? '开' : '关'
};
var brightness = {
id: '3',
value: brightness_value
};
arr.push(temperature);
arr.push(humidity);
arr.push(lamp);
arr.push(brightness);
var obj = { items: arr };
// util.console.log(util.cast.objectToJson(obj));
ui.main.cloudMessage.publish(util.getDeviceId()+'/post', util.cast.objectToJson(obj));
};
8、运行WeStudio模拟器,并在微信中打开Express云助手小程序,扫描模拟器中的二维码,添加设备。操作小程序或者模拟器,可以查看实际效果。
9、Express云助手小程序,可以在微信中搜索
完整的WeStudio工程,请在最新版本的WeStudio中打开例程“物一世IoT”