diff --git a/src/wechat_app/app.js b/src/wechat_app/app.js
new file mode 100644
index 0000000..b48f6ee
--- /dev/null
+++ b/src/wechat_app/app.js
@@ -0,0 +1,21 @@
+// app.js
+App({
+ onLaunch() {
+ // 展示本地存储能力
+ const logs = wx.getStorageSync('logs') || []
+ logs.unshift(Date.now())
+ wx.setStorageSync('logs', logs)
+
+ // 登录
+ wx.login({
+ success: res => {
+ // 发送 res.code 到后台换取 openId, sessionKey, unionId
+ }
+ })
+ },
+ globalData: {
+ userInfo: null,
+ selble:"", //所选择蓝牙的mac
+ bleUtil:"", //蓝牙助手
+ }
+})
diff --git a/src/wechat_app/app.json b/src/wechat_app/app.json
new file mode 100644
index 0000000..a3238bb
--- /dev/null
+++ b/src/wechat_app/app.json
@@ -0,0 +1,16 @@
+{
+ "pages":[
+ "pages/selble/selble",
+ "pages/index/index",
+ "pages/logs/logs"
+ ],
+ "window":{
+ "backgroundTextStyle":"light",
+ "navigationBarBackgroundColor": "#fff",
+ "navigationBarTitleText": "Weixin",
+ "navigationBarTextStyle":"black"
+ },
+ "style": "v2",
+ "lazyCodeLoading": "requiredComponents",
+ "sitemapLocation": "sitemap.json"
+}
diff --git a/src/wechat_app/app.wxss b/src/wechat_app/app.wxss
new file mode 100644
index 0000000..164a110
--- /dev/null
+++ b/src/wechat_app/app.wxss
@@ -0,0 +1,220 @@
+/**app.wxss**/
+page{
+ background: #EFF2F6;
+}
+.container {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-between;
+ padding: 200rpx 0;
+ box-sizing: border-box;
+}
+.match_screen{
+ width: 100vw;
+ height: 100vh
+}
+.flex_row, .flex_column {
+ display: flex;
+}
+
+.flex_row {
+ flex-direction: row;
+}
+
+.flex_column {
+ flex-direction: column;
+}
+
+.flex_vcenter, .flex_center {
+ align-items: center;
+}
+
+.flex_hcenter, .flex_center {
+ justify-content: center;
+}
+
+
+
+.flex_wrap {
+ flex-wrap: wrap;
+}
+
+.flex_space {
+ justify-content: space-between;
+}
+
+.flex_grow_1 {
+ flex-grow: 1;
+}
+
+.flex_end {
+ justify-content: flex-end;
+}
+
+.flex_start {
+ justify-content: flex-start;
+}
+
+.border_bottom_class {
+ border-bottom: 1px solid rgba(204, 204, 204, 1);
+}
+
+.border_bottom_class_foucs {
+ border-bottom: 1px solid rgba(46, 152, 233, 1);
+}
+
+.table_boot_two {
+ width: 16.6666667%;
+}
+
+.table_boot_three {
+ width: 25%;
+}
+
+.table_boot_four {
+ width: 33.33%;
+}
+
+.table_boot_nine {
+ width: 75%;
+}
+
+.table_boot_six {
+ width: 50%;
+}
+
+.table_boot_ten {
+ width: 83.3333333%;
+}
+
+.table_boot_eight {
+ width: 66.666667%;
+}
+
+.table_boot_seven {
+ width: 58.3333333%;
+}
+
+.table_boot_height_six {
+ height: 50%;
+}
+
+.table_boot_height_one {
+ height: 8.333333%;
+}
+
+.table_boot_height_two {
+ height: 16.6666667%;
+}
+
+.table_boot_height_three {
+ height: 25%;
+}
+
+.table_boot_height_four {
+ height: 33.33333333%;
+}
+
+.table_boot_height_five {
+ height: 41.6666667%;
+}
+
+.table_boot_height_seven {
+ height: 58.3333333%;
+}
+
+.table_boot_height_eight {
+ height: 66.666667%;
+}
+
+.table_boot_height_nine {
+ height: 75%;
+}
+
+.table_boot_height_ten {
+ height: 83.3333333%;
+}
+
+.table_boot_height_ele {
+ height: 91.66667%;
+}
+
+.table_boot_height_twle {
+ height: 100%;
+}
+
+.white_back{
+ background: #fff;
+}
+
+.pos_fixed {
+ position: fixed;
+ z-index: -1;
+}
+
+.text_center {
+ text-align: center;
+}
+
+
+.btn_yellow_class,.btn_yellow_class:active,.btn_yellow_class_dissable{
+ width:90%;
+ margin-left: 5%;
+ border-radius:4px;
+ color: #fff;
+ font-size:100%;
+ font-family:PingFangSC-Heavy;
+ font-weight:800;
+}
+
+.btn_yellow_class{
+ background:rgba(0,120,253,1);
+}
+
+.btn_yellow_class:active{
+ background:rgb(5, 100, 207);
+}
+
+.btn_yellow_class_dissable{
+ background:rgba(204,204,204,1);
+}
+
+.no_data_back{
+ width: 100vw;
+ height: 60vh
+}
+
+.no_data_img{
+ width: 20vw;
+ height: 20vw;
+}
+
+.no_data_hint{
+ font-size: 80%;
+ color:#B0B0B0;
+}
+
+.btn_disable{
+ position: fixed;
+ right: 3vw;
+ color: white;
+ font-size: 80%;
+ background:linear-gradient(180deg,rgba(189,189,189,1) 0%,rgba(102,102,102,1) 100%,rgba(204,204,204,1) 100%);
+ border-radius:10px;
+}
+
+.btn_normal,.btn_normal:active{
+ font-size: 80%;
+ color: white;
+ border-radius:10px;
+}
+
+.btn_normal{
+ background:linear-gradient(180deg,rgba(255,255,255,1) 0%,rgba(255,112,191,1) 0%,rgba(69,178,255,1) 0%,rgba(0,126,255,1) 100%);
+}
+
+.btn_normal:active{
+ background:rgba(0,126,255,1);
+}
diff --git a/src/wechat_app/images/ic_ble.png b/src/wechat_app/images/ic_ble.png
new file mode 100644
index 0000000..a4769a9
Binary files /dev/null and b/src/wechat_app/images/ic_ble.png differ
diff --git a/src/wechat_app/images/ic_sel.png b/src/wechat_app/images/ic_sel.png
new file mode 100644
index 0000000..a0bf45c
Binary files /dev/null and b/src/wechat_app/images/ic_sel.png differ
diff --git a/src/wechat_app/images/ic_unsel.png b/src/wechat_app/images/ic_unsel.png
new file mode 100644
index 0000000..194588f
Binary files /dev/null and b/src/wechat_app/images/ic_unsel.png differ
diff --git a/src/wechat_app/pages/index/handler.js b/src/wechat_app/pages/index/handler.js
new file mode 100644
index 0000000..a014934
--- /dev/null
+++ b/src/wechat_app/pages/index/handler.js
@@ -0,0 +1,110 @@
+let regeneratorRuntime = require("../../utils/runtime.js");
+var util = require("../../utils/util.js");
+const app = getApp();
+var isSend = false;
+
+//同步请求
+/**
+ * request请求,GET 默认header
+ */
+function sendBleMsg(data,that) {
+ that.appendLogs("发送数据 " + data + " 中",that);
+ return new Promise((success, fail) => {
+ var isSuccess = false;
+ app.globalData.bleUtil.sendMsg(data, function (res) {
+ isSuccess = true;
+ if (res.errCode == 0) {
+ that.appendLogs("发送数据 " + data + " 成功",that);
+ success(true);
+ } else {
+ that.appendLogs("发送数据 " + data + " 失败",that);
+ success(false);
+ }
+ }, false);
+ //3秒后若没有发送成功,则认为发送失败
+ setTimeout(function(res){
+ if(!isSuccess){
+ success(false);
+ that.appendLogs("发送数据 " + data + " 失败",that);
+ }
+ },3000);
+ });
+}
+
+function sleep(times,that) {
+ return new Promise((success, fail) => {
+ setTimeout(function (res) {
+ success(true);
+ that.appendLogs("延迟 " + times + " 毫秒",that);
+ }, times);
+ });
+}
+
+
+
+var sendList = async (sendlist,sendtimes,that) => {
+ var i = 0;
+ isSend = true;
+ while(isSend){
+ let result = await sendBleMsg(sendlist[i],that);
+ if(!result){
+ stop(that);
+ return;
+ }
+ await sleep(sendtimes,that);
+ i++;
+ if(i > sendlist.length - 1){
+ i = 0;
+ }
+ }
+}
+
+
+var sendCoustomList = async (sendlist,title,that) => {
+ that.appendLogs("开始发送功能 " + title ,that);
+ that.setData({
+ isRund:true
+ })
+ isSend = true;
+ while(isSend){
+ for(var x in sendlist){
+ if(sendlist[x].opertype == "DE"){
+ await sleep(sendlist[x].value,that);
+ } else if(sendlist[x].opertype == "SEND"){
+ let result = await sendBleMsg(sendlist[x].value,that);
+ if(!result){
+ stop(that);
+ return;
+ }
+ }
+ }
+ if(that.data.ismenuRund){
+ isSend = true;
+ } else {
+ isSend = false;
+ }
+ }
+
+ that.setData({
+ isRund:false
+ })
+ that.appendLogs("功能 " + title + "发送完毕",that);
+
+}
+
+
+var stop = function(that){
+ isSend = false;
+ if(that){
+ that.setData({
+ isRund:false
+ })
+ that.appendLogs("停止发送",that);
+ }
+}
+
+module.exports = {
+ sendList: sendList,
+ stop,
+ sendCoustomList
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/index/index.js b/src/wechat_app/pages/index/index.js
new file mode 100644
index 0000000..5e819fe
--- /dev/null
+++ b/src/wechat_app/pages/index/index.js
@@ -0,0 +1,485 @@
+// pages/uploadimg/uploadimg.js
+const app = getApp();
+var util = require("../../utils/util.js");
+var handler = require("handler.js");
+var timer = {};
+var menuToCmd = {};
+Page({
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ imgswiperset: { //swiper信息设置
+ indicator_dots: false, //是否显示面板指示点
+ autoplay: false, //是否自动切换
+ interval: 10000, //自动切换时间间隔
+ duration: 200, //滑动动画时长
+ indicator_color: '#b0b0b0', //指示点颜色
+ indicator_active_color: 'rgb(19, 157, 236)', //当前选中的指示点颜色
+ circular: false, //是否采用衔接滑
+ },
+ msg:"",
+ isShowDialog: false, //是否显示弹窗
+ statusinfo: {
+ status: '未连接(点击切换蓝牙)',
+ },
+ write_id:"--",
+ notifty_id:"--",
+ title:"选择服务",
+ logs:[],
+ sendtimes:0,
+ servicelist:[],
+ lastindex:"item0",
+ ismenuRund:false,//是否循环发送
+ customMen:[],//自定义控制菜单
+ isRund:false,//是否正在循环发送消息
+ menu:[
+ {
+ value:"",
+ issel:false,
+ },
+ {
+ value:"",
+ issel:false,
+ },
+ {
+ value:"",
+ issel:false,
+ },
+ {
+ value:"",
+ issel:false,
+ },
+ ]
+ },
+
+ /**
+ * 生命周期函数--监听页面加载
+ */
+ onLoad: function(options) {
+ if(app.globalData.selble.deviceId){
+ wx.setNavigationBarTitle({
+ title:(app.globalData.selble.name || "未知设备") + "(" + app.globalData.selble.deviceId + ")"
+ })
+ }
+ },
+
+ /**
+ * 生命周期函数--监听页面初次渲染完成
+ */
+ onReady: function() {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面显示
+ */
+ onShow: function() {
+ if (app.globalData.issel && app.globalData.bleUtil != "") {
+ var that = this;
+ that.data.statusinfo.status = '连接中';
+ app.globalData.issel = false;
+ appendLogs("连接设备中",that);
+ that.setData({
+ statusinfo: that.data.statusinfo
+ })
+ //连接蓝牙
+ app.globalData.bleUtil.connect(app.globalData.selble.deviceId, function(res) {
+ //连接回调
+ if (res.return_code == "0") {
+ that.data.statusinfo.status = '已连接';
+ appendLogs("连接设备成功",that);
+ that.setData({
+ statusinfo: that.data.statusinfo
+ })
+ } else {
+ that.data.statusinfo.status = '连接失败';
+ appendLogs("连接设备失败",that);
+ that.setData({
+ statusinfo: that.data.statusinfo
+ })
+ }
+ }, function(res) {
+ //接收到数据回调
+ console.log("接受到消息:" + res.value.strHexData);
+ appendLogs("接受到消息 " + res.value.strHexData,that);
+ });
+ }
+ getMenuList(this);
+ },
+
+ /**
+ * 生命周期函数--监听页面隐藏
+ */
+ onHide: function() {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面卸载
+ */
+ onUnload: function() {
+ this.selBle();
+ handler.stop();
+ },
+
+ /**
+ * 页面相关事件处理函数--监听用户下拉动作
+ */
+ onPullDownRefresh: function() {
+
+ },
+
+ /**
+ * 页面上拉触底事件的处理函数
+ */
+ onReachBottom: function() {
+
+ },
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function() {
+
+ },
+ menuCheckBocChange:function(res){
+ this.data.ismenuRund = res.detail.value;
+ },
+ gotoStop:function(res){
+ handler.stop(this);
+ },
+ doSendItem:function(res){
+
+ if (app.globalData.bleUtil == "") {
+ showHintModal("未连接设备");
+ appendLogs("未连接设备",this);
+ return;
+ }
+
+ if (this.data.write_id == '--') {
+ showHintModal("未选择可写服务");
+ appendLogs("未选择可写服务",this);
+ return;
+ }
+
+ var item = res.currentTarget.dataset.item;
+ var sendlist = getCMD(item);
+
+ if(!sendlist){
+ return;
+ }
+
+ handler.sendCoustomList(sendlist,item,this);
+
+ },
+ doClearData:function(res){
+ this.setData({
+ logs:[]
+ })
+ wx.showToast({
+ title: "清除成功",
+ icon:"none"
+ })
+ },
+ doRund:function(res){
+ if(this.data.isRund){
+ handler.stop(this);
+ return;
+ }
+ if (app.globalData.bleUtil == "") {
+ showHintModal("未连接设备");
+ appendLogs("未连接设备",this);
+ return;
+ }
+ if (!app.globalData.bleUtil.isCanWrite()) {
+ showHintModal("未选择可写服务");
+ appendLogs("未选择可写服务",this);
+ return;
+ }
+
+ var sendtimes = parseInt(this.data.sendtimes);
+
+ if(!sendtimes && sendtimes != 0){
+ showHintModal("循环发送间隔不正确");
+ appendLogs("循环发送间隔不正确",this);
+ return;
+ }
+
+ var that = this;
+
+ var menu = that.data.menu;
+ var sendlist = [];
+
+ for(var x in menu){
+ if(menu[x].value && menu[x].issel){
+ sendlist.push(menu[x].value);
+ }
+ }
+ if(sendlist.length == 0){
+ showHintModal("需循环发送的内容为空");
+ appendLogs("需循环发送的内容为空",this);
+ return;
+ }
+
+
+ appendLogs("开始循环发送",this);
+
+ this.setData({
+ isRund:true
+ })
+
+ handler.sendList(sendlist,sendtimes,that);
+
+
+ },
+ doGetSendTimes:function(res){
+ this.data.sendtimes = res.detail.value;
+ },
+ selBle: function(res) {
+ var that = this;
+ that.data.statusinfo.status = '已断开连接';
+ that.setData({
+ statusinfo:that.data.statusinfo
+ })
+ if (!app.globalData.bleUtil && app.globalData.bleUtil != "") {
+ app.globalData.bleUtil.disconnect(function(res) {});
+ }
+ appendLogs("断开当前连接",this);
+ },
+ doSend:function(res){
+ if (app.globalData.bleUtil == "") {
+ showHintModal("未连接设备");
+ appendLogs("未连接设备",this);
+ return;
+ }
+ var msg = res.detail.value.msg;
+
+ sendBleMsg(msg,this);
+ },
+ doSendValue:function(res){
+ if (app.globalData.bleUtil == "") {
+ showHintModal("未连接设备");
+ appendLogs("未连接设备",this);
+ return;
+ }
+ if (!app.globalData.bleUtil.isCanWrite()) {
+ showHintModal("未选择可写服务");
+ appendLogs("未选择可写服务",this);
+ return;
+ }
+ var index = res.currentTarget.dataset.index;
+ var menu = this.data.menu;
+ if (!menu[index].value) {
+ showHintModal("不能发送空值");
+ appendLogs("不能发送空值",this);
+ return;
+ }
+ sendBleMsg(menu[index].value,this);
+ },
+ doShowSelService:function(res){
+ var type = res.currentTarget.dataset.type;
+ if(!app.globalData.bleUtil || !app.globalData.bleUtil.getdevConStatus()){
+ showHintModal("未连接成功,请先连接成功再试");
+ return;
+ }
+ var servicelist = app.globalData.bleUtil.getServiceList();
+ if(!servicelist){
+ showHintModal("未成功获取服务,或服务不存在");
+ return;
+ }
+ var title = type == "write"?"选择可写服务":"选择可读/通知服务";
+ this.setData({
+ type,
+ isShowDialog:true,
+ title,
+ servicelist
+ })
+ },
+ /**
+ * 隐藏显示
+ */
+ doHidenDiaolog: function (res) {
+ this.setData({
+ isShowDialog:false
+ })
+ },
+ donothing: function (res) {
+
+ },
+ changeOpen:function(res){
+ var index = res.currentTarget.dataset.index;
+ var servicelist = this.data.servicelist;
+ servicelist[index].open = !servicelist[index].open;
+ this.setData({
+ servicelist
+ })
+ },
+ doShowMenu:function(res){
+ var item = res.currentTarget.dataset.item;
+ var index = res.currentTarget.dataset.index;
+ wx.showActionSheet({
+ itemList: ["编辑","删除"],
+ success:function(res) {
+ switch(res.tapIndex){
+ case 0:{
+ wx.navigateTo({
+ url: '../addsendbtn/addsendbtn?title=' + item ,
+ })
+ }
+ break;
+ case 1:{
+ wx.showModal({
+ content:"确认删除按钮 " + item + ",删除后不可恢复",
+ success:function(res) {
+ if(res.confirm){
+ app.globalData.menu.splice(index,1);
+ wx.setStorageSync("menulist", app.globalData.menu);
+ that.setData({
+ customMen:app.globalData.menu
+ })
+ }
+ }
+ })
+ }
+ break;
+ }
+ }
+ })
+ },
+ doSelUuid:function(res){
+ var item = res.currentTarget.dataset.item;
+ var each = res.currentTarget.dataset.each;
+ if(this.data.type == "write" && each.properties.write){
+ app.globalData.bleUtil.setWriteUUID(item.uuid,each.uuid);
+ wx.showToast({
+ title: '设置成功',
+ icon:"none"
+ })
+ this.setData({
+ isShowDialog:false,
+ write_id:each.uuid
+ })
+ } else if (this.data.type == "reno" && (each.properties.read || each.properties.notify)){
+ if(each.properties.notify){
+ app.globalData.bleUtil.setNotiftyUUID(item.uuid,each.uuid);
+ } else if(each.properties.read){
+ app.globalData.bleUtil.setReadUUID(item.uuid,each.uuid);
+ }
+ wx.showToast({
+ title: '设置成功',
+ icon:"none"
+ })
+ this.setData({
+ isShowDialog:false,
+ notifty_id:each.uuid
+ })
+ } else {
+ var hint = this.data.type == "write"?"当前服务不可写":"当前服务不可读且不可通知";
+ showHintModal(hint);
+ }
+ },
+ doGetInput:function(res){
+ var index = res.currentTarget.dataset.index;
+ var menu = this.data.menu;
+ menu[index].value = res.detail.value;
+ },
+ checkboxChange:function(res){
+ console.log(res);
+ const index = res.detail.value;
+ var menu = this.data.menu;
+ for(var x in menu){
+ menu[x].issel = false;
+ }
+ for(var j in index){
+ menu[index[j]].issel = true;
+ }
+ },
+ doReadValue:function(res){
+ if (app.globalData.bleUtil == "") {
+ showHintModal("未连接设备");
+ appendLogs("未连接设备",this);
+ return;
+ }
+ if (!app.globalData.bleUtil.isCanRead() && !app.globalData.bleUtil.isCanNotifty()) {
+ showHintModal("未选择可写服务");
+ appendLogs("未选择可写服务",this);
+ return;
+ }
+ app.globalData.bleUtil.doRead();
+ appendLogs("成功读取",this);
+ },
+ gotoAddSendBtn:function(res){
+ wx.navigateTo({
+ url: '../addsendbtn/addsendbtn',
+ })
+ },
+ appendLogs,
+})
+
+function appendLogs(info,that){
+ var logs = that.data.logs;
+ var date = new Date();
+ var nowtime = util.formatTime(date);
+ info = "【" + nowtime + "】" + info;
+ if(logs.length > 1000){
+ logs.shift();
+ }
+ logs.push(info);
+ that.setData({
+ logs,
+ lastindex:"item" + (logs.length - 1)
+ })
+}
+
+function showHintModal(msg) {
+ wx.showModal({
+ title: '提示',
+ content: msg,
+ showCancel: false,
+ confirmText: "我知道了"
+ })
+}
+
+function sendBleMsg(msg,that) {
+ appendLogs("发送数据 " + msg + " 中",that);
+ app.globalData.bleUtil.sendMsg(msg, function(res) {
+ if (res.errCode == 0) {
+ appendLogs("发送数据 " + msg + " 成功",that);
+ return false;
+ } else {
+ appendLogs("发送数据 " + msg + " 失败," + res.msg,that);
+ return true;
+ }
+ }, false);
+}
+
+function getMenuList(that){
+ if(app.globalData.menu){
+ that.setData({
+ customMen:app.globalData.menu
+ })
+ return;
+ }
+ let menulist = wx.getStorageSync('menulist');
+ if(!menulist){
+ menulist = [];
+ }
+ app.globalData.menu = menulist;
+ that.setData({
+ customMen:menulist
+ })
+}
+
+function getCMD(title){
+ if(menuToCmd[title]){
+ return menuToCmd[title];
+ }
+ let send = wx.getStorageSync(title);
+ if(!send){
+ util.showHintModal("不存在该条指令");
+ return;
+ }
+ menuToCmd[title] = send;
+ return send;
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/index/index.json b/src/wechat_app/pages/index/index.json
new file mode 100644
index 0000000..8835af0
--- /dev/null
+++ b/src/wechat_app/pages/index/index.json
@@ -0,0 +1,3 @@
+{
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/index/index.wxml b/src/wechat_app/pages/index/index.wxml
new file mode 100644
index 0000000..50aa418
--- /dev/null
+++ b/src/wechat_app/pages/index/index.wxml
@@ -0,0 +1,95 @@
+
+
+
+
+
+ {{title}}
+
+
+
+
+
+ {{item.uuid}}
+ ▼
+ ▲
+
+
+ {{each.uuid}}
+
+ {{each.properties.notify?"可通知/":""}}
+ {{each.properties.write?"可写/":""}}
+ {{each.properties.read?"可读/":""}}
+
+
+
+
+
+
+
+
+
+
+ {{statusinfo.status}}
+
+
+
+
+
+
+
+
+
+
+ 当前写服务:{{write_id}}
+ 当前读/通知服务:{{notifty_id}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示:左滑可进入自定义功能区
+
+
+
+
+ 自定义功能区
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示:右滑可返回发送区,长按可编辑或删除
+
+
+
+
+
+
+
+
+
+
+ {{item}}
+
+
+
+
\ No newline at end of file
diff --git a/src/wechat_app/pages/index/index.wxss b/src/wechat_app/pages/index/index.wxss
new file mode 100644
index 0000000..1f171fd
--- /dev/null
+++ b/src/wechat_app/pages/index/index.wxss
@@ -0,0 +1,242 @@
+/* pages/uploadimg/uploadimg.wxss */
+.main_view_back {
+ width: 100vw;
+}
+
+.item_view_back {
+ width: 90vw;
+ margin-left: 5vw;
+ margin-top: 1vw;
+
+}
+
+.item_img {
+ width: 5vw;
+ height: 5vw;
+}
+
+.item_title_name {
+ color: #000;
+ font-size: 90%;
+}
+
+.item_title {
+ width: 100%;
+ margin-top: 2vw;
+}
+
+.img_back_class {
+ width: 100%;
+ height: 81%;
+ margin-top: 2vw;
+}
+
+.img_size {
+ width: 50vw;
+ height: 50vw;
+ border-radius: 50%;
+}
+
+.border_blue {
+ border: 1px dashed rgba(0, 120, 253, 1);
+}
+
+.border_white {
+ border: 1px dashed white;
+}
+
+.small_img_size {
+ width: 5vw;
+ height: 5vw;
+}
+
+.blue_text {
+ color: #1A8DFF;
+ font-size: 90%;
+}
+
+.btn_disable {
+ width: 90%;
+ margin-left: 5%;
+ color: white;
+ font-size: 80%;
+ background: linear-gradient(180deg, rgba(189, 189, 189, 1) 0%, rgba(102, 102, 102, 1) 100%, rgba(204, 204, 204, 1) 100%);
+ border-radius: 10px;
+}
+
+.btn_normal {
+ width: 92%;
+ font-size: 80%;
+ color: white;
+ background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(255, 112, 191, 1) 0%, rgba(69, 178, 255, 1) 0%, rgba(0, 126, 255, 1) 100%);
+ border-radius: 10px;
+}
+
+.btn_normal:active {
+ width: 92%;
+ font-size: 80%;
+ color: white;
+ background: rgba(0, 126, 255, 1);
+ border-radius: 10px;
+}
+
+.item_title_back_class {
+ width: 87%;
+ margin-left: 5%;
+}
+
+.selimg_list {
+ width: 94vw;
+ margin: 3vw 0;
+}
+
+.sma_img_size {
+ width: 15vw;
+ height: 15vw;
+ margin-left: 3vw;
+ border-radius: 50%;
+}
+
+.btn_class,
+.btn_class:active {
+ width: 90vw;
+ margin-top: 10px;
+ margin-left: 5vw;
+ font-size: 90%;
+ color: #fff;
+ border-radius: 10px;
+}
+
+.btn_class {
+ background: rgb(51, 225, 231);
+}
+
+.btn_class:active {
+ background: rgb(51, 225, 231);
+}
+
+.send_back {
+ width: 84vw;
+ margin-left: 5vw;
+ margin-top: 3vw;
+ background: #FFF;
+ padding: 3vw;
+ border-radius: 5px;
+}
+
+
+
+.dialog_close {
+ font-size: 100%;
+ width: 100vw;
+ height: 15vw;
+ font-family: PingFangSC-Medium;
+ font-weight: 500;
+ background: #fff;
+ text-align: center;
+ color: rgba(0, 0, 0, 1);
+ box-shadow:0px -2px 5px 0px rgba(0, 0, 0, 0.1);
+}
+
+.dialog_top {
+ width: 80%;
+ padding: 3% 10%;
+ background: rgba(248, 248, 248, 1);
+ box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.1);
+}
+
+.dialog_devname {
+ font-size: 110%;
+ font-family: PingFangSC-Heavy;
+ font-weight: 800;
+ color: rgba(0, 0, 0, 1);
+}
+
+.dialog_mac {
+ font-size: 90%;
+ margin-top: 2%;
+ font-family: PingFangSC-Medium;
+ font-weight: 500;
+ color: rgba(0, 0, 0, 1);
+}
+
+.dialog_menu {
+ padding: 5%;
+ width: 90%;
+ background: #fff;
+ box-shadow:0px -2px 5px 0px rgba(0, 0, 0, 0.1);
+}
+
+.dialog_red_text, .dialog_green_text {
+ font-size: 80%;
+ font-family: PingFangSC-Medium;
+ font-weight: 500;
+ border-radius: 5px;
+ color: #fff;
+ padding: 1px 2%;
+ max-height: 6vw;
+ min-width: 16vw;
+}
+
+
+.dialog_red_text {
+ background: rgba(238, 68, 42, 1);
+}
+
+.dialog_green_text {
+ background: rgba(33, 167, 130, 1);
+}
+
+.small_text{
+ font-size: 100%;
+ color: #000;
+}
+
+.dialog_view_back{
+ width: 100vw;
+ height: 100vh;
+ top: 0;
+ position: fixed;
+ z-index: 2;
+ background: rgba(0, 0, 0, 0.8);
+}
+
+.dialog_cneter_view{
+ width: 80vw;
+ background: #fff;
+ border-radius: 10px;
+}
+
+.dialog_title_view{
+ width: 100%;
+ padding: 3% 0%;
+ background: linear-gradient(0deg, rgb(19, 138, 207) 0%, rgb(46, 164, 231) 100%);
+ border-radius: 10px 10px 0 0;
+ color: #fff;
+ font-size: 90%;
+}
+
+.dialog_content_view{
+ width: 90%;
+ padding: 5%;
+ height: 50vh;
+ color: #000;
+ font-size: 80%;
+}
+
+.dialog_text{
+ font-size:90%;
+ color:#000;
+}
+
+::-webkit-scrollbar {
+ display: none;
+ width: 0;
+ height: 0;
+ color: transparent;
+}
+
+.swiper_class{
+ width: 100vw;
+ height: 60vh;
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/logs/logs.js b/src/wechat_app/pages/logs/logs.js
new file mode 100644
index 0000000..85f6aac
--- /dev/null
+++ b/src/wechat_app/pages/logs/logs.js
@@ -0,0 +1,18 @@
+// logs.js
+const util = require('../../utils/util.js')
+
+Page({
+ data: {
+ logs: []
+ },
+ onLoad() {
+ this.setData({
+ logs: (wx.getStorageSync('logs') || []).map(log => {
+ return {
+ date: util.formatTime(new Date(log)),
+ timeStamp: log
+ }
+ })
+ })
+ }
+})
diff --git a/src/wechat_app/pages/logs/logs.json b/src/wechat_app/pages/logs/logs.json
new file mode 100644
index 0000000..3ee76c1
--- /dev/null
+++ b/src/wechat_app/pages/logs/logs.json
@@ -0,0 +1,4 @@
+{
+ "navigationBarTitleText": "查看启动日志",
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/logs/logs.wxml b/src/wechat_app/pages/logs/logs.wxml
new file mode 100644
index 0000000..0b6b645
--- /dev/null
+++ b/src/wechat_app/pages/logs/logs.wxml
@@ -0,0 +1,6 @@
+
+
+
+ {{index + 1}}. {{log.date}}
+
+
diff --git a/src/wechat_app/pages/logs/logs.wxss b/src/wechat_app/pages/logs/logs.wxss
new file mode 100644
index 0000000..94d4b88
--- /dev/null
+++ b/src/wechat_app/pages/logs/logs.wxss
@@ -0,0 +1,8 @@
+.log-list {
+ display: flex;
+ flex-direction: column;
+ padding: 40rpx;
+}
+.log-item {
+ margin: 10rpx;
+}
diff --git a/src/wechat_app/pages/selble/selble.js b/src/wechat_app/pages/selble/selble.js
new file mode 100644
index 0000000..37b369b
--- /dev/null
+++ b/src/wechat_app/pages/selble/selble.js
@@ -0,0 +1,212 @@
+// pages/selble/selble.js
+var Bletool = require("../../utils/bletool.js");
+// var util = require("../../utils/util.js");
+const app = getApp();
+var bleUtil;
+Page({
+
+ /**
+ * 页面的初始数据
+ */
+ data: {
+ getDevList: {}, //已扫描到设备列表
+ deviceslist: [
+
+ ], //蓝牙数据
+ devicename: 0,
+ repdata: "",
+ hint: "",
+ selmac:''
+ },
+
+ /**
+ * 生命周期函数--监听页面加载
+ */
+ onLoad: function (options) {
+ var that = this;
+ that.data.getDevList = {};
+ app.globalData.issel = false;
+ if (app.globalData.bleUtil == ""){
+ bleUtil = new Bletool();
+ app.globalData.bleUtil = bleUtil;
+ bleUtil.initble(function (res) {
+ console.log(res);
+ if (res.return_code == "0") {
+ setTimeout(function (res) {
+ //开始蓝牙扫描 10秒后停止扫描
+ wx.showNavigationBarLoading();
+ bleUtil.startScanle(function (res) {
+ //获取设备回调
+ console.log(res);
+ if (!that.data.getDevList[res.devices[0].deviceId]) {
+ var devices = that.data.deviceslist;
+ devices.push(res.devices[0]);
+ that.data.getDevList[res.devices[0].deviceId] = devices.length;
+ that.setData({
+ deviceslist: devices
+ });
+ } else {
+ var devices = that.data.deviceslist;
+ var index = that.data.getDevList[res.devices[0].deviceId] - 1;
+ devices[index].RSSI = res.devices[0].RSSI;
+ that.setData({
+ deviceslist: devices
+ });
+ }
+ }, function (res) {
+ if (res.msg == "扫描结束") {
+ //扫描结束
+ wx.hideNavigationBarLoading()
+ }
+ }, 10000, true);
+ }, 1000);
+ } else {
+ bleUtil = undefined;
+ app.globalData.bleUtil = "";
+ wx.showModal({
+ title: '提示',
+ content: '蓝牙初始化失败,请检查是否已打开蓝牙',
+ showCancel: false,
+ confirmText: "我知道了",
+ success:function(Res){
+ wx.navigateBack({
+ complete: (res) => {
+
+ },
+ })
+ }
+ })
+ }
+ }, function (res) {
+ console.log(res);
+
+ }, function (res) {
+ console.log(res);
+ });
+ } else {
+ bleUtil = app.globalData.bleUtil;
+ that.refresh();
+ app.globalData.bleUtil.disconnect(function (res) {
+ console.log(res);
+ });
+ }
+ },
+
+ /**
+ * 生命周期函数--监听页面初次渲染完成
+ */
+ onReady: function () {
+
+
+ },
+
+ /**
+ * 生命周期函数--监听页面显示
+ */
+ onShow: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面隐藏
+ */
+ onHide: function () {
+
+ },
+
+ /**
+ * 生命周期函数--监听页面卸载
+ */
+ onUnload: function () {
+ if (bleUtil) {
+ bleUtil.stopScanle();
+ }
+ if (app.globalData.bleUtil != "") {
+ app.globalData.bleUtil.close(function(res) {
+ console.log(res);
+ app.globalData.bleUtil = "";
+ });
+ }
+ },
+
+ /**
+ * 页面相关事件处理函数--监听用户下拉动作
+ */
+ onPullDownRefresh: function () {
+ this.refresh();
+ },
+
+ /**
+ * 页面上拉触底事件的处理函数
+ */
+ onReachBottom: function () {
+
+ },
+
+ /**
+ * 用户点击右上角分享
+ */
+ onShareAppMessage: function () {
+
+ },
+ selItem: function (res) {
+ var that = this;
+ var item = res.currentTarget.dataset.item;
+ app.globalData.selble = item;
+ that.setData({
+ selmac: item.deviceId
+ })
+ },
+ doback:function(res){
+ app.globalData.issel = true;
+ bleUtil.stopScanle();
+ wx.navigateTo({
+ url: '../index/index',
+ })
+ },
+ refresh:function(res){
+ var that = this;
+ if (bleUtil) {
+ wx.showNavigationBarLoading();
+ bleUtil.startScanle(function (res) {
+ //获取设备回调
+ console.log(res);
+ if (!that.data.getDevList[res.devices[0].deviceId]) {
+ var devices = that.data.deviceslist;
+ devices.push(res.devices[0]);
+ that.data.getDevList[res.devices[0].deviceId] = devices.length;
+ that.setData({
+ deviceslist: devices
+ });
+ } else {
+ var devices = that.data.deviceslist;
+ var index = that.data.getDevList[res.devices[0].deviceId] - 1;
+ devices[index].RSSI = res.devices[0].RSSI;
+ that.setData({
+ deviceslist: devices
+ });
+ }
+ }, function (res) {
+ if (res.return_code == 1) {
+ showHintModal("正在扫描中,请勿重复操作");
+ }
+ if (res.msg == "扫描结束") {
+ //扫描结束
+ wx.hideNavigationBarLoading()
+ }
+ }, 10000, true);
+ } else {
+ showHintModal("蓝牙未打开,请打开蓝牙后,重新打开该页面");
+ }
+ }
+})
+
+function showHintModal(msg) {
+ wx.showModal({
+ title: '提示',
+ content: msg,
+ showCancel: false,
+ confirmText: "我知道了",
+ success: function (res) { }
+ })
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/selble/selble.json b/src/wechat_app/pages/selble/selble.json
new file mode 100644
index 0000000..25481c5
--- /dev/null
+++ b/src/wechat_app/pages/selble/selble.json
@@ -0,0 +1,4 @@
+{
+ "usingComponents": {},
+ "navigationBarTitleText": "选择设备"
+}
\ No newline at end of file
diff --git a/src/wechat_app/pages/selble/selble.wxml b/src/wechat_app/pages/selble/selble.wxml
new file mode 100644
index 0000000..734a522
--- /dev/null
+++ b/src/wechat_app/pages/selble/selble.wxml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ {{item.name || "未知设备"}}({{item.deviceId}})
+
+
+
+
+
+ 信号值:{{item.RSSI || "0"}}
+
+
+ 广播包数据:{{item.advertisData || ""}}
+
+
+
+
+
+ 刷新
+
+
+
+
+
\ No newline at end of file
diff --git a/src/wechat_app/pages/selble/selble.wxss b/src/wechat_app/pages/selble/selble.wxss
new file mode 100644
index 0000000..94a9fd8
--- /dev/null
+++ b/src/wechat_app/pages/selble/selble.wxss
@@ -0,0 +1,43 @@
+/* pages/selble/selble.wxss */
+.item_class{
+ width: 94vw;
+ padding: 3vw 3vw 0vw 3vw;
+ background: #fff;
+}
+.ble_img{
+ width: 7vw;
+ height: 7vw;
+}
+.item_name_text{
+ margin-left: 5px;
+ font-size:90%;
+ font-family:PingFangSC-Medium;
+ font-weight:500;
+ color:rgba(51,51,51,1);
+}
+.item_sel_img{
+ width: 5vw;
+ height: 5vw;
+}
+.line{
+ margin-top:3vw;
+ width: 100%;
+ height: 1px;
+ background: #E4E4E4;
+
+}
+.bottom_fix_show{
+ width:90vw;
+ padding: 4vw 5vw;
+ position: fixed;
+ bottom: 0;
+ background: #fff;
+}
+.bottom_text{
+ display: flex;
+ font-size:90%;
+ font-family:PingFangSC-Medium;
+ font-weight:500;
+ color:rgba(12,135,255,1);
+}
+
diff --git a/src/wechat_app/project.config.json b/src/wechat_app/project.config.json
new file mode 100644
index 0000000..4ef61f8
--- /dev/null
+++ b/src/wechat_app/project.config.json
@@ -0,0 +1,52 @@
+{
+ "description": "项目配置文件",
+ "packOptions": {
+ "ignore": [],
+ "include": []
+ },
+ "setting": {
+ "bundle": false,
+ "userConfirmedBundleSwitch": false,
+ "urlCheck": true,
+ "scopeDataCheck": false,
+ "coverView": true,
+ "es6": true,
+ "postcss": true,
+ "compileHotReLoad": false,
+ "lazyloadPlaceholderEnable": false,
+ "preloadBackgroundData": false,
+ "minified": true,
+ "autoAudits": false,
+ "newFeature": false,
+ "uglifyFileName": false,
+ "uploadWithSourceMap": true,
+ "useIsolateContext": true,
+ "nodeModules": false,
+ "enhance": true,
+ "useMultiFrameRuntime": true,
+ "useApiHook": true,
+ "useApiHostProcess": true,
+ "showShadowRootInWxmlPanel": true,
+ "packNpmManually": false,
+ "enableEngineNative": false,
+ "packNpmRelationList": [],
+ "minifyWXSS": true,
+ "showES6CompileOption": false,
+ "minifyWXML": true,
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ }
+ },
+ "compileType": "miniprogram",
+ "libVersion": "2.19.4",
+ "appid": "wx08af813924f7522e",
+ "projectname": "miniprogram-92",
+ "condition": {},
+ "editorSetting": {
+ "tabIndent": "insertSpaces",
+ "tabSize": 2
+ },
+ "simulatorPluginLibVersion": {}
+}
\ No newline at end of file
diff --git a/src/wechat_app/project.private.config.json b/src/wechat_app/project.private.config.json
new file mode 100644
index 0000000..2f44481
--- /dev/null
+++ b/src/wechat_app/project.private.config.json
@@ -0,0 +1,7 @@
+{
+ "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+ "projectname": "imuviz",
+ "setting": {
+ "compileHotReLoad": true
+ }
+}
\ No newline at end of file
diff --git a/src/wechat_app/sitemap.json b/src/wechat_app/sitemap.json
new file mode 100644
index 0000000..ca02add
--- /dev/null
+++ b/src/wechat_app/sitemap.json
@@ -0,0 +1,7 @@
+{
+ "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+ "rules": [{
+ "action": "allow",
+ "page": "*"
+ }]
+}
\ No newline at end of file
diff --git a/src/wechat_app/utils/bletool.js b/src/wechat_app/utils/bletool.js
new file mode 100644
index 0000000..ded6652
--- /dev/null
+++ b/src/wechat_app/utils/bletool.js
@@ -0,0 +1,560 @@
+/**
+ * 蓝牙集成 插件
+ * 2020-06-10 灵
+ * 梦辛工作室
+ * v1.0.3
+ */
+
+var Until = {
+ getBleService() {
+ wx.getBLEDeviceServices({
+ deviceId: data.connectedDeviceId,
+ success: function (res) {
+ for (var i = 0; i < res.services.length; i++) {
+ console.log("service:" + res.services[i].uuid);
+ getChar(res.services[i]);
+ }
+ }
+ })
+ },
+}
+
+var data = {
+ uuid: "FFF0", //FFE0
+ status: 0, //可用状态 1 - 可用 0 - 不可用
+ sousuo: 0, //搜索状态 1 - 搜索中 0 - 为搜索
+ connectedDeviceId: "", //已连接设备uuid
+ serviceslist: [],
+ services: "", // 连接设备的服务
+ characteristics: "", // 连接设备的状态值
+ writeServicweId: "", // 可写服务uuid
+ writeCharacteristicsId: "", //可写特征值uuid
+ readServicweId: "", // 可读服务uuid
+ readCharacteristicsId: "", //可读特征值uuid
+ notifyServicweId: "", //通知服务UUid
+ notifyCharacteristicsId: "", //通知特征值UUID
+ inputValue: "",
+ characteristics1: "", // 连接设备的状态值
+ isOpenadatper: false, //是否初始化蓝牙适配器
+ connectStatus: false, //连接状态
+ onNotifyChange:{},
+
+ mTimeOut: {} //扫描Timeout对象
+}
+
+function ab2hex(buffer) {
+ var hexArr = Array.prototype.map.call(
+ new Uint8Array(buffer),
+ function (bit) {
+ return ('00' + bit.toString(16)).slice(-2)
+ }
+ )
+ return hexArr.join(' ');
+}
+
+function hex2str(str) {
+ var len = str.length / 2;
+ var result = "";
+ for (var i = 0; i < len; i++) {
+ let data = str.substring(i * 2, i * 2 + 2);
+ result += String.fromCharCode(parseInt(data, 16));
+ }
+ return result;
+}
+
+function strToHexCharCode(str) {
+ if (str === "")
+ return "";
+ var hexCharCode = [];
+ hexCharCode.push("0x");
+ for (var i = 0; i < str.length; i++) {
+ hexCharCode.push((str.charCodeAt(i)).toString(16));
+ }
+ return hexCharCode.join("");
+}
+
+function readNotify(re) {
+ if (!data.readServicweId && !data.readCharacteristicsId) {
+ re({
+ code: 1,
+ desc: "未选择读服务UUID和可读特征值UUID"
+ });
+ return;
+ }
+ // 必须在这里的回调才能获取
+ wx.onBLECharacteristicValueChange(function (res) {
+ console.log('characteristic value comed:', res);
+ let msg = ab2hex(res.value);
+ let str = hex2str(msg);
+ res.value.strHexData = msg;
+ res.value.strData = str;
+ re(res); //接受消息
+ })
+ wx.readBLECharacteristicValue({
+ deviceId: data.connectedDeviceId,
+ serviceId: data.readServicweId,
+ characteristicId: data.readCharacteristicsId,
+ success(res) {
+ console.log('readBLECharacteristicValue:', res.errCode)
+ }
+ })
+}
+
+function opennotify(re) {
+ if (!data.notifyServicweId && !data.notifyCharacteristicsId) {
+ re({
+ code: 1,
+ desc: "未选择服务UUID和特征值UUID"
+ });
+ return;
+ }
+ //开启通知
+ wx.notifyBLECharacteristicValueChange({
+ state: true,
+ deviceId: data.connectedDeviceId,
+ serviceId: data.notifyServicweId,
+ characteristicId: data.notifyCharacteristicsId,
+ success: function (res) {
+ console.log('notifyBLECharacteristicValueChange success', res.errMsg)
+
+ wx.onBLECharacteristicValueChange(function (res) {
+ let msg = ab2hex(res.value);
+ let str = hex2str(msg);
+ res.value.strHexData = msg;
+ res.value.strData = str;
+ console.log(res);
+ re(res); //接受消息
+ })
+ }
+ })
+}
+
+function getChar(services) {
+ services.characteristics = [];
+ //获取特征值
+ wx.getBLEDeviceCharacteristics({
+ deviceId: data.connectedDeviceId,
+ serviceId: services.uuid,
+ success: function (res) {
+ let notify_id, write_id, read_id;
+
+ for (let i = 0; i < res.characteristics.length; i++) {
+
+ let charc = res.characteristics[i];
+
+ if (charc.properties.notify && charc.uuid.indexOf(data.notifyCharacteristicsId) >= 0) {
+ notify_id = charc.uuid;
+ console.log("notify_id:" + notify_id);
+ }
+
+ if (charc.properties.write && charc.uuid.indexOf(data.writeCharacteristicsId) >= 0) {
+ write_id = charc.uuid;
+ console.log("write_id:" + write_id);
+ }
+
+ if (charc.properties.read && charc.uuid.indexOf(data.readCharacteristicsId) >= 0) {
+ read_id = charc.uuid;
+ console.log("read_id:" + read_id);
+ }
+
+ console.log("charc_uuid:" + charc.uuid);
+ services.characteristics.push(charc);
+
+ }
+
+ data.serviceslist.push(services);
+
+ // if (notify_id != null ) {
+ // data.notifyServicweId = services.uuid;
+ // data.notifyCharacteristicsId = notify_id;
+ // }
+ // if(write_id != null){
+ // data.writeServicweId = services.uuid;
+ // data.writeCharacteristicsId = write_id;
+ // }
+ // if(read_id != null){
+ // data.readServicweId = services.uuid;
+ // data.readCharacteristicsId = read_id;
+ // }
+ }
+ })
+}
+
+//蓝牙使用类
+class bletool {
+ /**
+ * 构造函数
+ *
+ * @param {Object} options 接口参数,key 为必选参数
+ */
+ constructor() {}
+ /**
+ * 设置uuid
+ */
+ setUUID(uuid) {
+ data.uuid = uuid;
+ }
+
+ setWriteUUID(serviceuuid, uuid) {
+ data.writeServicweId = serviceuuid;
+ data.writeCharacteristicsId = uuid;
+ }
+
+ isCanWrite(){
+ return (data.writeServicweId || false) && (data.writeCharacteristicsId || false);
+ }
+
+ setReadUUID(serviceuuid, uuid,callback) {
+ data.readServicweId = serviceuuid;
+ data.readCharacteristicsId = uuid;
+ if(callback){
+ data.onNotifyChange = callback;
+ }
+ readNotify(data.onNotifyChange);
+ }
+
+ isCanRead(){
+ return (data.readServicweId || false) && (data.readCharacteristicsId|| false);
+ }
+
+ setNotiftyUUID(serviceuuid, uuid,callback) {
+ data.notifyServicweId = serviceuuid;
+ data.notifyCharacteristicsId = uuid;
+ if(callback){
+ data.onNotifyChange = callback;
+ }
+ opennotify(data.onNotifyChange);
+ }
+
+ isCanNotifty(){
+ return (data.notifyServicweId || false) && (data.notifyCharacteristicsId|| false);
+ }
+
+ doRead(){
+ wx.readBLECharacteristicValue({
+ deviceId: data.connectedDeviceId,
+ serviceId: data.readServicweId,
+ characteristicId: data.readCharacteristicsId,
+ success(res) {
+ console.log('readBLECharacteristicValue:', res.errCode)
+ }
+ })
+ }
+
+ getServiceList() {
+ return data.serviceslist;
+ }
+ /**
+ * 获得蓝牙适配器状态
+ */
+ getAdapterStatus() {
+ return data.isOpenadatper;
+ }
+ /**
+ * 获得蓝牙连接状态
+ */
+ getdevConStatus() {
+ return data.connectStatus;
+ }
+ /**
+ * 初始化蓝牙
+ * @parameter chcb 蓝牙状态改变回调
+ * @parameter concb 蓝牙连接状态改变回调
+ * @parameter recb 初始化成功与否回调
+ */
+ initble(recb, chcb, concb) {
+ //打开适配器 判断是否支持蓝牙
+ var info = {
+ return_code: "1",
+ msg: ""
+ }
+ if (wx.openBluetoothAdapter) {
+ wx.openBluetoothAdapter({
+ success: function (res) {
+ /**
+ * 监听蓝牙适配器状态
+ */
+ data.isOpenadatper = true;
+ info.return_code = "0";
+ info.msg = "初始化成功!";
+ recb(info);
+ console.log(res);
+ wx.onBluetoothAdapterStateChange(
+ function (res) {
+ if (typeof chcb == "function") {
+ chcb(res);
+ }
+ data.sousuo = res.discovering ? 1 : 0,
+ data.status = res.available ? 1 : 0
+ }
+ );
+ /**
+ * 获取本机蓝牙适配器状态
+ */
+ wx.getBluetoothAdapterState({
+ success: function (res) {
+ data.sousuo = res.discovering ? 1 : 0,
+ data.status = res.available ? 1 : 0
+ }
+ });
+ /**
+ * 监听蓝牙状态状态
+ */
+ wx.onBLEConnectionStateChange(
+ function (res) {
+ concb(res);
+ data.connectedDeviceId = res.deviceId;
+ data.connectStatus = res.connected;
+ })
+ return true;
+ },
+ fail: function (res) {
+ info.return_code = "1";
+ info.msg = "初始化失败!";
+ recb(info);
+ data.isOpenadatper = false;
+
+ }
+ });
+ } else {
+ info.return_code = "1";
+ info.msg = "初始化失败!";
+ recb(info);
+ data.isOpenadatper = false;
+ }
+ }
+
+ /**
+ * 开始扫描
+ *@parameter getDevCb - 发现设备回调 endTime 扫描结束时间
+ *@return info{return_code:"0",msg:"",rep:{}}
+ *return_code 返回操作结果 msg - 返回操作信息 rep - 扫描到的蓝牙设备信息 infoFB- 返回操作信息 isduplica - 是否搜索重复设备
+ */
+ startScanle(getDevCb, infoFB, endTime, isduplica) {
+ var info = {
+ return_code: "1",
+ msg: "",
+ rep: {}
+ }
+ if (data.sousuo == 1) {
+ info.return_code = "1";
+ info.msg = "正在搜索中...";
+ infoFB(info);
+ } else {
+ wx.startBluetoothDevicesDiscovery({
+ allowDuplicatesKey: isduplica,
+ success: function (res) {
+ data.sousuo = 1;
+ info.return_code = "0";
+ info.msg = "搜索成功";
+ infoFB(info);
+ wx.onBluetoothDeviceFound(
+ function (res) {
+ if (typeof getDevCb == "function") {
+ res.devices[0].advertisData = ab2hex(res.devices[0].advertisData);
+ getDevCb(res);
+ }
+ })
+ },
+ fail:function(res){
+ data.sousuo = 0;
+ info.return_code = "0";
+ info.msg = "搜索失败";
+ info.res = res;
+ infoFB(info);
+ }
+ })
+ data.mTimeOut = setTimeout(function (res) {
+
+ wx.stopBluetoothDevicesDiscovery({
+ success: function (res) {
+ data.sousuo = 0;
+ info.return_code = "0";
+ info.msg = "扫描结束";
+ infoFB(info);
+ },
+ fail: function (res) {
+
+ }
+ })
+ }, endTime);
+ }
+ }
+ /**
+ * 停止扫描
+ * @return true - 成功 false - 失败
+ */
+ stopScanle() {
+ if (data.sousuo == 1) {
+ clearTimeout(data.mTimeOut);
+ }
+ wx.stopBluetoothDevicesDiscovery({
+ success: function (res) {
+ data.sousuo = 0;
+ },
+ fail: function (res) {}
+ })
+ }
+ /**
+ * 连接设备,连接超时时间3秒
+ * @parameter id - 设备id readCb - 设备接收数据回调 suceeF - 连接成功与否回调
+ * @return true - 成功 false - 失败
+ */
+ connect(id, suceeF, readCb) {
+ var info = {
+ return_code: "1",
+ msg: ""
+ }
+ if (data.connectStatus) {
+ info.return_code = "1";
+ info.msg = "当前已连接!";
+ suceeF(info);
+ } else {
+ wx.showLoading({
+ title: '连接蓝牙设备中...',
+ })
+ wx.createBLEConnection({
+ deviceId: id,
+ timeout: 10000,
+ success: function (res) {
+ wx.hideLoading();
+ data.connectStatus = true;
+ data.connectedDeviceId = id;
+ wx.showToast({
+ title: '连接成功',
+ icon: 'success',
+ duration: 1000
+ })
+ info.return_code = "0";
+ info.msg = "连接设备成功";
+ //获取服务
+ if (typeof readCb == "function") {
+ data.onNotifyChange = readCb;
+ Until.getBleService(readCb);
+ }
+ suceeF(info);
+ },
+ fail: function (res) {
+ wx.hideLoading()
+ wx.showToast({
+ title: '连接设备失败',
+ icon: 'none',
+ duration: 1000
+ })
+ info.return_code = "1";
+ info.msg = "连接设备失败";
+ console.log(res)
+ data.connectStatus = false;
+ suceeF(info);
+ }
+ })
+ wx.stopBluetoothDevicesDiscovery({
+ success: function (res) {
+ data.sousuo = 0;
+ console.log("停止蓝牙搜索")
+ console.log(res)
+ }
+ })
+ }
+ return info;
+ }
+ /**
+ *像蓝牙设备蓝牙发送数据
+ * msg - 发送的消息 sendab - 发送结果回调 ishex - 是否是hex字符串
+ */
+ sendMsg(msg, sendab, ishex) {
+ var info = {
+ errCode: "1",
+ msg: "发送失败!"
+ }
+ if (msg == "") {
+ sendab(info);
+ }
+ var hexs = "";
+ if (ishex) {
+ hexs = msg;
+ } else {
+ hexs = strToHexCharCode(msg);
+ }
+ var typedArray = new Uint8Array(hexs.match(/[\da-f]{2}/gi).map(function (h) {
+ return parseInt(h, 16);
+ }));
+ var buffer = typedArray.buffer;
+
+ if (!data.writeServicweId && !data.writeCharacteristicsId) {
+ sendab({
+ errCode: 1,
+ msg: "未选择可写服务UUID和可写特征值UUID"
+ });
+ return;
+ }
+ wx.writeBLECharacteristicValue({
+ deviceId: data.connectedDeviceId,
+ serviceId: data.writeServicweId,
+ characteristicId: data.writeCharacteristicsId,
+ value: buffer,
+ success: function (res) {
+ info.errCode = "0";
+ info.msg = "发送成功";
+ console.log(res);
+ if (typeof sendab == "function") {
+ sendab(info);
+ }
+ },
+ fail: function (res) {
+ console.log(res);
+ info.errCode = "1";
+ info.msg = "发送失败";
+ if (typeof sendab == "function") {
+ sendab(info);
+ }
+ }
+ })
+ return info;
+ }
+ /**
+ * 断开连接
+ *@return info{return_code:"0",msg:""} return_code 返回操作结果 msg - 返回操作信息
+ */
+ disconnect(infoFb) {
+ var info = {
+ return_code: "1",
+ msg: ""
+ }
+ if (data.connectStatus) {
+ wx.closeBLEConnection({
+ deviceId: data.connectedDeviceId,
+ success: function (res) {
+ data.connectStatus = false;
+ info.return_code = "0";
+ info.msg = "断开成功";
+ infoFb(info);
+ },
+ })
+ } else {
+ info.return_code = "1";
+ info.msg = "未连接任何设备";
+ infoFb(info);
+ }
+ }
+ /**
+ * 关闭适配器
+ */
+ close(infoFB) {
+ var info = {
+ return_code: "1",
+ msg: "关闭失败"
+ }
+ wx.closeBluetoothAdapter({
+ success: function (res) {
+ info.return_code = "0";
+ info.msg = "关闭成功!";
+ infoFB(info);
+ },
+ fail: function (res) {
+ infoFB(info);
+ }
+ })
+ }
+}
+module.exports = bletool;
\ No newline at end of file
diff --git a/src/wechat_app/utils/runtime.js b/src/wechat_app/utils/runtime.js
new file mode 100644
index 0000000..67da0bd
--- /dev/null
+++ b/src/wechat_app/utils/runtime.js
@@ -0,0 +1 @@
+!(function(global){"use strict";var Op=Object.prototype;var hasOwn=Op.hasOwnProperty;var undefined;var $Symbol=typeof Symbol==="function"?Symbol:{};var iteratorSymbol=$Symbol.iterator||"@@iterator";var asyncIteratorSymbol=$Symbol.asyncIterator||"@@asyncIterator";var toStringTagSymbol=$Symbol.toStringTag||"@@toStringTag";var inModule=typeof module==="object";var runtime=global.regeneratorRuntime;if(runtime){if(inModule){module.exports=runtime}return}runtime=global.regeneratorRuntime=inModule?module.exports:{};function wrap(innerFn,outerFn,self,tryLocsList){var protoGenerator=outerFn&&outerFn.prototype instanceof Generator?outerFn:Generator;var generator=Object.create(protoGenerator.prototype);var context=new Context(tryLocsList||[]);generator._invoke=makeInvokeMethod(innerFn,self,context);return generator}runtime.wrap=wrap;function tryCatch(fn,obj,arg){try{return{type:"normal",arg:fn.call(obj,arg)}}catch(err){return{type:"throw",arg:err}}}var GenStateSuspendedStart="suspendedStart";var GenStateSuspendedYield="suspendedYield";var GenStateExecuting="executing";var GenStateCompleted="completed";var ContinueSentinel={};function Generator(){}function GeneratorFunction(){}function GeneratorFunctionPrototype(){}var IteratorPrototype={};IteratorPrototype[iteratorSymbol]=function(){return this};var getProto=Object.getPrototypeOf;var NativeIteratorPrototype=getProto&&getProto(getProto(values([])));if(NativeIteratorPrototype&&NativeIteratorPrototype!==Op&&hasOwn.call(NativeIteratorPrototype,iteratorSymbol)){IteratorPrototype=NativeIteratorPrototype}var Gp=GeneratorFunctionPrototype.prototype=Generator.prototype=Object.create(IteratorPrototype);GeneratorFunction.prototype=Gp.constructor=GeneratorFunctionPrototype;GeneratorFunctionPrototype.constructor=GeneratorFunction;GeneratorFunctionPrototype[toStringTagSymbol]=GeneratorFunction.displayName="GeneratorFunction";function defineIteratorMethods(prototype){["next","throw","return"].forEach(function(method){prototype[method]=function(arg){return this._invoke(method,arg)}})}runtime.isGeneratorFunction=function(genFun){var ctor=typeof genFun==="function"&&genFun.constructor;return ctor?ctor===GeneratorFunction||(ctor.displayName||ctor.name)==="GeneratorFunction":false};runtime.mark=function(genFun){if(Object.setPrototypeOf){Object.setPrototypeOf(genFun,GeneratorFunctionPrototype)}else{genFun.__proto__=GeneratorFunctionPrototype;if(!(toStringTagSymbol in genFun)){genFun[toStringTagSymbol]="GeneratorFunction"}}genFun.prototype=Object.create(Gp);return genFun};runtime.awrap=function(arg){return{__await:arg}};function AsyncIterator(generator){function invoke(method,arg,resolve,reject){var record=tryCatch(generator[method],generator,arg);if(record.type==="throw"){reject(record.arg)}else{var result=record.arg;var value=result.value;if(value&&typeof value==="object"&&hasOwn.call(value,"__await")){return Promise.resolve(value.__await).then(function(value){invoke("next",value,resolve,reject)},function(err){invoke("throw",err,resolve,reject)})}return Promise.resolve(value).then(function(unwrapped){result.value=unwrapped;resolve(result)},reject)}}var previousPromise;function enqueue(method,arg){function callInvokeWithMethodAndArg(){return new Promise(function(resolve,reject){invoke(method,arg,resolve,reject)})}return previousPromise=previousPromise?previousPromise.then(callInvokeWithMethodAndArg,callInvokeWithMethodAndArg):callInvokeWithMethodAndArg()}this._invoke=enqueue}defineIteratorMethods(AsyncIterator.prototype);AsyncIterator.prototype[asyncIteratorSymbol]=function(){return this};runtime.AsyncIterator=AsyncIterator;runtime.async=function(innerFn,outerFn,self,tryLocsList){var iter=new AsyncIterator(wrap(innerFn,outerFn,self,tryLocsList));return runtime.isGeneratorFunction(outerFn)?iter:iter.next().then(function(result){return result.done?result.value:iter.next()})};function makeInvokeMethod(innerFn,self,context){var state=GenStateSuspendedStart;return function invoke(method,arg){if(state===GenStateExecuting){throw new Error("Generator is already running");}if(state===GenStateCompleted){if(method==="throw"){throw arg;}return doneResult()}context.method=method;context.arg=arg;while(true){var delegate=context.delegate;if(delegate){var delegateResult=maybeInvokeDelegate(delegate,context);if(delegateResult){if(delegateResult===ContinueSentinel)continue;return delegateResult}}if(context.method==="next"){context.sent=context._sent=context.arg}else if(context.method==="throw"){if(state===GenStateSuspendedStart){state=GenStateCompleted;throw context.arg;}context.dispatchException(context.arg)}else if(context.method==="return"){context.abrupt("return",context.arg)}state=GenStateExecuting;var record=tryCatch(innerFn,self,context);if(record.type==="normal"){state=context.done?GenStateCompleted:GenStateSuspendedYield;if(record.arg===ContinueSentinel){continue}return{value:record.arg,done:context.done}}else if(record.type==="throw"){state=GenStateCompleted;context.method="throw";context.arg=record.arg}}}}function maybeInvokeDelegate(delegate,context){var method=delegate.iterator[context.method];if(method===undefined){context.delegate=null;if(context.method==="throw"){if(delegate.iterator.return){context.method="return";context.arg=undefined;maybeInvokeDelegate(delegate,context);if(context.method==="throw"){return ContinueSentinel}}context.method="throw";context.arg=new TypeError("The iterator does not provide a 'throw' method")}return ContinueSentinel}var record=tryCatch(method,delegate.iterator,context.arg);if(record.type==="throw"){context.method="throw";context.arg=record.arg;context.delegate=null;return ContinueSentinel}var info=record.arg;if(!info){context.method="throw";context.arg=new TypeError("iterator result is not an object");context.delegate=null;return ContinueSentinel}if(info.done){context[delegate.resultName]=info.value;context.next=delegate.nextLoc;if(context.method!=="return"){context.method="next";context.arg=undefined}}else{return info}context.delegate=null;return ContinueSentinel}defineIteratorMethods(Gp);Gp[toStringTagSymbol]="Generator";Gp[iteratorSymbol]=function(){return this};Gp.toString=function(){return"[object Generator]"};function pushTryEntry(locs){var entry={tryLoc:locs[0]};if(1 in locs){entry.catchLoc=locs[1]}if(2 in locs){entry.finallyLoc=locs[2];entry.afterLoc=locs[3]}this.tryEntries.push(entry)}function resetTryEntry(entry){var record=entry.completion||{};record.type="normal";delete record.arg;entry.completion=record}function Context(tryLocsList){this.tryEntries=[{tryLoc:"root"}];tryLocsList.forEach(pushTryEntry,this);this.reset(true)}runtime.keys=function(object){var keys=[];for(var key in object){keys.push(key)}keys.reverse();return function next(){while(keys.length){var key=keys.pop();if(key in object){next.value=key;next.done=false;return next}}next.done=true;return next}};function values(iterable){if(iterable){var iteratorMethod=iterable[iteratorSymbol];if(iteratorMethod){return iteratorMethod.call(iterable)}if(typeof iterable.next==="function"){return iterable}if(!isNaN(iterable.length)){var i=-1,next=function next(){while(++i=0;--i){var entry=this.tryEntries[i];var record=entry.completion;if(entry.tryLoc==="root"){return handle("end")}if(entry.tryLoc<=this.prev){var hasCatch=hasOwn.call(entry,"catchLoc");var hasFinally=hasOwn.call(entry,"finallyLoc");if(hasCatch&&hasFinally){if(this.prev=0;--i){var entry=this.tryEntries[i];if(entry.tryLoc<=this.prev&&hasOwn.call(entry,"finallyLoc")&&this.prev=0;--i){var entry=this.tryEntries[i];if(entry.finallyLoc===finallyLoc){this.complete(entry.completion,entry.afterLoc);resetTryEntry(entry);return ContinueSentinel}}},"catch":function(tryLoc){for(var i=this.tryEntries.length-1;i>=0;--i){var entry=this.tryEntries[i];if(entry.tryLoc===tryLoc){var record=entry.completion;if(record.type==="throw"){var thrown=record.arg;resetTryEntry(entry)}return thrown;}}throw new Error("illegal catch attempt");},delegateYield:function(iterable,resultName,nextLoc){this.delegate={iterator:values(iterable),resultName:resultName,nextLoc:nextLoc};if(this.method==="next"){this.arg=undefined}return ContinueSentinel}}})((function(){return this})()||Function("return this")());
\ No newline at end of file
diff --git a/src/wechat_app/utils/util.js b/src/wechat_app/utils/util.js
new file mode 100644
index 0000000..764bc2c
--- /dev/null
+++ b/src/wechat_app/utils/util.js
@@ -0,0 +1,19 @@
+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
+}