| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- /**
- * 1. 获取本机蓝牙适配器状态 wx.getBluetoothAdapterState
- * 2. 初始化蓝牙适配器 wx.openBluetoothAdapter()
- * 3. 启动蓝牙发现 wx.wx.startBluetoothDevicesDiscovery()
- * 4. 获取扫描到的所有设备 wx.getBluetoothDevices()
- *
- *
- * 参数:
- * @callback function 回调函数,用于接收返回值
- *
- * 返回值:
- * ret:{isBluetoothAvailable:true, isBluetoothSearching:true, scanList:[]}
- * isBluetoothAvailable boolean 蓝牙适配器状态,true表示初始化蓝牙适配器成功
- * isBluetoothSearching boolean 蓝牙搜索状态,true表示开启蓝牙发现成功
- * scanList array 搜索的设备列表
- */
- function scanDevices(callback) {
- if (typeof callback != "function") {
- // console.log('Parameter callback is not a function');
- return;
- }
- ; //scanList格式如下:
- //[{RSSI:-xx, advertisServiceUUIDs:[], deviceId:'', name:''},{...}]
- //注意:Android系统的deviceId是设备的mac地址,iOS系统的deviceId是设备的UUID
- var ret = {
- isBluetoothAvailable: false,
- isBluetoothSearching: false,
- scanList: []
- };
- /**
- * 获取蓝牙适配器状态
- *
- */
- uni.getBluetoothAdapterState({
- success: function (res) {
- // console.log("---getBluetoothAdapterState--success:", res)
- ret.isBluetoothAvailable = res.available;
- ret.isBluetoothSearching = res.discovering;
- },
- fail: function (res) {
- console.log("---getBluetoothAdapterState--fail:", res);
- },
- complete: function (res) {
- /**
- * 初始化蓝牙
- */
- if (!ret.isBluetoothAvailable) {
- uni.openBluetoothAdapter({
- success: function (res) {
- // console.log("---openBluetoothAdapter--success:", res);
- ret.isBluetoothAvailable = true;
- startBluetoothDiscoveryAndScanDevice(ret, callback);
- },
- fail: function (res) {
- // console.log("---openBluetoothAdapter--fail:", res);
- callback(ret); //蓝牙初始化失败,直接返回,不进行后续搜索操作
- return;
- }
- });
- } else {
- startBluetoothDiscoveryAndScanDevice(ret, callback);
- }
- }
- });
- }
- function startBluetoothDiscoveryAndScanDevice(ret, callback) {
- /**
- * 开启蓝牙发现
- */
- if (!ret.isBluetoothSearching) {
- uni.startBluetoothDevicesDiscovery({
- services: [],
- allowDuplicatesKey: true,
- success: function (res) {
- // console.log("---startBluetoothDevicesDiscovery--success: ", res);
- ret.isBluetoothSearching = res.isDiscovering;
- },
- fail: function (res) {// console.log('---startBluetoothDevicesDiscovery--fail:', res);
- // 刷新页面后,开启蓝牙发现失败,暂时忽略10008错误
- // if (res.errCode != 10008) {
- // callback(ret);
- // }
- },
- complete: function (res) {
- // console.log('---startBluetoothDevicesDiscovery--complete:', res)
- if (res.errCode === 0 || res.errCode === 10008) {
- scanBluetoothDevice(ret, callback);
- } else {
- callback(ret);
- }
- }
- });
- } else {
- scanBluetoothDevice(ret, callback);
- }
- }
- function scanBluetoothDevice(ret, callback) {
- /**
- * 获取扫描到的所有设备
- */
- setTimeout(function () {
- uni.getBluetoothDevices({
- success: function (res) {
- //{devices: Array[11], errMsg: "getBluetoothDevices:ok"}
- // console.log('---getBluetoothDevices--success:', res);
- console.log('---getBluetoothDevices--success:', res.devices);
- var devArr = []; //根据广播UUID进行设备列表筛选
- for (var i = 0; i < res.devices.length; i++) {
- if (!('advertisServiceUUIDs' in res.devices[i])) {
- delete res.devices[i];
- continue;
- }
- for (let j = 0; j < res.devices[i].advertisServiceUUIDs.length; j++) {
- if (res.devices[i].advertisServiceUUIDs[j].toUpperCase().indexOf('FEF5') != -1) {
- var devSn = res.devices[i].name; // console.log("devSn:", devSn);
- if (devSn.indexOf("-") >= 0) {
- devArr.push({
- "deviceId": res.devices[i].deviceId,
- "name": devSn.split("-")[1],
- "RSSI": res.devices[i].RSSI
- });
- }
- }
- }
- }
- ret.scanList = devArr;
- callback(ret);
- },
- fail: function (res) {
- console.log('---getBluetoothDevices--fail:', res);
- callback(ret);
- }
- });
- }, 3000);
- }
- /**
- *
- * 参数:
- * @deviceid String 参考scanDevices方法
- * @sendData String 发送到设备的开门指令
- * @callback function 回调函数,用于处理返回值
- *
- * 返回值:
- * ret{errCode:'', errMsg:'', receiveData:''}
- * errCode: 错误码, 0表示开门成功
- * errMsg: 错误信息,Ok表示开门成功
- * receiveData: 接收的设备消息,消息内容为ac1c8表示开门成功
- */
- function openDoor(deviceid, sendData, callback) {
- var ret = {
- errCode: 0,
- errMsg: 'Ok',
- receiveData: ''
- };
- if (typeof callback != "function") {
- ret.errCode = 6;
- ret.errMsg = 'parameter callback is not a function';
- callback(ret);
- return;
- } else if (typeof deviceid != "string" || deviceid === '') {
- ret.errCode = 4;
- ret.errMsg = 'deviceId is not a string type or is empty';
- callback(ret);
- return;
- } else if (typeof sendData != "string" || sendData === '') {
- ret.errCode = 5;
- ret.errMsg = 'sendData is not a string type or is empty';
- callback(ret);
- return;
- }
- var serviceId = '';
- var characteristics = [];
- var notifyCharacter = '';
- var writeCharacter = '';
- var readCharacter = '';
- var deviceId = deviceid.toUpperCase(); //BLE蓝牙连接
- uni.createBLEConnection({
- deviceId: deviceId,
- success: function (res) {
- // console.log('---createBLEConnection--success:', res);
- /**
- * 监听特定BLE设备连接状态变化
- */
- uni.onBLEConnectionStateChange(function (res) {// 该方法回调中可以用于处理连接意外断开等异常情况
- // console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`);
- }); //获取指定设备的所有服务
- uni.getBLEDeviceServices({
- deviceId: deviceId,
- success: function (res) {
- //筛选指定的服务UUID
- for (var i = 0; i < res.services.length; i++) {
- if (res.services[i].uuid.toLowerCase().indexOf('0886') != -1 || res.services[i].uuid.toLowerCase().indexOf('ffe0') != -1) {
- serviceId = res.services[i].uuid;
- break;
- }
- }
- /**
- * 获取指定服务下的所有特征值
- */
- uni.getBLEDeviceCharacteristics({
- deviceId: deviceId,
- serviceId: serviceId,
- success: function (res) {
- for (var i = 0; i < res.characteristics.length; i++) {
- if (res.characteristics[i].uuid.toLowerCase().indexOf('878b') != -1) {
- notifyCharacter = res.characteristics[i].uuid;
- } else if (res.characteristics[i].uuid.toLowerCase().indexOf('878c') != -1) {
- writeCharacter = res.characteristics[i].uuid;
- readCharacter = res.characteristics[i].uuid;
- }
- }
- /**
- * 启用低功耗蓝牙设备特征值变化时的 notify 功能
- */
- uni.notifyBLECharacteristicValueChange({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: notifyCharacter,
- state: true,
- success: function (res) {// console.log('---notifyBLECharacteristicValueChange--success:', res.errMsg);
- }
- });
- /**
- * 监听低功耗蓝牙设备的特征值变化
- */
- uni.onBLECharacteristicValueChange(function (res) {
- // console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`);
- let buffer = res.value;
- let dataView = new DataView(buffer);
- let receiveData = '';
- for (let i = 0; i < buffer.byteLength; i++) {
- receiveData += dataView.getUint8(i).toString(16);
- }
- if (sendData.length <= 20) {
- // 向蓝牙设备发送20字节16进制数据,如果不超过20字节数据,监听低功耗蓝牙设备的特征值变化,如果超过,就不监听
- if (receiveData != 'ac1c8') {
- ret.errCode = 7;
- ret.errMsg = "paramater 'sendData' is incorrect.";
- }
- ret.receiveData = receiveData;
- callback(ret);
- }
- }); //向蓝牙设备发送20字节16进制数据,超过20字节数据,分包续传
- var data = sendData;
- var buffer_size = data.length > 20 ? data.length / 2 : 20;
- var buffer = new ArrayBuffer(buffer_size);
- var dataView = new DataView(buffer);
- for (let i = 0; i < data.length / 2; i++) {
- var subData = data.slice(2 * i, 2 * i + 2);
- dataView.setUint8(i, parseInt('0x' + subData));
- }
- /**
- * 写入特征值下的二进制数据
- *
- */
- setTimeout(function () {
- var count = 0;
- if (buffer_size == 20) {
- count = 1;
- } else {
- count = 2;
- }
- var send_data_array = new Array();
- for (let i = 0; i < count; i++) {
- var start_buffer = i * 20;
- var end_buffer = (i + 1) * 20;
- if (end_buffer > buffer.byteLength) {
- end_buffer = buffer.byteLength;
- }
- var buffer_content = buffer.slice(start_buffer, end_buffer);
- if (buffer_content.byteLength > 0) {
- send_data_array.push(buffer_content);
- }
- }
- var send_index = 0;
- send_bledata_device(send_index, send_data_array);
- function send_bledata_device(send_index, send_data_array) {
- // console.log("----deviceId=" + deviceId + "--serviceId=" + serviceId + "--send_index=" + send_index);
- uni.writeBLECharacteristicValue({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: writeCharacter,
- value: send_data_array[send_index],
- success: function (res) {
- console.log('++++++++writeBLECharacteristicValue-success:', res);
- if (send_index < send_data_array.length - 1) {
- setTimeout(function () {
- send_index += 1;
- send_bledata_device(send_index, send_data_array);
- }, 250);
- } else {
- ret.errCode = 0;
- callback(ret);
- }
- },
- fail: function (res) {
- ret.errCode = res.errCode; //3
- ret.errMsg = 'writeBLECharacteristicValue fail';
- console.log('++++++++writeBLECharacteristicValue-fail-errorCode:', ret.errCode);
- callback(ret);
- }
- });
- }
- }, 500);
- },
- fail: function (res) {
- ret.errCode = res.errCode; //2
- ret.errMsg = 'getBLEDeviceCharacteristics fail';
- callback(ret);
- }
- });
- }
- });
- },
- fail: function (res) {
- ret.errCode = res.errCode; //1
- ret.errMsg = 'createBLEConnection fail';
- callback(ret);
- }
- });
- }
- module.exports = {
- scanDevices: scanDevices,
- openDoor: openDoor
- };
|