云开发是 Serverless 云端一体化产品方案,通过云开发可以在无后端的情况下,进行微信小程序、Web 和 APP 应用的开发。在传统的物联网项目中,开发者往往需要考虑设备如何接入,应用如何开发,在开发物联网应用时需要部署复杂的后端环境,使用云开发,在无后端的情况下,实现安全、稳定的将微信小程序接入物联网平台。

很早之前,我写过一篇关于使用微信小程序调用 OneNET API 实现控制彩光灯的小程序,通过小程序直接请求 API,需要将产品 AK 存在小程序端,有安全风险。

通过云函数封装 OneNET API,更安全更高效,且无需后端部署服务器,近期需要做一个物联网项目,正好借这个机会重新熟悉一下 OneNET 的新能力,结合云开发,我将 OneNET 的 MQTTs 相关 API 进行了封装,供大家参考。

通过云开发,可以实现微信小程序、Web 应用、APP 读写 OneNET 物联网平台数据,实现更加友好的人机交互。

项目链接

Gist 云开发实现微信小程序接入 OneNET 物联网

云函数部署指南

以小程序云开发为例说明如何部署云函数。

注册微信小程序

注册微信小程序,获取 APPID。

创建微信小程序工程

使用微信开发者工具创建支持云开发的微信小程序,关键步骤是填入 APPID。

配置云开发环境

  • 点击云开发,开通环境并获取环境 ID
    20200501001657
  • 修改 app.js,填入环境 ID
    20200501001550

导入云函数

云函数封装我放到 gist 上了,链接 ===> 云开发实现微信小程序接入 OneNET 物联网
下载后拷贝到 cloudfunctions 文件夹中。
20200501001221

部署云函数

如需本地调试,需要本地安装依赖,否则可直接在云端安装依赖。
20200501001339
调整自定义超时时间为 10s 以上。
20200501002208

测试调用

用小程序发起调用,使用 MQTT.fx 模拟一个 MQTT 设备。
20200501002812
如图,设备收到了命令,因为是模拟设备为给平台回复确认信息,最终小程序应收到命令超时的错误信息。
20200501002629
模拟器显示的超时信息,实验成功。
20200501003041

云函数封装文档

概述

本节介绍云函数的封装,云函数的请求参数包含三部分,如下:

  • 鉴权部分(必要)
    • product_id 产品 ID
    • device_id 设备 ID
    • access_key 产品 AK
  • 函数名(必要)
    • option 所调用函数的函数名
  • 其他参数(非必要)
    • parameter 其他参数,一般需要参考 OneNET API 手册

注册设备

  • 为用户提供设备注册的方法,当 设备名称 已存在时,接口返回当前设备信息

  • option:registDevice

  • parameter

    • device_desc 设备描述
    • device_name 设备名称
  • 返回值手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "product_id": "341427",
    "device_id": "594507918",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "registDevice",
    "parameter": {
    "device_desc": "c4tcb",
    "device_name": "dev_tcb"
    }
    }

删除设备

  • 将设备从产品中删除

  • option:deleteDevice

  • 返回值手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    {
    "product_id": "341427",
    "device_id": "594799075",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "deleteDevice"
    }

更新设备 KEY

  • 为用户提供设备 key 的更新与自定义的方法

  • option:updateDeviceKey

  • parameter

    • force_offline 是否强制离线设备,默认为 true
  • 返回值手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "updateDeviceKey"
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "updateDeviceKey",
    "parameter": {
    "force_offline": false
    }
    }

设备命令

  • 直接向设备下发单播指令,同步设计,当设备收到命令并进行应答时,返回设备应答内容

  • 特别说明:同步下发命令超时时间为 10s,云函数自定义超时时间应大于 10s

  • option:synccmds

  • parameter

    • cmds(必要)文本型命令
  • 返回值手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "synccmds",
    "parameter": {
    "cmds": "TXISFINE"
    }
    }

查询设备镜像

  • 用于查询某个设备的设备镜像 json 文档

  • option:getDeviceImage

  • 返回值手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "getDeviceImage"
    }

更新设备镜像

  • option:updataDeviceImage

  • parameter

    • state(必要)
      • desired 应用期望属性,与 reported 至少存在一项
      • reported 设备上报属性,与 desired 至少存在一项
  • 返回值手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "updataDeviceImage",
    "parameter": {
    "state": {
    "desired": {
    "color": "green"
    },
    "reported": {
    "color": "red"
    }
    }
    }
    }

查询设备数据点

  • option:getDataPoints

  • parameter

    • par_str 查询参数,可以为空,构造方法请参考手册
  • 手册

  • 完整请求范例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "getDataPoints",
    "parameter": {
    "par_str": "datastream_id=ds&start=2017-01-01T00:00:00&limit=100"
    }
    }
    1
    2
    3
    4
    5
    6
    {
    "product_id": "341427",
    "device_id": "594770145",
    "access_key": "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
    "option": "getDataPoints"
    }

进阶操作

如何获取安全鉴权 Token

请参考 OneNET 开发者文档-Token 算法,目前云函数支持 PHP7.0 和 NodeJS8.9 两种运行时,对于安全鉴权 Token 获取我也进行了封装,PHP 和 NodeJS 实现 OneNET MQTTs Token 校验

将产品 AK 保存在云函数中

取消对const access_key的注释,并填入产品 AK,注释var const access_key,并不在自定义参数中传入 access_key。

20200430235031

在微信小程序中调用

例如,在微信小程序中调用云函数实现向设备下发命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
synccmds() {
wx.showLoading({
title: "执行中"
})
var _this = this;
wx.cloud.callFunction({
name: "onenet",
data: {
product_id: "341427",
device_id: "594507918",
access_key: "wPDifcotSNLT2wd179+BjF/VUmc4JH2AJdvLuGahaZ8=",
option: "synccmds",
parameter: {
cmds: "TXISFINE"
}
},
success: function (res) {
var re = JSON.stringify(res.result);
// 函数返回值
_this.setData({
log: re
});
wx.hideLoading({
complete: (res) => {},
})
}
});
}

问题反馈

留言 or 邮件
tocker#16iot.cn