uniapp 小程序低功耗蓝牙配网 blefi配网 物联网

发布于:2024-05-09 ⋅ 阅读:(131) ⋅ 点赞:(0)

1.获取蓝牙列表  bleList.vue

<template>
  <view>
    <button @touchstart="startSearch">获取蓝牙列表</button>
    <scroll-view :scroll-top="scrollTop" scroll-y class="content-pop">
      <view
        class="bluetoothItem"
        v-for="(item, index) in bluetoohList"
        :key="index"
        @click="openControl(item)"
      >
        <view class="textItem">蓝牙:{{ item.name }}</view>
        <view>{{ item.deviceId }}</view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      bluetoohList: [],
    };
  },
  onLoad: function (options) {
    this.startSearch();
  },
  methods: {
    // 连接蓝牙
    startSearch() {
      var that = this;
      uni.openBluetoothAdapter({
        success: (res) => {
          uni.getBluetoothAdapterState({
            success: (res) => {
              if (res.available) {
                if (res.discovering) {
                  uni.stopBluetoothDevicesDiscovery({
                    success: (res) => {},
                  });
                } else {
                  that.getBluetoothDevices();
                }
                that.checkPemission();
              } else {
                uni.showToast({
                  title: "本机蓝牙不可用",
                  mask: true,
                });
              }
            },
          });
        },
        fail: (err) => {
          that.openSetting();
        },
      });
    },
    openSetting() {
      uni.showModal({
        title: "检测到您没打开蓝牙权限,是否去设置打开?",
        confirmText: "确认",
        cancelText: "取消",
        cancelColor: "#999999", //取消按钮颜色
        confirmColor: "#00A0E9", //确定按钮颜色
        success: (res) => {
          if (res.confirm) {
            uni.openSetting({
              //opensetting是调起设置页面的
              success: (res) => {
                if (res.authSetting == true) {
                  //判断res.authsetting的值是true还是false
                  uni.openBluetoothAdapter({
                    success: (res) => {
                      this.startSearch();
                    },
                  });
                }
              },
            });
          } else {
            // 取消
            return false;
          }
        },
      });
    },
    checkPemission() {
      //android 6.0以上需授权地理位置权限
      var that = this;
      const sys = uni.getSystemInfoSync();
      if (sys.platform == "ios") {
        that.getBluetoothDevices();
      } else if (sys.platform == "android") {
        console.log(
          app
            .getSystem()
            .substring(
              app.getSystem().length - (app.getSystem().length - 8),
              app.getSystem().length - (app.getSystem().length - 8) + 1
            )
        );
        if (
          app.globalData
            .getSystem()
            .substring(
              app.globalData.getSystem().length -
                (app.globalData.getSystem().length - 8),
              app.globalData.getSystem().length -
                (app.globalData.getSystem().length - 8) +
                1
            ) > 5
        ) {
          uni.getSetting({
            success: (res) => {
              console.log(res);
              if (!res.authSetting["scope.userLocation"]) {
                uni.authorize({
                  scope: "scope.userLocation",
                  complete: (res) => {
                    that.getBluetoothDevices();
                  },
                });
              } else {
                that.getBluetoothDevices();
              }
            },
          });
        }
      }
    },
    //获取蓝牙设备信息
    getBluetoothDevices() {
      var that = this;
      uni.showLoading({
        title: "蓝牙搜索中",
        mask: true,
      });
      // 开始搜寻附近的蓝牙外围设备
      uni.startBluetoothDevicesDiscovery({
        success: (res) => {
          setTimeout(() => {
            // 获取搜索到的设备信息
            uni.getBluetoothDevices({
              success: (res) => {
                that.bluetoohList = [];
                var num = 0;
                for (var i = 0; i < res.devices.length; ++i) {
                  if (res.devices[i].name != "未知设备") {
                    that.bluetoohList[num] = res.devices[i];
                    num++;
                  }
                }
                uni.stopPullDownRefresh(); // 停止当前页面下拉刷新
                uni.stopBluetoothDevicesDiscovery({
                  // 停止搜索蓝牙设备
                  success: (res) => {
                    uni.hideLoading();
                  },
                });
              },
            });
          }, 5000);
        },
      });
    },
    // 连接蓝牙 跳转到连接页面
    openControl(item) {
      let params = {
        list: this.bluetoohList,
        info: item,
      };

      uni.redirectTo({
        url:
          "/pages/blefi/blefi?info=" +
          encodeURIComponent(JSON.stringify(params)),
      });
    },
  },
};
</script>

<style scoped>
.content-pop {
  width: 100vw;
  max-height: 55vh;
  padding: 0 30rpx;
}
.bluetoothItem {
  padding: 20rpx 0;
  font-weight: 400;
  font-size: 28rpx;
  border-bottom: 1rpx solid #f4f4f4;
  text-align: left;
}
.textItem {
  display: block;
  margin-bottom: 10rpx;
}
</style>

2.选择蓝牙进行连接  blefi.vue

<template>
  <text>打印机正在连接中...</text>
</template>

<script>
export default {
  data() {
    return {
      bluInfo: {},
      services: [],
      serviceId: 0,
      writeCharacter: false,
      readCharacter: false,
      notifyCharacter: false,
      deviceId: "",
      notifyCharaterId: "",
      notifyServiceId: "",
      writeCharaterId: "",
      writeServiceId: "",
      readCharaterId: "",
      readServiceId: "",
    };
  },
  onLoad(option) {
    // 接收页面传递的数据
    this.bluInfo = JSON.parse(decodeURIComponent(option.info));
    this.bluetooh(this.bluInfo.info.deviceId);
    this.deviceId = this.bluInfo.info.deviceId;
  },
  methods: {
    bluetooh(deviceId) {
      var that = this;
      uni.stopBluetoothDevicesDiscovery({
        success: (res) => {},
      });
      uni.createBLEConnection({
        deviceId: deviceId,
        success: (res) => {
          that.getSeviceId();
        },
        fail: (e) => {
          that.bluetoothFail();
        },
        complete: (e) => {},
      });
    },
    // 连接成功后保存连接状态
    getSeviceId() {
      var that = this;
      uni.getBLEDeviceServices({
        deviceId: this.deviceId,
        success: (res) => {
          that.services = res.services;
          that.getCharacteristics();
        },
        fail: (e) => {
          that.bluetoothFail();
        },
        complete: (e) => {},
      });
    },
    getCharacteristics() {
      var that = this;
      var list = that.services;
      var num = that.serviceId;
      var write = that.writeCharacter;
      var read = that.readCharacter;
      var notify = that.notifyCharacter;
      uni.getBLEDeviceCharacteristics({
        deviceId: this.deviceId,
        serviceId: list[num].uuid,
        success: (res) => {
          for (var i = 0; i < res.characteristics.length; ++i) {
            var properties = res.characteristics[i].properties;
            var item = res.characteristics[i].uuid;
            if (!notify) {
              if (properties.notify) {
                this.notifyCharaterId = item;
                this.notifyServiceId = list[num].uuid;
                notify = true;
              }
            }
            if (!write) {
              if (properties.write) {
                this.writeCharaterId = item;
                this.writeServiceId = list[num].uuid;
                write = true;
              }
            }
            if (!read) {
              if (properties.read) {
                readServiceId.readCharaterId = item;
                readServiceId.readServiceId = list[num].uuid;
                read = true;
              }
            }
          }
          if (!write || !notify || !read) {
            num++;
            (that.writeCharacter = write),
              (that.readCharacter = read),
              (that.notifyCharacter = notify),
              (that.serviceId = num);
            if (num == list.length) {
              // console.log("找不到该读写的特征值")
              that.bluetoothFail();
            } else {
              that.getCharacteristics();
            }
          } else {
            that.bluetoothSuccess(res);
          }
        },
        fail: (e) => {
          that.bluetoothFail();
        },
      });
    },
    // 蓝牙连接打印机
    bluetoothSuccess(res) {
      let info = {
        deviceId: this.deviceId,
        notifyCharaterId: thid.notifyCharaterId,
        notifyServiceId: thid.notifyServiceId,
        writeCharaterId: thid.writeCharaterId,
        writeServiceId: thid.writeServiceId,
        readCharaterId: thid.readCharaterId,
        readServiceId: thid.readServiceId,
      };
      uni.setStorageSync("blefiInfo", info);
      uni.showModal({
        title: "连接成功",
        confirmText: "继续",
        confirmColor: "#00A0E9", //确定按钮颜色
        showCancel: false, //没有取消按钮的弹框
        success: (res) => {
          if (res.confirm) {
            // 蓝牙连接成功,跳转到下一页面
            uni.redirectTo({
              url: "/pages/blefi/blefiWifi",
            });
          }
        },
      });
    },
    bluetoothFail() {
      // 蓝牙连接失败,跳转到失败页面
      uni.redirectTo({
        url: "/pages/blefi/blefiFail",
      });
    },
  },
};
</script>

3. 低功耗蓝牙连接WiFi  blefiWifi.vue

<template>
  <view>
    <text>{{ wifiSSID }}</text>
    <input type="text" placeholder="请输入WLAN密码" v-model="password" />
    <button @click="settiing">连接</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      bleInfo: {},
      wifiSSID: "your SSID",
      password: "",
      bleSendSequence: 0,
      connected: true,
      wifiCountDown: 0,
      wifiCountInterval: null, // 定时器
      dataEnum: {
        PACKAGE_VALUE: 0x01,
        SUBTYPE_NEG: 0x00,
        SUBTYPE_STA_WIFI_BSSID: 0x01,
        SUBTYPE_STA_WIFI_SSID: 0x02,
        SUBTYPE_STA_WIFI_PASSWORD: 0x03,
        SUBTYPE_SOFTAP_WIFI_SSID: 0x04,
        SUBTYPE_SOFTAP_WIFI_PASSWORD: 0x05,
        SUBTYPE_SOFTAP_MAX_CONNECTION_COUNT: 0x06,
        SUBTYPE_SOFTAP_AUTH_MODE: 0x07,
        SUBTYPE_SOFTAP_CHANNEL: 0x08,
        SUBTYPE_USERNAME: 0x09,
        SUBTYPE_CA_CERTIFICATION: 0x0a,
        SUBTYPE_CLIENT_CERTIFICATION: 0x0b,
        SUBTYPE_SERVER_CERTIFICATION: 0x0c,
        SUBTYPE_CLIENT_PRIVATE_KEY: 0x0d,
        SUBTYPE_SERVER_PRIVATE_KEY: 0x0e,
        SUBTYPE_WIFI_CONNECTION_STATE: 0x0f,
        SUBTYPE_VERSION: 0x10,
        SUBTYPE_WIFI_LIST: 0x11,
        SUBTYPE_ERROR: 0x12,
        SUBTYPE_CUSTOM_DATA: 0x13,
      },
      controllEnum: {
        PACKAGE_VALUE: 0x00,
        SUBTYPE_ACK: 0x00,
        SUBTYPE_SET_SEC_MODE: 0x01,
        SUBTYPE_SET_OP_MODE: 0x02,
        SUBTYPE_CONNECT_WIFI: 0x03,
        SUBTYPE_DISCONNECT_WIFI: 0x04,
        SUBTYPE_GET_WIFI_STATUS: 0x05,
        SUBTYPE_DEAUTHENTICATE: 0x06,
        SUBTYPE_GET_VERSION: 0x07,
        SUBTYPE_CLOSE_CONNECTION: 0x08,
        SUBTYPE_GET_WIFI_LIST: 0x09,
      },
    };
  },
  // 二级页面清除
  onUnload() {
    wx.offBLEConnectionStateChange();
    if (this.wifiCountInterval) {
      clearInterval(this.wifiCountInterval);
      this.wifiCountInterval = null;
    }
  },
  onLoad(options) {
    this.bleInfo = uni.getStorageSync("blefiInfo");
    var that = this;
    wx.getBLEDeviceServices({
      deviceId: this.bleInfo.deviceId,
      success: function (res) {
        wx.getBLEDeviceCharacteristics({
          deviceId: this.bleInfo.deviceId,
          serviceId: this.bleInfo.notifyServiceId,
          success: function (res) {
            wx.notifyBLECharacteristicValueChange({
              state: true,
              deviceId: this.bleInfo.deviceId,
              serviceId: this.bleInfo.notifyServiceId,
              characteristicId: this.bleInfo.notifyCharaterId,
              success: function (res) {
                console.log("启用notify成功");
              },
            });
          },
        });
      },
    });
    wx.onBLEConnectionStateChange((res) => {
      that.connected = res.connected;
      if (!res.connected) {
        uni.hideLoading();
        // 蓝牙连接失败,跳转到失败页面
        uni.redirectTo({
          url: "/pages/blefi/blefiFail",
        });
      }
    });
    // 接收配网打印机回传的数据
    wx.onBLECharacteristicValueChange(function (res) {
      uni.hideLoading();
      var receive = that.ab2strt(res.value);
      console.log("接收到数据 receive : " + receive);
      // 处理接收的数据........
    });
  },
  methods: {
    // 将 ArrayBuffer 转换为16进度字符串
    ab2strt(buff) {
      var hexArr = Array.prototype.map.call(
        new Uint8Array(buff),
        function (bit) {
          return ("00" + bit.toString(16)).slice(-2);
        }
      );
      return hexArr.join(" ");
    },
    settiing() {
      // 取消wifi连接成功/失败页面
      this.wifiCountDown = 30;
      this.startSMSTimer();
      uni.showLoading({
        title: "连接中",
        mask: true,
      });
      if (this.connected) {
        this.sendSSID();
        this.sendPASSWORD();
        this.notifyConnect();
      } else {
        uni.hideLoading();
        // 蓝牙连接失败,跳转到失败页面
        uni.redirectTo({
          url: "/pages/blefi/blefiFail",
        });
      }
    },
    startSMSTimer() {
      this.wifiCountInterval = setInterval(() => {
        this.wifiCountDown--;
        if (this.wifiCountDown <= 0) {
          clearInterval(this.wifiCountInterval);
          this.wifiCountInterval = null;
          uni.hideLoading();
          // 蓝牙连接wifi失败
          uni.redirectTo({
            url: "/pages/blefi/wifiFile",
          });
        }
      }, 1000);
    },
    sendSSID() {
      // SSID转UTF-8
      let password = this.utf16to8(this.wifiSSID);

      let u8buffer = new Uint8Array(password.length);
      for (var i = 0; i < password.length; i++) {
        u8buffer[i] = password.charCodeAt(i);
      }
      this.bleSendCMD(
        this.dataEnum.PACKAGE_VALUE,
        this.dataEnum.SUBTYPE_STA_WIFI_SSID,
        0,
        u8buffer
      );
    },
    utf16to8(str) {
      var out, i, len, c;
      out = "";
      len = str.length;
      for (i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if (c >= 0x0001 && c <= 0x007f) {
          out += str.charAt(i);
        } else if (c > 0x07ff) {
          out += String.fromCharCode(0xe0 | ((c >> 12) & 0x0f));
          out += String.fromCharCode(0x80 | ((c >> 6) & 0x3f));
          out += String.fromCharCode(0x80 | ((c >> 0) & 0x3f));
        } else {
          out += String.fromCharCode(0xc0 | ((c >> 6) & 0x1f));
          out += String.fromCharCode(0x80 | ((c >> 0) & 0x3f));
        }
      }
      return out;
    },
    sendPASSWORD() {
      let password = this.password;
      let u8buffer = new Uint8Array(password.length);
      for (var i = 0; i < password.length; i++) {
        u8buffer[i] = password.charCodeAt(i);
      }
      this.bleSendCMD(
        this.dataEnum.PACKAGE_VALUE,
        this.dataEnum.SUBTYPE_STA_WIFI_PASSWORD,
        0,
        u8buffer
      );
    },
    notifyConnect() {
      let password = this.password;
      let u8buffer = new Uint8Array(password.length);
      for (var i = 0; i < password.length; i++) {
        u8buffer[i] = password.charCodeAt(i);
      }
      this.bleSendCMD(
        this.controllEnum.PACKAGE_VALUE,
        this.controllEnum.SUBTYPE_CONNECT_WIFI,
        0,
        u8buffer
      );
    },
    //ESP32的蓝牙配网命令接口
    bleSendCMD(CMD, subCMD, frameControl, payload) {
      var newValue = new ArrayBuffer(payload.length + 6);
      var u8array = new Uint8Array(newValue);
      var LSB_Type = ((subCMD & 0x3f) << 2) | (CMD & 0x03);

      u8array[0] = LSB_Type;
      u8array[1] = frameControl;
      u8array[2] = this.bleSendSequence;
      u8array[3] = payload.length;
      for (let i = 0; i < payload.length; i++) {
        u8array[4 + i] = payload[i];
      }
      this.bleSendSequence++;

      if (this.connected) {
        wx.writeBLECharacteristicValue({
          deviceId: this.bleInfo.deviceId,
          serviceId: this.bleInfo.writeServiceId,
          characteristicId: this.bleInfo.writeCharaterId,
          value: newValue,
        });
      }
    },
  },
};
</script>

4. 手机连接蓝牙失败、蓝牙连接WiFi成功/失败(关闭蓝牙连接)

<script>
export default {
  onLoad() {
   let deviceId = uni.getStorageSync("blefiInfo").deviceId
    uni.closeBLEConnection({
      deviceId: deviceId,
    });
  },
};
</script>