remove unused mini program

This commit is contained in:
Supowang
2022-06-23 11:13:23 +08:00
parent ea326bc4b8
commit 4c4d515d59
98 changed files with 0 additions and 10660 deletions

View File

@@ -1,2 +0,0 @@
## 蓝牙升级微信小程序源码

View File

@@ -1,12 +0,0 @@
//app.js
App({
globalData: {
},
onLaunch: function () {
this.globalData.SystemInfo = wx.getSystemInfoSync()
//console.log(this.globalData.SystemInfo)
wx.setKeepScreenOn({
keepScreenOn: true
})
},
})

View File

@@ -1,14 +0,0 @@
{
"pages": [
"pages/hardware/ble/index/index",
"pages/hardware/ble/device/index"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#f8f8f8",
"navigationBarTitleText": "TencentOS tiny 蓝牙OTA示例",
"navigationBarTextStyle": "black",
"backgroundColor": "#f8f8f8"
},
"sitemapLocation": "sitemap.json"
}

View File

@@ -1,51 +0,0 @@
/**app.wxss**/
/* .container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 100rpx 0;
box-sizing: border-box;
} */
.flex-row {
display: flex;
flex-flow: row nowrap;
}
.flex-row-wrap {
display: flex;
flex-flow: row wrap;
}
.flex-column-reverse {
display: flex;
flex-flow: column-reverse nowrap;
}
.center {
justify-content: center;
align-items: center;
}
.left {
justify-content: flex-start;
align-items: center;
}
.right {
justify-content: flex-end;
align-items: center;
}
.space-between {
justify-content: space-between;
align-items: center;
}
.space-around {
justify-content: space-around;
align-items: center;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,441 +0,0 @@
// 1. 小程序发布版本或者体验版本连续写ble需要加延时否则会导致写失败1008。本地调试本身有延时因此不需要加需要注释掉
// 2. 安卓系统调试蓝牙会有黏包问题。[ACK, ACK, ..] [C, C] ...
// 3. ymodem.h DOWNLOAD_TIMEOUT 配置需要注意过小的话写block时间过长会导致接收端超时重新进入普通模式
// 4. NAK 重传逻辑暂不支持
// https://www.amobbs.com/thread-5704281-1-1.html
const app = getApp()
const util = require('../../../../utils/util.js');
const bleapi = require('../../../../utils/hardware/ble/ble-api.js');
const Packet = require('../../../../utils/hardware/ble/packet.js')
var msgQueue = []
var fileBuffer
var fileName
var bUse1K = true
var DownLoadMode = 0
const SyncTimeout = 15000 // 等待C
const RecvTimeout = 5000 // 等待ACK
/*
SOH 0x01 协议头(128bytes类型)
STX 0x02 协议头(1k类型)
EOT 0x04 传输结束
ACK 0x06 接收响应
NAK 0x15 失败响应
CAN 0x18 取消传输
C 0x43 开启文件传输
*/
const EOT = 0x04
const ACK = 0x06
const CAN = 0x18
const NAK = 0x15
const C = 0x43
Page({
data: {
device: {
// connected: true,
// deviceId: "90:9A:77:26:5D:64",
// name: "HC-08",
},
receiveText: '',
downloadLog: '',
},
acceptDataFromPrevPage() {
const eventChannel = this.getOpenerEventChannel()
return new Promise((resolve, reject) => {
eventChannel.on('eventData', function (data) {
resolve(data)
})
})
},
onLoad: async function(options) {
console.log(util.formatTime())
let data = await this.acceptDataFromPrevPage()
console.log("accept data from prev page", data)
this.setData({
device: data.device,
})
// 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
await bleapi.onBLEConnectionStateChange(this.onStateChange)
// 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification
if (this.data.device.characteristic.properties.notify == true) {
console.log("notifyBLECharacteristicValueChange and register value change callback")
await bleapi.notifyBLECharacteristicValueChanged(
this.data.device.deviceId,
this.data.device.service.uuid,
this.data.device.characteristic.uuid)
await bleapi.onBLECharacteristicValueChange(this.onMessage)
}
},
onUnload: function(e) {
let deviceId = this.data.device.deviceId
console.log("onUnload close the ble connection", deviceId)
bleapi.closeBLEConnection(deviceId)
},
onStateChange: function(res) {
console.log("onBLEConnectionStateChange", res.connected)
this.setData({
[`device.connected`]: res.connected
})
},
formSubmit: async function(e) {
console.log(e.detail.value)
let value = e.detail.value.textarea
try {
await this.writeData(util.str2abUint8(value))
wx.showToast({
icon: 'none',
title: '写数据成功',
duration: 1000,
})
} catch (e) {
wx.showToast({
icon: 'none',
title: '写数据失败',
duration: 2000,
})
}
},
formReset(e) {
console.log(e)
this.setData({
inputText: '',
})
},
bindTextAreaBlur: function(e) {
console.log(e.detail.value)
this.setData({
inputText: e.detail.value,
})
},
chose: function() {
wx.chooseMessageFile({
count: 1,
type: 'file',
success: (res) => {
console.log(res)
fileName = res.tempFiles[0].name
wx.getFileSystemManager().readFile({
filePath: res.tempFiles[0].path,
// encoding: 'binary',
success: (res2) => {
console.log(res2)
fileBuffer = new Uint8Array(res2.data)
this.setData({
file_name: fileName,
file_size: res.tempFiles[0].size,
})
}
})
}
})
},
writeData: async function(payload) {
console.log(`writeData len(${payload.byteLength})`, payload, new Date().toISOString())
if (!this.data.device.connected) {
wx.showModal({
title: '提示',
content: '蓝牙已断开,请重新连接设备',
showCancel: false,
success: function(res) {}
})
return Promise.reject(`ble disconnect`)
}
let pos = 0;
let bytes = payload.byteLength
while (bytes > 0) {
let frameBuffer;
if (bytes > 20) {
frameBuffer = payload.slice(pos, pos + 20);
pos += 20;
bytes -= 20;
} else {
frameBuffer = payload.slice(pos, pos + bytes);
pos += bytes;
bytes -= bytes;
}
// console.log(`frame(${frameBuffer.byteLength})`, frameBuffer)
try {
await bleapi.writeBLECharacteristicValue(
this.data.device.deviceId,
this.data.device.service.uuid,
this.data.device.characteristic.uuid,
frameBuffer
)
// Android手机连续调用会存在写失败的可能性建议加延时
await util.delayMs(20)
} catch (e) {
return Promise.reject(e)
}
}
return Promise.resolve()
},
onMessage: function(data) {
let datastr = util.ab2strHex(data)
console.log('onMessage:', datastr, msgQueue, new Date().toISOString())
let str = util.ArrayBuffer2str(data)
this.setData({
receiveText: this.data.receiveText + str
})
if (DownLoadMode) { // 下载模式
let arr = new Uint8Array(data)
for (let i = 0; i < arr.length; i++) {
if (arr[i] == CAN) { // 取消传输
DownLoadMode = false
}
msgQueue.push(arr[i])
}
this.setData({
downloadLog: this.data.downloadLog + `${datastr}\r\n`
})
} else { // 普通模式
console.log("normal onReceive:", str)
}
},
upload: async function() {
let that = this
if (!this.data.device.connected) {
wx.showModal({
title: '提示',
content: '蓝牙已断开',
showCancel: false,
success: function(res) {}
})
return
}
if (!fileName || fileBuffer.length == 0) {
wx.showModal({
content: "请先选择固件",
showCancel: false
});
return
}
wx.showLoading({
title: '准备上传...',
mask: true,
})
this.setData({
send_percent: 0,
timestamp_start: "",
timestamp_end: "",
})
DownLoadMode = 1
console.log(`upload begin. bytes: ${fileBuffer.length} /1024: ${fileBuffer.length/1024}`)
try {
await this.recieveByte(C, SyncTimeout)
wx.showLoading({
title: '开始上传...',
mask: true,
})
this.setData({
timestamp_start: util.formatTime(),
date_start: new Date()
})
console.log("send blockZero begin")
let id = 0
let blockZero = Packet.getNormalPacket(id, Packet.getZeroContent(fileName, fileBuffer.length))
await that.writeData(blockZero.buffer)
await that.recieveByte(ACK, RecvTimeout)
await that.recieveByte(C, SyncTimeout)
console.log("send blockZero complete")
wx.showLoading({
title: '上传中...',
mask: true,
})
console.log("send file begin")
let nInterval = (bUse1K == true) ? 1024 : 128;
for (let i = 0; i < fileBuffer.length; i += nInterval) {
console.log("send block " + (i / nInterval + 1) + " start");
let upper = (fileBuffer.length < i + nInterval) ?
fileBuffer.length : i + nInterval;
let payloadBuf = new Uint8Array(nInterval);
for (let j = i; j < upper; j++) {
payloadBuf[j - i] = fileBuffer[j];
}
id = i / nInterval + 1;
let block = (bUse1K == true) ? Packet.getLongPacket(id, payloadBuf) : Packet.getNormalPacket(id, payloadBuf);
await that.writeData(block.buffer)
try {
// TODO: NAK 重传逻辑
await that.recieveByte(ACK, RecvTimeout)
} catch (e) {
console.error(`${(i / nInterval) + 1} block lost a ack`, e)
}
console.log("send block " + ((i / nInterval) + 1) + " succceed!");
this.setData({
send_percent: parseInt((i) / fileBuffer.length * 100),
})
}
console.log("send file complete")
// EOT处理
// 超时,
// 返回 NAK, 则重传EOT
// 返回 ACK, 则结束
console.log("send EOT");
let sendEOTAndRetry = this.autoRetry(async function(buf) {
await that.writeData(new Uint8Array([EOT]).buffer)
console.log(`waiting ACK`, new Date().toISOString())
let c = await that.recieve(RecvTimeout)
if (c == ACK) {
console.log(`receive ACK 0x${c.toString(16)}`)
// 处理黏包的情况 [ACK, ACK]
while (msgQueue.length > 0) {
if (msgQueue[0] == ACK) {
let c = msgQueue.shift()
console.log(`shift ${c.toString(16)} from queue`, msgQueue)
} else {
break
}
}
} else if (c == NAK) {
console.log(`receive NAK 0x${c.toString(16)}`)
// 处理黏包情况 [NAK, ACK, C]
if (msgQueue.length > 0) {
await that.recieveByte(ACK, RecvTimeout)
} else {
throw `receive NAK 0x${c.toString(16)}, resend EOT`
}
}
}, 2)
await sendEOTAndRetry(new Uint8Array([EOT]).buffer)
await that.recieveByte(C, SyncTimeout)
console.log("send last block begin")
let blockLast = Packet.getNormalPacket(0, new Uint8Array(128));
await that.writeData(blockLast.buffer)
await that.recieveByte(ACK, RecvTimeout)
console.log("send last block compelte")
DownLoadMode = 0
let diff = new Date().getTime() - this.data.date_start.getTime()
let rate = Math.round(fileBuffer.length * 1000 / diff) * 100 / 100
console.log("upload complete")
this.setData({
send_percent: 100,
timestamp_end: util.formatTime(),
rate: rate,
})
wx.showModal({
content: "上传完成",
showCancel: false
});
} catch (e) {
DownLoadMode = 0
console.error("upload fail:", e)
wx.showModal({
content: "上传失败,请重试\r\n" + e,
showCancel: false
});
}
wx.hideLoading()
console.log("msgQueue", msgQueue)
msgQueue = [] // clear msgQueue
},
reciveByteAndRetry: async function(expect, timeout, retryNum) {
let func = this.autoRetry(this.recieveByte, retryNum)
await func(expect, timeout)
},
recieveByte: async function(expect, timeout) {
console.log(`waiting 0x${expect.toString(16)} for ${timeout}ms ...`, new Date().toISOString())
try {
let c = await this.recieve(timeout)
if (c == CAN) { // 接收端终止
throw `receive 0x${c.toString(16)}. cancel tranmission`
}
if (c != expect) {
throw `expect 0x${expect.toString(16)}, but recieve 0x${c.toString(16)}`
}
// 处理黏包的情况
while (msgQueue.length > 0) {
if (msgQueue[0] == expect) {
let c = msgQueue.shift()
console.log(`shift ${c.toString(16)} from queue`, msgQueue)
} else {
break
}
}
Promise.resolve(c)
} catch (e) {
throw `waiting 0x${expect.toString(16)} fail: ${e}`
}
},
recieve: async function(timeout) {
// console.log("start recieve", new Date().toISOString())
let elaspe = timeout
const interval = 500
while (elaspe > 0) {
elaspe = elaspe - interval
// console.log(`xxxx`, msgQueue.length, elaspe)
if (msgQueue.length > 0) {
let c = msgQueue.shift();
console.log(`receive from queue: ${c.toString(16)}`, msgQueue)
return Promise.resolve(c)
}
await util.delayMs(interval)
}
return Promise.reject(`receive timeout ${timeout}ms ${new Date().toISOString()}`)
},
/*
example:
let sendLastblockAndRetry = this.autoRetry(async function (buf) {
await that.writeData(buf);
await that.recieveByte(ACK, RecvTimeout)
}, 3)
await sendLastblockAndRetry(blockLast.buffer)
*/
autoRetry(func, retryMax) {
let retryNum = retryMax;
return async function funcR() {
let params = arguments
while (retryNum--) {
try {
await func(...params)
break
} catch (e) {
if (retryNum > 0) {
console.error(`retry ${retryMax - retryNum} time. error:`, e);
continue
} else {
throw e
}
}
}
}
},
RecvCleanTap: function() {
this.setData({
receiveText: ''
})
},
sendValue: async function(e) {
let val = e.currentTarget.dataset.val
try {
await this.writeData(util.str2abUint8(val))
wx.showToast({
icon: 'none',
title: '发送成功',
duration: 1000,
})
} catch (e) {
wx.showToast({
icon: 'none',
title: '发送失败',
duration: 2000,
})
}
},
})

View File

@@ -1,3 +0,0 @@
{
"usingComponents": {}
}

View File

@@ -1,94 +0,0 @@
<!--pages/ble-device/index.wxml-->
<template name="connectStatus">
<view wx:if="{{ connected }}">
<view style="color:green; font-weight:bold">已连接</view>
</view>
<view wx:elif="{{ !connected }}">
<view style="color:#ff0000; font-weight:bold">已断开</view>
</view>
<view wx:else>
<view style="color:#ff0000; font-weight:bold">未连接</view>
</view>
</template>
<view class="container">
<view class="title">
设备信息
</view>
<view class="box">
<view class="box-cell flex-row space-between">
<view>设备名称</view>
<view>{{device.name}}</view>
</view>
<view class="box-cell flex-row space-between">
<view>设备ID</view>
<view>{{device.deviceId}}</view>
</view>
<view class="box-cell flex-row space-between">
<view>连接状态</view>
<view>
<template is="connectStatus" data="{{connected:device.connected}}" />
</view>
<!-- <view>{{device.connected}}</view> -->
</view>
</view>
<view class="flex-row space-between">
<view class="title">
串口输出
</view>
<view>
<button size="mini" type="default" bindtap="RecvCleanTap">清空</button>
</view>
</view>
<textarea class="revc_text" maxlength="-1" disabled value="{{receiveText}}" />
<view class="title">
固件升级
</view>
<view class="box">
<view class="box-cell flex-row space-between">
<view>菜单选项</view>
<view>
<button class="menu-item" size="mini" type="default" data-val="1" bindtap="sendValue">1</button>
<button class="menu-item" size="mini" type="default" data-val="2" bindtap="sendValue">2</button>
<button class="menu-item" size="mini" type="default" data-val="3" bindtap="sendValue">3</button>
<button class="menu-item" size="mini" type="default" data-val="4" bindtap="sendValue">4</button>
</view>
</view>
<view class="box-cell flex-row space-between">
<view>
固件升级
</view>
<view>
<button class="menu-item" size="mini" type="default" bindtap="chose">选择固件</button>
<button class="menu-item" size="mini" type="default" bindtap="upload">上传固件</button>
</view>
</view>
<view wx:if="{{file_name}}">
<view class="box-cell flex-row space-between">
<view>文件名(大小)</view>
<view>{{file_name}} {{file_size}}</view>
</view>
</view>
<view wx:if="{{timestamp_start}}">
<progress class="" percent="{{send_percent}}" show-info border-radius="10" stroke-width="5" />
</view>
<view wx:if="{{timestamp_end}}">
<view class="box-cell flex-column">
<view>begin@{{timestamp_start}}</view>
<view>finish@{{timestamp_end}}</view>
<view>rate@{{rate}}(B/s)</view>
</view>
</view>
</view>
<!-- <form catchsubmit="formSubmit" catchreset="formReset">
<textarea class="send_text" name="textarea" maxlength="-1" value="{{inputText}}" />
<view class="btn-area flex-row space-between">
<button size="mini" type="default" formType="reset">清空</button>
<button size="mini" type="primary" formType="submit">发送</button>
</view>
</form> -->
</view>

View File

@@ -1,78 +0,0 @@
page {
width: 100%;
height: 100%;
position: relative;
color: #333;
background-color: #F8F8F8;
font-size: 16px;
/*font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif;*/
font-family: PingFang SC, Helvetica Neue, Hiragino Sans GB, Helvetica, Microsoft YaHei, Arial;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: transparent;
}
.container {
margin: 20rpx 30rpx
}
.title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 10rpx;
padding-left: 20rpx;
}
.box {
margin-bottom: 30rpx;
padding: 20rpx;
border: 2rpx solid #d9d9d9;
border-radius: 20rpx;
background: white;
}
.box-cell {
padding-bottom: 10rpx;
line-height: 50rpx;
font-size: 32rpx;
color: #666;
/* border-bottom: 2rpx solid #d9d9d9; */
}
.send_text {
height: 100rpx;
width: 90%;
border: 2px solid #39beff;
margin: 10px auto;
padding: 5px;
}
.file {
display: flex;
flex-direction: column;
}
.file_name {
float: left;
padding-left: 10px;
}
.file_size {
float: left;
padding-left: 10px;
}
.revc_text {
width: 100%;
height: 400rpx;
border: 1rpx solid grey;
/* margin: 0 auto 10px; */
padding: 5rpx;
/* padding-bottom: 10rpx; */
margin-bottom: 20rpx;
font-size: 25rpx;
}
.menu-item {
margin-left: 20rpx
}

View File

@@ -1,129 +0,0 @@
const app = getApp()
let util = require('../../../../utils/util.js');
let bleapi = require('../../../../utils/hardware/ble/ble-api.js');
Page({
data: {
searching: false,
devicesList: []
},
onLoad: async function (options) {
this.search()
},
onUnload: async function () {
bleapi.closeBluetoothAdapter()
},
onBluetoothDeviceFound() {
let that = this
return new Promise((resolve) => {
wx.onBluetoothDeviceFound(function (res) {
var name = res.devices[0].name
if (name) {
console.log("onBluetoothDeviceFound:", name, res);
that.data.devicesList.push(res.devices[0])
that.setData({
devicesList: that.data.devicesList
})
}
})
resolve()
console.log("onBluetoothDeviceFound start")
})
},
search: async function() {
try {
await bleapi.closeBluetoothAdapter()
await bleapi.openBluetoothAdapter()
} catch(e) {
wx.showModal({
content: "请检查手机蓝牙是否打开",
showCancel: false
});
return
}
try {
// 开始扫描蓝牙设备
await bleapi.startBluetoothDevicesDiscovery([])
this.setData({
searching: true,
devicesList: []
})
await this.onBluetoothDeviceFound()
// 每次扫描蓝牙设备10秒
await util.delayMs(10000)
if (this.data.searching) {
this.setData({
searching: false
})
await bleapi.stopBluetoothDevicesDiscovery()
}
} catch (e) {
console.error(e)
wx.showModal({
content: "搜索设备失败\n" + e,
showCancel: false
});
}
},
connect: async function(e) {
console.log(e.currentTarget)
wx.showLoading({
title: '连接蓝牙设备中...',
})
let deviceId = e.currentTarget.id
let deviceName = e.currentTarget.dataset.name
try {
await bleapi.stopBluetoothDevicesDiscovery()
await bleapi.closeBLEConnection(deviceId)
// 创建BLE连接
await bleapi.createBLEConnection(deviceId)
// 读取BLE设备的 Services
let service = null
let services = await bleapi.getBLEDeviceServices(deviceId)
let serviceId = '0000FFE0-0000-1000-8000-00805F9B34FB' // 指定ServiceID
for (let i = 0; i < services.length; i++) {
if (services[i].isPrimary && services[i].uuid == serviceId) {
service = services[i]
break
}
}
// 读取BLE设备指定 ServiceId 的 Characteristics
let characteristics = await bleapi.getBLEDeviceCharacteristics(deviceId, service.uuid)
let characteristic = characteristics[0] // 默认选择第一个特征值
console.log('characteristic', characteristic)
// 完成连接BLE设备跳转到该设备页面
let device = {
connected: true,
name: deviceName,
deviceId: deviceId,
service: service,
characteristic: characteristic,
services: services,
characteristics: characteristics,
}
console.log(device)
wx.hideLoading()
wx.navigateTo({
url: '../device/index',
success: function(res) {
res.eventChannel.emit('eventData', {
device: device,
})
}
})
} catch (e) {
console.error(e)
wx.showToast({
title: "连接蓝牙失败,请重试",
icon: "none"
})
}
},
})

View File

@@ -1,3 +0,0 @@
{
"usingComponents": {}
}

View File

@@ -1,15 +0,0 @@
<view class="container">
<scroll-view scroll-y style="width:690rpx;height:{{list_height}}rpx">
<block wx:for="{{devicesList}}" wx:key="deviceId">
<view class="list-item" id="{{item.deviceId}}" data-name="{{item.name}}" bindtap="connect">
<view style="display:flex;flex-direction:column;width:80%">
<text style="font-size:medium;word-break:break-all">设备名称: {{item.name}}</text>
<text style="font-size:x-small;color:gray;word-break:break-all">设备ID: {{item.deviceId}}</text>
<text style="font-size:x-small;color:gray;word-break:break-all">信号强度RSSI: {{item.RSSI}}</text>
</view>
<image style="width:36px;height:36px" mode="aspectFit" src="/images/bluetooth.png"></image>
</view>
</block>
</scroll-view>
<button type="primary" class="button" loading="{{searching}}" bindtap="search">{{searching?"搜索中...":"搜索蓝牙设备"}}</button>
</view>

View File

@@ -1,27 +0,0 @@
page {
background-color: #f8f8f8;
}
.container {
padding: 0 30rpx 0 30rpx;
align-items: center;
}
.list-item {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 10px 0 10px 0;
box-sizing: border-box;
border: 1px solid #000;
border-style: none none solid none;
border-bottom-color: lightgray;
}
.list-item:last-child {
border-style: none;
}
.button {
position: fixed;
width: 690rpx;
bottom: 30rpx;
}

View File

@@ -1,7 +0,0 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

View File

@@ -1,554 +0,0 @@
/**
* 初始化蓝牙模块
*
* @return {Object} 调用结果
*/
function openBluetoothAdapter() {
return new Promise((resolve, reject) => {
wx.openBluetoothAdapter({
success(res) {
resolve(res)
},
fail(res) {
reject(res)
}
})
})
}
/**
* 关闭蓝牙模块
*
* @return {Object} 调用结果
*/
function closeBluetoothAdapter() {
return new Promise((resolve, reject) => {
wx.closeBluetoothAdapter({
complete(res) {
resolve(res)
}
})
})
}
/**
* 监听蓝牙状态
*
* @param {function} onBluetoothStateChange 函数对象,监听蓝牙状态变化的回调函数
* @return void
*/
function onBluetoothAdapterStateChange(onBluetoothStateChange) {
return new Promise((resolve) => {
wx.onBluetoothAdapterStateChange(function(res) {
// console.log('onBluetoothAdapterStateChange, now is', res)
onBluetoothStateChange(res)
})
resolve()
})
}
/**
* 启动搜索蓝牙设备功能
*
* @param {string} services 蓝牙服务
* @return void
*/
function startBluetoothDevicesDiscovery(services) {
return new Promise((resolve, reject) => {
wx.startBluetoothDevicesDiscovery({
services: services || [],
allowDuplicatesKey: false,
success(res) {
console.log("wx.startBluetoothDevicesDiscovery success")
resolve(res)
},
fail(res) {
console.log("wx.startBluetoothDevicesDiscovery fail")
reject(res)
}
})
})
}
/**
* 关闭搜索蓝牙设备功能
*
* @return void
*/
function stopBluetoothDevicesDiscovery() {
return new Promise((resolve, reject) => {
wx.stopBluetoothDevicesDiscovery({
complete(res) {
console.log("wx.stopBluetoothDevicesDiscovery success")
resolve()
}
})
})
}
/**
* 断开与低功耗蓝牙设备的连接
*
* @param {string} deviceId 蓝牙设备ID
* @return void
*/
function closeBLEConnection(deviceId) {
return new Promise((resolve, reject) => {
wx.closeBLEConnection({
deviceId,
success(res) {
console.log(`closeBLEConnection ${deviceId} success`, res)
},
fail(res) {
console.log(`closeBLEConnection ${deviceId} fail`, res)
},
complete(res) {
resolve()
}
})
})
}
/**
* 连接低功耗蓝牙设备
*
* @param {string} deviceId 蓝牙设备ID
* @return {Object} 调用结果
*/
function createBLEConnection(deviceId) {
return new Promise((resolve, reject) => {
wx.createBLEConnection({
deviceId: deviceId,
timeout: 5000, // TO_CHECK: 设置连接蓝牙超时时间
success: function(res) {
console.log(`createBLEConnection ${deviceId} success`, res)
resolve(res)
},
fail: function(res) {
console.log(`createBLEConnection ${deviceId} fail`, res);
reject(new Error(res.errMsg || 'wx.createBLEConnection fail'))
}
})
})
}
/**
* 监听低功耗蓝牙连接状态的改变事件
*
* @param {function} onStateChange 函数对象,连接状态变化的回调函数
* @return void
*/
function onBLEConnectionStateChange(onStateChange) {
return new Promise((resolve) => {
wx.onBLEConnectionStateChange(function(res) { // 该方法回调中可以用于处理连接意外断开等异常情况
// console.log(`onBLEConnectionStateChange device ${res.deviceId} state has changed, connected: ${res.connected}`)
onStateChange(res)
})
resolve()
})
}
/**
* 获取蓝牙设备所有服务
*
* @param {string} deviceId 蓝牙设备ID
* @return {Object} 调用结果
*/
function getBLEDeviceServices(deviceId) {
return new Promise((resolve, reject) => {
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function(res) {
console.log(`wx.getBLEDeviceServices ${deviceId} success:`, res.services)
resolve(res.services)
},
fail(res) { // 获取蓝牙服务失败
console.log(`wx.getBLEDeviceServices ${deviceId} fail:`, res)
reject(res.errMsg || 'wx.getBLEDeviceServices fail')
}
})
})
}
/**
* 获取蓝牙设备某个服务中所有特征值
*
* @param {string} deviceId 蓝牙设备ID
* @param {string} serviceId 蓝牙服务ID
* @return {Object} 调用结果
*/
function getBLEDeviceCharacteristics(deviceId, serviceId) {
return new Promise((resolve, reject) => {
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success(res) {
console.log(`wx.getBLEDeviceCharacteristics ${deviceId} ${serviceId} success:`, res.characteristics)
resolve(res.characteristics)
},
fail(res) { // 读取蓝牙特征值失败
console.log(`wx.getBLEDeviceCharacteristics ${deviceId} ${serviceId} fail`, res)
reject(res.errMsg || 'wx.getBLEDeviceCharacteristics fail')
},
})
})
}
/**
* 启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值
* 注:必须设备的特征值支持 notify 或者 indicate 才可以成功调用
*
* @param {string} deviceId 蓝牙设备ID
* @param {string} serviceId 蓝牙服务ID
* @param {string} notifyCharacteristicId 蓝牙特征值ID
* @return {Object} 调用结果
*/
function notifyBLECharacteristicValueChanged(deviceId, serviceId, notifyCharacteristicId) {
return new Promise((resolve, reject) => {
wx.notifyBLECharacteristicValueChanged({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: notifyCharacteristicId,
state: true,
success(res) {
console.log(`wx.notifyBLECharacteristicValueChanged ${deviceId} ${serviceId} ${notifyCharacteristicId} success`);
resolve(true)
},
fail(err) {
console.log(`wx.notifyBLECharacteristicValueChanged ${deviceId} ${serviceId} ${notifyCharacteristicId} fail`, err);
reject("启用蓝牙特征值notify功能失败")
}
})
})
}
/**
* 监听低功耗蓝牙设备的特征值变化事件
* 注:必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification
*
* @param {function} onMessage 函数对象,读数据的回调函数
* @return void
*/
function onBLECharacteristicValueChange(onMessage) {
var receivedData = null
return new Promise((resolve, reject) => {
wx.onBLECharacteristicValueChange(function(res) {
//{value: ArrayBuffer, deviceId: "D8:00:D2:4F:24:17", serviceId: "ba11f08c-5f14-0b0d-1080-007cbe238851-0x600000460240", characteristicId: "0000cd04-0000-1000-8000-00805f9b34fb-0x60800069fb80"}
onMessage(res.value)
})
resolve()
})
}
/**
* 向低功耗蓝牙设备特征值中写入二进制数据
* 注:必须设备的特征值支持 write 才可以成功调用
*
* @param {string} deviceId 蓝牙设备ID
* @param {string} serviceId 蓝牙服务ID
* @param {string} writeCharacteristicId 蓝牙特征值ID
* @param {string} payload 数据必须是ArrayBuffer类型
* @return {Object} 调用结果
*/
function writeBLECharacteristicValue(deviceId, serviceId, writeCharacteristicId, payload) {
return new Promise((resolve, reject) => {
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: writeCharacteristicId,
value: payload, // parameter.value should be ArrayBuffer
fail(res) {
console.log(`writeBLECharacteristicValue fail: ${deviceId} ${serviceId} ${writeCharacteristicId}`, res)
reject(res)
},
success(res) {
resolve(res)
}
})
})
}
/**
* 读取低功耗蓝牙设备的特征值的二进制数据值。
* 注:必须设备的特征值支持 read 才可以成功调用; 接口读取到的信息需要在 onBLECharacteristicValueChange 方法注册的回调中获取
*
* @param {string} deviceId 蓝牙设备ID
* @param {string} serviceId 蓝牙服务ID
* @param {string} readCharacteristicId 蓝牙特征值ID
* @return {Object} 调用结果
*/
function readBLECharacteristicValue(deviceId, serviceId, readCharacteristicId) {
return new Promise((resolve, reject) => {
wx.readBLECharacteristicValue({
deviceId: deviceId,
serviceId: serviceId,
characteristicId: readCharacteristicId,
fail(res) {
console.log(`readBLECharacteristicValue fail: ${deviceId} ${serviceId} ${readCharacteristicId}`, res)
reject(res)
},
success(res) {
resolve(res)
}
})
})
}
/**
* 连接设备
*
* @param {string} deviceId 蓝牙设备ID
* @return {Object} 设备连接信息
*/
function connectDevice(deviceId) {
return closeBLEConnection(deviceId).then(() => {
// 断开重连需要间隔1s,否则会出现假连接成功
// 还有一种方式是 getConnectedBluetoothDevices对比已连接的蓝牙如果已连接直接跳到设备页面
return createBLEConnection(deviceId)
}).then(() => {
// 读取 BLE services
return getBLEDeviceServices(deviceId)
}).then(([deviceId, services]) => {
// 读取 BLE Characteristics
for (let i = 0; i < services.length; i++) {
if (services[i].isPrimary) { // 确定对应服务。这里使用第一个primary服务
let serviceId = services[i].uuid
return getBLEDeviceCharacteristics(deviceId, serviceId)
}
}
return Promise.reject(new Error('未找到蓝牙主服务'))
}).then(
// 必须先启用 notifyBLECharacteristicValueChange 才能监听到设备 onBLECharacteristicValueChange 事件
([deviceId, serviceId, characteristics]) => {
let notifyCharacteristicId = null
let writeCharacteristicId = null
let readCharacteristicId = null
characteristics.forEach(function(item, index) {
if (item.properties.notify == true) {
notifyCharacteristicId = item.uuid
notifyBLECharacteristicValueChanged(deviceId, serviceId, item.uuid)
}
if (item.properties.write == true) {
writeCharacteristicId = item.uuid
}
if (item.properties.read == true) {
readCharacteristicId = item.uuid
}
})
let device = {
connected: true,
deviceId: deviceId,
serviceId: serviceId,
notifyCharacteristicId: notifyCharacteristicId,
writeCharacteristicId: writeCharacteristicId,
readCharacteristicId: readCharacteristicId,
}
return Promise.resolve(device)
}
)
}
/**
* 根据名称搜索设备
*
* @param {string} name 蓝牙设备名称
* @param {string} timeout 搜索超时时间单位ms
* @param {array} services 蓝牙设备的服务ID
* @return {string} deviceId 蓝牙设备ID
*/
function searchDeviceName(name, timeout, services = ["6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]) {
console.log("search begin", name)
let timer = null
let searchTimeout = new Promise((resolve, reject) => {
timer = setTimeout(function() {
console.log("searchDeviceName timeout", name)
stopBluetoothDevicesDiscovery()
reject(null)
}, timeout);
})
let search = Promise.resolve()
.then(() => {
return closeBluetoothAdapter()
})
.then(() => {
return openBluetoothAdapter()
})
.then(() => {
return startBluetoothDevicesDiscovery(services)
})
.then(() => {
return new Promise((resolve) => {
console.log("wx.onBluetoothDeviceFound start")
wx.onBluetoothDeviceFound(function(res) {
let foundName = res.devices[0].localName // TODO: localName or name?
if (foundName && foundName == name) {
console.log("searchDeviceName found:", name, res);
wx.offBluetoothDeviceFound(this)
clearTimeout(timer)
stopBluetoothDevicesDiscovery()
resolve(res.devices[0].deviceId)
}
})
})
})
return Promise.race([search, searchTimeout])
}
async function searchDevices(name, timeout, services = ["6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]) {
console.log("searchDevices", name)
let timer = null
let searchTimeout = new Promise((resolve, reject) => {
timer = setTimeout(function() {
console.log("searchDevices timeout", name)
stopBluetoothDevicesDiscovery()
reject(null)
}, timeout);
})
let search = Promise.resolve()
.then(() => {
return closeBluetoothAdapter()
})
.then(() => {
return openBluetoothAdapter()
})
.then(() => {
return startBluetoothDevicesDiscovery(services)
})
.then(() => {
return new Promise((resolve) => {
console.log("wx.onBluetoothDeviceFound start")
wx.onBluetoothDeviceFound(function(res) {
let foundName = res.devices[0].localName // TODO: localName or name?
if (foundName && foundName == name) {
console.log("searchDeviceName found:", name, res);
wx.offBluetoothDeviceFound(this)
clearTimeout(timer)
stopBluetoothDevicesDiscovery()
resolve(res.devices[0].deviceId)
}
})
})
})
return Promise.race([search, searchTimeout])
}
// function searchAndConnect(name, timeout, services = ["6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]) {
function searchAndConnect(name, timeout, services = []) {
return searchDeviceName(name, timeout, services).then(res => {
let devicesList = res
if (devicesList.length == 0) {
return Promise.reject(false)
}
let deviceId = devicesList[0].deviceId
return connectDevice(deviceId)
})
}
// 扫描设备
function scanDevicesForSometime(services, ms) {
startBluetoothDevicesDiscovery(services).then(res => {
console.log("wx.startBluetoothDevicesDiscovery success", res)
})
setTimeout(function() {
wx.stopBluetoothDevicesDiscovery({
success(res) {
console.log("wx.stopBluetoothDevicesDiscovery success", res)
},
fail(e) {
console.log("wx.stopBluetoothDevicesDiscovery fail", res)
}
})
}, ms);
}
// 扫描设备
function connectFailAnalysis(deviceId) {
console.log("scanDevices ...")
let that = this
let found = false
let discovery = Promise.resolve().then(
() => {
return openBluetoothAdapter()
}
).then(
() => {
return startBluetoothDevicesDiscovery([])
// return startBluetoothDevicesDiscovery(["6E400001-B5A3-F393-E0A9-E50E24DCCA9E"])
}
).then(
() => {
let devicesList = []
return new Promise((resolve) => {
wx.onBluetoothDeviceFound(function(res) {
let name = res.devices[0].name
if (name != "") {
console.log("onBluetoothDeviceFound:", name, res);
devicesList.push(res.devices[0])
let foundDeviceId = res.devices[0].deviceId
console.log("found", foundDeviceId, deviceId)
// 尝试连接,读取等
if (foundDeviceId = deviceId) {
found = true
}
}
})
resolve()
})
}
)
let discoveryTimeout = new Promise(resolve => {
setTimeout(resolve, 10000);
}).then(res => {
console.log("discoveryTimeout")
return stopBluetoothDevicesDiscovery()
}).then(res => {
return new Promise(res => {
console.log("xxxx", found)
if (found) {
console.log("found", deviceId)
resolve(true)
} else {
console.log("not found", deviceId)
reject(false)
}
})
})
return Promise.race([discovery, discoveryTimeout])
}
module.exports = {
// 蓝牙适配器
closeBluetoothAdapter: closeBluetoothAdapter,
openBluetoothAdapter: openBluetoothAdapter,
onBluetoothAdapterStateChange: onBluetoothAdapterStateChange,
startBluetoothDevicesDiscovery: startBluetoothDevicesDiscovery,
stopBluetoothDevicesDiscovery: stopBluetoothDevicesDiscovery,
// BLE连接
closeBLEConnection: closeBLEConnection,
createBLEConnection: createBLEConnection,
onBLEConnectionStateChange: onBLEConnectionStateChange,
// BLE服务和特征值
getBLEDeviceServices: getBLEDeviceServices,
getBLEDeviceCharacteristics: getBLEDeviceCharacteristics,
notifyBLECharacteristicValueChanged: notifyBLECharacteristicValueChanged,
onBLECharacteristicValueChange: onBLECharacteristicValueChange,
// BLE读写
writeBLECharacteristicValue: writeBLECharacteristicValue,
readBLECharacteristicValue: readBLECharacteristicValue,
// wrapper
scanDevicesForSometime: scanDevicesForSometime,
searchDeviceName: searchDeviceName,
connectDevice: connectDevice,
searchAndConnect: searchAndConnect,
connectFailAnalysis: connectFailAnalysis,
}

View File

@@ -1,83 +0,0 @@
"use strict";
function UpdateCRC16(crcIn, byte) {
let crc = crcIn;
let inNum = byte | 0x100;
do {
crc <<= 1;
crc = crc & 0xFFFFFFFF;
inNum <<= 1;
inNum = inNum & 0xFFFFFFFF;
if (inNum & 0x100) {
++crc;
}
if (crc & 0x10000) {
crc ^= 0x1021;
crc = crc & 0xFFFFFFFF;
}
} while (!(inNum & 0x10000));
return crc & 0xffff;
}
function crc16(data, size) {
let crc = 0;
for (let i = 0; i < size; i++) {
crc = UpdateCRC16(crc, data[i])
}
crc = UpdateCRC16(crc, 0);
crc = UpdateCRC16(crc, 0);
return crc & 0xffff;
}
function crc16_backup(buf, len) {
// let crc = 0x0000;
let crc = 0xFFFF;
for (let pos = 0; pos < len; pos++) {
// XOR byte into least sig. byte of crc
crc ^= buf[pos];
crc = crc & 0xFFFF;
for (let i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
crc = crc & 0xFFFF;
}
else {// Else LSB is not set
crc >>= 1; // Just shift right
crc = crc & 0xFFFF;
}
}
}
return crc;
}
/*
int calcrc(char *ptr, int count)
{
int crc;
char i;
crc = 0;
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
} while(--i);
}
return (crc);
}
*/
module.exports = crc16;

View File

@@ -1,109 +0,0 @@
let crc16 = require('./crc16.js')
const SOH = 0x01 /* start of 128-byte data packet */
const STX = 0x02 /* start of 1024-byte data packet */
const EOT = 0x04 /* end of transmission */
const ACK = 0x06 /* acknowledge */
const NAK = 0x15 /* negative acknowledge */
const CA = 0x18 /* two of these in succession aborts transfer */
const CRC16 = 0x43 /* 'C' == 0x43, request 16-bit CRC */
const NEGATIVE_BYTE = 0xFF
const ABORT1 = 0x41 /* 'A' == 0x41, abort by user */
const ABORT2 = 0x61 /* 'a' == 0x61, abort by user */
const NAK_TIMEOUT = 10000
const DOWNLOAD_TIMEOUT = 1000 /* One second retry delay */
const MAX_ERRORS = 10
const NORMAL_LEN = 128;
const LONG_LEN = 1024;
const DATA_INDEX = 3;
function getNormalPacket(id, contentBuf) {
let buf = new Uint8Array(NORMAL_LEN + 3 + 2); //NORMAL_LEN
let i = 0;
buf[i++] = SOH;
buf[i++] = id;
buf[i++] = 0xFF - id;
if (contentBuf.length > NORMAL_LEN) {
throw new Error("Over normal packet size limit");
}
for (let j = 0; j < contentBuf.length; j++) {
buf[i++] = contentBuf[j];
}
while (i < NORMAL_LEN + 3) {
buf[i++] = 0x1A;
}
let bufcrc = buf.slice(3, 3 + NORMAL_LEN)
let crc = crc16(bufcrc, NORMAL_LEN);
buf[i++] = (crc >> 8) & 0xFF;
buf[i++] = crc & 0xFF;
// console.log("packet forming End i = ", i);
return buf;
}
function getLongPacket (id, contentBuf) {
let buf = new Uint8Array(LONG_LEN + 3 + 2);
let i = 0;
buf[i++] = STX;
buf[i++] = id;
buf[i++] = 0xFF - id;
if (contentBuf.length > LONG_LEN) {
throw new Error("Over long packet size limit");
}
for (let j = 0; j < contentBuf.length; j++) {
buf[i++] = contentBuf[j];
}
while (i < LONG_LEN + 3) {
buf[i++] = 0x1A;
}
let bufcrc = buf.slice(3, LONG_LEN + 3)
let crc = crc16(bufcrc, LONG_LEN);
buf[i++] = (crc >> 8) & 0xFF;
buf[i++] = crc & 0xFF;
// console.log("packet forming End i = ", i);
return buf;
}
function getZeroContent (fileSymbol, fileLen) {
let buf = new Uint8Array(128);
// let fileLenBuf = Uint8Array.from(fileLen + '')
// let symbolBuf = Uint8Array.from(fileSymbol)
let fileLenStr = fileLen.toString()
let i = 0, j = 0;
for (j = 0; j < fileSymbol.length; j++) {
buf[i++] = fileSymbol.charCodeAt(j)
}
buf[i++] = 0;
for (j = 0; j < fileLenStr.length; j++) {
buf[i++] = fileLenStr.charCodeAt(j)
}
// buf[i++] = 32;
return buf;
}
let packet = {
getZeroContent: getZeroContent,
getNormalPacket: getNormalPacket,
getLongPacket: getLongPacket
};
module.exports = packet;

View File

@@ -1,97 +0,0 @@
const formatTime = function(date) {
if (!date) {
date = new Date()
}
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
// await util.delayMs(1000)
const delayMs = (ms) => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
// ArrayBuffer转16进制字符串
// ArrayBuffer => hex string
function ab2strHex(ab) {
let hexArr = Array.prototype.map.call(
new Uint8Array(ab),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
}
// string => ArrayBuffer Uint8
function str2abUint8(str) {
var buf = new ArrayBuffer(str.length); // 2 bytes for each char
var bufView = new Uint8Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
// string => ArrayBuffer Uint16
function str2abUint16(str) {
var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
function ArrayBuffer2str(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
}
function Uint8Array2str(arr) {
return String.fromCharCode.apply(null, arr);
}
// let retryPromise = util.autoRetry(promise, 1);
// refer to: https://blog.csdn.net/github_38589282/article/details/77414358
function autoRetry(func, retryMax) {
let retryNum = retryMax;
return async function funcR() {
let params = arguments
while (retryNum--) {
try {
await func(...params)
} catch (e) {
if (retryNum > 0) {
console.error(`retry ${retryMax - retryNum} time. error:`, e);
continue
} else {
throw e
}
}
}
};
}
module.exports = {
// autoRetry: autoRetry,
formatTime: formatTime,
delayMs: delayMs,
ab2strHex: ab2strHex,
str2abUint8: str2abUint8,
str2abUint16: str2abUint16,
ArrayBuffer2str: ArrayBuffer2str,
Uint8Array2str: Uint8Array2str,
}

View File

@@ -1,73 +0,0 @@
{
"miniprogramRoot": "miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"coverView": true,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enhance": true
},
"compileType": "miniprogram",
"libVersion": "2.10.2",
"appid": "wx394efa031612f9b5",
"projectname": "iap",
"debugOptions": {
"hidedInDevtools": []
},
"isGameTourist": false,
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"cloudfunctionTemplateRoot": "cloudfunctionTemplate",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"gamePlugin": {
"current": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": [
{
"id": 0,
"name": "ble-device",
"pathName": "pages/hardware/ble/device/index",
"query": "",
"scene": null
}
]
}
}
}

View File

@@ -1,3 +0,0 @@
### 智能灯小程序DEMO-云开发方式(云函数)
[参见 doc/17.Mini_Program_Quick_Start.md#云开发方式(云函数)](https://github.com/Tencent/TencentOS-tiny/blob/master/doc/17.Mini_Program_Quick_Start.md#124-%E4%BA%91%E5%BC%80%E5%8F%91%E6%96%B9%E5%BC%8F%E4%BA%91%E5%87%BD%E6%95%B0)

View File

@@ -1,40 +0,0 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotexplorerClient = tencentcloud.iotexplorer.v20190423.Client;
const models = tencentcloud.iotexplorer.v20190423.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
console.log("event:", event);
let cred = new Credential(event.secretId, event.secretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotexplorer.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotexplorerClient(cred, event.region, clientProfile);
let req = new models.ControlDeviceDataRequest();
req.ProductId = event.productId;
req.DeviceName = event.deviceName;
req.Data = event.data;
console.log("req:", req);
return new Promise((resolve, reject) => {
client.ControlDeviceData(req, function(errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg);
}
console.log(response);
resolve(response)
});
})
}

View File

@@ -1,15 +0,0 @@
{
"name": "control",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tencentcloud-sdk-nodejs": "^3.0.77",
"wx-server-sdk": "latest"
}
}

View File

@@ -1,549 +0,0 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@cloudbase/database": {
"version": "0.1.1",
"resolved": "https://registry.npm.taobao.org/@cloudbase/database/download/@cloudbase/database-0.1.1.tgz",
"integrity": "sha1-yf/JK3HhkAVxljkL6odpZ3f/l/8=",
"requires": {
"bson": "^4.0.2"
}
},
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/aspromise/download/@protobufjs/aspromise-1.1.2.tgz",
"integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
},
"@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/base64/download/@protobufjs/base64-1.1.2.tgz",
"integrity": "sha1-TIVzDlm5ofHzSQR9vyQpYDS7JzU="
},
"@protobufjs/codegen": {
"version": "2.0.4",
"resolved": "https://registry.npm.taobao.org/@protobufjs/codegen/download/@protobufjs/codegen-2.0.4.tgz",
"integrity": "sha1-fvN/DQEPsCitGtWXIuUG2SYoFcs="
},
"@protobufjs/eventemitter": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/eventemitter/download/@protobufjs/eventemitter-1.1.0.tgz",
"integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
},
"@protobufjs/fetch": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/fetch/download/@protobufjs/fetch-1.1.0.tgz",
"integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
"requires": {
"@protobufjs/aspromise": "^1.1.1",
"@protobufjs/inquire": "^1.1.0"
}
},
"@protobufjs/float": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/float/download/@protobufjs/float-1.0.2.tgz",
"integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
},
"@protobufjs/inquire": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/inquire/download/@protobufjs/inquire-1.1.0.tgz",
"integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
},
"@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/path/download/@protobufjs/path-1.1.2.tgz",
"integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
},
"@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/pool/download/@protobufjs/pool-1.1.0.tgz",
"integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
},
"@protobufjs/utf8": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/utf8/download/@protobufjs/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
},
"@types/long": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/@types/long/download/@types/long-4.0.0.tgz",
"integrity": "sha1-cZVR0jUtMBrIuB23Mqy2vcKNve8="
},
"@types/node": {
"version": "10.14.13",
"resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-10.14.13.tgz?cache=0&sync_timestamp=1563391049881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-10.14.13.tgz",
"integrity": "sha1-rHhtYjhgrfOaP1HWKUgKrNam7sc="
},
"ajv": {
"version": "6.10.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"asn1": {
"version": "0.2.4",
"resolved": "http://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
"integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "http://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "http://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.8.0",
"resolved": "http://registry.npm.taobao.org/aws4/download/aws4-1.8.0.tgz",
"integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8="
},
"base64-js": {
"version": "1.3.0",
"resolved": "http://registry.npm.taobao.org/base64-js/download/base64-js-1.3.0.tgz",
"integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"bson": {
"version": "4.0.2",
"resolved": "https://registry.npm.taobao.org/bson/download/bson-4.0.2.tgz",
"integrity": "sha1-KSn9/tGhRbHDYZCKK5UKbPS+0sI=",
"requires": {
"buffer": "^5.1.0",
"long": "^4.0.0"
}
},
"buffer": {
"version": "5.2.1",
"resolved": "http://registry.npm.taobao.org/buffer/download/buffer-5.2.1.tgz",
"integrity": "sha1-3Vf6DxCaxZxgJHkETcp7iz0LcdY=",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "http://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz",
"integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"dashdash": {
"version": "1.14.1",
"resolved": "http://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "http://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"extend": {
"version": "3.0.2",
"resolved": "http://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
"integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "http://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz?cache=0&sync_timestamp=1562517919182&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-deep-equal%2Fdownload%2Ffast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "http://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.3",
"resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz?cache=0&sync_timestamp=1562216133657&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fform-data%2Fdownload%2Fform-data-2.3.3.tgz",
"integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "http://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz",
"integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
},
"getpass": {
"version": "0.1.7",
"resolved": "http://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.1.3",
"resolved": "http://mirrors.cloud.tencent.com/npm/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"requires": {
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "http://registry.npm.taobao.org/has/download/has-1.0.3.tgz",
"integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
"requires": {
"function-bind": "^1.1.1"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"ieee754": {
"version": "1.1.13",
"resolved": "http://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz",
"integrity": "sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q="
},
"is-regex": {
"version": "1.0.4",
"resolved": "http://registry.npm.taobao.org/is-regex/download/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"requires": {
"has": "^1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "http://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "http://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-schema": {
"version": "0.2.3",
"resolved": "http://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "http://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz",
"integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "http://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npm.taobao.org/lodash.merge/download/lodash.merge-4.6.2.tgz",
"integrity": "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo="
},
"long": {
"version": "4.0.0",
"resolved": "http://registry.npm.taobao.org/long/download/long-4.0.0.tgz",
"integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.40.0.tgz",
"integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.24.tgz",
"integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=",
"requires": {
"mime-db": "1.40.0"
}
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "http://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz",
"integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU="
},
"performance-now": {
"version": "2.1.0",
"resolved": "http://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"protobufjs": {
"version": "6.8.8",
"resolved": "http://mirrors.cloud.tencent.com/npm/protobufjs/-/protobufjs-6.8.8.tgz",
"integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.0",
"@types/node": "^10.1.0",
"long": "^4.0.0"
}
},
"psl": {
"version": "1.2.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/psl/-/psl-1.2.0.tgz",
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA=="
},
"punycode": {
"version": "2.1.1",
"resolved": "http://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz",
"integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew="
},
"qs": {
"version": "6.5.2",
"resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz",
"integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY="
},
"request": {
"version": "2.88.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz",
"integrity": "sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "http://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz",
"integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
},
"sax": {
"version": "1.2.4",
"resolved": "http://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz",
"integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
},
"sshpk": {
"version": "1.16.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
"tcb-admin-node": {
"version": "1.9.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tcb-admin-node/-/tcb-admin-node-1.9.0.tgz",
"integrity": "sha512-TYoBo66CEIIw1QzgK4Jq43G45zvBE6ZB35LbDV8wwLQvg6CiZHlmOTVZkgj2YZ8O87ELi+ZE3UBVNZM3nFa6lQ==",
"requires": {
"@cloudbase/database": "0.1.1",
"is-regex": "^1.0.4",
"lodash.merge": "^4.6.1",
"request": "^2.87.0",
"xml2js": "^0.4.19"
}
},
"tencentcloud-sdk-nodejs": {
"version": "3.0.77",
"resolved": "http://mirrors.cloud.tencent.com/npm/tencentcloud-sdk-nodejs/-/tencentcloud-sdk-nodejs-3.0.77.tgz",
"integrity": "sha512-DULk7IFdR8BQnvC1iRuj+GrYnuU72Lj3oyIO1U2pubf71GtN9PeZ/9km2T7lsCeySU/J6jCTvwVPZaIhip/H1g==",
"requires": {
"request": "^2.85.0"
}
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "http://mirrors.cloud.tencent.com/npm/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
},
"dependencies": {
"punycode": {
"version": "1.4.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
}
}
},
"tslib": {
"version": "1.10.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "http://mirrors.cloud.tencent.com/npm/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"uri-js": {
"version": "4.2.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"requires": {
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"verror": {
"version": "1.10.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
"wx-server-sdk": {
"version": "0.8.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/wx-server-sdk/-/wx-server-sdk-0.8.1.tgz",
"integrity": "sha512-mE7O3E7GtRhqk1ukWw2+NiykaO5DaJYiMFCeHrwvekYTVL5Z2nFXnSrUx6nPg/vZ7LWWQbCgQlGOygBjj2+hkQ==",
"requires": {
"protobufjs": "6.8.8",
"tcb-admin-node": "1.9.0",
"tslib": "^1.9.3"
}
},
"xml2js": {
"version": "0.4.19",
"resolved": "http://mirrors.cloud.tencent.com/npm/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "http://mirrors.cloud.tencent.com/npm/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
}
}
}

View File

@@ -1,37 +0,0 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotexplorerClient = tencentcloud.iotexplorer.v20190423.Client;
const models = tencentcloud.iotexplorer.v20190423.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
console.log("event:", event);
let cred = new Credential(event.secretId, event.secretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotexplorer.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotexplorerClient(cred, event.region, clientProfile);
let req = new models.DescribeDeviceDataRequest();
req.ProductId = event.productId;
req.DeviceName = event.deviceName;
console.log("req:", req);
return new Promise((resolve, reject) => {
client.DescribeDeviceData(req, function(errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg);
}
console.log(response);
resolve(response)
});
})
}

View File

@@ -1,15 +0,0 @@
{
"name": "iotexplorer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tencentcloud-sdk-nodejs": "^3.0.77",
"wx-server-sdk": "latest"
}
}

View File

@@ -1,29 +0,0 @@
//app.js
App({
globalData: {
// 腾讯云物联网开发平台explorer中获取 产品ID和设备名称
productId: "U2LPAXBT2C", // 产品ID
deviceName: "royye_light", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, secretKey
secretId: "xxx",
secretKey: "xxx",
// 接口 Region 字段。一般不需要修改
region: "ap-guangzhou",
// 云开发的环境ID。此处需要替换为云开发创建的环境ID
env: "tos-demo"
},
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用wx.cloud.xxx会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: this.globalData.env,
traceUser: true,
})
}
}
})

View File

@@ -1,13 +0,0 @@
{
"pages": [
"pages/index/index"
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#F6F6F6",
"navigationBarTitleText": "智能灯云开发Demo",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json"
}

View File

@@ -1,156 +0,0 @@
/**app.wxss**/
.container {
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
}
button {
background: initial;
}
button:focus{
outline: 0;
}
button::after{
border: none;
}
page {
background: #f6f6f6;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.userinfo, .uploader, .tunnel {
margin-top: 40rpx;
height: 140rpx;
width: 100%;
background: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
border-left: none;
border-right: none;
display: flex;
flex-direction: row;
align-items: center;
transition: all 300ms ease;
}
.userinfo-avatar {
width: 100rpx;
height: 100rpx;
margin: 20rpx;
border-radius: 50%;
background-size: cover;
background-color: white;
}
.userinfo-avatar:after {
border: none;
}
.userinfo-nickname {
font-size: 32rpx;
color: #007aff;
background-color: white;
background-size: cover;
}
.userinfo-nickname::after {
border: none;
}
.uploader, .tunnel {
height: auto;
padding: 0 0 0 40rpx;
flex-direction: column;
align-items: flex-start;
box-sizing: border-box;
}
.uploader-text, .tunnel-text {
width: 100%;
line-height: 52px;
font-size: 34rpx;
color: #007aff;
}
.uploader-container {
width: 100%;
height: 400rpx;
padding: 20rpx 20rpx 20rpx 0;
display: flex;
align-content: center;
justify-content: center;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.uploader-image {
width: 100%;
height: 360rpx;
}
.tunnel {
padding: 0 0 0 40rpx;
}
.tunnel-text {
position: relative;
color: #222;
display: flex;
flex-direction: row;
align-content: center;
justify-content: space-between;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.tunnel-text:first-child {
border-top: none;
}
.tunnel-switch {
position: absolute;
right: 20rpx;
top: -2rpx;
}
.disable {
color: #888;
}
.service {
position: fixed;
right: 40rpx;
bottom: 40rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background: linear-gradient(#007aff, #0063ce);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-content: center;
justify-content: center;
transition: all 300ms ease;
}
.service-button {
position: absolute;
top: 40rpx;
}
.service:active {
box-shadow: none;
}
.request-text {
padding: 20rpx 0;
font-size: 24rpx;
line-height: 36rpx;
word-break: break-all;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -1,132 +0,0 @@
const app = getApp()
Page({
data: {
client: null,
deviceData: {},
items: [
{ name: '红色', value: 0, color: "red"},
{ name: '绿色', value: 1, color: "green" },
{ name: '蓝色', value: 2, color: "blue" },
]
},
onLoad: function (options) {
console.log("index onLoad")
if (!app.globalData.productId) {
wx.showToast({
title: "产品ID不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.deviceName) {
wx.showToast({
title: "设备名称不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.secretId) {
wx.showToast({
title: "访问密钥SecretId不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.secretKey) {
wx.showToast({
title: "访问密钥SecretKey不能为空",
icon: 'none',
duration: 3000
})
return
}
this.setData({
productId: app.globalData.productId,
deviceName: app.globalData.deviceName,
})
this.queryDeviceData()
},
queryDeviceData()
{
wx.showLoading()
let queryData = {
productId: app.globalData.productId,
deviceName: app.globalData.deviceName,
secretId: app.globalData.secretId,
secretKey: app.globalData.secretKey,
region: app.globalData.region,
}
console.log(queryData);
// 调用云函数query
wx.cloud.callFunction({
name: 'query',
data: queryData,
success: res => {
try {
let deviceData = JSON.parse(res.result.Data)
this.setData({
deviceData: deviceData
})
console.log("result:", deviceData)
wx.showToast({
title: '调用成功',
})
} catch (e) {
wx.showToast({
icon: 'none',
title: '调用失败',
})
console.log(res.result.Data, e)
}
},
fail: err => {
wx.showToast({
icon: 'none',
title: '调用失败',
})
console.error('[云函数] [iotexplorer] 调用失败:', err)
}
})
},
controlDeviceData(e) {
wx.showLoading()
let data = e.detail.value
if (data.power_switch == true) {
data.power_switch = 1
} else {
data.power_switch = 0
}
console.log('form data', data)
let controlData = {
productId: app.globalData.productId,
deviceName: app.globalData.deviceName,
secretId: app.globalData.secretId,
secretKey: app.globalData.secretKey,
region: app.globalData.region,
data: JSON.stringify(data),
}
console.log(controlData);
// 调用云函数control
wx.cloud.callFunction({
name: 'control',
data: controlData,
success: res => {
wx.showToast({
title: '调用成功',
})
console.log(res.result)
},
fail: err => {
wx.showToast({
icon: 'none',
title: '调用失败:' + err,
})
console.error('[云函数] [iotexplorer] 调用失败:', err)
}
})
},
})

View File

@@ -1,57 +0,0 @@
<view style="display:flex; flex-direction:column; align-items:center;">
<image style="width:80px; height:80px;" src="../../images/led.png" mode="cover"></image>
</view>
<view class="body">
<view style="font-weight: bold;">
设备信息
</view>
<view class="box">
<view class="cell">
<view class="status-left">产品ID</view>
<view class="status-right">{{productId}}</view>
</view>
<view class="cell">
<view class="status-left">设备名称</view>
<view class="status-right">{{deviceName}}</view>
</view>
</view>
<text>\n</text>
<form bindsubmit="controlDeviceData">
<view style="display:flex; flex-direction:row; justify-content: space-between;">
<view style="font-weight: bold;">
智能灯云开发Demo
</view>
<view>
<button type="primary" size="mini" bindtap="queryDeviceData">查询</button>
<button style="margin-left:20rpx" type="primary" size="mini" form-type="submit">发送</button>
</view>
</view>
<view class="box">
<view class="cell">
<view>开关</view>
<view>
<switch name="power_switch" checked="{{deviceData.power_switch.Value}}" />
</view>
</view>
<view class="cell">
<view>颜色</view>
<view>
<radio-group name="color">
<label style="color:{{item.color}}" class="radio" wx:for="{{items}}" wx:key="unique" wx:for-index="idx">
<radio color="{{item.color}}" value="{{item.value}}" checked="{{idx == deviceData.color.Value}}" />{{item.name}}
</label>
</radio-group>
</view>
</view>
<view class="cell">
<view>亮度</view>
<view style="width:80%">
<slider name="brightness" min="0" max="100" value="{{deviceData.brightness.Value}}" show-value/>
</view>
</view>
</view>
</form>
</view>

View File

@@ -1,16 +0,0 @@
.body {
margin: 10rpx 20rpx;
}
.box {
padding: 0rpx 20rpx;
border-top: 2px solid #000;
}
.cell {
margin-top: 10rpx;
margin-bottom: 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
}

View File

@@ -1,7 +0,0 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

View File

@@ -1,50 +0,0 @@
{
"miniprogramRoot": "miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": true,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"appid": "wx394efa031612f9b5",
"projectname": "iotexplorer_mp_cloudfunctions_demo",
"libVersion": "2.7.7",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"cloudfunctionTemplateRoot": "cloudfunctionTemplate",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"list": []
},
"miniprogram": {
"current": 0
}
}
}

View File

@@ -1,3 +0,0 @@
### 智能灯小程序DEMO-普通开发方式SDK
[参见 doc/17.Mini_Program_Quick_Start.md#普通开发方式SDK](https://github.com/Tencent/TencentOS-tiny/blob/master/doc/17.Mini_Program_Quick_Start.md#123-%E6%99%AE%E9%80%9A%E5%BC%80%E5%8F%91%E6%96%B9%E5%BC%8Fsdk)

View File

@@ -1,14 +0,0 @@
//app.js
App({
globalData: {
// 腾讯云物联网开发平台explorer中获取 产品ID和设备名称
productId: "U2LPAXBT2C", // 产品ID
deviceName: "royye_light", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, secretKey
secretId: "xxx",
secretKey: "xxx",
},
onLaunch: function(options) {
console.log("onLaunch")
},
})

View File

@@ -1,17 +0,0 @@
{
"pages": [
"pages/index/index"
],
"window": {
"navigationBarBackgroundColor": "#FAFAFA",
"navigationBarTitleText": "智能灯 Demo",
"navigationBarTextStyle": "black",
"backgroundTextStyle": "dark",
"backgroundColor": "#f9f9f9"
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"sitemapLocation": "sitemap.json"
}

View File

@@ -1,4 +0,0 @@
/**app.wxss**/
page{
background: #f9f9f9;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -1,5 +0,0 @@
### NOTE
感谢halenhuang适配的iotexplorer小程序js接口iotclient_for_miniprogram
注意iotclient_for_miniprogram非iotexplorer官方小程序SDK仅用于方便开发者调试TencentOS tiny示例。

View File

@@ -1,272 +0,0 @@
/*
* Copyright (c) 2018 THL A29 Limited, a Tencent company. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const models = require("./iotmodel.js");
const AbstractClient = require('./iotclientbase.js');
const DescribeProjectResponse = models.DescribeProjectResponse;
const ControlDeviceDataResponse = models.ControlDeviceDataResponse;
const DescribeDeviceDataHistoryRequest = models.DescribeDeviceDataHistoryRequest;
const DescribeStudioProductRequest = models.DescribeStudioProductRequest;
const DeleteProjectRequest = models.DeleteProjectRequest;
const DeviceDataHistoryItem = models.DeviceDataHistoryItem;
const ProductEntry = models.ProductEntry;
const GetStudioProductListResponse = models.GetStudioProductListResponse;
const DescribeModelDefinitionResponse = models.DescribeModelDefinitionResponse;
const ProjectEntryEx = models.ProjectEntryEx;
const GetProjectListRequest = models.GetProjectListRequest;
const DeleteStudioProductResponse = models.DeleteStudioProductResponse;
const ModifyStudioProductResponse = models.ModifyStudioProductResponse;
const ControlDeviceDataRequest = models.ControlDeviceDataRequest;
const SearchStudioProductRequest = models.SearchStudioProductRequest;
const ReleaseStudioProductResponse = models.ReleaseStudioProductResponse;
const ProjectEntry = models.ProjectEntry;
const ModifyProjectResponse = models.ModifyProjectResponse;
const ModifyModelDefinitionRequest = models.ModifyModelDefinitionRequest;
const CreateStudioProductResponse = models.CreateStudioProductResponse;
const DeleteStudioProductRequest = models.DeleteStudioProductRequest;
const ModifyProjectRequest = models.ModifyProjectRequest;
const ModifyStudioProductRequest = models.ModifyStudioProductRequest;
const DescribeDeviceDataHistoryResponse = models.DescribeDeviceDataHistoryResponse;
const CreateStudioProductRequest = models.CreateStudioProductRequest;
const ProductModelDefinition = models.ProductModelDefinition;
const CreateProjectResponse = models.CreateProjectResponse;
const ReleaseStudioProductRequest = models.ReleaseStudioProductRequest;
const DescribeModelDefinitionRequest = models.DescribeModelDefinitionRequest;
const DeleteProjectResponse = models.DeleteProjectResponse;
const GetProjectListResponse = models.GetProjectListResponse;
const DescribeDeviceDataResponse = models.DescribeDeviceDataResponse;
const SearchStudioProductResponse = models.SearchStudioProductResponse;
const DescribeProjectRequest = models.DescribeProjectRequest;
const GetStudioProductListRequest = models.GetStudioProductListRequest;
const DescribeDeviceDataRequest = models.DescribeDeviceDataRequest;
const ModifyModelDefinitionResponse = models.ModifyModelDefinitionResponse;
const CreateProjectRequest = models.CreateProjectRequest;
const DescribeStudioProductResponse = models.DescribeStudioProductResponse;
/**
* iotexplorer client
* @class
*/
class IotexplorerClient extends AbstractClient {
constructor( secretid, secretkey) {
super( secretid, secretkey);
}
/**
* 提供修改产品的名称和描述等信息的能力
* @param {ModifyStudioProductRequest} req
* @param {function(string, ModifyStudioProductResponse):void} cb
* @public
*/
ModifyStudioProduct(req, cb) {
let resp = new ModifyStudioProductResponse();
this.request("ModifyStudioProduct", req, resp, cb);
}
/**
* 提供删除某个项目下产品的能力
* @param {DeleteStudioProductRequest} req
* @param {function(string, DeleteStudioProductResponse):void} cb
* @public
*/
DeleteStudioProduct(req, cb) {
let resp = new DeleteStudioProductResponse();
this.request("DeleteStudioProduct", req, resp, cb);
}
/**
* 根据设备产品ID、设备名称获取设备上报的属性数据。
* @param {DescribeDeviceDataRequest} req
* @param {function(string, DescribeDeviceDataResponse):void} cb
* @public
*/
DescribeDeviceData(req, cb) {
let resp = new DescribeDeviceDataResponse();
this.request("DescribeDeviceData", req, resp, cb);
}
/**
* 根据设备产品ID、设备名称获取设备数据。
* @param {DescribeDeviceRequest} req
* @param {function(string, DescribeDeviceResponse):void} cb
* @public
*/
DescribeDevice(req, cb) {
let resp = new DescribeDeviceDataResponse();
this.request("DescribeDevice", req, resp, cb);
}
/**
* 提供根据产品名称查找产品的能力
* @param {SearchStudioProductRequest} req
* @param {function(string, SearchStudioProductResponse):void} cb
* @public
*/
SearchStudioProduct(req, cb) {
let resp = new SearchStudioProductResponse();
this.request("SearchStudioProduct", req, resp, cb);
}
/**
* 查询项目详情
* @param {DescribeProjectRequest} req
* @param {function(string, DescribeProjectResponse):void} cb
* @public
*/
DescribeProject(req, cb) {
let resp = new DescribeProjectResponse();
this.request("DescribeProject", req, resp, cb);
}
/**
* 查询产品配置的数据模板信息
* @param {DescribeModelDefinitionRequest} req
* @param {function(string, DescribeModelDefinitionResponse):void} cb
* @public
*/
DescribeModelDefinition(req, cb) {
let resp = new DescribeModelDefinitionResponse();
this.request("DescribeModelDefinition", req, resp, cb);
}
/**
* 提供修改产品的数据模板的能力
* @param {ModifyModelDefinitionRequest} req
* @param {function(string, ModifyModelDefinitionResponse):void} cb
* @public
*/
ModifyModelDefinition(req, cb) {
let resp = new ModifyModelDefinitionResponse();
this.request("ModifyModelDefinition", req, resp, cb);
}
/**
* 产品开发完成并测试通过后,通过发布产品将产品设置为发布状态
* @param {ReleaseStudioProductRequest} req
* @param {function(string, ReleaseStudioProductResponse):void} cb
* @public
*/
ReleaseStudioProduct(req, cb) {
let resp = new ReleaseStudioProductResponse();
this.request("ReleaseStudioProduct", req, resp, cb);
}
/**
* 为用户提供新建项目的能力,用于集中管理产品和应用。
* @param {CreateProjectRequest} req
* @param {function(string, CreateProjectResponse):void} cb
* @public
*/
CreateProject(req, cb) {
let resp = new CreateProjectResponse();
this.request("CreateProject", req, resp, cb);
}
/**
* 为用户提供新建产品的能力,用于管理用户的设备
* @param {CreateStudioProductRequest} req
* @param {function(string, CreateStudioProductResponse):void} cb
* @public
*/
CreateStudioProduct(req, cb) {
let resp = new CreateStudioProductResponse();
this.request("CreateStudioProduct", req, resp, cb);
}
/**
* 提供查询用户所创建的项目列表查询功能。
* @param {GetProjectListRequest} req
* @param {function(string, GetProjectListResponse):void} cb
* @public
*/
GetProjectList(req, cb) {
let resp = new GetProjectListResponse();
this.request("GetProjectList", req, resp, cb);
}
/**
* 获取设备在指定时间范围内上报的历史数据。
* @param {DescribeDeviceDataHistoryRequest} req
* @param {function(string, DescribeDeviceDataHistoryResponse):void} cb
* @public
*/
DescribeDeviceDataHistory(req, cb) {
let resp = new DescribeDeviceDataHistoryResponse();
this.request("DescribeDeviceDataHistory", req, resp, cb);
}
/**
* 提供删除某个项目的能力
* @param {DeleteProjectRequest} req
* @param {function(string, DeleteProjectResponse):void} cb
* @public
*/
DeleteProject(req, cb) {
let resp = new DeleteProjectResponse();
this.request("DeleteProject", req, resp, cb);
}
/**
* 提供查看茶品详细信息的能力包括产品的ID、数据协议、认证类型等重要参数
* @param {DescribeStudioProductRequest} req
* @param {function(string, DescribeStudioProductResponse):void} cb
* @public
*/
DescribeStudioProduct(req, cb) {
let resp = new DescribeStudioProductResponse();
this.request("DescribeStudioProduct", req, resp, cb);
}
/**
* 根据设备产品ID、设备名称设置控制设备的属性数据。
* @param {ControlDeviceDataRequest} req
* @param {function(string, ControlDeviceDataResponse):void} cb
* @public
*/
ControlDeviceData(req, cb) {
let resp = new ControlDeviceDataResponse();
this.request("ControlDeviceData", req, resp, cb);
}
/**
* 提供查询某个项目下所有产品信息的能力。
* @param {GetStudioProductListRequest} req
* @param {function(string, GetStudioProductListResponse):void} cb
* @public
*/
GetStudioProductList(req, cb) {
let resp = new GetStudioProductListResponse();
this.request("GetStudioProductList", req, resp, cb);
}
/**
* 修改项目
* @param {ModifyProjectRequest} req
* @param {function(string, ModifyProjectResponse):void} cb
* @public
*/
ModifyProject(req, cb) {
let resp = new ModifyProjectResponse();
this.request("ModifyProject", req, resp, cb);
}
}
module.exports = IotexplorerClient;

View File

@@ -1,167 +0,0 @@
const Sign = require("./sign.js");
/**
* @inner
*/
class AbstractClient {
/**
* 实例化client对象
* @param {string} productid 产品ID
*/
constructor( secretid,secretkey) {
this.endpoint = "iotexplorer.tencentcloudapi.com";
this.path = "/";
this.method = "GET";
this.apiVersion = "2019-04-23";
this.region = "ap-guangzhou";
this.secretid = secretid;
this.secretkey = secretkey;
}
/**
* @inner
*/
succRequest(resp, cb, data) {
resp.deserialize(data);
cb(null, resp);
}
/**
* @inner
*/
failRequest(err, cb) {
cb(err, null);
}
/**
* @inner
*/
//request(action, req, resp, cb) {
// this.doRequest(action, req).then(data => this.succRequest(resp, cb, data), error => this.failRequest(error, cb));
//}
/**
* @inner
*/
request(action, req, resp, cb) {
let params = this.mergeData(req);
params = this.formatRequestData(action, params);
var fullurl = this.formatFullUrl(params);
var thisclient = this;
console.log(fullurl);
wx.request({
url: fullurl,
header: {
'content-type': 'application/json' // 默认值
},
success(res) {
console.log("statusCode", res.statusCode)
// console.log("header", res.header)
console.log("data", res.data)
if(res.statusCode != 200){
thisclient.failRequest(res.statusCode, cb);
}
else {
//data = JSON.parse(res.data);
var data = res.data;
if (data.Response.Error) {
thisclient.failRequest(data.Response.Error.Message, cb);
return;
}
thisclient.succRequest(resp, cb, data.Response);
}
},
fail(res){
console.log("fail res", res)
if (!res.statusCode) {
res.statusCode = res.errMsg
}
thisclient.failRequest(res.statusCode, cb);
}
})
}
/**
* @inner
*/
mergeData(data, prefix = "") {
let ret = {};
for (let k in data) {
if (data[k] === null) {
continue;
}
if (data[k] instanceof Array || data[k] instanceof Object) {
Object.assign(ret, this.mergeData(data[k], prefix + k + "."));
} else {
ret[prefix + k] = data[k];
}
}
return ret;
}
/**
* @inner
*/
formatRequestData(action, params) {
params.Action = action;
params.Nonce = Math.round(Math.random() * 65535);
params.Timestamp = Math.round(Date.now() / 1000);
params.Version = this.apiVersion;
if (this.secretid) {
params.SecretId = this.secretid;
}
if (this.region) {
params.Region = this.region;
}
let signStr = this.formatSignString(params);
params.Signature = encodeURIComponent(Sign.sign(this.secretkey, signStr));
return params;
}
/**
* @inner
*/
formatSignString(params) {
let strParam = "";
let keys = Object.keys(params);
keys.sort();
for (let k in keys) {
//k = k.replace(/_/g, '.');
strParam += ("&" + keys[k] + "=" + params[keys[k]]);
}
//签名原文串的拼接规则为: 请求方法 + 请求主机 +请求路径 + ? + 请求字符串
let strSign = this.method + this.endpoint + this.path + "?" + strParam.slice(1);
return strSign;
}
/**
* @inner
*/
formatFullUrl(params) {
let strParam = "";
let keys = Object.keys(params);
//keys.sort();
for (let k in keys) {
//k = k.replace(/_/g, '.');
strParam += ("&" + keys[k] + "=" + params[keys[k]]);
}
let strUrl = "https://" + this.endpoint + this.path + "?" + strParam.slice(1);
return strUrl;
}
}
module.exports = AbstractClient;

View File

@@ -1,32 +0,0 @@
/**
* @inner
*/
class AbstractModel {
constructor() {
}
/**
* @inner
*/
deserialize(params) {
}
/**
* 将object转化为json格式的string
* @return {string}
*/
to_json_string() {
return JSON.stringify(this);
}
/**
* 将json格式的string转化为object
* @param {string} dataString
*/
from_json_string(dataString) {
let params = JSON.parse(dataString);
this.deserialize(params);
}
}
module.exports = AbstractModel;

View File

@@ -1,196 +0,0 @@
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS PUB 180-1
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*/
/*
* Configurable variables. You may need to tweak these to be compatible with
* the server-side, but the defaults work in most cases.
*/
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
var b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
/*
* These are the functions you'll usually want to call
* They take string arguments and return either hex or base-64 encoded strings
*/
function hex_sha1(s) { return binb2hex(core_sha1(str2binb(s), s.length * chrsz)); }
function b64_sha1(s) { return binb2b64(core_sha1(str2binb(s), s.length * chrsz)); }
function str_sha1(s) { return binb2str(core_sha1(str2binb(s), s.length * chrsz)); }
function hex_hmac_sha1(key, data) { return binb2hex(core_hmac_sha1(key, data)); }
function b64_hmac_sha1(key, data) { return binb2b64(core_hmac_sha1(key, data)); }
function str_hmac_sha1(key, data) { return binb2str(core_hmac_sha1(key, data)); }
/*
* Perform a simple self-test to see if the VM is working
*/
function sha1_vm_test() {
return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
}
/*
* Calculate the SHA-1 of an array of big-endian words, and a bit length
*/
function core_sha1(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << (24 - len % 32);
x[((len + 64 >> 9) << 4) + 15] = len;
var w = Array(80);
var a = 1732584193;
var b = -271733879;
var c = -1732584194;
var d = 271733878;
var e = -1009589776;
for (var i = 0; i < x.length; i += 16) {
var olda = a;
var oldb = b;
var oldc = c;
var oldd = d;
var olde = e;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = x[i + j];
else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
safe_add(safe_add(e, w[j]), sha1_kt(j)));
e = d;
d = c;
c = rol(b, 30);
b = a;
a = t;
}
a = safe_add(a, olda);
b = safe_add(b, oldb);
c = safe_add(c, oldc);
d = safe_add(d, oldd);
e = safe_add(e, olde);
}
return Array(a, b, c, d, e);
}
/*
* Perform the appropriate triplet combination function for the current
* iteration
*/
function sha1_ft(t, b, c, d) {
if (t < 20) return (b & c) | ((~b) & d);
if (t < 40) return b ^ c ^ d;
if (t < 60) return (b & c) | (b & d) | (c & d);
return b ^ c ^ d;
}
/*
* Determine the appropriate additive constant for the current iteration
*/
function sha1_kt(t) {
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
(t < 60) ? -1894007588 : -899497514;
}
/*
* Calculate the HMAC-SHA1 of a key and some data
*/
function core_hmac_sha1(key, data) {
var bkey = str2binb(key);
if (bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = bkey[i] ^ 0x36363636;
opad[i] = bkey[i] ^ 0x5C5C5C5C;
}
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
return core_sha1(opad.concat(hash), 512 + 160);
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safe_add(x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
/*
* Convert an 8-bit or 16-bit string to an array of big-endian words
* In 8-bit function, characters >255 have their hi-byte silently ignored.
*/
function str2binb(str) {
var bin = Array();
var mask = (1 << chrsz) - 1;
for (var i = 0; i < str.length * chrsz; i += chrsz)
bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i % 32);
return bin;
}
/*
* Convert an array of big-endian words to a string
*/
function binb2str(bin) {
var str = "";
var mask = (1 << chrsz) - 1;
for (var i = 0; i < bin.length * 32; i += chrsz)
str += String.fromCharCode((bin[i >> 5] >>> (32 - chrsz - i % 32)) & mask);
return str;
}
/*
* Convert an array of big-endian words to a hex string.
*/
function binb2hex(binarray) {
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
var str = "";
for (var i = 0; i < binarray.length * 4; i++) {
str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF);
}
return str;
}
/*
* Convert an array of big-endian words to a base-64 string
*/
function binb2b64(binarray) {
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var str = "";
for (var i = 0; i < binarray.length * 4; i += 3) {
var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16)
| (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8)
| ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF);
for (var j = 0; j < 4; j++) {
if (i * 8 + j * 6 > binarray.length * 32) str += b64pad;
else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F);
}
}
return str;
}
/* Main function: returns a hex string representing the SHA256 value of the
given data */
function sha1_digest(key,data) {
return b64_hmac_sha1(key,data);
}
module.exports = {
sha1_digest: sha1_digest
}

View File

@@ -1,250 +0,0 @@
/*
* A JavaScript implementation of the SHA256 hash function.
*
* FILE: sha256.js
* VERSION: 0.8
* AUTHOR: Christoph Bichlmeier <informatik@zombiearena.de>
*
* NOTE: This version is not tested thoroughly!
*
* Copyright (c) 2003, Christoph Bichlmeier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* ======================================================================
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* SHA256 logical functions */
function rotateRight(n, x) {
return ((x >>> n) | (x << (32 - n)));
}
function choice(x, y, z) {
return ((x & y) ^ (~x & z));
}
function majority(x, y, z) {
return ((x & y) ^ (x & z) ^ (y & z));
}
function sha256_Sigma0(x) {
return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x));
}
function sha256_Sigma1(x) {
return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x));
}
function sha256_sigma0(x) {
return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3));
}
function sha256_sigma1(x) {
return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10));
}
function sha256_expand(W, j) {
return (W[j & 0x0f] += sha256_sigma1(W[(j + 14) & 0x0f]) + W[(j + 9) & 0x0f] +
sha256_sigma0(W[(j + 1) & 0x0f]));
}
/* Hash constant words K: */
var K256 = new Array(
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
);
/* global arrays */
var ihash, count, buffer;
var sha256_hex_digits = "0123456789abcdef";
/* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters:
overflow) */
function safe_add(x, y) {
var lsw = (x & 0xffff) + (y & 0xffff);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
/* Initialise the SHA256 computation */
function sha256_init() {
ihash = new Array(8);
count = new Array(2);
buffer = new Array(64);
count[0] = count[1] = 0;
ihash[0] = 0x6a09e667;
ihash[1] = 0xbb67ae85;
ihash[2] = 0x3c6ef372;
ihash[3] = 0xa54ff53a;
ihash[4] = 0x510e527f;
ihash[5] = 0x9b05688c;
ihash[6] = 0x1f83d9ab;
ihash[7] = 0x5be0cd19;
}
/* Transform a 512-bit message block */
function sha256_transform() {
var a, b, c, d, e, f, g, h, T1, T2;
var W = new Array(16);
/* Initialize registers with the previous intermediate value */
a = ihash[0];
b = ihash[1];
c = ihash[2];
d = ihash[3];
e = ihash[4];
f = ihash[5];
g = ihash[6];
h = ihash[7];
/* make 32-bit words */
for (var i = 0; i < 16; i++)
W[i] = ((buffer[(i << 2) + 3]) | (buffer[(i << 2) + 2] << 8) | (buffer[(i << 2) + 1]
<< 16) | (buffer[i << 2] << 24));
for (var j = 0; j < 64; j++) {
T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j];
if (j < 16) T1 += W[j];
else T1 += sha256_expand(W, j);
T2 = sha256_Sigma0(a) + majority(a, b, c);
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
/* Compute the current intermediate hash value */
ihash[0] += a;
ihash[1] += b;
ihash[2] += c;
ihash[3] += d;
ihash[4] += e;
ihash[5] += f;
ihash[6] += g;
ihash[7] += h;
}
/* Read the next chunk of data and update the SHA256 computation */
function sha256_update(data, inputLen) {
var i, index, curpos = 0;
/* Compute number of bytes mod 64 */
index = ((count[0] >> 3) & 0x3f);
var remainder = (inputLen & 0x3f);
/* Update number of bits */
if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++;
count[1] += (inputLen >> 29);
/* Transform as many times as possible */
for (i = 0; i + 63 < inputLen; i += 64) {
for (var j = index; j < 64; j++)
buffer[j] = data.charCodeAt(curpos++);
sha256_transform();
index = 0;
}
/* Buffer remaining input */
for (var j = 0; j < remainder; j++)
buffer[j] = data.charCodeAt(curpos++);
}
/* Finish the computation by operations such as padding */
function sha256_final() {
var index = ((count[0] >> 3) & 0x3f);
buffer[index++] = 0x80;
if (index <= 56) {
for (var i = index; i < 56; i++)
buffer[i] = 0;
} else {
for (var i = index; i < 64; i++)
buffer[i] = 0;
sha256_transform();
for (var i = 0; i < 56; i++)
buffer[i] = 0;
}
buffer[56] = (count[1] >>> 24) & 0xff;
buffer[57] = (count[1] >>> 16) & 0xff;
buffer[58] = (count[1] >>> 8) & 0xff;
buffer[59] = count[1] & 0xff;
buffer[60] = (count[0] >>> 24) & 0xff;
buffer[61] = (count[0] >>> 16) & 0xff;
buffer[62] = (count[0] >>> 8) & 0xff;
buffer[63] = count[0] & 0xff;
sha256_transform();
}
/* Split the internal hash values into an array of bytes */
function sha256_encode_bytes() {
var j = 0;
var output = new Array(32);
for (var i = 0; i < 8; i++) {
output[j++] = ((ihash[i] >>> 24) & 0xff);
output[j++] = ((ihash[i] >>> 16) & 0xff);
output[j++] = ((ihash[i] >>> 8) & 0xff);
output[j++] = (ihash[i] & 0xff);
}
return output;
}
/* Get the internal hash as a hex string */
function sha256_encode_hex() {
var output = new String();
for (var i = 0; i < 8; i++) {
for (var j = 28; j >= 0; j -= 4)
output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f);
}
return output;
}
/* Main function: returns a hex string representing the SHA256 value of the
given data */
function sha256_digest(data) {
sha256_init();
sha256_update(data, data.length);
sha256_final();
return sha256_encode_hex();
}
/* test if the JS-interpreter is working properly */
function sha256_self_test() {
return sha256_digest("message digest") ==
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650";
}
module.exports = {
sha256_digest: sha256_digest
}

View File

@@ -1,24 +0,0 @@
const crypto = require('./sha1.js');
/**
* @inner
*/
class Sign {
static sign(secretKey, signStr) {
// let signMethodMap = {
// HmacSHA1: "sha1",
// HmacSHA256: "sha256"
// };
// if (!signMethodMap.hasOwnProperty(signMethod)) {
// throw new Exception("signMethod invalid, signMethod only support (HmacSHA1, HmacSHA256)");
// }
// let hmac = crypto.createHmac(signMethodMap[signMethod], secretKey || "");
// return hmac.update(Buffer.from(signStr, 'utf8')).digest('base64')
// let test = crypto.sha1_digest("12345678", "87654321");
let hmac = crypto.sha1_digest(secretKey,signStr);
return hmac;
}
}
module.exports = Sign;

View File

@@ -1,101 +0,0 @@
const iotclient = require('./iotclient.js')
const iotmodel = require('./iotmodel.js')
const SECRETID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const SECRETKEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const PRODUCTID = "XXXXXX";
const DEVICENAME = "royye_light";
function test(cb) {
//testGetDeviceHistory(cb);
testGetDeviceData(cb);
// testGetDeviceStatus(cb);
}
function testGetDeviceStatus(cb) {
// 实例化要请求产品的client对象
let client = new iotclient(SECRETID,SECRETKEY);
// 实例化一个请求对象
let req = new iotmodel.DescribeDeviceDataRequest();
req.DeviceName = DEVICENAME;
req.ProductId = PRODUCTID;
// 通过client对象调用想要访问的接口需要传入请求对象以及响应回调函数
client.DescribeDevice(req, function (err, response) {
// 请求异常返回,打印异常信息
if (err) {
console.log(err);
cb("failed:" + err);
return;
}
// 请求正常返回打印response对象
console.log(response.to_json_string());
cb("GetDeviceStatus success");
});
}
function testGetDeviceData(cb) {
// 实例化要请求产品的client对象
let client = new iotclient(SECRETID, SECRETKEY);
// 实例化一个请求对象
let req = new iotmodel.DescribeDeviceDataRequest();
req.DeviceName = DEVICENAME;
req.ProductId = PRODUCTID;
// 通过client对象调用想要访问的接口需要传入请求对象以及响应回调函数
client.DescribeDeviceData(req, function (err, response) {
// 请求异常返回,打印异常信息
if (err) {
console.log(err);
cb("failed:" + err);
return;
}
// 请求正常返回打印response对象
console.log(response.to_json_string());
cb("GetDeviceData success");
});
}
function testGetDeviceHistory(cb) {
// 实例化要请求产品的client对象
let client = new iotclient(SECRETID, SECRETKEY);
// 实例化一个请求对象
let req = new iotmodel.DescribeDeviceDataHistoryRequest();
req.MinTime = Math.round(Date.parse('2019-08-07T10:00:00.875+08:00'));
req.MaxTime = Math.round(Date.parse('2019-08-07T18:00:00.875+08:00'));
req.FieldName = "color";
req.Limit = 5;
req.DeviceName = DEVICENAME;
req.ProductId = PRODUCTID;
//var tt = req.to_json_string();
// 通过client对象调用想要访问的接口需要传入请求对象以及响应回调函数
client.DescribeDeviceDataHistory(req, function (err, response) {
// 请求异常返回,打印异常信息
if (err) {
console.log(err);
cb("failed:"+err);
return;
}
// 请求正常返回打印response对象
console.log(response.to_json_string());
cb("DescribeDeviceDataHistory success:"+response.Results.length);
});
}
module.exports = {
test: test
}

View File

@@ -1,19 +0,0 @@
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
module.exports = {
formatTime: formatTime
}

View File

@@ -1,126 +0,0 @@
const app = getApp()
const iotmodel = require("../../iotclient_for_miniprogram/iotmodel.js");
import IotexplorerClient from '../../iotclient_for_miniprogram/iotclient.js';
Page({
data: {
client: null,
deviceData: {},
items: [
{ name: '红色', value: 0, color: "red"},
{ name: '绿色', value: 1, color: "green" },
{ name: '蓝色', value: 2, color: "blue" },
]
},
onLoad: function (options) {
console.log("index onLoad")
if (!app.globalData.productId) {
wx.showToast({
title: "产品ID不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.deviceName) {
wx.showToast({
title: "设备名称不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.secretId) {
wx.showToast({
title: "访问密钥SecretId不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.secretKey) {
wx.showToast({
title: "访问密钥SecretKey不能为空",
icon: 'none',
duration: 3000
})
return
}
this.setData({
productId: app.globalData.productId,
deviceName: app.globalData.deviceName,
})
// 实例化要请求产品的client对象
this.data.client = new IotexplorerClient(app.globalData.secretId, app.globalData.secretKey)
this.queryDeviceData()
},
queryDeviceData()
{
let that = this
wx.showLoading()
// 实例化一个请求对象
let req = new iotmodel.DescribeDeviceDataRequest();
req.DeviceName = app.globalData.deviceName;
req.ProductId = app.globalData.productId;
// 通过client对象调用想要访问的接口需要传入请求对象以及响应回调函数
this.data.client.DescribeDeviceData(req, function (err, response) {
if (err) {
console.log("err:", err);
wx.showToast({
title: "查询失败 " + err,
icon: 'none',
duration: 3000
})
return;
}
wx.showToast({
title: "查询成功",
icon: 'none',
duration: 1000
})
let deviceData = JSON.parse(response.Data)
that.setData({
deviceData: deviceData
})
console.log(that.data.deviceData);
});
},
controlDeviceData(e) {
let that = this
wx.showLoading()
let data = e.detail.value
if (data.power_switch == true) {
data.power_switch = 1
} else {
data.power_switch = 0
}
console.log('form data', e.detail.value)
// 实例化一个请求对象
let req = new iotmodel.ControlDeviceDataRequest();
req.DeviceName = app.globalData.deviceName;
req.ProductId = app.globalData.productId;
req.Data = JSON.stringify(data);
// 通过client对象调用想要访问的接口需要传入请求对象以及响应回调函数
this.data.client.ControlDeviceData(req, function (err, response) {
if (err) {
console.log(err);
wx.showToast({
title: "操作失败 " + err,
icon: 'none',
duration: 3000
})
return;
}
console.log(err)
wx.showToast({
title: "操作成功",
icon: 'none',
duration: 1000
})
});
},
})

View File

@@ -1,57 +0,0 @@
<view style="display:flex; flex-direction:column; align-items:center;">
<image style="width:80px; height:80px;" src="../../images/led.png" mode="cover"></image>
</view>
<view class="body">
<view style="font-weight: bold;">
设备信息
</view>
<view class="box">
<view class="cell">
<view class="status-left">产品ID</view>
<view class="status-right">{{productId}}</view>
</view>
<view class="cell">
<view class="status-left">设备名称</view>
<view class="status-right">{{deviceName}}</view>
</view>
</view>
<text>\n</text>
<form bindsubmit="controlDeviceData">
<view style="display:flex; flex-direction:row; justify-content: space-between;">
<view style="font-weight: bold;">
智能灯 Demo
</view>
<view>
<button type="primary" size="mini" bindtap="queryDeviceData">查询</button>
<button style="margin-left:20rpx" type="primary" size="mini" form-type="submit">发送</button>
</view>
</view>
<view class="box">
<view class="cell">
<view>开关</view>
<view>
<switch name="power_switch" checked="{{deviceData.power_switch.Value}}" />
</view>
</view>
<view class="cell">
<view>颜色</view>
<view>
<radio-group name="color">
<label style="color:{{item.color}}" class="radio" wx:for="{{items}}" wx:key="unique" wx:for-index="idx">
<radio color="{{item.color}}" value="{{item.value}}" checked="{{idx == deviceData.color.Value}}" />{{item.name}}
</label>
</radio-group>
</view>
</view>
<view class="cell">
<view>亮度</view>
<view style="width:80%">
<slider name="brightness" min="0" max="100" value="{{deviceData.brightness.Value}}" show-value/>
</view>
</view>
</view>
</form>
</view>

View File

@@ -1,16 +0,0 @@
.body {
margin: 10rpx 20rpx;
}
.box {
padding: 0rpx 20rpx;
border-top: 2px solid #000;
}
.cell {
margin-top: 10rpx;
margin-bottom: 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
}

View File

@@ -1,57 +0,0 @@
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"coverView": true,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"compileType": "miniprogram",
"libVersion": "2.4.0",
"appid": "wx394efa031612f9b5",
"projectname": "iotexplorer_mp_demo",
"debugOptions": {
"hidedInDevtools": []
},
"isGameTourist": false,
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"currentL": -1,
"list": []
},
"miniprogram": {
"current": -1,
"list": []
}
}
}

View File

@@ -1,7 +0,0 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

View File

@@ -1,24 +0,0 @@
# 设备联动Demo
## 配置文件 miniprogram/config.js
```
// 传感设备配置
const SensorDevice = {
// 腾讯云物联网通信平台中获取 产品ID和设备名称
ProductId: "ZLN6Q20QHU", // 产品ID
DeviceName: "dev001", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, SecretKey
SecretId: "XXXX",
SecretKey: "XXXX",
}
// 执行设备配置
const ExecuteDevice = {
ProductId: "U1BZWHF7F9", // 产品ID
DeviceName: "dev_01", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, SecretKey
SecretId: "XXXX",
SecretKey: "XXXX",
Topic: "U1BZWHF7F9/dev_01/data"
}
```

View File

@@ -1,38 +0,0 @@
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotcloudClient = tencentcloud.iotcloud.v20180614.Client;
const models = tencentcloud.iotcloud.v20180614.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
// 云函数入口函数
exports.main = async (event, context) => {
let cred = new Credential(event.SecretId, event.SecretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotcloud.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotcloudClient(cred, "ap-guangzhou", clientProfile);
let req = new models.PublishMessageRequest();
// req.Topic = "U1BZWHF7F9/dev_01/data";
// req.DeviceName = "dev_01";
// req.ProductId = "U1BZWHF7F9";
req.Topic = event.Topic
req.DeviceName = event.DeviceName;
req.ProductId = event.ProductId;
req.Payload = event.Payload;
return new Promise((resolve, reject)=>{
client.PublishMessage(req, function (errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg)
return;
}
console.log(response.to_json_string());
resolve(response)
});
})
}

View File

@@ -1,14 +0,0 @@
{
"name": "iothub-publish",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

View File

@@ -1,34 +0,0 @@
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotcloudClient = tencentcloud.iotcloud.v20180614.Client;
const models = tencentcloud.iotcloud.v20180614.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
exports.main = async (event, context) => {
let cred = new Credential(event.SecretId, event.SecretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotcloud.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotcloudClient(cred, "ap-guangzhou", clientProfile);
let req = new models.DescribeDeviceShadowRequest();
req.DeviceName = event.DeviceName;
req.ProductId = event.ProductId;
return new Promise((resolve, reject)=>{
client.DescribeDeviceShadow(req, function (errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg)
return;
}
console.log(response.to_json_string());
resolve(response)
});
})
}

View File

@@ -1,15 +0,0 @@
{
"name": "iotexplorer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tencentcloud-sdk-nodejs": "^3.0.77",
"wx-server-sdk": "latest"
}
}

View File

@@ -1,549 +0,0 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@cloudbase/database": {
"version": "0.1.1",
"resolved": "https://registry.npm.taobao.org/@cloudbase/database/download/@cloudbase/database-0.1.1.tgz",
"integrity": "sha1-yf/JK3HhkAVxljkL6odpZ3f/l/8=",
"requires": {
"bson": "^4.0.2"
}
},
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/aspromise/download/@protobufjs/aspromise-1.1.2.tgz",
"integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
},
"@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/base64/download/@protobufjs/base64-1.1.2.tgz",
"integrity": "sha1-TIVzDlm5ofHzSQR9vyQpYDS7JzU="
},
"@protobufjs/codegen": {
"version": "2.0.4",
"resolved": "https://registry.npm.taobao.org/@protobufjs/codegen/download/@protobufjs/codegen-2.0.4.tgz",
"integrity": "sha1-fvN/DQEPsCitGtWXIuUG2SYoFcs="
},
"@protobufjs/eventemitter": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/eventemitter/download/@protobufjs/eventemitter-1.1.0.tgz",
"integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
},
"@protobufjs/fetch": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/fetch/download/@protobufjs/fetch-1.1.0.tgz",
"integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
"requires": {
"@protobufjs/aspromise": "^1.1.1",
"@protobufjs/inquire": "^1.1.0"
}
},
"@protobufjs/float": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/float/download/@protobufjs/float-1.0.2.tgz",
"integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
},
"@protobufjs/inquire": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/inquire/download/@protobufjs/inquire-1.1.0.tgz",
"integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
},
"@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/path/download/@protobufjs/path-1.1.2.tgz",
"integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
},
"@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/pool/download/@protobufjs/pool-1.1.0.tgz",
"integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
},
"@protobufjs/utf8": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/utf8/download/@protobufjs/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
},
"@types/long": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/@types/long/download/@types/long-4.0.0.tgz",
"integrity": "sha1-cZVR0jUtMBrIuB23Mqy2vcKNve8="
},
"@types/node": {
"version": "10.14.13",
"resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-10.14.13.tgz?cache=0&sync_timestamp=1563391049881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-10.14.13.tgz",
"integrity": "sha1-rHhtYjhgrfOaP1HWKUgKrNam7sc="
},
"ajv": {
"version": "6.10.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"asn1": {
"version": "0.2.4",
"resolved": "http://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
"integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "http://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "http://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.8.0",
"resolved": "http://registry.npm.taobao.org/aws4/download/aws4-1.8.0.tgz",
"integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8="
},
"base64-js": {
"version": "1.3.0",
"resolved": "http://registry.npm.taobao.org/base64-js/download/base64-js-1.3.0.tgz",
"integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"bson": {
"version": "4.0.2",
"resolved": "https://registry.npm.taobao.org/bson/download/bson-4.0.2.tgz",
"integrity": "sha1-KSn9/tGhRbHDYZCKK5UKbPS+0sI=",
"requires": {
"buffer": "^5.1.0",
"long": "^4.0.0"
}
},
"buffer": {
"version": "5.2.1",
"resolved": "http://registry.npm.taobao.org/buffer/download/buffer-5.2.1.tgz",
"integrity": "sha1-3Vf6DxCaxZxgJHkETcp7iz0LcdY=",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "http://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz",
"integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"dashdash": {
"version": "1.14.1",
"resolved": "http://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "http://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"extend": {
"version": "3.0.2",
"resolved": "http://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
"integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "http://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz?cache=0&sync_timestamp=1562517919182&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-deep-equal%2Fdownload%2Ffast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "http://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.3",
"resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz?cache=0&sync_timestamp=1562216133657&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fform-data%2Fdownload%2Fform-data-2.3.3.tgz",
"integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "http://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz",
"integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
},
"getpass": {
"version": "0.1.7",
"resolved": "http://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.1.3",
"resolved": "http://mirrors.cloud.tencent.com/npm/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"requires": {
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "http://registry.npm.taobao.org/has/download/has-1.0.3.tgz",
"integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
"requires": {
"function-bind": "^1.1.1"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"ieee754": {
"version": "1.1.13",
"resolved": "http://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz",
"integrity": "sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q="
},
"is-regex": {
"version": "1.0.4",
"resolved": "http://registry.npm.taobao.org/is-regex/download/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"requires": {
"has": "^1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "http://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "http://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-schema": {
"version": "0.2.3",
"resolved": "http://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "http://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz",
"integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "http://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npm.taobao.org/lodash.merge/download/lodash.merge-4.6.2.tgz",
"integrity": "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo="
},
"long": {
"version": "4.0.0",
"resolved": "http://registry.npm.taobao.org/long/download/long-4.0.0.tgz",
"integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.40.0.tgz",
"integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.24.tgz",
"integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=",
"requires": {
"mime-db": "1.40.0"
}
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "http://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz",
"integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU="
},
"performance-now": {
"version": "2.1.0",
"resolved": "http://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"protobufjs": {
"version": "6.8.8",
"resolved": "http://mirrors.cloud.tencent.com/npm/protobufjs/-/protobufjs-6.8.8.tgz",
"integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.0",
"@types/node": "^10.1.0",
"long": "^4.0.0"
}
},
"psl": {
"version": "1.2.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/psl/-/psl-1.2.0.tgz",
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA=="
},
"punycode": {
"version": "2.1.1",
"resolved": "http://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz",
"integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew="
},
"qs": {
"version": "6.5.2",
"resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz",
"integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY="
},
"request": {
"version": "2.88.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz",
"integrity": "sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "http://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz",
"integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
},
"sax": {
"version": "1.2.4",
"resolved": "http://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz",
"integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
},
"sshpk": {
"version": "1.16.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
"tcb-admin-node": {
"version": "1.9.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tcb-admin-node/-/tcb-admin-node-1.9.0.tgz",
"integrity": "sha512-TYoBo66CEIIw1QzgK4Jq43G45zvBE6ZB35LbDV8wwLQvg6CiZHlmOTVZkgj2YZ8O87ELi+ZE3UBVNZM3nFa6lQ==",
"requires": {
"@cloudbase/database": "0.1.1",
"is-regex": "^1.0.4",
"lodash.merge": "^4.6.1",
"request": "^2.87.0",
"xml2js": "^0.4.19"
}
},
"tencentcloud-sdk-nodejs": {
"version": "3.0.77",
"resolved": "http://mirrors.cloud.tencent.com/npm/tencentcloud-sdk-nodejs/-/tencentcloud-sdk-nodejs-3.0.77.tgz",
"integrity": "sha512-DULk7IFdR8BQnvC1iRuj+GrYnuU72Lj3oyIO1U2pubf71GtN9PeZ/9km2T7lsCeySU/J6jCTvwVPZaIhip/H1g==",
"requires": {
"request": "^2.85.0"
}
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "http://mirrors.cloud.tencent.com/npm/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
},
"dependencies": {
"punycode": {
"version": "1.4.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
}
}
},
"tslib": {
"version": "1.10.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "http://mirrors.cloud.tencent.com/npm/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"uri-js": {
"version": "4.2.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"requires": {
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"verror": {
"version": "1.10.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
"wx-server-sdk": {
"version": "0.8.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/wx-server-sdk/-/wx-server-sdk-0.8.1.tgz",
"integrity": "sha512-mE7O3E7GtRhqk1ukWw2+NiykaO5DaJYiMFCeHrwvekYTVL5Z2nFXnSrUx6nPg/vZ7LWWQbCgQlGOygBjj2+hkQ==",
"requires": {
"protobufjs": "6.8.8",
"tcb-admin-node": "1.9.0",
"tslib": "^1.9.3"
}
},
"xml2js": {
"version": "0.4.19",
"resolved": "http://mirrors.cloud.tencent.com/npm/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "http://mirrors.cloud.tencent.com/npm/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
}
}
}

View File

@@ -1,37 +0,0 @@
// 云函数入口文件
const cloud = require('wx-server-sdk')
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotexplorerClient = tencentcloud.iotexplorer.v20190423.Client;
const models = tencentcloud.iotexplorer.v20190423.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
cloud.init()
// 云函数入口函数
exports.main = async(event, context) => {
console.log("event:", event);
let cred = new Credential(event.SecretId, event.SecretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotexplorer.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotexplorerClient(cred, "ap-guangzhou", clientProfile);
let req = new models.DescribeDeviceDataRequest();
req.ProductId = event.ProductId;
req.DeviceName = event.DeviceName;
console.log("req:", req);
return new Promise((resolve, reject) => {
client.DescribeDeviceData(req, function(errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg);
}
console.log(response);
resolve(response)
});
})
}

View File

@@ -1,15 +0,0 @@
{
"name": "iotexplorer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tencentcloud-sdk-nodejs": "^3.0.77",
"wx-server-sdk": "latest"
}
}

View File

@@ -1,22 +0,0 @@
//app.js
App({
globalData: {
},
onLaunch: function () {
wx.setKeepScreenOn({
keepScreenOn: true
})
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用wx.cloud.xxx会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: "tos-demo",
traceUser: true,
})
}
}
})

View File

@@ -1,13 +0,0 @@
{
"pages": [
"pages/index/index"
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#F6F6F6",
"navigationBarTitleText": "设备联动Demo",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json"
}

View File

@@ -1,156 +0,0 @@
/**app.wxss**/
.container {
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
}
button {
background: initial;
}
button:focus{
outline: 0;
}
button::after{
border: none;
}
page {
background: #f6f6f6;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.userinfo, .uploader, .tunnel {
margin-top: 40rpx;
height: 140rpx;
width: 100%;
background: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
border-left: none;
border-right: none;
display: flex;
flex-direction: row;
align-items: center;
transition: all 300ms ease;
}
.userinfo-avatar {
width: 100rpx;
height: 100rpx;
margin: 20rpx;
border-radius: 50%;
background-size: cover;
background-color: white;
}
.userinfo-avatar:after {
border: none;
}
.userinfo-nickname {
font-size: 32rpx;
color: #007aff;
background-color: white;
background-size: cover;
}
.userinfo-nickname::after {
border: none;
}
.uploader, .tunnel {
height: auto;
padding: 0 0 0 40rpx;
flex-direction: column;
align-items: flex-start;
box-sizing: border-box;
}
.uploader-text, .tunnel-text {
width: 100%;
line-height: 52px;
font-size: 34rpx;
color: #007aff;
}
.uploader-container {
width: 100%;
height: 400rpx;
padding: 20rpx 20rpx 20rpx 0;
display: flex;
align-content: center;
justify-content: center;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.uploader-image {
width: 100%;
height: 360rpx;
}
.tunnel {
padding: 0 0 0 40rpx;
}
.tunnel-text {
position: relative;
color: #222;
display: flex;
flex-direction: row;
align-content: center;
justify-content: space-between;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.tunnel-text:first-child {
border-top: none;
}
.tunnel-switch {
position: absolute;
right: 20rpx;
top: -2rpx;
}
.disable {
color: #888;
}
.service {
position: fixed;
right: 40rpx;
bottom: 40rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background: linear-gradient(#007aff, #0063ce);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-content: center;
justify-content: center;
transition: all 300ms ease;
}
.service-button {
position: absolute;
top: 40rpx;
}
.service:active {
box-shadow: none;
}
.request-text {
padding: 20rpx 0;
font-size: 24rpx;
line-height: 36rpx;
word-break: break-all;
}

View File

@@ -1,24 +0,0 @@
// 传感设备配置
const SensorDevice = {
// 腾讯云物联网通信平台中获取 产品ID和设备名称
ProductId: "ZLN6Q20QHU", // 产品ID
DeviceName: "dev001", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, SecretKey
SecretId: "XXXX",
SecretKey: "XXXX",
}
// 执行设备配置
const ExecuteDevice = {
ProductId: "U1BZWHF7F9", // 产品ID
DeviceName: "dev_01", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, SecretKey
SecretId: "XXXX",
SecretKey: "XXXX",
Topic: "U1BZWHF7F9/dev_01/data"
}
module.exports = {
SensorDevice: SensorDevice,
ExecuteDevice: ExecuteDevice,
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -1,266 +0,0 @@
const app = getApp()
const config = require('../../config.js')
var util = require('../../utils/util.js');
var wxCharts = require('../../utils/wxcharts.js');
var lineChart = null;
var startPos = null;
Page({
data: {
tempHigh: 20,
sensorDevice: {},
executeDevice: {},
chartDataTemp: [],
chartDataHumi: [],
chartCategories: [],
},
onLoad: async function(options) {
console.log("index onLoad")
while (true) {
let executor = await this.queryExecuteDeviceStatus()
let sensor = await this.querySensorDeviceStatus()
this.renderChart(sensor.temperature.Value, sensor.humidity.Value)
let temp = sensor.temperature.Value
console.log(temp)
if (temp >= this.data.tempHigh) {
if (executor.light == 0) {
wx.showModal({
title: '提示',
content: `温度达到门限(${this.data.tempHigh}),打开风扇和灯`,
showCancel: false,
})
this.turnOnLight()
this.turnOnFan()
}
} else {
// this.turnOffLight()
// this.turnOffFan()
}
await util.delayMs(5000)
}
},
sliderChange(e) {
console.log(e.detail)
this.setData({
tempHigh: e.detail.value
})
},
renderChart(temperature, humidity) {
let epoch = Math.round(new Date().getTime() / 1000)
let timestamp = util.formatEpoch(epoch)
if (this.data.chartDataTemp.length > 5) {
this.data.chartDataTemp.pop();
this.data.chartDataHumi.pop();
this.data.chartCategories.pop();
}
this.data.chartDataTemp.unshift(temperature)
this.data.chartDataHumi.unshift(humidity)
this.data.chartCategories.unshift(timestamp.substring(11))
this.setData({
timestamp: timestamp,
chartDataTemp: this.data.chartDataTemp,
chartDataHumi: this.data.chartDataHumi,
chartCategories: this.data.chartCategories,
})
this.renderChartTemp(400, 160)
this.renderChartHumi(400, 160)
},
// 查询传感器设备状态
async querySensorDeviceStatus() {
let res = await wx.cloud.callFunction({
name: 'query',
data: config.SensorDevice
})
console.log("sensorDevice status", res.result.Data)
let data = JSON.parse(res.result.Data)
this.setData({
sensorDevice: data
})
return this.data.sensorDevice
},
// 查询执行设备状态
async queryExecuteDeviceStatus() {
let res = await wx.cloud.callFunction({
name: 'iothub-shadow-query',
data: config.ExecuteDevice,
})
console.log("executeDevice status", res.result)
let deviceData = JSON.parse(res.result.Data)
// this.setData({
// executeDevice: deviceData.payload.state.reported
// })
return deviceData.payload.state.reported
},
async turnOnLight() {
await this.control({
light: 1
})
this.setData({
[`executeDevice.light`]: 1
})
},
async turnOffLight() {
await this.control({
light: 0
})
this.setData({
[`executeDevice.light`]: 0
})
},
async turnOnFan() {
await this.control({
motor: 1
})
this.setData({
[`executeDevice.motor`]: 1
})
},
async turnOffFan() {
await this.control({
motor: 0
})
this.setData({
[`executeDevice.motor`]: 0
})
},
async control(obj) {
let data = config.ExecuteDevice
data.Payload = JSON.stringify(obj)
await wx.cloud.callFunction({
name: 'iothub-publish',
data: data
})
},
async switchChange(e) {
let value = 0
if (e.detail.value == true) {
value = 1
}
let item = e.currentTarget.dataset.item
let obj = {
[`${item}`]: value
}
wx.showLoading()
let data = config.ExecuteDevice
data.Payload = JSON.stringify(obj)
console.log(data)
await wx.cloud.callFunction({
name: 'iothub-publish',
data: data
})
wx.hideLoading()
},
touchHandler: function(e) {
if (!lineChart) {
return;
}
lineChart.scrollStart(e);
},
moveHandler: function(e) {
if (!lineChart) {
return;
}
lineChart.scroll(e);
},
touchEndHandler: function(e) {
if (!lineChart) {
return;
}
lineChart.scrollEnd(e);
lineChart.showToolTip(e, {
format: function(item, category) {
return category + ' ' + item.name + ':' + item.data
}
});
},
renderChartHumi: function(windowWidth, windowHeight) {
lineChart = new wxCharts({
canvasId: 'chartHumi',
type: 'line',
categories: this.data.chartCategories, // simulationData.categories,
animation: false,
series: [{
name: '湿度',
data: this.data.chartDataHumi, // simulationData.data2,
format: function(val, name) {
return val.toFixed(2) + "%";
// return val + "%";
}
}],
xAxis: {
disableGrid: false,
fontColor: '#666666',
},
yAxis: {
// title: '湿度 (%)',
// format: function (val) {
// return val.toFixed(2);
// },
max: 100,
min: 50,
disabled: false,
},
width: windowWidth,
height: windowHeight,
legend: true,
dataLabel: true,
dataPointShape: true,
enableScroll: true,
extra: {
lineStyle: 'curve'
},
});
},
renderChartTemp: function(windowWidth, windowHeight) {
lineChart = new wxCharts({
canvasId: 'chartTemp',
type: 'line',
categories: this.data.chartCategories, // simulationData.categories,
animation: false,
series: [{
name: '温度',
data: this.data.chartDataTemp, //simulationData.data,
format: function(val, name) {
return val.toFixed(2) + "℃";
// return val + "℃";
}
}],
xAxis: {
disableGrid: false
},
yAxis: {
// title: '温度 (℃)',
// format: function (val) {
// return val.toFixed(2);
// },
min: 15,
max: 25,
disabled: false,
},
width: windowWidth,
height: windowHeight,
legend: true,
dataLabel: true,
dataPointShape: true,
enableScroll: true,
extra: {
lineStyle: 'curve'
},
});
},
createSimulationData: function() {
var categories = [];
var data = [];
var data2 = [];
for (var i = 0; i < 10; i++) {
categories.push('201620162-' + (i + 1));
data.push(Math.random() * (20 - 10) + 10);
data2.push(Math.random() * (20 - 10) + 30);
}
return {
categories: categories,
data: data,
data2: data2
}
},
})

View File

@@ -1,66 +0,0 @@
<!-- <wxs module="dateUtil" src="../../utils/timeutil.wxs"> -->
<view style="display:flex; flex-direction:column; align-items:center;">
<image style="width:200px; height:60px;" src="../../images/TencentOS_tiny_log.png" mode="cover"></image>
</view>
<view class="body">
<form bindsubmit="">
<view style="display:flex; flex-direction:row; justify-content: space-between;">
<view style="font-weight: bold;">
传感设备
</view>
<view>
{{timestamp}}
</view>
</view>
<view class="box">
<view class="cell">
<view class="left">温度</view>
<view class="right">
{{sensorDevice.temperature.Value}}
</view>
<view class="unit">℃</view>
</view>
<canvas canvas-id="chartTemp" disable-scroll="false" class="canvas" bindtouchstart="touchHandler" bindtouchmove="moveHandler" bindtouchend="touchEndHandler"></canvas>
<view class="cell">
<view class="left">湿度</view>
<view class="right">
{{sensorDevice.humidity.Value}}
</view>
<view class="unit">%</view>
</view>
</view>
<canvas canvas-id="chartHumi" disable-scroll="false" class="canvas" bindtouchstart="touchHandler" bindtouchmove="moveHandler" bindtouchend="touchEndHandler"></canvas>
</form>
<form bindsubmit="">
<view style="display:flex; flex-direction:row; justify-content: space-between;">
<view style="font-weight: bold;">
执行设备
</view>
</view>
<view class="box">
<view class="cell">
<view>照明</view>
<view>
<switch name="light" data-item="light" checked="{{executeDevice.light}}" bindchange="switchChange" />
</view>
</view>
<view class="cell">
<view>风扇</view>
<view>
<switch name="motor" data-item="motor" checked="{{executeDevice.motor}}" bindchange="switchChange" />
</view>
</view>
<view class="cell">
<view>温度门限</view>
</view>
<slider bindchange="sliderChange" min="0" max="100" value="{{tempHigh}}" show-value/>
</view>
</form>
</view>
<view>
</view>

View File

@@ -1,32 +0,0 @@
.body {
margin: 10rpx 20rpx;
}
.box {
padding: 0rpx 20rpx;
border-top: 2px solid #000;
}
.cell {
margin-top: 10rpx;
margin-bottom: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.left {
width: 50%;
text-align: left;
}
.right {
width: 40%;
text-align: right;
}
.unit {
width: 10%;
text-align: right;
}

View File

@@ -1,7 +0,0 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

View File

@@ -1,48 +0,0 @@
var formatNumber = function (n) {
n = n.toString()
return n[1] ? n : '0' + n
}
var regYear = getRegExp("(y+)", "i");
var dateFormat = function (timestamp, format) {
if (!format) {
format = "yyyy-MM-dd hh:mm:ss";
}
timestamp = parseInt(timestamp);
var realDate = getDate(timestamp);
function timeFormat(num) {
return num < 10 ? '0' + num : num;
}
var date = [
["M+", timeFormat(realDate.getMonth() + 1)],
["d+", timeFormat(realDate.getDate())],
["h+", timeFormat(realDate.getHours())],
["m+", timeFormat(realDate.getMinutes())],
["s+", timeFormat(realDate.getSeconds())],
["q+", Math.floor((realDate.getMonth() + 3) / 3)],
["S+", realDate.getMilliseconds()],
];
var reg1 = regYear.exec(format);
// console.log(reg1[0]);
if (reg1) {
format = format.replace(reg1[1], (realDate.getFullYear() + '').substring(4 - reg1[1].length));
}
for (var i = 0; i < date.length; i++) {
var k = date[i][0];
var v = date[i][1];
var reg2 = getRegExp("(" + k + ")").exec(format);
if (reg2) {
format = format.replace(reg2[1], reg2[1].length == 1
? v : ("00" + v).substring(("" + v).length));
}
}
return format;
}
module.exports = {
dateFormat: dateFormat
}

View File

@@ -1,33 +0,0 @@
// await util.delayMs(1000)
const delayMs = (ms) => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
function Appendzero(obj) {
if (obj < 10) return "0" + "" + obj;
else return obj;
}
// epoch => datetime str
// 1578450878 => 2019-10-23 18:05:30
function formatEpoch(epoch) {
var dateTime = new Date(parseInt(epoch) * 1000)
var year = dateTime.getFullYear();
var month = dateTime.getMonth() + 1;
var day = dateTime.getDate();
var hour = dateTime.getHours();
var minute = dateTime.getMinutes();
var second = dateTime.getSeconds();
var now = new Date();
var now_new = Date.parse(now.toDateString()); //typescript转换写法
var milliseconds = now_new - dateTime;
var timeSpanStr = year + '-' + Appendzero(month) + '-' + Appendzero(day) + ' ' + Appendzero(hour) + ':' + Appendzero(minute) + ':' + Appendzero(second);
return timeSpanStr;
}
module.exports = {
delayMs: delayMs,
formatEpoch: formatEpoch,
}

View File

@@ -1,52 +0,0 @@
{
"miniprogramRoot": "miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"coverView": true,
"nodeModules": true,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enhance": true
},
"appid": "wx394efa031612f9b5",
"projectname": "qcloud_device_linkage_demo",
"libVersion": "2.7.7",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"cloudfunctionTemplateRoot": "cloudfunctionTemplate",
"compileType": "miniprogram",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"list": []
},
"miniprogram": {
"current": 0
}
}
}

View File

@@ -1,28 +0,0 @@
### 小程序云开发DEMO-智慧农业
本示例小程序配合 TencentOS_tiny开发板 + 智慧农业传感器扩展板(E53-IA1) 使用
+ 设备端
+ 示例代码路径
TencentOS-tiny/examples/sensor_e53_ia1_e2e_demo
+ 配置信息 e53_ia1_e2e_demo_config.h
```c
#define MQTT_PRODUCT_ID "U1BZWHF7F9"
#define MQTT_DEV_NAME "dev_01"
#define MQTT_CLIENT_ID "U1BZWHF7F9dev_01"
#define MQTT_USR_NAME "U1BZWHF7F9dev_01;12010126;O3I57;1611533066"
#define MQTT_PASSWORD "6ebcf20c9f7f725b5bcf18a85cc7a49479f489eea65946f92ba18a51a135c89e;hmacsha256"
#define MQTT_SUBSCRIBE_TOPIC "U1BZWHF7F9/dev_01/data"
#define MQTT_PUBLISH_TOPIC "$shadow/operation/U1BZWHF7F9/dev_01" // $shadow/operation/{MQTT_PRODUCT_ID}/{MQTT_DEV_NAME}
```
在 腾讯云控制台-物联网通信-产品-设备-设备信息-设备密钥中 获取
![设备密钥](./miniprogram/images/mp_iothub_secret.png)
+ 云开发
+ 云函数说明
+ iothub-shadow-query 调用接口:物联网通信-设备影子相关接口-获取设备影子
+ iothub-publish 调用接口:物联网通信-消息相关接口-发布消息
+ 云函数开发指引参考:
+ [doc/17.Mini_Program_Quick_Start.md](https://github.com/Tencent/TencentOS-tiny/blob/master/doc/17.Mini_Program_Quick_Start.md) - 云开发方式(云函数)

View File

@@ -1,38 +0,0 @@
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotcloudClient = tencentcloud.iotcloud.v20180614.Client;
const models = tencentcloud.iotcloud.v20180614.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
// 云函数入口函数
exports.main = async (event, context) => {
let cred = new Credential(event.SecretId, event.SecretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotcloud.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotcloudClient(cred, "ap-guangzhou", clientProfile);
let req = new models.PublishMessageRequest();
// req.Topic = "U1BZWHF7F9/dev_01/data";
// req.DeviceName = "dev_01";
// req.ProductId = "U1BZWHF7F9";
req.Topic = event.Topic
req.DeviceName = event.DeviceName;
req.ProductId = event.ProductId;
req.Payload = event.Payload;
return new Promise((resolve, reject)=>{
client.PublishMessage(req, function (errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg)
return;
}
console.log(response.to_json_string());
resolve(response)
});
})
}

View File

@@ -1,14 +0,0 @@
{
"name": "iothub-publish",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

View File

@@ -1,34 +0,0 @@
const tencentcloud = require("tencentcloud-sdk-nodejs");
const IotcloudClient = tencentcloud.iotcloud.v20180614.Client;
const models = tencentcloud.iotcloud.v20180614.Models;
const Credential = tencentcloud.common.Credential;
const ClientProfile = tencentcloud.common.ClientProfile;
const HttpProfile = tencentcloud.common.HttpProfile;
exports.main = async (event, context) => {
let cred = new Credential(event.SecretId, event.SecretKey);
let httpProfile = new HttpProfile();
httpProfile.endpoint = "iotcloud.tencentcloudapi.com";
let clientProfile = new ClientProfile();
clientProfile.httpProfile = httpProfile;
let client = new IotcloudClient(cred, "ap-guangzhou", clientProfile);
let req = new models.DescribeDeviceShadowRequest();
req.DeviceName = event.DeviceName;
req.ProductId = event.ProductId;
return new Promise((resolve, reject)=>{
client.DescribeDeviceShadow(req, function (errMsg, response) {
if (errMsg) {
console.log(errMsg);
reject(errMsg)
return;
}
console.log(response.to_json_string());
resolve(response)
});
})
}

View File

@@ -1,15 +0,0 @@
{
"name": "iotexplorer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tencentcloud-sdk-nodejs": "^3.0.77",
"wx-server-sdk": "latest"
}
}

View File

@@ -1,549 +0,0 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@cloudbase/database": {
"version": "0.1.1",
"resolved": "https://registry.npm.taobao.org/@cloudbase/database/download/@cloudbase/database-0.1.1.tgz",
"integrity": "sha1-yf/JK3HhkAVxljkL6odpZ3f/l/8=",
"requires": {
"bson": "^4.0.2"
}
},
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/aspromise/download/@protobufjs/aspromise-1.1.2.tgz",
"integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
},
"@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/base64/download/@protobufjs/base64-1.1.2.tgz",
"integrity": "sha1-TIVzDlm5ofHzSQR9vyQpYDS7JzU="
},
"@protobufjs/codegen": {
"version": "2.0.4",
"resolved": "https://registry.npm.taobao.org/@protobufjs/codegen/download/@protobufjs/codegen-2.0.4.tgz",
"integrity": "sha1-fvN/DQEPsCitGtWXIuUG2SYoFcs="
},
"@protobufjs/eventemitter": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/eventemitter/download/@protobufjs/eventemitter-1.1.0.tgz",
"integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
},
"@protobufjs/fetch": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/fetch/download/@protobufjs/fetch-1.1.0.tgz",
"integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
"requires": {
"@protobufjs/aspromise": "^1.1.1",
"@protobufjs/inquire": "^1.1.0"
}
},
"@protobufjs/float": {
"version": "1.0.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/float/download/@protobufjs/float-1.0.2.tgz",
"integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
},
"@protobufjs/inquire": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/inquire/download/@protobufjs/inquire-1.1.0.tgz",
"integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
},
"@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npm.taobao.org/@protobufjs/path/download/@protobufjs/path-1.1.2.tgz",
"integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
},
"@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/pool/download/@protobufjs/pool-1.1.0.tgz",
"integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
},
"@protobufjs/utf8": {
"version": "1.1.0",
"resolved": "https://registry.npm.taobao.org/@protobufjs/utf8/download/@protobufjs/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
},
"@types/long": {
"version": "4.0.0",
"resolved": "https://registry.npm.taobao.org/@types/long/download/@types/long-4.0.0.tgz",
"integrity": "sha1-cZVR0jUtMBrIuB23Mqy2vcKNve8="
},
"@types/node": {
"version": "10.14.13",
"resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-10.14.13.tgz?cache=0&sync_timestamp=1563391049881&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-10.14.13.tgz",
"integrity": "sha1-rHhtYjhgrfOaP1HWKUgKrNam7sc="
},
"ajv": {
"version": "6.10.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"asn1": {
"version": "0.2.4",
"resolved": "http://registry.npm.taobao.org/asn1/download/asn1-0.2.4.tgz",
"integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/assert-plus/download/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "http://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "http://registry.npm.taobao.org/aws-sign2/download/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.8.0",
"resolved": "http://registry.npm.taobao.org/aws4/download/aws4-1.8.0.tgz",
"integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8="
},
"base64-js": {
"version": "1.3.0",
"resolved": "http://registry.npm.taobao.org/base64-js/download/base64-js-1.3.0.tgz",
"integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM="
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"bson": {
"version": "4.0.2",
"resolved": "https://registry.npm.taobao.org/bson/download/bson-4.0.2.tgz",
"integrity": "sha1-KSn9/tGhRbHDYZCKK5UKbPS+0sI=",
"requires": {
"buffer": "^5.1.0",
"long": "^4.0.0"
}
},
"buffer": {
"version": "5.2.1",
"resolved": "http://registry.npm.taobao.org/buffer/download/buffer-5.2.1.tgz",
"integrity": "sha1-3Vf6DxCaxZxgJHkETcp7iz0LcdY=",
"requires": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "http://registry.npm.taobao.org/caseless/download/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npm.taobao.org/combined-stream/download/combined-stream-1.0.8.tgz",
"integrity": "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8=",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "http://registry.npm.taobao.org/core-util-is/download/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"dashdash": {
"version": "1.14.1",
"resolved": "http://registry.npm.taobao.org/dashdash/download/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "http://registry.npm.taobao.org/ecc-jsbn/download/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"extend": {
"version": "3.0.2",
"resolved": "http://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz",
"integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "http://registry.npm.taobao.org/extsprintf/download/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npm.taobao.org/fast-deep-equal/download/fast-deep-equal-2.0.1.tgz?cache=0&sync_timestamp=1562517919182&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffast-deep-equal%2Fdownload%2Ffast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/fast-json-stable-stringify/download/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "http://registry.npm.taobao.org/forever-agent/download/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.3",
"resolved": "https://registry.npm.taobao.org/form-data/download/form-data-2.3.3.tgz?cache=0&sync_timestamp=1562216133657&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fform-data%2Fdownload%2Fform-data-2.3.3.tgz",
"integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "http://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz",
"integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
},
"getpass": {
"version": "0.1.7",
"resolved": "http://registry.npm.taobao.org/getpass/download/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/har-schema/download/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.1.3",
"resolved": "http://mirrors.cloud.tencent.com/npm/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"requires": {
"ajv": "^6.5.5",
"har-schema": "^2.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "http://registry.npm.taobao.org/has/download/has-1.0.3.tgz",
"integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=",
"requires": {
"function-bind": "^1.1.1"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"ieee754": {
"version": "1.1.13",
"resolved": "http://registry.npm.taobao.org/ieee754/download/ieee754-1.1.13.tgz",
"integrity": "sha1-7BaFWOlaoYH9h9N/VcMrvLZwi4Q="
},
"is-regex": {
"version": "1.0.4",
"resolved": "http://registry.npm.taobao.org/is-regex/download/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"requires": {
"has": "^1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/is-typedarray/download/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "http://registry.npm.taobao.org/isstream/download/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "http://registry.npm.taobao.org/jsbn/download/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-schema": {
"version": "0.2.3",
"resolved": "http://registry.npm.taobao.org/json-schema/download/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "http://registry.npm.taobao.org/json-schema-traverse/download/json-schema-traverse-0.4.1.tgz",
"integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "http://registry.npm.taobao.org/json-stringify-safe/download/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npm.taobao.org/lodash.merge/download/lodash.merge-4.6.2.tgz",
"integrity": "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo="
},
"long": {
"version": "4.0.0",
"resolved": "http://registry.npm.taobao.org/long/download/long-4.0.0.tgz",
"integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npm.taobao.org/mime-db/download/mime-db-1.40.0.tgz",
"integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.24.tgz",
"integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=",
"requires": {
"mime-db": "1.40.0"
}
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "http://registry.npm.taobao.org/oauth-sign/download/oauth-sign-0.9.0.tgz",
"integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU="
},
"performance-now": {
"version": "2.1.0",
"resolved": "http://registry.npm.taobao.org/performance-now/download/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"protobufjs": {
"version": "6.8.8",
"resolved": "http://mirrors.cloud.tencent.com/npm/protobufjs/-/protobufjs-6.8.8.tgz",
"integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.0",
"@types/node": "^10.1.0",
"long": "^4.0.0"
}
},
"psl": {
"version": "1.2.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/psl/-/psl-1.2.0.tgz",
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA=="
},
"punycode": {
"version": "2.1.1",
"resolved": "http://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz",
"integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew="
},
"qs": {
"version": "6.5.2",
"resolved": "http://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz",
"integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY="
},
"request": {
"version": "2.88.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz",
"integrity": "sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "http://registry.npm.taobao.org/safer-buffer/download/safer-buffer-2.1.2.tgz",
"integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo="
},
"sax": {
"version": "1.2.4",
"resolved": "http://registry.npm.taobao.org/sax/download/sax-1.2.4.tgz",
"integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk="
},
"sshpk": {
"version": "1.16.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
"tcb-admin-node": {
"version": "1.9.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tcb-admin-node/-/tcb-admin-node-1.9.0.tgz",
"integrity": "sha512-TYoBo66CEIIw1QzgK4Jq43G45zvBE6ZB35LbDV8wwLQvg6CiZHlmOTVZkgj2YZ8O87ELi+ZE3UBVNZM3nFa6lQ==",
"requires": {
"@cloudbase/database": "0.1.1",
"is-regex": "^1.0.4",
"lodash.merge": "^4.6.1",
"request": "^2.87.0",
"xml2js": "^0.4.19"
}
},
"tencentcloud-sdk-nodejs": {
"version": "3.0.77",
"resolved": "http://mirrors.cloud.tencent.com/npm/tencentcloud-sdk-nodejs/-/tencentcloud-sdk-nodejs-3.0.77.tgz",
"integrity": "sha512-DULk7IFdR8BQnvC1iRuj+GrYnuU72Lj3oyIO1U2pubf71GtN9PeZ/9km2T7lsCeySU/J6jCTvwVPZaIhip/H1g==",
"requires": {
"request": "^2.85.0"
}
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "http://mirrors.cloud.tencent.com/npm/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
},
"dependencies": {
"punycode": {
"version": "1.4.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
}
}
},
"tslib": {
"version": "1.10.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "http://mirrors.cloud.tencent.com/npm/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"uri-js": {
"version": "4.2.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"requires": {
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "http://mirrors.cloud.tencent.com/npm/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"verror": {
"version": "1.10.0",
"resolved": "http://mirrors.cloud.tencent.com/npm/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
"wx-server-sdk": {
"version": "0.8.1",
"resolved": "http://mirrors.cloud.tencent.com/npm/wx-server-sdk/-/wx-server-sdk-0.8.1.tgz",
"integrity": "sha512-mE7O3E7GtRhqk1ukWw2+NiykaO5DaJYiMFCeHrwvekYTVL5Z2nFXnSrUx6nPg/vZ7LWWQbCgQlGOygBjj2+hkQ==",
"requires": {
"protobufjs": "6.8.8",
"tcb-admin-node": "1.9.0",
"tslib": "^1.9.3"
}
},
"xml2js": {
"version": "0.4.19",
"resolved": "http://mirrors.cloud.tencent.com/npm/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "http://mirrors.cloud.tencent.com/npm/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
}
}
}

View File

@@ -1,25 +0,0 @@
//app.js
App({
globalData: {
// 腾讯云物联网通信平台中获取 产品ID和设备名称
productId: "U1BZWHF7F9", // 产品ID
deviceName: "dev_01", // 设备名称
// 腾讯云控制台-访问管理-访问密钥-API密钥管理中获取 SecretId, SecretKey
secretId: "xxx",
secretKey: "xxx",
},
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用wx.cloud.xxx会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: "tos-demo",
traceUser: true,
})
}
}
})

View File

@@ -1,13 +0,0 @@
{
"pages": [
"pages/index/index"
],
"window": {
"backgroundColor": "#F6F6F6",
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#F6F6F6",
"navigationBarTitleText": "智慧农业Demo",
"navigationBarTextStyle": "black"
},
"sitemapLocation": "sitemap.json"
}

View File

@@ -1,156 +0,0 @@
/**app.wxss**/
.container {
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
}
button {
background: initial;
}
button:focus{
outline: 0;
}
button::after{
border: none;
}
page {
background: #f6f6f6;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.userinfo, .uploader, .tunnel {
margin-top: 40rpx;
height: 140rpx;
width: 100%;
background: #fff;
border: 1px solid rgba(0, 0, 0, 0.1);
border-left: none;
border-right: none;
display: flex;
flex-direction: row;
align-items: center;
transition: all 300ms ease;
}
.userinfo-avatar {
width: 100rpx;
height: 100rpx;
margin: 20rpx;
border-radius: 50%;
background-size: cover;
background-color: white;
}
.userinfo-avatar:after {
border: none;
}
.userinfo-nickname {
font-size: 32rpx;
color: #007aff;
background-color: white;
background-size: cover;
}
.userinfo-nickname::after {
border: none;
}
.uploader, .tunnel {
height: auto;
padding: 0 0 0 40rpx;
flex-direction: column;
align-items: flex-start;
box-sizing: border-box;
}
.uploader-text, .tunnel-text {
width: 100%;
line-height: 52px;
font-size: 34rpx;
color: #007aff;
}
.uploader-container {
width: 100%;
height: 400rpx;
padding: 20rpx 20rpx 20rpx 0;
display: flex;
align-content: center;
justify-content: center;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.uploader-image {
width: 100%;
height: 360rpx;
}
.tunnel {
padding: 0 0 0 40rpx;
}
.tunnel-text {
position: relative;
color: #222;
display: flex;
flex-direction: row;
align-content: center;
justify-content: space-between;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.tunnel-text:first-child {
border-top: none;
}
.tunnel-switch {
position: absolute;
right: 20rpx;
top: -2rpx;
}
.disable {
color: #888;
}
.service {
position: fixed;
right: 40rpx;
bottom: 40rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
background: linear-gradient(#007aff, #0063ce);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);
display: flex;
align-content: center;
justify-content: center;
transition: all 300ms ease;
}
.service-button {
position: absolute;
top: 40rpx;
}
.service:active {
box-shadow: none;
}
.request-text {
padding: 20rpx 0;
font-size: 24rpx;
line-height: 36rpx;
word-break: break-all;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -1,94 +0,0 @@
const app = getApp()
Page({
data: {
productId: app.globalData.productId,
deviceName: app.globalData.deviceName,
stateReported: {},
},
onLoad: function (options) {
console.log("index onLoad")
if (!app.globalData.productId) {
wx.showToast({
title: "产品ID不能为空",
icon: 'none',
duration: 3000
})
return
} else if (!app.globalData.deviceName) {
wx.showToast({
title: "设备名称不能为空",
icon: 'none',
duration: 3000
})
return
}
this.update()
},
update() {
wx.showLoading()
wx.cloud.callFunction({
name: 'iothub-shadow-query',
data: {
ProductId: app.globalData.productId,
DeviceName: app.globalData.deviceName,
SecretId: app.globalData.secretId,
SecretKey: app.globalData.secretKey,
},
success: res => {
wx.showToast({
title: '调用成功',
})
let deviceData = JSON.parse(res.result.Data)
this.setData({
stateReported: deviceData.payload.state.reported
})
console.log("result:", deviceData)
},
fail: err => {
wx.showToast({
icon: 'none',
title: '调用失败',
})
console.error('[云函数] [iotexplorer] 调用失败:', err)
}
})
},
switchChange(e) {
let value = 0
if (e.detail.value == true) {
value = 1
}
let item = e.currentTarget.dataset.item
let obj = {
[`${item}`]: value
}
let payload = JSON.stringify(obj)
console.log(payload)
wx.showLoading()
wx.cloud.callFunction({
name: 'iothub-publish',
data: {
SecretId: app.globalData.secretId,
SecretKey: app.globalData.secretKey,
ProductId: app.globalData.productId,
DeviceName: app.globalData.deviceName,
Topic: app.globalData.productId + "/" + app.globalData.deviceName + "/data",
Payload: payload,
},
success: res => {
wx.showToast({
title: '调用成功',
})
console.log("res:", res)
},
fail: err => {
wx.showToast({
icon: 'none',
title: '调用失败',
})
console.error('[云函数] [iotexplorer] 调用失败:', err)
}
})
},
})

View File

@@ -1,65 +0,0 @@
<view style="display:flex; flex-direction:column; align-items:center;">
<image style="width:200px; height:60px;" src="../../images/TencentOS_tiny_log.png" mode="cover"></image>
</view>
<view class="body">
<view style="font-weight: bold;">
设备信息
</view>
<view class="box">
<view class="cell">
<view class="status-left">产品ID</view>
<view class="status-right">{{productId}}</view>
</view>
<view class="cell">
<view class="status-left">设备名称</view>
<view class="status-right">{{deviceName}}</view>
</view>
</view>
<text>\n</text>
<form bindsubmit="">
<view style="display:flex; flex-direction:row; justify-content: space-between;">
<view style="font-weight: bold;">
农业Demo
</view>
<view>
<button type="primary" size="mini" bindtap="update">刷新</button>
</view>
</view>
<view class="box">
<view class="cell">
<view>照明</view>
<view>
<switch name="light" data-item="light" checked="{{stateReported.light}}" bindchange="switchChange"/>
</view>
</view>
<view class="cell">
<view>风扇</view>
<view>
<switch name="motor" data-item="motor" checked="{{stateReported.motor}}" bindchange="switchChange"/>
</view>
</view>
<view class="cell">
<view class="left">温度</view>
<view class="right">
{{stateReported.temperature}}
</view>
<view class="unit">℃</view>
</view>
<view class="cell">
<view class="left">湿度</view>
<view class="right">
{{stateReported.humidity}}
</view>
<view class="unit">%</view>
</view>
<view class="cell">
<view class="left">光照强度</view>
<view class="right">{{stateReported.light_intensity}}</view>
<view class="unit">lux</view>
</view>
</view>
</form>
</view>

View File

@@ -1,31 +0,0 @@
.body {
margin: 10rpx 20rpx;
}
.box {
padding: 0rpx 20rpx;
border-top: 2px solid #000;
}
.cell {
margin-top: 10rpx;
margin-bottom: 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.left {
width: 50%;
text-align: left;
}
.right {
width: 40%;
text-align: right;
}
.unit {
width: 10%;
text-align: right;
}

View File

@@ -1,7 +0,0 @@
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}

View File

@@ -1,47 +0,0 @@
{
"miniprogramRoot": "miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"autoAudits": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"nodeModules": true
},
"appid": "wx394efa031612f9b5",
"projectname": "qcloud_iothub_mp_cloudfunctions_farmai",
"libVersion": "2.7.7",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"cloudfunctionTemplateRoot": "cloudfunctionTemplate",
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"list": []
},
"miniprogram": {
"current": 0
}
}
}