bluWKM.js 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. // 安卓平台上,在调用 notifyBLECharacteristicValueChange 成功后立即调用 writeBLECharacteristicValue 接口,在部分机型上会发生 10008 系统错误
  2. // var http = require("../utils/config.js");
  3. var interval = null;
  4. const cmd = {
  5. heartBeat: 'heart', // 心跳包
  6. unlock: 'openBike', // 开锁命令
  7. lock: 'lock', // 开锁命令
  8. bell: 'bellBike', // 关锁命令
  9. temporaryUnlockBike: 'temporaryUnlockBike', // 关锁命令
  10. temporaryLockBike: 'temporaryLockBike', // 关锁命令
  11. batteryUnlock: 'batteryUnlock', // 关锁命令
  12. batteryLock: 'batteryLock', // 关锁命令
  13. // login: 'login', // 关锁命令
  14. status: 'status', // 关锁命令
  15. reboot: 'reboot'
  16. }
  17. const errorCode = {
  18. no_connection: 10006, //失去连接
  19. no_service: 10004, //没有找到指定服务
  20. apdater_no_avilable: 10001, //当前蓝牙适配器不可用
  21. discovery_timeOut: 1100, //扫描失败
  22. connet_timeOut: 10003 //连接超时
  23. }
  24. const GetBluUrl = 'https://bike.hanyiyun.com/app-api/bike/getKey';
  25. let util = require('./bluUtil.js');
  26. let dataTransition = require('./dataTransition.js');
  27. class BluetoothManager {
  28. constructor() {
  29. this._connectDeviceName = 'shanxiango'
  30. this._isFoundDevice = false
  31. this._deviceId = ''
  32. this._serviceId = ''
  33. this._bikeMainId = ''
  34. this._mac = '',
  35. this._sequenceId = 10
  36. this._characteristicId = ''
  37. this._characteristicId_write = ''
  38. this._discovering = false
  39. this.discoveryTimeOut = 10 * 1000
  40. this.isConnecting = false
  41. this.isAuth = false
  42. this.connnectTimeOut = 5 * 1000 //连接超时时间
  43. this.hardwareCallbackTimeOut = 5 * 1000 //硬件回调超时时间
  44. this.adapterStateChangeCallBack = undefined
  45. this.onConnectionStateChange = undefined
  46. this.heartTimer = ''
  47. // 处理接受数据
  48. this._receiveLength = 0
  49. this._receiveData = ''
  50. // this.initialNotification()
  51. this.readyStopDiscovery = false //标记准备关闭扫描
  52. this.instructions = '' //记录指令
  53. this.writeIndex = 0
  54. }
  55. /*******初始化各种回调**********/
  56. initialNotification() {
  57. var that = this;
  58. console.log('initialNotification')
  59. // this.getConnectedBluetoothDevices()
  60. // 监听蓝牙适配器状态改变
  61. uni.showLoading({
  62. title: '蓝牙连接中'
  63. })
  64. uni.onBluetoothAdapterStateChange(
  65. res => {
  66. console.log('onBluetoothAdapterStateChange', res)
  67. // this.connectDeivece(this._bikeMainId,this.instructions)
  68. if (that.adapterStateChangeCallBack) {
  69. that.adapterStateChangeCallBack(res)
  70. }
  71. if (res.available == false) {
  72. this.isConnecting = false;
  73. }
  74. }
  75. )
  76. // // 监听扫描到的设备
  77. uni.onBluetoothDeviceFound(
  78. res => {
  79. console.log('监听扫描到的设备')
  80. if (that._isFoundDevice) {
  81. return
  82. }
  83. console.log(res)
  84. for (var i = 0; i < res.devices.length; i++) {
  85. const device = res.devices[i];
  86. var name = device.name
  87. console.log(name, device.deviceId)
  88. if (name === 'shanxiango') {
  89. if (device.localName != name) return;
  90. if (name != that._connectDeviceName) return;
  91. let bf = device.advertisData.slice(2, 10);
  92. var abc = util.ab2hex(bf)
  93. let contentArr = util.strAverage2Arr(abc, 2)
  94. contentArr.reverse();
  95. var string = contentArr.join('').toUpperCase() //mac地址
  96. console.log(string, 'Mead===>', res.devices[i], that._mac)
  97. if (!that._isFoundDevice && name == that._connectDeviceName) {
  98. // 获取车辆中控编号
  99. console.log(that._mac)
  100. if (string == that._mac) {
  101. console.log('-------found ---', device.name, string)
  102. console.log(device)
  103. console.log(device.deviceId)
  104. that._isFoundDevice = true
  105. that._deviceId = device.deviceId
  106. if (that.deviceFoundBlock) {
  107. that.deviceFoundBlock(device.deviceId)
  108. }
  109. break
  110. // uni.stopBluetoothDevicesDiscovery()
  111. }
  112. }
  113. }
  114. }
  115. return
  116. }
  117. )
  118. // 监听蓝牙连接状态
  119. uni.onBLEConnectionStateChange(
  120. res => {
  121. console.log(res)
  122. console.log('监听蓝牙连接状态', res, this._deviceId)
  123. this.isConnecting = res.connected
  124. if (res.deviceId == this._deviceId && res.connected == false) {
  125. console.log('onBLEConnectionStateChange fail', this._connectionFailBlock);
  126. if (this._connectionFailBlock) {
  127. // uni.showModal({
  128. // title: '提示',
  129. // content: '蓝牙连接超时',
  130. // showCancel: false
  131. // })
  132. uni.hideLoading()
  133. this._connectionFailBlock(res)
  134. this._connectionFailBlock = undefined
  135. }
  136. if (this.onConnectionStateChange) {
  137. this.onConnectionStateChange(res)
  138. }
  139. uni.closeBLEConnection({
  140. deviceId: this._deviceId,
  141. success: function(res) {
  142. console.log('closeBLEConnection', res)
  143. },
  144. })
  145. }
  146. }
  147. )
  148. // 监听特征值变化
  149. uni.onBLECharacteristicValueChange(
  150. characteristic => {
  151. console.log('监听特征值变化', characteristic)
  152. if (characteristic.value) {
  153. let res = characteristic.value
  154. let resData = util.ab2hex(res.value);
  155. if (this._receiveLength == 0) {
  156. this._receiveLength = parseInt(resData.slice(8, 12), 16)
  157. }
  158. this._receiveData += resData
  159. if (this._receiveData.length === (this._receiveLength * 2 + 16)) {
  160. let _receiveData = this._receiveData
  161. console.log(_receiveData, '_receiveData')
  162. let flay = _receiveData.slice(0, 4)
  163. let crc16 = _receiveData.slice(12, 16);
  164. let systemState = _receiveData.slice(4, 6); //4c
  165. let sequenceId_16 = _receiveData.slice(6, 8); //0a
  166. let body = _receiveData.slice(16)
  167. let contentArr = util.addFlagBeforeArr(util.strAverage2Arr(body, 2));
  168. //校检数据
  169. if (parseInt(dataTransition.getCRC16(contentArr), 16) == parseInt(crc16, 16)) {
  170. let value = util.hexStringToArrayBuffer(`aa12${systemState}${sequenceId_16}00000000`);
  171. if (flay === 'aa10') {
  172. if (body.indexOf('aa10550b') > -1) {
  173. if (this.getRandomSuccessBlock) {
  174. this.getRandomSuccessBlock(body)
  175. this.getRandomSuccessBlock = undefined
  176. }
  177. }
  178. console.log('指令发送成功', body)
  179. } else if (flay === 'aa00') {} else if (flay === 'aa30') {
  180. console.log('校检错误')
  181. } else {
  182. // this.writeBLECharacteristicValue(value)
  183. // that.analysisBLEContent(body)
  184. }
  185. }
  186. // 返回ACK
  187. this._receiveLength = 0
  188. this._receiveData = ''
  189. }
  190. }
  191. }
  192. )
  193. }
  194. failToGetConnected() {
  195. var that = this;
  196. if (!that.getConnectedTimer) {
  197. clearTimeout(that.getConnectedTimer);
  198. that.getConnectedTimer = null;
  199. }
  200. that.getConnectedTimer = setTimeout(function() {
  201. uni.getBluetoothAdapterState({
  202. success: function(res) {
  203. console.log(res);
  204. var available = res.available;
  205. if (!available) {
  206. uni.showLoading({
  207. title: '请开蓝牙',
  208. icon: 'loading',
  209. duration: 2000
  210. })
  211. } else {
  212. if (!that.connectedDevice['state']) {
  213. that.getConnectedBluetoothDevices();
  214. }
  215. }
  216. },
  217. fail: function(err) {
  218. console.log(err);
  219. }
  220. })
  221. }, 3000);
  222. }
  223. /***********初始化接口***************/
  224. connectDeivece(bikeMainId, command = false) {
  225. console.log(this.isConnecting, this._bikeMainId, bikeMainId, cmd)
  226. this.instructions = command;
  227. // this._bikeMainId = bikeMainId;
  228. // this.isConnecting = true;
  229. if (this.isConnecting && bikeMainId == this._bikeMainId) {
  230. return new Promise(
  231. (resolve, reject) => {
  232. if (command == cmd.unlock) {
  233. this.unlockBike()
  234. } else if (command == cmd.lock) {
  235. this.lockBike()
  236. } else if (command == cmd.bell) {
  237. this.play_voice()
  238. } else if (command == cmd.batteryUnlock) {
  239. this.diankai()
  240. } else if (command == cmd.reboot) {
  241. this.chongqi()
  242. }
  243. resolve(true)
  244. return
  245. }
  246. )
  247. } else {
  248. if (this._deviceId) {
  249. this.closeConnection(this._deviceId)
  250. }
  251. }
  252. this._bikeMainId = bikeMainId //当前车辆编号
  253. // 初始化蓝牙
  254. this.initialNotification()
  255. return this.openAdapter().then(res => {
  256. return this.getSecretKey()
  257. }).then(res => {
  258. return this.startDiscovery()
  259. }).then(
  260. res => {
  261. console.log('startDiscovery---------', res)
  262. this._discovering = true
  263. // 等待发现设备
  264. return this.waitForDeviceFound()
  265. },
  266. reject => {
  267. console.log(reject)
  268. uni.showToast({
  269. title: '连接失败请检查蓝牙',
  270. icon: 'none'
  271. })
  272. }
  273. ).then(
  274. res => {
  275. console.log('stopDiscovery---------')
  276. this.readyStopDiscovery = true
  277. //关闭扫描
  278. return this.stopDiscovery()
  279. }
  280. ).then(
  281. res => {
  282. this.readyStopDiscovery = false
  283. this._discovering = false
  284. console.log('createConnection---------', res)
  285. //开始连接设备
  286. console.log(this._deviceId)
  287. return this.createConnection(this._deviceId)
  288. }
  289. ).then(
  290. res => {
  291. console.log('getServices---------', res)
  292. // 获取服务
  293. return this.getServices(this._deviceId)
  294. }
  295. ).then(
  296. res => {
  297. console.log('getCharacteristics---------', res)
  298. // 获取特征值
  299. console.log(this._deviceId)
  300. console.log(this._serviceId)
  301. return this.getCharacteristics(this._deviceId, this._serviceId)
  302. }
  303. ).then(
  304. res => {
  305. console.log('openNotifyChsValueChange---------', res)
  306. // 开启notify通道
  307. console.log('开启notify通道')
  308. console.log(this._deviceId, '=>', this._serviceId, '<++', this._characteristicId)
  309. switch (uni.getSystemInfoSync().platform) {
  310. case 'android':
  311. console.log('客户端是Android')
  312. return this.openNotifyChsValueChange(this._deviceId, this._serviceId, this._characteristicId_write)
  313. break;
  314. case 'ios':
  315. console.log('客户端是iOS')
  316. return this.openNotifyChsValueChange(this._deviceId, this._serviceId, this._characteristicId)
  317. break;
  318. }
  319. }
  320. )
  321. .then(
  322. res => {
  323. return this.onBLECharacteristicValueChange()
  324. }
  325. ).then(
  326. res => {
  327. if (command == cmd.unlock) {
  328. return this.unlockBike()
  329. } else if (command == cmd.lock) {
  330. return this.lockBike()
  331. } else if (command == cmd.bell) {
  332. return this.play_voice()
  333. } else if (command == cmd.batteryUnlock) {
  334. return this.diankai()
  335. } else if (command == cmd.reboot) {
  336. return this.chongqi()
  337. }
  338. return
  339. }
  340. )
  341. }
  342. // 监听特征值变化
  343. onBLECharacteristicValueChange() {
  344. let that = this
  345. uni.onBLECharacteristicValueChange(
  346. characteristic => {
  347. console.log('onBLECharacteristicValueChange', characteristic)
  348. setTimeout(function() {
  349. uni.showToast({
  350. title: '请求成功',
  351. icon: 'none'
  352. })
  353. }, 1000)
  354. // if (characteristic.value) {
  355. // let res = characteristic.value
  356. // let resData = util.ab2hex(res);
  357. // // 4244 00 04 0a0a0505
  358. // // 0a 01 01 a463
  359. // // mead
  360. // let resDatas = resData.split('4244').filter((res) => {
  361. // return res
  362. // }).map((res) => {
  363. // return '4244' + res
  364. // })
  365. // resDatas.forEach(res_data => {
  366. // //业务
  367. // console.log(res_data, 'resData')
  368. // let data = res_data.slice(0, -4)
  369. // console.log(data, 'data')
  370. // if (this.instruct != cmd.bell) {
  371. // this.writeIndex = this.writeIndex + 1
  372. // var zhiling = uni.getStorageSync('zhiling');
  373. // var arr1 = [];
  374. // if (zhiling == '' || zhiling == undefined) {
  375. // arr1 = arr1.concat(data)
  376. // } else {
  377. // arr1 = zhiling.concat(data)
  378. // }
  379. // uni.setStorageSync('zhiling', arr1)
  380. // var number = 1;
  381. // interval = setInterval(() => {
  382. // number += 1;
  383. // console.log(arr1)
  384. // console.log(data)
  385. // console.log(this.writeIndex)
  386. // console.log(arr1[this.writeIndex - 1])
  387. // if (arr1[this.writeIndex - 1] == data) {
  388. // console.log('111')
  389. // //成功响应 调接口告诉后台
  390. // clearInterval(interval)
  391. // if (this.instructions == cmd.unlock) {
  392. // var key5 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x0A', '0x07', '0x01', '0x02', '0x00', '0x00', '0x00', '0x00', '0x00']
  393. // let value2 = util.CRC(key5)
  394. // var value3 = '424400010A0A05050A0701020000000000' + value2
  395. // this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value3), '123')
  396. // this.instructions = cmd.bell
  397. // }
  398. // if (this.instructions == cmd.lock) {
  399. // //播放语音
  400. // var key5 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x0A', '0x07', '0x01', '0x01', '0x00', '0x00', '0x00', '0x00', '0x00']
  401. // let value2 = util.CRC(key5)
  402. // var value3 = '424400010A0A05050A0701010000000000' + value2
  403. // this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value3))
  404. // this.instructions = cmd.bell
  405. // }
  406. // return;
  407. // } else {
  408. // //未成功响应 再次发指令
  409. // if (number % 5 == 0) {
  410. // console.log(number)
  411. // //每5秒执行一次写入数据
  412. // if (this.instructions == cmd.unlock) {
  413. // this.unlockBike()
  414. // } else if (this.instructions == cmd.lock) {
  415. // this.lockBike()
  416. // } else if (this.instructions == cmd.bell) {
  417. // this.play_voice()
  418. // } else if (this.instructions == cmd.batteryUnlock) {
  419. // this.diankai()
  420. // } else if (this.instructions == cmd.reboot) {
  421. // this.chongqi()
  422. // }
  423. // clearInterval(interval)
  424. // }
  425. // }
  426. // if (number >= 30) {
  427. // //超时清空定时器
  428. // clearInterval(interval)
  429. // }
  430. // }, 1000);
  431. // }
  432. // let xiaojian = res_data.slice(res_data.length - 4)
  433. // let arr = [],
  434. // body = [];
  435. // for (let i = 0, index = 0; i < (data.length / 2); i++) {
  436. // arr.push('0x' + data.slice(index, index + 2))
  437. // if (index >= 16) {
  438. // body.push(data.slice(index, index + 2))
  439. // }
  440. // index = index + 2
  441. // }
  442. // let value = util.CRC(arr)
  443. // console.log(body)
  444. // console.log(value, 'value')
  445. // console.log(xiaojian, 'xiaojian')
  446. // if (value == xiaojian) {
  447. // console.log('数据正确')
  448. // switch (body[0]) {
  449. // case '01':
  450. // //获取ECU状态
  451. // break
  452. // case '02':
  453. // //电门开关
  454. // break
  455. // case '03':
  456. // //防盗开关
  457. // break
  458. // case '04':
  459. // //照明灯开关
  460. // break
  461. // case '05':
  462. // //开电池仓
  463. // break
  464. // case '06':
  465. // //后座锁开关
  466. // break
  467. // case '07':
  468. // //后轮锁开关
  469. // break
  470. // case '08':
  471. // //获取配置信息
  472. // break
  473. // case '09':
  474. // //综合参数配置
  475. // break
  476. // case '0a':
  477. // //语音设置
  478. // break
  479. // case '0b':
  480. // //重启设置
  481. // break
  482. // case '0c':
  483. // //获取ECU信息
  484. // break
  485. // case '0d':
  486. // //2.13 设置服务器域名(IP)和端口
  487. // break
  488. // case '0e':
  489. // //2.14 获取服务器域名(IP)和端口
  490. // break
  491. // case '0f':
  492. // //2.15 接单设置
  493. // break
  494. // }
  495. // }
  496. // });
  497. // // var resData = '424400040a0a05050a0101a463'
  498. // }
  499. if (characteristic.value) {
  500. let res = characteristic.value
  501. let resData = util.ab2hex(res);
  502. if (this._receiveLength == 0) {
  503. this._receiveLength = parseInt(resData.slice(8, 12), 16)
  504. }
  505. this._receiveData += resData
  506. if (this._receiveData.length === (this._receiveLength * 2 + 16)) {
  507. let _receiveData = this._receiveData
  508. console.log(_receiveData)
  509. let flay = _receiveData.slice(0, 4)
  510. let crc16 = _receiveData.slice(12, 16);
  511. let systemState = _receiveData.slice(4, 6); //4c
  512. let sequenceId_16 = _receiveData.slice(6, 8); //0a
  513. let dcArr = [];
  514. let body = _receiveData.slice(16)
  515. let contentArr = util.addFlagBeforeArr(util.strAverage2Arr(body, 2));
  516. //校检数据
  517. if (parseInt(dataTransition.getCRC16(contentArr), 16) == parseInt(crc16, 16)) {
  518. let response = util.hexStringToArrayBuffer(`aa12${systemState}${sequenceId_16}00000000`);
  519. if (flay === 'aa10') {
  520. console.log(this.getRandomSuccessBlock, 'getRandomSuccessBlock')
  521. if (this.getRandomSuccessBlock) {
  522. this.getRandomSuccessBlock(body)
  523. this.getRandomSuccessBlock = undefined
  524. }
  525. console.log('指令发送成功', body)
  526. } else if (flay === 'aa00') {} else if (flay === 'aa30') {
  527. console.log('CRC校验失败', body);
  528. } else {
  529. //响应数据
  530. // that.writeBLECharacteristicValue(response, undefined)
  531. // that.analysisBLEContent(body)
  532. }
  533. }
  534. this._receiveLength = 0
  535. this._receiveData = ''
  536. }
  537. }
  538. }
  539. )
  540. }
  541. //获取秘钥
  542. getSecretKey(box_no) {
  543. if (!box_no) box_no = this._bikeMainId
  544. let that = this
  545. console.log(box_no)
  546. return new Promise(function(res, rej) {
  547. let param = {
  548. box_no: box_no //我公司是通过设备编号获取的密钥
  549. };
  550. uni.request({
  551. url: 'https://bike.saas.yufengjiayun.com/app-api/bike/getKey',
  552. data: param,
  553. header: {
  554. Authorization: 'bearer' + ' ' + uni.getStorageSync('token').token
  555. },
  556. success: (resp) => {
  557. console.log(resp)
  558. that._mac = resp.data.key
  559. res(resp.data.key);
  560. },
  561. fail: (err) => {
  562. console.log(err)
  563. }
  564. })
  565. });
  566. }
  567. waitForDeviceFound() {
  568. return new Promise(
  569. (resolve, reject) => {
  570. this.deviceFoundBlock = resolve
  571. console.log('waitForDeviceFound ----')
  572. console.log(this._discovering, '<==>', !this._isFoundDevice)
  573. setTimeout(() => {
  574. console.log('waitForDeviceFound ++++', this._discovering, this._isFoundDevice)
  575. // 全局断了,_discovering 变为false(发心跳包失败,closeApater引起)
  576. console.log(this._discovering, '==>', !this._isFoundDevice)
  577. if (this._discovering && !this._isFoundDevice) {
  578. uni.showToast({
  579. title: '蓝牙扫描超时',
  580. icon: 'none'
  581. })
  582. console.log('waitForDeviceFound 扫描超时00', 'isconnecting :', this.isConnecting)
  583. reject({
  584. errCode: errorCode.discovery_timeOut
  585. })
  586. }
  587. if (this._discovering) {
  588. this.stopDiscovery()
  589. }
  590. }, this.discoveryTimeOut);
  591. }
  592. )
  593. }
  594. disconnecDevice() {
  595. return this.closeConnection(this._deviceId).then(
  596. res => {
  597. return this.closeAdapter()
  598. }
  599. )
  600. }
  601. /***********初始化接口***************/
  602. /***********蓝牙处理*************/
  603. // 打开适配器
  604. openAdapter() {
  605. console.log('打开适配器')
  606. return new Promise(
  607. (resolve, reject) => {
  608. uni.openBluetoothAdapter({
  609. success: resolve,
  610. fail: reject
  611. })
  612. }
  613. )
  614. }
  615. // 关闭适配器
  616. closeAdapter() {
  617. console.log('关闭适配器')
  618. this._isFoundDevice = false
  619. this._discovering = false
  620. this.isConnecting = false
  621. this.adapterStateChangeCallBack = undefined
  622. this.onConnectionStateChange = undefined
  623. return new Promise(
  624. (resolve, reject) => {
  625. this.isOpenAdpater = false
  626. this.isConnecting = false
  627. uni.closeBluetoothAdapter({
  628. success: resolve,
  629. fail: reject
  630. })
  631. }
  632. )
  633. }
  634. // 开启扫描
  635. startDiscovery() {
  636. console.log('开启扫描')
  637. return new Promise(
  638. (resolve, reject) => {
  639. uni.startBluetoothDevicesDiscovery({
  640. services: ['FFF0'],
  641. allowDuplicatesKey: true,
  642. success: resolve,
  643. fail: reject
  644. })
  645. }
  646. )
  647. }
  648. // 关闭扫描
  649. stopDiscovery() {
  650. console.log('关闭扫描')
  651. this._isFoundDevice = false;
  652. uni.hideLoading()
  653. return new Promise(
  654. (resolve, reject) => {
  655. uni.stopBluetoothDevicesDiscovery({
  656. success: resolve,
  657. fail: reject
  658. })
  659. }
  660. )
  661. }
  662. // 创建连接
  663. createConnection(deviceId) {
  664. console.log('创建连接')
  665. console.log(deviceId)
  666. return new Promise(
  667. (resolve, reject) => {
  668. this._connectionFailBlock = undefined
  669. this._connectionFailBlock = reject
  670. // this._needToToastConnectError = true
  671. console.log(deviceId)
  672. console.log(this.connnectTimeOut)
  673. uni.createBLEConnection({
  674. deviceId: deviceId,
  675. // timeout: this.connnectTimeOut,
  676. success: res => {
  677. console.log('--------createConnection success', res)
  678. // 创建成果并不代表发指令成功,有可能连接连接创建成功了,但是发指令的时候连接中断了
  679. resolve(res)
  680. },
  681. fail: error => {
  682. console.log('--------createConnection fail', error)
  683. this._connectionFailBlock = undefined
  684. reject(error)
  685. }
  686. })
  687. }
  688. )
  689. }
  690. // 关闭连接
  691. closeConnection(deviceId) {
  692. console.log('关闭连接')
  693. return new Promise(
  694. (resolve, reject) => {
  695. uni.closeBLEConnection({
  696. deviceId: deviceId,
  697. success: resolve,
  698. fail: reject
  699. })
  700. }
  701. )
  702. }
  703. // 获取服务
  704. getServices(deviceId) {
  705. console.log('获取服务')
  706. let that = this
  707. console.log(deviceId)
  708. return new Promise(
  709. (resolve, reject) => {
  710. this._connectionFailBlock = undefined
  711. this._connectionFailBlock = reject
  712. setTimeout(function() {
  713. uni.getBLEDeviceServices({
  714. deviceId: deviceId,
  715. success: res => {
  716. console.log(res)
  717. // if (res.errCode === 0) {
  718. res.services.forEach(function(value, index, array) {
  719. console.log("设备所有的UUId", value.uuid);
  720. if (value.uuid.indexOf('FFF0') > -1) { //找到serviceId包含FEF6的服务
  721. that._serviceId = array[index].uuid;
  722. // resolve(serviceId)
  723. console.log(that._serviceId)
  724. }
  725. })
  726. // }
  727. resolve(res)
  728. },
  729. fail: error => {
  730. console.log('getServices fail', error)
  731. reject(error)
  732. }
  733. })
  734. }, 3000)
  735. }
  736. )
  737. }
  738. // 获取特征值
  739. getCharacteristics(deviceId, serviceId) {
  740. console.log('获取特征值')
  741. let that = this
  742. console.log(deviceId)
  743. console.log(serviceId)
  744. return new Promise(
  745. (resolve, reject) => {
  746. this._connectionFailBlock = undefined
  747. this._connectionFailBlock = reject
  748. uni.getBLEDeviceCharacteristics({
  749. deviceId: deviceId,
  750. serviceId: serviceId,
  751. success: res => {
  752. console.log('getCharacteristics success', res)
  753. for (let i = 0; i < res.characteristics.length; i++) {
  754. if (res.characteristics[i].properties.notify && !res.characteristics[i].properties.write) {
  755. that._characteristicId = res.characteristics[i].uuid; //读的uuid
  756. console.log('读')
  757. }
  758. if (res.characteristics[i].properties.write) {
  759. that._characteristicId_write = res.characteristics[i].uuid; //写的uuid
  760. console.log('写')
  761. }
  762. }
  763. resolve(res)
  764. },
  765. fail: error => {
  766. console.log('getCharacteristics fail', error)
  767. reject(error)
  768. }
  769. })
  770. }
  771. )
  772. }
  773. // 开启notify功能,订阅特征值
  774. openNotifyChsValueChange(deviceId, serviceId, characteristicId) {
  775. let that = this;
  776. console.log(deviceId, serviceId, characteristicId)
  777. console.log(characteristicId, 'characteristicId')
  778. console.log(serviceId, 'serviceId')
  779. console.log(deviceId, 'deviceId')
  780. return new Promise(
  781. (resolve, reject) => {
  782. this._connectionFailBlock = undefined
  783. this._connectionFailBlock = reject
  784. uni.notifyBLECharacteristicValueChange({
  785. deviceId: deviceId,
  786. serviceId: serviceId,
  787. characteristicId: characteristicId,
  788. state: true,
  789. success: res => {
  790. console.log('openNotifyChsValueChange success', res)
  791. resolve(res)
  792. },
  793. fail: error => {
  794. console.log('openNotifyChsValueChange fail', error)
  795. reject(error)
  796. this.connectDeivece(this._bikeMainId, this.instructions)
  797. }
  798. })
  799. }
  800. )
  801. }
  802. //开锁
  803. unlockBike() {
  804. uni.showLoading({
  805. title: '开锁中...'
  806. })
  807. var key2 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x02', '0x01', '0x01']
  808. let value = util.CRC(key2)
  809. console.log(value)
  810. var value1 = '424400010A0A0505020101' + value
  811. console.log(value1)
  812. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value1), '123')
  813. //播放语音
  814. var key5 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x0A', '0x07', '0x01', '0x02', '0x00',
  815. '0x00', '0x00', '0x00', '0x00'
  816. ]
  817. let value2 = util.CRC(key5)
  818. var value3 = '424400010A0A05050A0701020000000000' + value2
  819. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value3), '123')
  820. }
  821. //发送关锁指令
  822. lockBike() {
  823. uni.showLoading({
  824. title: '关锁中...'
  825. })
  826. var key2 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x02', '0x01', '0x00']
  827. let value = util.CRC(key2)
  828. console.log(value)
  829. var value1 = '424400010A0A0505020100' + value
  830. console.log(value1)
  831. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value1))
  832. //播放语音
  833. var key5 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x0A', '0x07', '0x01', '0x01', '0x00',
  834. '0x00', '0x00', '0x00', '0x00'
  835. ]
  836. let value2 = util.CRC(key5)
  837. var value3 = '424400010A0A05050A0701010000000000' + value2
  838. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value3))
  839. }
  840. play_voice() {
  841. uni.showLoading({
  842. title: '响铃中...'
  843. })
  844. var key5 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x0A', '0x07', '0x01', '0x09', '0x00',
  845. '0x00', '0x00', '0x00', '0x00'
  846. ]
  847. let value = util.CRC(key5)
  848. console.log(value)
  849. var value1 = '424400010A0A05050A0701090000000000' + value
  850. console.log(value1)
  851. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value1))
  852. }
  853. diankai() {
  854. uni.showLoading({
  855. title: '开电池锁中...'
  856. })
  857. var key3 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x05', '0x01', '0x01']
  858. let value = util.CRC(key3)
  859. console.log(value)
  860. var value1 = '424400010A0A0505050101' + value
  861. console.log(value1)
  862. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value1))
  863. }
  864. chongqi() {
  865. uni.showLoading({
  866. title: '重启中...'
  867. })
  868. var key3 = ['0x42', '0x44', '0x00', '0x01', '0x0A', '0x0A', '0x05', '0x05', '0x0B', '0x07', '0x01', '0x01', '0x01',
  869. '0x01', '0x01', '0x01', '0x01'
  870. ]
  871. let value = util.CRC(key3)
  872. console.log(value)
  873. var value1 = '424400010A0A05050B0701010101010101' + value
  874. console.log(value1)
  875. this.writeBLECharacteristicValue(util.hexStringToArrayBuffer(value1))
  876. }
  877. //发送数据
  878. writeBLECharacteristicValue(data, reject) {
  879. console.log(this._deviceId, this._serviceId, this._characteristicId_write, '发送参数');
  880. console.log(data)
  881. uni.writeBLECharacteristicValue({
  882. deviceId: this._deviceId,
  883. serviceId: this._serviceId,
  884. characteristicId: this._characteristicId_write,
  885. value: data,
  886. success: res => {
  887. console.log('writeBLECharacteristicValue success', res)
  888. },
  889. fail: err => {
  890. console.log('writeBLECharacteristicValue fail', err, this._deviceId, this._serviceId, this._characteristicId)
  891. // if(){
  892. this.isConnecting = false;
  893. // }
  894. // reject(err)
  895. this.closeConnection(this._deviceId)
  896. },
  897. complete(res) {
  898. console.log(res, 'complete')
  899. switch (uni.getSystemInfoSync().platform) {
  900. case 'android':
  901. console.log('客户端是Android')
  902. uni.showToast({
  903. title:'操作成功'
  904. })
  905. return
  906. break;
  907. case 'ios':
  908. console.log('客户端是iOS')
  909. return
  910. break;
  911. }
  912. }
  913. })
  914. }
  915. /**
  916. * 根据指令码生成指令帧数据
  917. * commandCode --> 指令码
  918. * array --> 额为携带的数据
  919. */
  920. // generateCommandData(commandCode, array) {
  921. // let sequenceId_16 = dataTransition.getSequenceId(this._sequenceId);
  922. // // this._sequenceId++;
  923. // let sendData = '';
  924. // console.log(commandCode)
  925. // // console.log(sequenceId_16)
  926. // switch (commandCode) {
  927. // case cmd.unlock:
  928. // sendData = '03 00 02 01 00';
  929. // break
  930. // case cmd.lock:
  931. // sendData = '03 00 01 01 01';
  932. // break;
  933. // case cmd.bell:
  934. // sendData = '03 00 04 01 01';
  935. // break;
  936. // case cmd.batteryUnlock:
  937. // sendData = '03 00 05 01 01';
  938. // break;
  939. // case cmd.batteryLock:
  940. // sendData = '03 00 05 01 00';
  941. // break;
  942. // case cmd.temporaryUnlockBike:
  943. // sendData = '03 00 02 01 00 07 01 01';
  944. // break
  945. // case cmd.temporaryLockBike:
  946. // sendData = '03 00 07 01 08';
  947. // break;
  948. // // case cmd.login:
  949. // // // let secretKey = array.key.toString().trim().toLowerCase();
  950. // // console.log(secretKey)
  951. // // // let c = secretKey.toString().replace(/\s+/g, "");
  952. // // // let cLength = dataTransition.getSecretKeyLength(c);
  953. // // //发送内容
  954. // // let send = `02 00 01`; //02 连接命令 01连接请求 cLength秘钥长度。
  955. // // sendData = `${send} ${secretKey}`;
  956. // // console.log(sendData, 'sendValue')
  957. // // break;
  958. // case cmd.status:
  959. // sendData = '42 44 00 01 0A 0A 05 05'
  960. // console.log(sendData)
  961. // break
  962. // case cmd.ack:
  963. // sendData = array.data
  964. // break;
  965. // }
  966. // let header = dataTransition.header(sendData);
  967. // console.log(header)
  968. // if (commandCode == 'responseAck') {
  969. // header = ''
  970. // }
  971. // let data = header + sendData.replace(/\s+/g, "");
  972. // console.log(data)
  973. // console.log(`发送${commandCode}指令`, data);
  974. // return data;
  975. // }
  976. /*******util*********/
  977. }
  978. // export {
  979. // BluetoothManager
  980. // }
  981. module.exports = {
  982. BluetoothManager: BluetoothManager,
  983. BtErrorCode: errorCode,
  984. CMD: cmd
  985. }