柒零 1 yıl önce
ebeveyn
işleme
c0a08e71b2

+ 31 - 5
app.js

@@ -14,11 +14,10 @@ App({
         console.error('隐藏 TabBar 失败', err);
       }
     });
-    // 展示本地存储能力
-    // const logs = wx.getStorageSync('logs') || []
-    // logs.unshift(Date.now())
-    // wx.setStorageSync('logs', logs)
-    // this.globalData.selectedTabIndex = wx.getStorageSync("selectedTabIndex") || 0;
+
+    this.globalData.SystemInfo = wx.getDeviceInfo()
+    this.data.system = this.globalData.SystemInfo.platform;
+
 
     // 登录
     wx.login({
@@ -97,6 +96,33 @@ App({
   onShow() {
     wx.hideTabBar()
   },
+  onHide: function () {
+    wx.setStorageSync('userName', '');
+    wx.setStorageSync('isLogin', false);
+    wx.setStorageSync('deviceList', []);
+    wx.setStorageSync('doDevices', []);
+  },
+  buf2hex: function (buffer) {
+    return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('')
+  },
+  buf2string: function (buffer) {
+    var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
+    var str = ''
+    for (var i = 0; i < arr.length; i++) {
+      str += String.fromCharCode(arr[i])
+    }
+    return str
+  },
+  data: {
+    service_uuid: "0000FFF0-0000-1000-8000-00805F9B34FB",
+    characteristic_write_uuid: "0000FFF1-0000-1000-8000-00805F9B34FB",
+    characteristic_read_uuid: "0000FFF2-0000-1000-8000-00805F9B34FB",
+    name: "LZ-OTA",
+    md5Key: "",
+    system: 'ios',
+    userName: "",
+    isLogin: false
+  },
   globalData: {
     userInfo: null,
     selectedTabIndex: 0

+ 597 - 6
subpages/addMattresses/addMattresses.js

@@ -1,4 +1,10 @@
 // subpages/addMattresses/addMattresses.js
+
+const app = getApp();
+const util = require('../../utils/util.js');
+const timeOut = 20; //超时时间
+var timeId = "";
+var sequenceControl = 0;
 Page({
 
   /**
@@ -8,23 +14,47 @@ Page({
     showBluetoothList: false,
     showBluetoothConnected: false,//连接中
     isBluetoothConnected: false,//连接成功
-    bluetoothConnectedStep: 5,
+    bluetoothConnectedStep: 0,
     placeOfUse: "",
     usingHuman: "",
     sn: "",
-    wifi: "",
-    wifiPassWord: "",
+    ssid: "",
+    password: "",
     bluetoothSelectIndex: -1,
     activeIcon: "/subpages/images/ic_blue_radio_check.png",
     normalIcon: "/subpages/images/ic_blue_radio_uncheck.png",
-    bluetoothList: ['', ''],
+    deviceList: [],
+    deviceId: "",
+    deviceIds: [],
+    wifiInfo: null,
+    deviceId: "",
+    password: "",
+    notice: "",
     value: 90,
     gradientColor: {
       '0%': '#00CEB2',
       '50%': '#00C7FF',
       '100%': '#53DAFF',
     },
-    statusDefault: ['蓝牙连接...', '蓝牙连接成功', '成功获取设备信息', '发送配置信息...', '配置信息发送成功', '连接成功'],
+    statusDefault: ['蓝牙连接...', '蓝牙连接成功', '成功获取设备信息', '获取属性信息成功', '发送配置信息...', '配置信息发送成功', '连接成功'],
+    descFailList: ["蓝牙连接失败", "获取设备信息失败", "获取属性信息失败", "发送配置信息失败", "分配网络失败"],
+    failure: false,
+    value: 0,
+    desc: "设备连接...",
+    blueConnectNum: 0,
+    isChecksum: true,
+    isEncrypt: false,
+    flagEnd: false,
+    defaultData: 1,
+    ssidType: 2,
+    passwordType: 3,
+    meshIdType: 3,
+    deviceNo: 0,
+    uuid: "",
+    serviceId: "",
+    meshId: "",
+    processList: [],
+    result: [],
   },
   onClose() {
     this.setData({ showBluetoothList: false, showBluetoothConnected: false });
@@ -34,12 +64,571 @@ Page({
     this.setData({ bluetoothSelectIndex: index });
 
   },
+  commitData() { 
+    console.log(this.data.placeOfUse);
+    console.log(this.data.usingHuman);
+    console.log(this.data.deviceId);
+    console.log(this.data.ssid);
+    console.log(this.data.password);
+    this.checkSn(this.data.deviceId);
+   
+    
+  },
+  // 开启蓝牙
+  bindViewBlue: function () {
+    const that = this;
+    wx.closeBluetoothAdapter();
+    wx.openBluetoothAdapter({
+      success(res) {
+        //console.log(res);
+        that.getBluDevice()
+      },
+      fail(res) {
+        console.log(res);
+        wx.showToast({
+          icon:'none',
+          title: "请打开系统蓝牙"
+        });
+      }
+    })
+  },
+// 获取蓝牙设备列表
+  getBluDevice () {
+    var self = this;
+    //第一步检查蓝牙适配器是否可用
+    wx.onBluetoothAdapterStateChange(function (res) {
+      if (!res.available) {
+        util.showToast('蓝牙不可用');
+        return false;
+      }
+    });
+    //第二步关闭适配器,重新来搜索
+    wx.openBluetoothAdapter({
+      success: function (res) {
+        wx.getBluetoothAdapterState({
+          success: function (res) {
+            wx.stopBluetoothDevicesDiscovery({
+              success: function (res) {
+                wx.startBluetoothDevicesDiscovery({
+                  success: function (res) {
+                    wx.onBluetoothDeviceFound(function (res) {
+                      var list = util.filterDevice(res.devices, "name");
+                      if (list.length > 0) {
+                        console.log('==========onBluetoothDeviceFound===========');
+                        console.log(list);
+                        var deviceList = self.data.deviceList;
+                        var doDevices = wx.getStorageSync('doDevices');
+                        if (doDevices) {
+                        } else {
+                          doDevices = [];
+                        }
+                        console.log(deviceList);
+                        console.log(doDevices);
+                        wx.setStorageSync('doDevices', doDevices);
+
+                        wx.hideLoading();
+                        list.forEach(function (item) {
+                          var flag = true;
+                          for (var i = 0; i < deviceList.length; i++) {
+                            var itemSub = deviceList[i];
+                            if (itemSub.deviceId === item.deviceId) {
+                              flag = false;
+                              break;
+                            }
+                          }
+                          if (flag) {
+                            var arrD = item['name'].split(' ');
+                            item['sn'] = arrD[1];
+                            wx.request({
+                              url: 'https://aipush.aidsleep.cn/checkbeds',
+                              method: 'POST',
+                              header: {
+                                'content-type': 'application/json' // 设置请求的 header
+                              },
+                              data: {
+                                "snlists": arrD[1], // 需要发送的数据
+                                "token": "89835e65993fee4a6a6cbbe4c271da51e5521822934e13769e61cadabaed72c3"
+                              },
+                              success: function (res) {
+                                //console.log(res);
+                                if (res.data.data[arrD[1]].trim() == 'yes') {
+                                  item['beOnline'] = 'icon-deng-ok';
+                                } else {
+                                  item['beOnline'] = '';
+                                  if (doDevices.indexOf(item['deviceId']) >= 0) {
+                                    item['beOnline'] = 'icon-deng-ok';
+                                  }
+                                }
+                                deviceList.push(item);
+                                self.setData({
+                                  deviceList: deviceList,
+                                  showBluetoothList:true
+                                });
+                                wx.setStorageSync('deviceList', deviceList);
+                              },
+                              fail: function (error) {
+                                console.error(error);
+                              }
+                            });
+                          }
+                        })
+                      }
+                    })
+                  }
+                })
+              },
+              fail: function (res) {
+                console.log(res);
+              }
+            });
+          },
+          fail: function (res) {
+            console.log(res);
+          }
+        });
+      },
+      fail: function (res) {
+        console.log(res);
+      }
+    });
+
+  },
+  commitBluetooth() {
+    this.onClose();
+    var deviceId = this.data.deviceList[this.data.bluetoothSelectIndex].deviceId;
+    this.setData({
+      deviceId: deviceId,
+      sn:deviceId
+    })
+  },
+// 开始配网
+  bindViewConnect() {
+    const that = this;
+    if (bluetoothSelectIndex < 0) {
+      util.showToast("没有指定要配网的设备");
+      return false;
+    }
+    var deviceIds = this.data.deviceList[this.data.bluetoothSelectIndex];
+    if (this.data.deviceList.length == 0 || deviceIds.length === 0) {
+      util.showToast("没有指定要配网的设备");
+      return false;
+    }
+
+    wx.startWifi({
+      success(res) {
+        //console.log(' ================== startWifi ================== ');
+        //console.log(res);
+        wx.getConnectedWifi({
+          success(res) {
+            that.getWifiInfo();
+          },
+          fail: function (err) {
+            console.log(' ================== startWifi fail ================== ');
+            console.log(err);
+            if (app.data.sytem == 'ios') {
+              util.showToast("获取Wi-Fi信息失败,请更新微信到最新版");
+            } else {
+              util.showToast("获取Wi-Fi信息失败");
+            }
+          }
+        });
+      }
+    });
+    that.gotoProvision()
+  },
+// 获取Wifi
+  getWifiInfo: function () {
+    const self = this;
+    wx.startWifi({
+      success(res) {
+        //console.log(res)
+        // 先取一次,防止IOS获取不到
+        wx.getConnectedWifi({
+          success(res) {
+            self.setData({
+              wifiInfo: res.wifi
+            });
+            //console.log('== getConnectedWifi ==');
+            //console.log(res);
+            if (res.frequency >= 2412 && res.frequency <= 2472) { } else {
+              self.setData({
+                notice: "温馨提示:当前您连接的Wi-Fi网络是5G频段,建议连接2.4G频段配网"
+              })
+            }
+          },
+          fail: function (err) {
+            util.showToast("获取Wi-Fi信息失败");
+           
+          }
+        })
+        wx.onWifiConnected(function (res) {
+          // console.log('== onWifiConnected ==');
+          // console.log(res);
+          self.setData({
+            wifiInfo: res.wifi
+          })
+        })
+      },
+      fail(res) {
+        console.log('WIFI初始化失败', res)
+        util.showToast("WIFI初始化失败");
+      }
+    })
+  },
+  gotoProvision: function () {
+    const wifiInfo = this.data.wifiInfo;
+    const ssid = wifiInfo != null ? wifiInfo.SSID : null;
+    const bssid = wifiInfo != null ? wifiInfo.BSSID : null;
+    const password = this.data.password;
+    if (wifiInfo == null) {
+      util.showToast("没有Wi-Fi连接");
+      return;
+    } else {
+      if (ssid == null || ssid == '' || password == '') {
+        util.showToast("WiFi登录名和密码不能为空");
+        return;
+      } else {
+        const info = {
+          ssid: ssid,
+          bssid: bssid,
+          password: password,
+          deviceIds: this.data.deviceId
+        }
+        this.blueConnect();
+      }
+    }
+  },
+// 蓝牙链接
+  blueConnect: function (event) {
+    //console.log(' =============== blueConnect start ===============')
+    var self = this;
+    sequenceControl = 0;
+    self.setData({
+      flagEnd: false,
+      serviceId: "",
+      uuid: "",
+      showBluetoothConnected:true
+    });
+    self.setProcess(0, util.descSucList[0],1);
+    //第一步检查蓝牙适配器是否可用
+    wx.onBluetoothAdapterStateChange(function (res) {
+      if (!res.available) {
+        util.showToast('蓝牙不可用');
+        return false;
+      }
+    });
+    //console.log(app.data);
+    if (app.data.sytem == 'ios') {
+
+    }
+
+    //console.log('deviceId = ' + self.data.deviceId)
+    wx.createBLEConnection({
+      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 
+      deviceId: self.data.deviceId,
+      timeout: 10000,
+      success: function (res) {
+        wx.setBLEMTU({
+          deviceId: self.data.deviceId,
+          mtu: 128
+        })
+        //console.log("============ createBLEConnection success =============")
+        //console.log(self.data.deviceId)
+        self.getDeviceServices(self.data.deviceId);
+      },
+      fail: function (res) {
+        console.log("============ createBLEConnection fail =============")
+        console.log(res)
+        console.log(self.data.blueConnectNum)
+        var num = self.data.blueConnectNum;
+        if (num < 3) {
+          self.blueConnect();
+          num++;
+          self.setData({
+            blueConnectNum: num
+          })
+        } else {
+          self.setFailProcess(true, res.errCode + "::" + util.descFailList[0]);
+        }
+      }
+    })
+  },
+  getDeviceServices: function (deviceId) {
+    var self = this;
+    wx.getBLEDeviceServices({
+      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 
+      deviceId: deviceId,
+      success: function (res) {
+        self.setProcess(10, util.descSucList[1],2);
+        var services = res.services;
+        if (services.length > 0) {
+          for (var i = 0; i < services.length; i++) {
+            var uuid = services[i].uuid;
+            if (uuid == app.data.service_uuid) {
+              self.getDeviceCharacteristics(deviceId, uuid);
+              return false;
+            }
+          }
+        }
+      },
+      fail: function (res) {
+        self.setFailProcess(true, res.errCode + "::" + util.descFailList[1]);
+      }
+    })
+  },
+
+  getDeviceCharacteristics: function (deviceId, serviceId) {
+    //console.log(" ============== getDeviceCharacteristics =============== ");
+    var self = this;
+    wx.getBLEDeviceCharacteristics({
+      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 
+      deviceId: deviceId,
+      serviceId: serviceId,
+      success: function (res) {
+        self.setProcess(40, util.descSucList[2],3);
+        var list = res.characteristics;
+        if (list.length > 0) {
+          for (var i = 0; i < list.length; i++) {
+            var uuid = list[i].uuid;
+            if (uuid == app.data.characteristic_write_uuid) {
+              self.openNotify(deviceId, serviceId, uuid);
+              self.setData({
+                serviceId: serviceId,
+                uuid: uuid,
+              })
+              return false;
+            }
+          }
+        }
+      },
+      fail: function (res) {
+        console.log(res);
+        self.setFailProcess(true, res.errCode + "::" + util.descFailList[2]);
+      }
+    })
+  },
+
+  //连接超时
+  onTimeout: function (num) {
+    const self = this;
+    timeId = setInterval(function () {
+      if (num < timeOut) {
+        num++;
+      } else {
+        clearInterval(timeId);
+        self.setFailProcess(true, res.errCode + "::" + util.descFailList[4]);
+      }
+    }, 1000)
+  },
+  //启用通知
+  openNotify: function (deviceId, serviceId, characteristicId) {
+    //console.log("=========== openNotify ============");
+    var self = this;
+    wx.notifyBLECharacteristicValueChange({
+      state: true, // 启用 notify 功能
+      deviceId: deviceId,
+      serviceId: serviceId,
+      characteristicId: app.data.characteristic_read_uuid,
+      success: function (res) {
+        //console.log(res);
+        self.writeDevice(deviceId, serviceId, characteristicId, null);
+        self.onNotify();
+      },
+      fail: function (res) {
+        console.log(res);
+      }
+    })
+  },
+  //监听通知
+  onNotify: function () {
+    //console.log("=========== onNotify ============");
+    var self = this;
+    wx.onBLECharacteristicValueChange(function (res) {
+      //console.log(res);
+      self.getResultType(util.ab2hex(res.value));
+    })
+  },
+  // 设备数据开始写入
+  writeDevice: function (deviceId, serviceId, characteristicId, data) {
+    //console.log("===== writeDevice =====");
+    var self = this,
+      obj = {};
+    self.setProcess(60, util.descSucList[4],3);
+    sequenceControl = parseInt(sequenceControl) + 1;
+    if (!util._isEmpty(data)) {
+      obj = util.isSubcontractor(data, true, sequenceControl);
+    } else {
+      data = util.writeData(self.getCharCodeat('"' + self.data.ssid + '","' + self.data.password + '"'));
+      obj = util.isSubcontractor(data, self.data.isChecksum, sequenceControl);
+    }
+    var typedArray = new Uint8Array(obj.lenData)
+    wx.writeBLECharacteristicValue({
+      deviceId: deviceId,
+      serviceId: serviceId,
+      characteristicId: characteristicId,
+      value: typedArray.buffer,
+      success: function (res) {
+        //console.log(res);
+        if (obj.flag) {
+          self.writeDevice(deviceId, serviceId, characteristicId, obj.laveData);
+        } else {
+          self.setProcess(80, util.descSucList[5],4);
+        }
+      },
+      fail: function (res) {
+        console.log(res);
+        self.setFailProcess(true, res.errCode + "::" + util.descFailList[3]);
+      }
+    })
+  },
+  getResultType: function (list) {
+    console.log(' ========= getResultType ========= ');
+    var self = this;
+    console.log(list);
+    var deviceList = wx.getStorageSync('deviceList');
+    console.log(deviceList);
+    if (list.length < 4) {
+      self.setFailProcess(true, res.errCode + "::" + util.descFailList[4]);
+      return false;
+    }
+    var val = list[4];
+    if (val == "00") {
+      var idx = self.data.deviceNo + 1;
+      var doDevices = wx.getStorageSync('doDevices');
+      if (doDevices) {
+        if (doDevices.indexOf(self.data.deviceId) < 0) {
+          doDevices.push(self.data.deviceId);
+        }
+      } else {
+        doDevices = [self.data.deviceId];
+      }
+      wx.setStorageSync('doDevices', doDevices);
+      var deviceSn = self.data.deviceId;
+      for (var i = 0; i < deviceList.length; i++) {
+        var itemSub = deviceList[i];
+        if (itemSub.deviceId === self.data.deviceId) {
+          deviceSn = itemSub.sn;
+          break;
+        }
+      }
+
+      if (idx < self.data.deviceIds.length) {
+        self.setProcess(90, 'SN:' + deviceSn + ' 连接成功', 5);
+        wx.closeBLEConnection({
+          deviceId: self.data.deviceId,
+          success: function (res) { }
+        })
+        self.setData({
+          deviceNo: idx,
+          deviceId: self.data.deviceIds[idx],
+          blueConnectNum: 0
+        });
+        self.blueConnect();
+      } else {
+        self.setProcess(90, 'SN:' + deviceSn + ' 连接成功', 5);
+        self.setProcess(100, util.descSucList[6],6);
+        self.setData({
+          result: [],
+        })
+      }
+    } else {
+      self.setFailProcess(true, res.errCode + "::" + util.descFailList[4])
+    }
+  },
+  setProcess: function (value, desc,step = 0) {
+    var self = this,
+      list = [];
+    list = self.data.processList;
+    if (list.indexOf(desc) == -1) {
+      list.push(desc);
+    }
+    if (self.data.value <= value) {
+      self.setData({
+        value: value,
+        bluetoothConnectedStep:step
+      });
+    }
+    self.setData({
+      processList: list
+    });
+    //console.log(value);
+    //console.log(desc);
+
+    if (value == 100) {
+      self.closeConnect();
+      wx.closeBluetoothAdapter();
+      self.setData({
+        isBluetoothConnected:true,
+        desc: util.descSucList[6]
+      });
+      clearInterval(timeId);
+      sequenceControl = 0;
+    }
+  },
+
+  setFailProcess: function (flag, desc) {
+    var self = this,
+      list = [];
+    list = self.data.processList;
+    list.push(desc);
+    self.setData({
+      failure: flag,
+      processList: list
+    });
+  },
+  closeConnect: function () {
+    var self = this;
+    wx.closeBLEConnection({
+      deviceId: self.data.deviceId,
+      success: function (res) { }
+    })
+  },
   /**
    * 生命周期函数--监听页面加载
    */
   onLoad(options) {
+    if (options.type && options.type == "edit") {
+      wx.setNavigationBarTitle({
+        title:"编辑床垫"
+      })
+      this.setData({
+        placeOfUse: "",
+        usingHuman: "",
+        sn: "",
+        ssid: "",
+        password: "",
+      })
+    }
 
   },
+  checkSn(sntram) { 
+    const that = this;
+    wx.request({
+      url: 'https://aipush.aidsleep.cn/customerlist',
+      method: 'POST',
+      data: {
+        token: "89835e65993fee4a6a6cbbe4c271da51e5521822934e13769e61cadabaed72c3" || wx.getStorageSync('token'),
+        sntram: sntram,
+      },
+      success: (res) => {
+        var incustom = res.data.incustom;
+        if (incustom == "true") {
+          that.bindViewConnect();
+        } else {
+          wx.showToast({
+            icon: 'none',
+            title: "sn 不合法"
+          });
+        }
+      },
+      fail: () => {
+        wx.showToast({
+          icon: 'none',
+          title: "sn 不合法"
+        });
+      }
+    });
+  },
 
   /**
    * 生命周期函数--监听页面初次渲染完成
@@ -66,7 +655,9 @@ Page({
    * 生命周期函数--监听页面卸载
    */
   onUnload() {
-
+    wx.offWifiConnected({});
+    wx.stopWifi({})
+    this.closeConnect()
   },
 
   /**

+ 10 - 10
subpages/addMattresses/addMattresses.wxml

@@ -4,7 +4,7 @@
     <view class="notice-view">
         <image src="/subpages/images/ic_notice_tips.png" class="notice-icon"></image>
         <view class="marquee-container">
-            <text class="marquee-text marquee-text-animation">温馨提示:增加床垫设备之前,请将手机连接室内WIFI,并...</text>
+            <text class="marquee-text marquee-text-animation">温馨提示:增加床垫设备之前,请将手机连接室内WIFI,并且保持蓝牙打开状态。</text>
         </view>
     </view>
 
@@ -13,37 +13,37 @@
             clearable border="{{ true }}" />
         <van-field model:value="{{ usingHuman }}" center title-width="150rpx" label="使用人:" placeholder="可填写本人或者其他人名称"
             clearable border="{{ true }}" />
-        <van-field model:value="{{ sn }}" center title-width="150rpx" clearable label="SN:" placeholder="请输入"
+        <van-field model:value="{{ deviceId }}" center title-width="150rpx" clearable label="SN:" placeholder="请输入"
             border="{{ true }}" use-button-slot>
-            <view slot="button" class="lysb-btn">
+            <view slot="button" class="lysb-btn" bindtap="bindViewBlue">
                 <image src="/subpages/images/ic_ly.png" class="ly-icon"></image>
                 <text>蓝牙识别</text>
             </view>
-        </van-field><van-field model:value="{{ wifi }}" center title-width="150rpx" label="WIFI:" placeholder="AIDSLEEP"
+        </van-field><van-field model:value="{{ ssid }}" center title-width="150rpx" label="WIFI:" placeholder="AIDSLEEP"
             clearable border="{{ true }}" />
-        <van-field model:value="{{ wifiPassWord }}" center title-width="150rpx" label="WIFI密码:" placeholder="请输入密码"
+        <van-field model:value="{{ password }}" center title-width="150rpx" label="WIFI密码:" placeholder="请输入密码"
             clearable border="{{ false }}" />
     </view>
-    <text class="commit-btn">提交配置</text>
+    <text class="commit-btn" bindtap="commitData">提交配置</text>
 
     <!-- 选择蓝牙 -->
     <van-popup show="{{ showBluetoothList }}" round position="bottom" custom-style="height: 50%;background:#F7F7F7;"
         close-on-click-overlay="{{false}}" bind:close="onClose">
         <view class="bluetooth-view">
             <view class="bluetoothList">
-                <view wx:for="{{bluetoothList}}" wx:key="index" class="bluetooth-item" data-index="{{index}}"
+                <view wx:for="{{deviceList}}" wx:key="index" class="bluetooth-item" data-index="{{index}}"
                     bindtap="checkBluetoothSelectIndex">
                     <image src="/subpages/images/ic_bluetooth.png" class="bluetooth-icon"></image>
                     <view class="bluetooth-content">
-                        <text class="bluetooth-title">LZ-0TA 332016851371332016851371332016851371332016851371</text>
-                        <text class="bluetooth-rssi">RSSI: -50</text>
+                        <text class="bluetooth-title">{{item.name}}</text>
+                        <text class="bluetooth-rssi">RSSI: {{item.RSSI}}</text>
                     </view>
                     <image src="{{bluetoothSelectIndex == index ? activeIcon : normalIcon}}" class="bluetooth-radio">
                     </image>
                 </view>
 
             </view>
-            <text class="sure-btn">确定</text>
+            <text class="sure-btn" bindtap="commitBluetooth">确定</text>
         </view>
     </van-popup>
 

+ 77 - 1
subpages/myMattress/myMattress.js

@@ -5,8 +5,84 @@ Page({
    * 页面的初始数据
    */
   data: {
+    mList:[]
   },
 
+  getList() {
+    const that = this;
+    wx.request({
+      url: 'https://aipush.aidsleep.cn/customerlist',
+      method: 'POST',
+      data: {
+        token: "89835e65993fee4a6a6cbbe4c271da51e5521822934e13769e61cadabaed72c3" || wx.getStorageSync('token'),
+        udi: wx.getStorageSync('unionid'),
+      },
+      success: (res) => {
+        var loadData = res.data.data;
+        if (loadData) {
+          that.setData({
+            mList: loadData
+          })
+
+        } else {
+        }
+      },
+      fail: () => {
+      }
+    });
+  },
+  showMenu(e) {
+    const item = e.currentTarget.dataset.item;
+    console.log(item);
+    const that = this;
+    wx.showActionSheet({
+      itemList: ['编辑', '删除'],
+      success: function (e) {
+        console.log(e.tapIndex) //没有item项下的key或index
+        if (e.tapIndex == 0) {
+          // 编辑
+          wx.navigateTo({
+            url:"/subpages/addMattresses/addMattresses?type=edit"
+          })
+        } else {
+          // 删除
+          that.deleteItem(item);
+        }
+      }
+    })
+  },
+  deleteItem(item) {
+    const that = this;
+    wx.request({
+      url: 'https://aipush.aidsleep.cn/customerlist',
+      method: 'POST',
+      data: {
+        token: "89835e65993fee4a6a6cbbe4c271da51e5521822934e13769e61cadabaed72c3" || wx.getStorageSync('token'),
+        pid: item.pid,
+      },
+      success: (res) => {
+        var code = res.data.code;
+        if (code) {
+          wx.showToast({
+            icon: 'none',
+            title: "删除成功"
+          });
+          that.getList();
+        } else {
+          wx.showToast({
+            icon: 'none',
+            title: "删除失败"
+          });
+        }
+      },
+      fail: () => {
+        wx.showToast({
+          icon: 'none',
+          title: "删除失败"
+        });
+      }
+    });
+  },
   /**
    * 生命周期函数--监听页面加载
    */
@@ -24,7 +100,7 @@ Page({
    * 生命周期函数--监听页面显示
    */
   onShow() {
-
+    this.getList();
   },
 
   /**

+ 6 - 5
subpages/myMattress/myMattress.wxml

@@ -1,15 +1,16 @@
 <!--subpages/myMattress/myMattress.wxml-->
 <view>
     <view class="mattress-list">
-        <view class="mattress-item">
+        <view wx:for="{{mList}}" wx:key="index" class="mattress-item">
             <image class="item-cover" src="/subpages/images/ic_gyms.png"></image>
             <view class="right-content">
                 <text class="item-title">爱眠客床垫</text>
-                <text class="item-offline">未连接</text><!-- <text class="item-online">已连接</text> -->
-                <text class="item-sn">SN:7834*****1234</text>
-                <text class="item-user">使用人:本人</text>
+                <text wx:if="{{item.status == 1}}" class="item-online">已连接</text>
+                <text wx:else class="item-offline">未连接</text>
+                <text class="item-sn">SN:{{item.sn}}</text>
+                <text class="item-user">使用人:{{item.person}}</text>
             </view>
-            <view class="menu-btn"><van-icon name="ellipsis" /></view>
+            <view class="menu-btn" data-item="{{item}}" bindtap="showMenu"><van-icon name="ellipsis" /></view>
         </view>
 
     </view>

+ 506 - 1
utils/util.js

@@ -14,6 +14,511 @@ const formatNumber = n => {
   return n[1] ? n : `0${n}`
 }
 
+const FRAME_CTRL_POSITION_ENCRYPTED = 0;
+const FRAME_CTRL_POSITION_CHECKSUM = 1;
+const FRAME_CTRL_POSITION_DATA_DIRECTION = 2;
+const FRAME_CTRL_POSITION_REQUIRE_ACK = 3;
+const FRAME_CTRL_POSITION_FRAG = 4;
+const DIRECTION_OUTPUT = 0;
+const DIRECTION_INPUT = 1;
+const AES_BASE_IV = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+const NEG_SET_SEC_TOTAL_LEN = 0x00;
+const NEG_SET_SEC_ALL_DATA = 0x01;
+const PACKAGE_VALUE = 0x01;
+const SUBTYPE_NEG = 0x00;
+const SUBTYPE_END = 0x03;
+const SUBTYPE_WIFI_NEG = 0x09;
+const SUBTYPE_SET_SSID = 0x2;
+const SUBTYPE_SET_PWD = 0x3;
+const SUBTYPE_WIFI_LIST_NEG = 11;
+const SUBTYPE_NEGOTIATION_NEG = 0;
+const SUBTYPE_CUSTOM_DATA = 0x13;
+const PACKAGE_MSG_HEADER = 0xCD;
+const PACKAGE_MSG_TYPE = 0x1F;
+var DH_P = "cf5cf5c38419a724957ff5dd323b9c45c3cdd261eb740f69aa94b8bb1a5c96409153bd76b24222d03274e4725a5406092e9e82e9135c643cae98132b0d95f7d65347c68afc1e677da90e51bbab5f5cf429c291b4ba39c6b2dc5e8c7231e46aa7728e87664532cdf547be20c9a3fa8342be6e34371a27c06f7dc0edddd2f86373";
+var DH_G = "02";
+
+const descSucList = ["蓝牙连接...", "蓝牙连接成功", "成功获取设备信息", "获取属性信息成功", "发送配置信息...", "配置信息发送成功", "连接成功"];
+const descFailList = ["蓝牙连接失败", "获取设备信息失败", "获取属性信息失败", "发送配置信息失败", "分配网络失败"];
+const successList = { "0": "NULL", "1": "STA", "2": "SoftAP", "3": "SoftAP & STA" };
+const failList = { "0": "sequence error", "1": "checksum error", "2": "decrypt error", "3": "encrypt error", "4": "init security error", "5": "dh malloc error", "6": "dh param error", "7": "read param error", "8": "make public error" };
+var CRC_TB = [
+  0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+  0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+  0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+  0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+  0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+  0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+  0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+  0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+  0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+  0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+  0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+  0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+  0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+  0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+  0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+  0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+];
+
+const showToast = title => {
+  wx.showToast({
+    title: title,
+    icon: 'none',
+    duration: 2000
+  })
+}
+//转16进制
+const ab2hex = buffer => {
+  var hexArr = Array.prototype.map.call(
+    new Uint8Array(buffer),
+    function (bit) {
+      return ('00' + bit.toString(16)).slice(-2)
+    }
+  )
+  return hexArr;
+}
+//16进制转字符串
+const hexCharCodeToStr = hexCharCodeStr => {
+  var trimedStr = hexCharCodeStr.trim();
+  var rawStr =
+    trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
+  var len = rawStr.length;
+  if (len % 2 !== 0) {
+    alert("非法格式ASCII码!");
+    return "";
+  }
+  var curCharCode;
+  var resultStr = [];
+  for (var i = 0; i < len; i = i + 2) {
+    curCharCode = parseInt(rawStr.substr(i, 2), 16); // ASCII Code Value
+    resultStr.push(String.fromCharCode(curCharCode));
+  }
+  return resultStr.join("");
+}
+//过滤名称
+const filterDevice = (devices, name) => {
+  var list = [];
+  for (var i = 0; i < devices.length; i++) {
+    var device = devices[i];
+    if (device[name] != '') {
+      //console.log(device[name])
+      if (device[name].indexOf('LZ-OTA') !== -1) {
+        device['beOnline'] = '';
+        list.push(device);
+      }
+    }
+  }
+  return list;
+  // var arr = sortArrObj(list,[['RSSI','asc']]);
+  // return arr.length > 3?arr.slice(0,3):arr;
+}
+//获去type
+const getType = (pkgType, subType) => {
+  return (subType << 2) | pkgType;
+}
+//unit8Arry转数组
+const uint8ArrayToArray = uint8Array => {
+  var array = [];
+
+  for (var i = 0; i < uint8Array.byteLength; i++) {
+    array[i] = uint8Array[i];
+  }
+
+  return array;
+}
+//16进制转二进制数组 
+const hexToBinArray = str => {
+  var dec = parseInt(str, 16),
+    bin = dec.toString(2),
+    len = bin.length;
+  if (len < 8) {
+    var diff = 8 - len,
+      zeros = "";
+    for (var i = 0; i < diff; i++) {
+      zeros += "0";
+    }
+    bin = zeros + bin;
+  }
+  return bin.split("");
+}
+//16进制转数组
+const hexByArray = str => {
+  var arr = [];
+  if (str.length % 2 != 0) {
+    str = "0" + str;
+  }
+  for (var i = 0; i < str.length; i += 2) {
+    arr.push(str.substring(i, i + 2))
+  }
+  return arr;
+}
+//16进制转整形数组
+const hexByInt = str => {
+  var arr = [];
+  if (str.length % 2 != 0) {
+    str = "0" + str;
+  }
+  for (var i = 0; i < str.length; i += 2) {
+    arr.push(parseInt(str.substring(i, i + 2), 16))
+  }
+  return arr;
+}
+//排序
+const sortBy = (attr, rev) => {
+  //第二个参数没有传递 默认升序排列
+  if (rev == undefined) {
+    rev = 1;
+  } else {
+    rev = (rev) ? 1 : -1;
+  }
+  return function (a, b) {
+    a = a[attr];
+    b = b[attr];
+    if (a < b) {
+      return rev * -1;
+    } else if (a > b) {
+      return rev * 1;
+    }
+    return 0;
+  }
+}
+
+/**
+ * 对数组对象的指定属性进行排序
+ * @param {Array} arr 数组对象
+ * @param {Array} rules 排序规则,每个元素都是形如 ['key', 'asc'] 或者 ['key', 'desc'] 的数组
+ */
+function sortArrObj(arr, rules) {
+  return arr.sort((a, b) => {
+    for (let i = 0; i < rules.length; i++) {
+      const [key, direction] = rules[i];
+      const order = direction === 'desc' ? -1 : 1;
+      if (a[key] < b[key]) {
+        return -1 * order;
+      }
+      if (a[key] > b[key]) {
+        return 1 * order;
+      }
+    }
+    return 0;
+  });
+}
+//判断非空
+const _isEmpty = str => {
+  if (str === "" || str === null || str === undefined || str === "null" || str === "undefined") {
+    return true;
+  } else {
+    return false;
+  }
+}
+//组装数据格式 
+const writeData = (data) => {
+  var value = [];
+  value.push(0xcd);
+  value.push(0x1f);
+  value.push(0x00);
+  value.push(data.length + 4);
+  value = value.concat(data);
+  value.push(0xff);
+  value.push(0xff);
+  value.push(0xff);
+  value.push(0xff);
+  return value;
+}
+
+const writeSetting = (data) => {
+  var value = [];
+  value.push(0xcd);
+  value.push(0x23);
+  value.push(0x00);
+  value.push(data.length + 4);
+  value = value.concat(data);
+  value.push(0xff);
+  value.push(0xff);
+  value.push(0xff);
+  value.push(0xff);
+  return value;
+}
+
+//是否分包
+const isSubcontractor = (data, checksum, sequence) => {
+  var len = 0, lenData = [], laveData = [], flag = false;
+  var total = data.length;
+  if (total > 20) {
+    if (checksum) {
+      lenData = data.slice(0, 18);
+      laveData = data.slice(18);
+    } else {
+      lenData = data.slice(0, 14);
+      laveData = data.slice(14);
+    }
+    len = lenData.length;
+    flag = true;
+  } else {
+    lenData = data;
+    len = lenData.length;
+  }
+  if (checksum) {
+    //lenData = assemblyChecksum(lenData, len, sequence);
+  }
+  return { "len": len, "lenData": lenData, "laveData": laveData, "flag": flag }
+}
+const assemblyChecksum = (list, len, sequence, encrypt) => {
+  var checkData = [];
+  checkData.push(sequence);
+  checkData.push(len);
+  checkData = checkData.concat(list);
+  var crc = caluCRC(0, checkData);
+  var checksumByte1 = crc & 0xff;
+  var checksumByte2 = (crc >> 8) & 0xff;
+  list.push(checksumByte1);
+  list.push(checksumByte2);
+  return list;
+}
+//加密发送的数据
+const encrypt = (aesjs, md5Key, sequence, data, checksum) => {
+  var iv = generateAESIV(sequence), sumArr = [], list = [];
+  if (checksum) {
+    var len = data.length - 2;
+    list = data.slice(0, len);
+    sumArr = data.slice(len);
+  } else {
+    list = data;
+  }
+  var encryptData = uint8ArrayToArray(blueAesEncrypt(aesjs, md5Key, iv, new Uint8Array(list)));
+  return encryptData.concat(sumArr);
+}
+// aes加密
+const blueAesEncrypt = (aesjs, mdKey, iv, bytes) => {
+  var aesOfb = new aesjs.ModeOfOperation.ofb(mdKey, iv);
+  var encryptedBytes = aesOfb.encrypt(bytes);
+  return encryptedBytes;
+}
+
+//获取Frame Control
+const getFrameCTRLValue = (encrypted, checksum, direction, requireAck, frag) => {
+  var frame = 0;
+  if (encrypted) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_ENCRYPTED);
+  }
+  if (checksum) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_CHECKSUM);
+  }
+  if (direction == DIRECTION_INPUT) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_DATA_DIRECTION);
+  }
+  if (requireAck) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_REQUIRE_ACK);
+  }
+  if (frag) {
+    frame = frame | (1 << FRAME_CTRL_POSITION_FRAG);
+  }
+  return frame;
+}
+//获取aes iv
+const generateAESIV = sequence => {
+  var result = [];
+  for (var i = 0; i < 16; i++) {
+    if (i == 0) {
+      result[0] = sequence;
+    } else {
+      result[i] = AES_BASE_IV[i];
+    }
+  }
+  return result;
+}
+//计算CRC值
+const caluCRC = (crc, pByte) => {
+  crc = (~crc) & 0xffff;
+  for (var i in pByte) {
+    crc = CRC_TB[((crc & 0xffff) >> 8) ^ (pByte[i] & 0xff)] ^ ((crc & 0xffff) << 8);
+  }
+  return (~crc) & 0xffff;
+}
+const hsvToRgb = (h, s, v) => {
+  var r, g, b;
+  var i = Math.floor(h * 6);
+  var f = h * 6 - i;
+  var p = v * (1 - s);
+  var q = v * (1 - f * s);
+  var t = v * (1 - (1 - f) * s);
+
+  switch (i % 6) {
+    case 0: r = v, g = t, b = p; break;
+    case 1: r = q, g = v, b = p; break;
+    case 2: r = p, g = v, b = t; break;
+    case 3: r = p, g = q, b = v; break;
+    case 4: r = t, g = p, b = v; break;
+    case 5: r = v, g = p, b = q; break;
+  }
+
+  return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
+}
+const rgbToHsv = (r, g, b) => {
+  r = r / 255, g = g / 255, b = b / 255;
+  var max = Math.max(r, g, b), min = Math.min(r, g, b);
+  var h, s, v = max;
+
+  var d = max - min;
+  s = max == 0 ? 0 : d / max;
+
+  if (max == min) {
+    h = 0; // achromatic
+  } else {
+    switch (max) {
+      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+      case g: h = (b - r) / d + 2; break;
+      case b: h = (r - g) / d + 4; break;
+    }
+    h /= 6;
+  }
+
+  return Math.round(h * 360);
+}
+const createCanvas = (self) => {
+  var context = wx.createCanvasContext('firstCanvas', self);
+  var width = Math.floor(self.data.width * 0.7),
+    height = width,
+    cx = width / 2,
+    cy = height / 2,
+    radius = width / 2.3,
+    imageData,
+    pixels,
+    hue, sat, value,
+    i = 0, x, y, rx, ry, d,
+    f, g, p, u, v, w, rgb;
+  wx.canvasGetImageData({
+    canvasId: 'firstCanvas',
+    x: 0,
+    y: 0,
+    width: width,
+    height: height,
+    success(res) {
+      var pixels = res.data;
+      for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++, i = i + 4) {
+          rx = x - cx;
+          ry = y - cy;
+          d = rx * rx + ry * ry;
+          if (d < radius * radius) {
+            hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI);
+            sat = Math.sqrt(d) / radius;
+            g = Math.floor(hue);
+            f = hue - g;
+            u = 255 * (1 - sat);
+            v = 255 * (1 - sat * f);
+            w = 255 * (1 - sat * (1 - f));
+            pixels[i] = [255, v, u, u, w, 255, 255][g];
+            pixels[i + 1] = [w, 255, 255, v, u, u, w][g];
+            pixels[i + 2] = [u, u, w, 255, 255, v, u][g];
+            pixels[i + 3] = 255;
+          }
+        }
+      }
+      wx.canvasPutImageData({
+        canvasId: 'firstCanvas',
+        x: 0,
+        y: 0,
+        width: width,
+        height: height,
+        data: pixels,
+        success(res) {
+          setTimeout(function () {
+            context.beginPath();
+            context.arc(cx, cy, radius * 0.6, 0, 2 * Math.PI);
+            context.fillStyle = "#12151e";
+            context.fill();
+            context.stroke();
+            context.draw(true);
+            context.beginPath();
+            context.arc(cx, cy, radius, 0, 2 * Math.PI);
+            context.strokeStyle = "#12151e";
+            context.lineWidth = 5;
+            context.stroke();
+            context.draw(true);
+          })
+
+        },
+        fail(res) {
+        }
+      }, self)
+    }
+  })
+}
+const getColor = (self, event) => {
+  //console.log(event);
+  var x = event.touches[0].x,
+    y = event.touches[0].y;
+  wx.canvasGetImageData({
+    canvasId: "firstCanvas",
+    x: x,
+    y: y,
+    width: 1,
+    height: 1,
+    success(res) {
+      var r = res.data[0],
+        g = res.data[1],
+        b = res.data[2];
+      //console.log(r, g, b);
+      // 特殊值过滤
+      if ((r == 0 && g == 0 && b == 0) || (r == 18 && g == 21 && b == 30)) {
+        return false;
+      } else {
+        self.setData({
+          color: "rgba(" + r + ", " + g + ", " + b + ", " + self.data.currentLuminanceText / 100 + ")",
+          currentSaturationText: 100,
+          currentSaturation: 100,
+          currentHue: rgbToHsv(r, g, b)
+        })
+        self.setDeviceStatus();
+      }
+    }
+  })
+}
 module.exports = {
-  formatTime
+  formatTime,
+  showToast: showToast,
+  ab2hex: ab2hex,
+  hexCharCodeToStr: hexCharCodeToStr,
+  filterDevice: filterDevice,
+  getType: getType,
+  hexToBinArray: hexToBinArray,
+  hexByArray: hexByArray,
+  hexByInt: hexByInt,
+  sortBy: sortBy,
+  sortArrObj: sortArrObj,
+  writeData: writeData,
+  writeSetting: writeSetting,
+  isSubcontractor: isSubcontractor,
+  getFrameCTRLValue: getFrameCTRLValue,
+  uint8ArrayToArray: uint8ArrayToArray,
+  generateAESIV: generateAESIV,
+  caluCRC: caluCRC,
+  encrypt: encrypt,
+  DH_P: DH_P,
+  DH_G: DH_G,
+  DIRECTION_OUTPUT: DIRECTION_OUTPUT,
+  DIRECTION_INPUT: DIRECTION_INPUT,
+  NEG_SET_SEC_TOTAL_LEN: NEG_SET_SEC_TOTAL_LEN,
+  NEG_SET_SEC_ALL_DATA: NEG_SET_SEC_ALL_DATA,
+  PACKAGE_VALUE: PACKAGE_VALUE,
+  SUBTYPE_NEG: SUBTYPE_NEG,
+  PACKAGE_CONTROL_VALUE: PACKAGE_MSG_HEADER,
+  SUBTYPE_WIFI_MODEl: PACKAGE_MSG_TYPE,
+  SUBTYPE_WIFI_NEG: SUBTYPE_WIFI_NEG,
+  SUBTYPE_WIFI_LIST_NEG: SUBTYPE_WIFI_LIST_NEG,
+  SUBTYPE_NEGOTIATION_NEG: SUBTYPE_NEGOTIATION_NEG,
+  SUBTYPE_SET_SSID: SUBTYPE_SET_SSID,
+  SUBTYPE_SET_PWD: SUBTYPE_SET_PWD,
+  SUBTYPE_END: SUBTYPE_END,
+  SUBTYPE_CUSTOM_DATA: SUBTYPE_CUSTOM_DATA,
+  hsvToRgb: hsvToRgb,
+  rgbToHsv: rgbToHsv,
+  createCanvas: createCanvas,
+  getColor: getColor,
+  descSucList: descSucList,
+  descFailList: descFailList,
+  successList: successList,
+  _isEmpty: _isEmpty
 }