BlueMgr.js 30 KB

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