智能家居:微信小程序与阿里云IOT设备交互实战

一、准备工作

1.1 硬件设备

本场 Chat 中开发实战课程我们需要采购如下硬件设备: Ruff 套件 和 激光PM2.5传感器。
在这里插入图片描述

1.2 开发软件:

我们需要准备如下软件环境和开发工具:

Node.js v8.7.0
Ruff SDK v1.11.12
Sublime Text 3 编辑器
微信开发者工具 v1.02

1.3 云资源

我们本次 IoT 物联网开发实战涉及以下云资源的使用:

物联网平台 IoT :提供设备接入,数据流转,指令下行能力;
函数计算 FC :Serverless 计算平台;

二、技术架构

本次开发实战基于 Ruff 开发板,使用温湿度传感器 (DHT11) 和激光PM2.5传感器 (SDS011) 采集家居环境数据;LED 灯可以调整灯光颜色;LCD 显示屏展示当前温湿度值。 Ruff 开发板作为主控,通过JavaScript 版本 SDK 接入阿里云 IoT 物联网平台,更新实时状态到设备影子。通过函数计算提供数据查询和控制指令 API ,用户可以在微信小程序端实时查看家居环境数据,控制 LED 灯的开关,调整灯光颜色。

完整技术架构如下:
在这里插入图片描述

三、Ruff 硬件开发

3.1 Ruff 简介

Ruff 是一个支持 JavaScript 开发应用的物联网操作系统,为软件开发者提供开放、高效、敏捷的物联网应用开发平台,让 IoT 应用开发更简单。
在这里插入图片描述
整个 Ruff 开发体系包括 Ruff OS、Ruff SDK、Ruff 软件仓库、Ruff Kit 开发套件。 只要您有软件开发经验,就可以用 Ruff 开发硬件应用。
Ruff OS 运行在硬件板卡上,为 Ruff 应用提供运行环境。
Ruff SDK 安装在开发机电脑上,包含开发相关的所有工具。
Ruff 软件仓库是云端的在线软件包管理平台,提供软件包下载和分享服务。
Ruff Kit 开发套件由 Ruff 开发板 (ruff-mbd-v1) 和多个外设模块组成,帮助快速上手。
在这里插入图片描述

3.2 Ruff 开发的基本步骤

3.2.1 下载安装 Ruff SDK

根据你的操作系统,下载并安装 Ruff SDK 。

在安装完成后,在命令行中执行 rap --version,如果正确输出当前的 SDK 版本,则说明 Ruff SDK 安装成功。

$ rap --version
1.11.4

3.2.2 创建项目

使用命令行打开项目文件夹,再逐行执行下列命令,rap 工具会初始化项目并下载开发板的配置信息及依赖。

# 新建项目文件夹
$ mkdir ruff-iot-device
# 进入项目文件夹
$ cd ruff-iot-device/
# 初始化 Ruff 项目,根据提示填写应用名称,版本,作者等
$ rap init
? app name: ruff-iot-device
? version: 0.1.0
? description: 
? author: 
Installing main board module...
Downloading package "ruff-mbd-v1"...
Extracting package "ruff-mbd-v1" (4.2.10)...
Downloading package "led-gpio"...
Extracting package "led-gpio" (3.0.5)...
Downloading package "button-gpio"...
Extracting package "button-gpio" (2.0.9)...
Downloading package "pca9685"...
Extracting package "pca9685" (2.0.5)...
Downloading package "ltc2309"...
Extracting package "ltc2309" (3.0.1)...
Downloading package "mcp23017"...
Extracting package "mcp23017" (2.0.5)...
Downloading package "ruff-v1-sys-usb"...
Extracting package "ruff-v1-sys-usb" (0.3.1)...
Created files:
- package.json
- .rapignore
- README.md
- src/index.js
- test/test.js
- app.json
Done, happy crafting!

3.2.3 传感器硬件选择和驱动

传感器信息列表:
在这里插入图片描述
在项目中添加传感器设备和驱动模块

$ rap device add dht
? model: dht11
Searching supported drivers from Rap registry...
? select a driver for device "dht11"(DHT11): dht11@0.3.6
Installing driver...
Downloading package "dht11"...
Extracting package "dht11" (0.3.6)...
- dht11@0.3.6 (https://rap.ruff.io/raps/dht11)
Adding device "dht11" to configuration...
Adding input "dht11/gpio" (gpio) to configuration...
Configuration updated.

3.2.4 应用开发

安装阿里云IoT物联网平台设备端 SDK

$ rap install aliyun-iot-device-mqtt --save

依赖 lib 安装完成后,整个工程目录如下:
在这里插入图片描述
应用程序 设备端完整应用程序代码可以在附录中获取,这里我们只介绍几个关键代码片段。 空气质量数据:

//空气质量数据
$('#air').on('aqi', function(error, pm25, pm10) {
    if (error) {
        console.log(error);
        return;
    }
    reported.pm25 = pm25;
    reported.pm10 = pm10;
});
$('#light').setRGB(rgb, function(error, rgb) {
    if (!error) {
        reported.lightStatus = 'on';
        reported.lightRGB = desired.lightRGB;

        updateShadowData();
    }
});

温湿度数据:

//温度
$('#dht').getTemperature(function(error, temperature) {
    console.log(error)
    if (!error) {
        reported.temperature = temperature;
    }
});
//湿度
$('#dht').getRelativeHumidity(function(error, humidity) {
    console.log(error)
    if (!error) {
        reported.humidity = humidity;
    }
});

LED 灯颜色调整:

//LED灯
$('#light').setRGB(rgb, function(error, rgb) {
    if (!error) {
        reported.lightStatus = 'on';
        reported.lightRGB = lightRGB;
    }
});

设备影子同步:

//设备影子更新topic
var updateShadowTopic = "/shadow/update/" + options.productKey + "/" + options.deviceName;

function updateShadowData() {
    //LCD显示屏 信息更新
    $('#lcd').clear();
    $('#lcd').setCursor(0, 0);
    $('#lcd').print("T:" + reported.temperature + " C,H:" + reported.humidity + "%");

    $('#lcd').setCursor(0, 1);
    $('#lcd').print("LED:" + reported.lightStatus + ",C:" + reported.lightRGB);

        //设备影子 reported数据结构
    var data = {
        method: "update",
        state: {
            reported: reported
        },
        version: Date.now()
    }
    console.log('updateShadow', JSON.stringify(data));
      //设备影子 更新
    client.publish(updateShadowTopic, JSON.stringify(data));
}

设备影子更新后,我们就可以在云端看到数据:
在这里插入图片描述

3.2.5 连接硬件设备

Ruff 主板接口如下图:
在这里插入图片描述
我们可以通过 rap 命令查看硬件接线方式,并按图所示使用杜邦线连接设备串口接入对应主板串口。

$ rap layout --visual

在这里插入图片描述

3.2.6 程序部署

配置开发板的网络访问能力

将 Ruff 开发板上的 micro USB 接口与 USB 电源线连接,Ruff 开发板随即启动。
开发板成功启动后,会搭建一个名为 Ruff_xxx 的无线热点。电脑连接该热点。
在这里插入图片描述
在浏览器中访问 192.168.78.1。
填写本地无线网络的 SSID 和 PASSWORD 并确认。如下图所示:
在这里插入图片描述
等待主板重启后,会自动接入本地网络。

部署应用到主板 电脑接入开发板的 Ruff_xxx 无线热点,在命令行中执行如下命令:

$ rap deploy -s

如果一切顺利,在应用启动成功后稍等片刻,就可以看到红色板载 LED 已经点亮了。

我们在设备控制台应用控制界面看到应用已经启动。
在这里插入图片描述
在设备控制台应用日志界面看到应用当前的日志信息。应用程序使用 console.log 方法输出的信息,也可以在这里查看
在这里插入图片描述

四、IoT 物联网平台云端开发

在 IoT 物联网平台,我们创建一个产品家居环境,并在功能定义部分添加如下属性:
在这里插入图片描述
物模型定义完成后,控制台产品详情如下:
在这里插入图片描述
然后,我们基于家居环境产品创建一个具体设备,获取设备身份三元组。
在这里插入图片描述

五、在函数计算平台开发业务接口

为了和微信小程序通信,我们需要创建 2 个API:获取设备数据(getDeviceShadow)和发送控制指令(sendCommand)

5.1 设备影子

物联网平台提供设备影子功能,用于缓存设备状态。设备在线时,可以直接获取云端指令;设备离线时,上线后可以主动拉取云端指令。 设备影子是一个 JSON 文档,用于存储设备上报状态、应用程序期望状态信息。 每个设备有且只有一个设备影子,设备可以通过MQTT获取和设置设备影子来同步状态,该同步可以是影子同步给设备,也可以是设备同步给影子。
在这里插入图片描述

5.2 获取设备状态数据 getDeviceShadow

根据 IoT物联网平台服务端 API 文档 getDeviceShadow API ,我们可以通过查询设备的影子信息,获取设备最新状态。该接口定义如下:
在这里插入图片描述
在这里插入图片描述
在此我们不需要创建服务端应用,而是在函数计算平台创建一个函数 getDeviceShadow ,配置HTTP触发器,具体如下:
在这里插入图片描述
我们采用 Nodejs 语言来编写函数,调用 IoT 物联网平台的 POP API : getDeviceShadow API ,传入参数,获取最新数据,代码内容如下:

const getRawBody = require('raw-body');

const co = require('co');
const RPCClient = require('@alicloud/pop-core').RPCClient;

const options = {
    accessKey: "替换你的accessKey",
    accessKeySecret: "替换你的accessKeySecret",
};
//创建 pop rpc client
const iotClient = new RPCClient({
    accessKeyId: options.accessKey,
    secretAccessKey: options.accessKeySecret,
    endpoint: options.endpoint || 'https://iot.cn-shanghai.aliyuncs.com',
    apiVersion: options.apiVersion || '2018-01-20'
});

// 函数入口
module.exports.handler = function(req, resp, context) {

    try {
        getRawBody(req, function(err, body) {
            if (err) {
                resp.send(JSON.stringify(err))
                return;
            }
            body = JSON.parse(decodeURIComponent(body.toString()))

            const productKey = body.productKey;
            const deviceName = body.deviceName;

            const qos = body.qos || 1;


            co(function*() {
                try {
                    // 1.构造iot API
                    // 这里是POP API的Action
                    const action = 'GetDeviceShadow';
                    // 这里是POP API的入参params
                    const params = {
                        ProductKey: productKey,
                        DeviceName: deviceName
                    };

                    //2.发送请求
                    const response = yield iotClient.request(action, params);
                    const ShadowMessage = JSON.parse(response.ShadowMessage)
                    resp.send(JSON.stringify(ShadowMessage.state.reported))
                } catch (err) {
                    resp.send(JSON.stringify(err));
                }
            });


        })

    } catch (err) {
        resp.send("err:" + JSON.stringify(err))
    }

};

5.3 发送控制指令 sendCommand

同上,我们创建一个函数 sendCommand ,使用 IoT 物联网平台服务端 API 文档 Pub API ,实现控制 LED 灯的指令下发。完整代码内容如下:

module.exports.handler = function(req, resp, context) {

    try {
        getRawBody(req, function(err, body) {
            if (err) {
                resp.send(JSON.stringify(err))
                return;
            }
            body = JSON.parse(decodeURIComponent(body.toString()))

            const productKey = body.productKey;
            const topicFullName = body.topicFullName;
            const message = body.message || {};

            const qos = body.qos || 1;


            co(function*() {
                try {
                    // 1.构造iot API
                    // 这里是POP API的Action
                    const action = 'Pub';
                    // 这里是POP API的入参params
                    const params = {
                        ProductKey: productKey,
                        TopicFullName: topicFullName,
                        MessageContent: new Buffer(JSON.stringify(message)).toString('base64'),
                        Qos: qos
                    };
                    //2.发送请求
                    const response = yield iotClient.request(action, params);

                    resp.send(JSON.stringify(response))
                } catch (err) {
                    resp.send(JSON.stringify(err));
                }
            });


        })

    } catch (err) {
        resp.send("err:" + JSON.stringify(err))
    }

};

至此,我们 2 个业务用到的 API 就开发完成了。我们可以在函数计算平台发起测试调用,验证我们服务可用性。
在这里插入图片描述

六、微信小程序开发

6.1 小程序云端配置

首先,我们要注册微信小程序开发者账号,参考微信官方文档 。 然后,我们需要完善小程序基本信息,包括:图标、名称、介绍等。 最后,我们在控制台添加 request 合法域名:https://xxx.cn-shanghai.fc.aliyuncs.com ,以保证微信不拦截我们小程序的 HTTPS 请求。参考下图示例:
在这里插入图片描述

6.2 小程序开发

根据我们电脑实际情况,从微信官网地址下载并安装微信开发者工具。

打开 IDE 工具,创建 index 的页面。
在这里插入图片描述
这里有小程序完整开发文档,我们主要使用 **wx.request **完成网络请求。

发送网络请求 wx.request 接口细节:
在这里插入图片描述

wx.request({
      url: '函数计算的 HTTP API url',
      method: 'POST',
      data: {
        "deviceName": "设备名", "productKey": "产品code"
      },
      header: {
        'content-type': 'application/json'
      },
      success(res) {
        console.log(res.data)

        wx.hideLoading()
        // 更新到 UI 界面
        updateUI(res.data)
      }
    })

6.3 Echarts 图表

在小程序页面,我们使用了 echarts 组件的仪表盘,展示空气质量PM2.5数据。 gauge 配置如下:

import * as echarts from '../../ec-canvas/echarts';

function initChart(canvas, width, height) {
  const chart = echarts.init(canvas, null, {
    width: width,
    height: height
  });
  canvas.setChart(chart);

  var option = {
    backgroundColor: "#f8f8f8",
    color: ["#37A2DA", "#32C5E9", "#67E0E3"],
    series: [{
      name: '空气质量',
      min: 0, 
      max: 500,   
      splitNumber: 10,  
      type: 'gauge',
      detail: {
        formatter: '{value}'
      },
      axisLine: {
        show: true,
        lineStyle: {
          width: 10,
          shadowBlur: 0,
          color: [
            [0.3, '#67e0e3'],
            [0.7, '#37a2da'],
            [1, '#fd666d']
          ]
        }
      },
      data: [{
        value: 80,
        name:'空气质量'
      }],
      splitLine: { 
        show: true, 
        length: 13, 
        lineStyle: { 
          color: '#aaa',
          width: 2,
          type: 'solid'
        }
      },
      title: {
        show: true,
        offsetCenter: [0, 70],
        textStyle: {
          color: '#333',
          fontSize: 15
        }
      },
      pointer: {
        length: '90%',
        width: 6,
        color: 'auto'
      }
    }]
  };
  chart.setOption(option, true);

  return chart;
}

Page({
  data: {
    ec: {
      onInit: initChart
    }
  }
})

七、附录

[1] 项目完整 GitHub代码(硬件设备+后台服务器+小程序),请加QQ群:649564523 备注CSDN

[2] IoT 物联网平台官方文档:https://help.aliyun.com/product/30520.html

[3] 函数计算官方文档:https://help.aliyun.com/product/50980.html

[4] Ruff 官网:http://ruff.io

[5] Echarts 官网:https://echarts.baidu.com

[6] 微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/index.html

发布了11 篇原创文章 · 获赞 7 · 访问量 1915

猜你喜欢

转载自blog.csdn.net/qq_43572158/article/details/104428869
今日推荐