remove unused mini program
@@ -1,2 +0,0 @@
|
||||
## 蓝牙升级微信小程序源码
|
||||
|
@@ -1,12 +0,0 @@
|
||||
//app.js
|
||||
App({
|
||||
globalData: {
|
||||
},
|
||||
onLaunch: function () {
|
||||
this.globalData.SystemInfo = wx.getSystemInfoSync()
|
||||
//console.log(this.globalData.SystemInfo)
|
||||
wx.setKeepScreenOn({
|
||||
keepScreenOn: true
|
||||
})
|
||||
},
|
||||
})
|
@@ -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"
|
||||
}
|
@@ -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;
|
||||
}
|
Before Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 9.4 KiB |
@@ -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,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
@@ -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>
|
@@ -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
|
||||
}
|
@@ -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"
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
@@ -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>
|
@@ -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;
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
@@ -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,
|
||||
}
|
@@ -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;
|
@@ -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;
|
@@ -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,
|
||||
}
|
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@@ -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)
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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="
|
||||
}
|
||||
}
|
||||
}
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"window": {
|
||||
"backgroundColor": "#F6F6F6",
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#F6F6F6",
|
||||
"navigationBarTitleText": "智能灯云开发Demo",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
@@ -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;
|
||||
}
|
Before Width: | Height: | Size: 6.8 KiB |
@@ -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)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
@@ -1 +0,0 @@
|
||||
{}
|
@@ -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>
|
@@ -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;
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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)
|
@@ -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")
|
||||
},
|
||||
})
|
@@ -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"
|
||||
}
|
@@ -1,4 +0,0 @@
|
||||
/**app.wxss**/
|
||||
page{
|
||||
background: #f9f9f9;
|
||||
}
|
Before Width: | Height: | Size: 6.8 KiB |
@@ -1,5 +0,0 @@
|
||||
### NOTE
|
||||
|
||||
感谢halenhuang适配的iotexplorer小程序js接口iotclient_for_miniprogram
|
||||
|
||||
注意:iotclient_for_miniprogram非iotexplorer官方小程序SDK,仅用于方便开发者调试TencentOS tiny示例。
|
@@ -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;
|
@@ -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;
|
@@ -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;
|
@@ -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
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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;
|
@@ -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
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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
|
||||
})
|
||||
});
|
||||
},
|
||||
})
|
@@ -1 +0,0 @@
|
||||
{}
|
@@ -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>
|
@@ -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;
|
||||
}
|
@@ -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": []
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
@@ -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"
|
||||
}
|
||||
```
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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="
|
||||
}
|
||||
}
|
||||
}
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"window": {
|
||||
"backgroundColor": "#F6F6F6",
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#F6F6F6",
|
||||
"navigationBarTitleText": "设备联动Demo",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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,
|
||||
}
|
Before Width: | Height: | Size: 47 KiB |
@@ -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
|
||||
}
|
||||
},
|
||||
})
|
@@ -1 +0,0 @@
|
||||
{}
|
@@ -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>
|
@@ -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;
|
||||
}
|
||||
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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,
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
@@ -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}
|
||||
```
|
||||
在 腾讯云控制台-物联网通信-产品-设备-设备信息-设备密钥中 获取
|
||||
|
||||

|
||||
|
||||
+ 云开发
|
||||
+ 云函数说明
|
||||
+ 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) - 云开发方式(云函数)
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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)
|
||||
});
|
||||
})
|
||||
}
|
@@ -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"
|
||||
}
|
||||
}
|
@@ -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="
|
||||
}
|
||||
}
|
||||
}
|
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"pages": [
|
||||
"pages/index/index"
|
||||
],
|
||||
"window": {
|
||||
"backgroundColor": "#F6F6F6",
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#F6F6F6",
|
||||
"navigationBarTitleText": "智慧农业Demo",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
@@ -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;
|
||||
}
|
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 105 KiB |
@@ -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)
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
@@ -1 +0,0 @@
|
||||
{}
|
@@ -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>
|
@@ -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;
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|