物一世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”

results matching ""

    No results matching ""