connection.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. import ble_store from "../store/bluetooth";
  2. import game_store from "../store/game";
  3. import Toast from "../../static/vant/toast/toast";
  4. import Notify from "../../static/vant/notify/notify";
  5. import {LOG_DEBUG, LOG_WECHAT, LOG_WECHAT_ERROR} from "./log";
  6. function getDeviceWriteInfo() {
  7. let deviceId = ble_store.getters.getDeviceId();
  8. let serviceId = ble_store.getters.getServiceId();
  9. let characteristicWriteId = ble_store.getters.getCharacteristicWriteId();
  10. let characteristicNotifyId = ble_store.getters.getCharacteristicNotifyId();
  11. return { deviceId, serviceId, characteristicWriteId, characteristicNotifyId};
  12. }
  13. /**
  14. * 判断一代脑机
  15. */
  16. function isJELLYFISH() {
  17. let $code = ble_store.getters.getDeviceSn();
  18. return $code.indexOf("JELLYFISH") >= 0;
  19. }
  20. /**
  21. * ArrayBuffer转16进度字符串示例
  22. * @param buffer
  23. * @returns {string}
  24. */
  25. function ab2hex(buffer) {
  26. const hexArr = Array.prototype.map.call(
  27. new Uint8Array(buffer), function (bit) {
  28. return ("00" + bit.toString(16)).slice(-2);
  29. }
  30. );
  31. return hexArr.join("");
  32. }
  33. /**
  34. * todo 解析hex
  35. * @param hexStr
  36. * @param count
  37. * @param start
  38. * @returns {string}
  39. */
  40. function doAnalysis(hexStr, count, start = 6) {
  41. let $result = "";
  42. //从下标6开始往后截取
  43. let $str = hexStr.substring(start);
  44. let $data = $str.substring(0, count * 2);
  45. for (let $i = 0; $i < $data.length; $i += 2) {
  46. let $code = parseInt($data.substring($i, $i+2), 16)
  47. $result += String.fromCharCode($code)
  48. }
  49. return $result;
  50. }
  51. export default {
  52. /**
  53. * 获取蓝牙设备服务
  54. * @param deviceId 脑机mac
  55. */
  56. getBLEDeviceServices(deviceId) {
  57. const that = this;
  58. wx.getBLEDeviceServices({
  59. deviceId,
  60. success: (res) => {
  61. LOG_DEBUG("获取蓝牙设备服务service:\n", JSON.stringify(res.services));
  62. for (let i = 0; i < res.services.length; i++) {
  63. LOG_DEBUG("第" + (i + 1) + "个UUID:" + res.services[i].uuid + "\n");
  64. if (res.services[i].uuid.indexOf('6E') !== -1 || res.services[i].uuid.indexOf('0000FFF0') !== -1) {
  65. // 获取蓝牙设备某个服务中所有特征值
  66. that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
  67. ble_store.setters.setServiceId(res.services[i].uuid);
  68. LOG_DEBUG("脑机deviceId(mac)", deviceId, "notifyServicesId:" + res.services[i].uuid);
  69. return;
  70. }
  71. }
  72. },
  73. fail() {
  74. let deviceId = wx.getStorageSync('deviceId');
  75. //断开蓝牙连接
  76. wx.closeBLEConnection({
  77. deviceId: deviceId
  78. });
  79. },
  80. });
  81. },
  82. /**
  83. * 获取蓝牙设备某个服务中所有特征值
  84. */
  85. getBLEDeviceCharacteristics(deviceId, serviceId) {
  86. const that = this;
  87. wx.getBLEDeviceCharacteristics({
  88. deviceId,
  89. serviceId,
  90. success: (res) => {
  91. LOG_DEBUG("获取服务", serviceId, "的特征值:\n", JSON.stringify(res));
  92. for (let i = 0; i < res.characteristics.length; i++) {
  93. let item = res.characteristics[i]
  94. if (item.properties.read) {
  95. LOG_DEBUG("第" + (i + 1) + ",该特征值可读:" + item.uuid);
  96. }
  97. if (item.properties.write) {
  98. LOG_DEBUG("第" + (i + 1) + ",该特征值可写:" + item.uuid);
  99. if(item.uuid.indexOf("0002") !== -1){
  100. ble_store.setters.setCharacteristicWriteId(item.uuid);
  101. //打开数据帧 (打开大包数据)
  102. that.SendOrder("ff", "打开数据帧");
  103. }
  104. }
  105. if (item.properties.notify || item.properties.indicate) {
  106. LOG_DEBUG("第" + (i + 1) + ",该特征值可监听:" + item.uuid);
  107. if(item.uuid.indexOf("0003") !== -1){
  108. ble_store.setters.setCharacteristicNotifyId(item.uuid);
  109. }
  110. // 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征。
  111. wx.notifyBLECharacteristicValueChange({
  112. deviceId: deviceId,
  113. serviceId: serviceId,
  114. characteristicId: item.uuid,
  115. state: true,
  116. success() {
  117. that.notifyDatas(null);
  118. LOG_DEBUG("init正在监听特征值:", item.uuid);
  119. }
  120. });
  121. }
  122. }
  123. },
  124. fail() {
  125. let deviceId = wx.getStorageSync('deviceId');
  126. //断开蓝牙连接
  127. wx.closeBLEConnection({
  128. deviceId: deviceId
  129. });
  130. },
  131. });
  132. },
  133. /**
  134. * 脑机连接教具
  135. */
  136. sendToyConnection(toyItem) {
  137. let that = this;
  138. if(toyItem && toyItem["hex"]) {
  139. let $hex = toyItem["hex"].substr(toyItem["hex"].length - 2, 2);
  140. if ($hex === "80") {
  141. wx.setStorageSync("report_mode", 2)
  142. } else {
  143. wx.setStorageSync("report_mode", 1)
  144. }
  145. LOG_DEBUG("连接教具(获取连接ID):", `03 00 ${$hex} 00 0A`, JSON.stringify(toyItem));
  146. // 连接教具: 03 00 ${$hex} 00 0a
  147. that.sendConnectOneToMore($hex);
  148. }
  149. },
  150. /**
  151. * 发送一对多连接
  152. * 连接教具(获取连接ID)
  153. */
  154. sendConnectOneToMore(id) {
  155. this.WriteBufferInBle(`03 00 ${id} 00 0A`, "一对多教具连接");
  156. },
  157. /**
  158. * 发送一对一连接
  159. * 连接教具(使用获取的ID)
  160. */
  161. sendConnectOneToOne(id) {
  162. ble_store.setters.setCurrentToyId(id);
  163. this.WriteBufferInBle(`03 00 ${id} 01 0A`, "连接教具(使用获取的ID)")
  164. },
  165. /**
  166. * 连接教具(使用下发的ID)
  167. */
  168. sendConnectOneToToy(id) {
  169. ble_store.setters.setCurrentToyId(id);
  170. this.WriteBufferInBle(`03 00 ${id} 02 0A`, "连接教具(使用下发的ID)")
  171. },
  172. /**
  173. * 写入8位指令
  174. * @param id 末尾id
  175. * @param $comments
  176. * @constructor
  177. */
  178. SendOrder(id, $comments = "") {
  179. let $hexStr = `03 00 00 00 ${id}`;
  180. this.WriteBufferInBle($hexStr, $comments)
  181. },
  182. /**
  183. * 打开或关闭LED灯 AA CC 03 00 00 ctrl EC CKS
  184. * 00/01
  185. */
  186. SendLedOrder(id) {
  187. let $hexStr = `03 00 00 ${id} ec`;
  188. this.WriteBufferInBle($hexStr, "控制脑机LED灯")
  189. },
  190. /**
  191. * 设置教具为无运动状态 AA CC 03 00 00 00 34 CKS
  192. * 00/01
  193. */
  194. SendMotionOrder(id) {
  195. let $hexStr = `03 00 00 ${id} 34`;
  196. this.WriteBufferInBle($hexStr, "设置教具为无运动状态")
  197. },
  198. /**
  199. * 自动发送RF重连教具
  200. * @param {Boolean} isOn 是否打开重连功能
  201. * @param timeOut 有效时间
  202. * AA CC 03 00 01 0a d0 21
  203. */
  204. sendAutoConnectRf(isOn, timeOut) {
  205. let onVal = isOn ? '01' : '00';
  206. let mTimeOut = timeOut.toString(16);
  207. if (mTimeOut.length === 1) {
  208. mTimeOut = `0${mTimeOut}`;
  209. }
  210. let $hexStr = `03 00 ${onVal} ${mTimeOut} d0`;
  211. this.WriteBufferInBle($hexStr, "RF重连");
  212. },
  213. /**
  214. * 开启脑控
  215. */
  216. sendControl() {
  217. let that = this;
  218. wx.showLoading({
  219. title: "正在启动"
  220. })
  221. setTimeout(()=>{
  222. that.SendOrder("07", "开启脑控");
  223. },500)
  224. },
  225. /**
  226. * 关闭脑控
  227. */
  228. sendControlClose() {
  229. let that = this
  230. setTimeout(()=>{
  231. // 打开LED
  232. that.SendLedOrder("01");
  233. },500);
  234. setTimeout(()=>{
  235. // 关闭脑控
  236. that.SendOrder("09", "关闭脑控");
  237. ble_store.setters.setCurrentToyId("00");
  238. },1000);
  239. //如果是一代脑机则发送 00 教具
  240. if (isJELLYFISH()) {
  241. setTimeout(()=>{
  242. that.sendConnectOneToMore('00');
  243. },1500);
  244. }
  245. },
  246. /**
  247. * todo 写入buffer
  248. * @param $hex
  249. * @param $buffer_len
  250. * @param $comments
  251. * @constructor
  252. */
  253. WriteBufferInBle($hex, $comments = "", $buffer_len = 8) {
  254. let { deviceId, serviceId, characteristicWriteId } = getDeviceWriteInfo();
  255. let $code = ble_store.getters.getDeviceSn();
  256. if (deviceId && serviceId && characteristicWriteId) {
  257. let $hex_header = "aa cc ";
  258. let $hex_sum = 0;
  259. let $hex_ary = $hex.split(" ");
  260. $hex_ary.forEach(($val) => {
  261. $hex_sum += parseInt($val, 16);
  262. })
  263. let $checksum = ($hex_sum ^ parseInt("ffffffff", 16)) & parseInt("ff", 16);
  264. $hex = $hex_header + $hex + " " + ("00" + $checksum.toString(16)).substr(-2, 2);
  265. let buffer = new ArrayBuffer($buffer_len);
  266. let dataView = new DataView(buffer);
  267. $hex_ary = $hex.split(" ");
  268. $hex_ary.forEach(($val, $index) => {
  269. dataView.setUint8($index, parseInt($val, 16))
  270. })
  271. wx.writeBLECharacteristicValue({
  272. deviceId: deviceId,
  273. serviceId: serviceId,
  274. characteristicId: characteristicWriteId,
  275. value: buffer,
  276. success: function () {
  277. LOG_WECHAT($code, "写入指令:", $hex, $comments);
  278. },
  279. fail: function (err) {
  280. LOG_WECHAT_ERROR($code, "写入指令失败:", $hex, $comments, JSON.stringify(err));
  281. },
  282. });
  283. }
  284. },
  285. /**
  286. * 监听脑机数据
  287. * @param $this
  288. */
  289. notifyDatas($this) {
  290. const that = this;
  291. let deviceId = ble_store.getters.getDeviceId();
  292. console.log("%c监听脑机数据", "color:red;", deviceId);
  293. // 监听蓝牙低功耗设备的特征值变化事件
  294. wx.onBLECharacteristicValueChange((characteristic) => {
  295. let hexStr = ab2hex(characteristic.value);
  296. let $code = ble_store.getters.getDeviceSn();
  297. let $comments = "";
  298. // 处理打开脑控的应答
  299. if (hexStr.toUpperCase().indexOf("AADD07") >= 0) {
  300. ble_store.setters.setBluetoothLinkStatus(true);
  301. $comments = "打开脑控的应答";
  302. }
  303. // 收到发送UUID的应答立马发送连接教具的指令
  304. if (hexStr.toUpperCase().indexOf("AADD8E") >= 0) {
  305. let $currentToyId = ble_store.getters.getCurrentToyId();
  306. //发送教具连接(连接教具(使用下发的ID))
  307. that.sendConnectOneToToy($currentToyId);
  308. $comments = "连接教具(使用下发的ID)的应答";
  309. }
  310. if (hexStr.toUpperCase().indexOf("AAEE87") >= 0) {
  311. let $currentToyId = ble_store.getters.getCurrentToyId();
  312. //获取教具设备编号
  313. if ($currentToyId !== '80') {
  314. that.SendOrder('87', "获取教具编号")
  315. }
  316. $comments = "获取教具编号异常";
  317. }
  318. //let $game_status = game_store.getters.getGameStatus();
  319. //let $currentToyId = ble_store.getters.getCurrentToyId();
  320. // 连接页面
  321. if($this && $this.$options.name){
  322. LOG_DEBUG("当前页面名称:", $this?$this.$options.name:"");
  323. // 监听脑机电量
  324. if (hexStr.substring(0, 8) === "55550203") {
  325. $comments = "监听脑机电量";
  326. let $power = parseInt(hexStr.substring(8, 10), 16);
  327. // let $voltage = parseInt(hexStr.substring(10, 12), 16);
  328. // // 监听是否插入USB
  329. // $this.hasUsb = $voltage.toString().substring(0, 1) === "1";
  330. if ($power) {
  331. $this.device_power = $power;
  332. }
  333. if ($power < 10 && $power > 0) {
  334. wx.showToast({ title: "脑机电量不足", icon: "none", duration: 2000});
  335. }
  336. }
  337. // 判断教具连接
  338. if (hexStr.toUpperCase().indexOf("AADD0A") >= 0) {
  339. $comments = "连接教具的应答";
  340. //没连接上教具
  341. if (hexStr.toUpperCase().indexOf("AADD0A0000") >= 0) {
  342. if(!isJELLYFISH()){
  343. $this.connect_toy = 3;
  344. }
  345. return false;
  346. }
  347. let $baseIndex = hexStr.toUpperCase().indexOf("AADD0A");
  348. let $hex_index = hexStr.substring($baseIndex + 28, 30)
  349. let $toy_id = hexStr.substring($baseIndex + 8, 10)
  350. LOG_DEBUG("连接HEX:", $hex_index, "教具ID:", $toy_id)
  351. // 连接上教具
  352. if (new RegExp("00").test($hex_index) === true) {
  353. if (isJELLYFISH()){
  354. // 一代脑机
  355. $this.connect_toy = 2;
  356. if($this.toy_item && $this.toy_item.name){
  357. wx.showToast({title: "已连接到" + $this.toy_item.name });
  358. }
  359. } else {
  360. LOG_DEBUG("一对多")
  361. // 发送一对一连接 03 00 ${$toy_id} 01 0A
  362. that.sendConnectOneToOne($toy_id);
  363. ble_store.setters.setCurrentToyId($toy_id);
  364. // current_toy_id = $toy_id;
  365. }
  366. }
  367. if (new RegExp("01").test($hex_index) === true) {
  368. LOG_DEBUG("一对一")
  369. if($this.toy_item && $this.toy_item.name){
  370. wx.showToast({title: "已连接到" + $this.toy_item.name });
  371. }
  372. //连接成功
  373. $this.connect_toy = 2;
  374. // 判断冥想模式不发送获取教具名字
  375. if ($toy_id !== "80") {
  376. // 获取一次教具名称
  377. setTimeout(() => {
  378. that.SendOrder('87', "获取教具编号")
  379. }, 3000)
  380. // 不断获取教具电量
  381. let toy_interval = setInterval(() => {
  382. let $game_status = game_store.getters.getGameStatus();
  383. if($game_status === 0 || $game_status === 3){
  384. clearInterval(toy_interval);
  385. } else{
  386. that.SendOrder('8a', "获取教具电量");
  387. }
  388. }, 10000);
  389. }
  390. }
  391. }
  392. // 获取教具名称
  393. if (hexStr.toUpperCase().indexOf("AADD87") >= 0) {
  394. let $currentToyId = ble_store.getters.getCurrentToyId();
  395. let $mHexStr = hexStr.substring(hexStr.toUpperCase().indexOf("AADD87"))
  396. let $datas = doAnalysis($mHexStr, 10);
  397. let $number = $datas.match(/\d+/);
  398. $number = $number ? $number : "00000000";
  399. let toy_list_pre = {'00': "", '01': "SW", '02': "KL", '04': "SC", '05': "PP", '06': "SU", '09': "UF", '12': "JM", '13': "QM"}
  400. let $sn = toy_list_pre[$currentToyId] + $number;
  401. $this.toy_sn = $sn;
  402. //保存教具sn
  403. ble_store.setters.setToySn($sn);
  404. LOG_DEBUG("获取教具名称hexStr:", hexStr, ",获取教具名称$sn", $sn);
  405. $comments = "获取教具名称";
  406. }
  407. // 获取教具电量
  408. if (hexStr.toUpperCase().indexOf("AADD8A") >= 0) {//接收教具电量状态
  409. let $_hexStr = hexStr.substring(hexStr.toUpperCase().indexOf("AADD8A") + 6);
  410. let $power = parseInt($_hexStr.substring(0, 2), 16)
  411. if ($power > 0) {
  412. $this.toy_power = $power
  413. }
  414. $comments = "获取教具电量的应答";
  415. }
  416. // 教具断链(连续多次到教具的命令没有响应)
  417. if (hexStr.toUpperCase().indexOf("AAEE70") >= 0) {
  418. //connect_toy = false
  419. wx.showModal({
  420. content: "教具已断开",
  421. success(res) {
  422. if (res.confirm) {
  423. let $game_status = game_store.getters.getGameStatus();
  424. if ($game_status === 1 || $game_status === 2) {
  425. $this.endTheGame();
  426. }
  427. $this.connect_toy = 3;
  428. }
  429. }
  430. })
  431. $comments = "连续多次到教具的命令没有响应";
  432. }
  433. // 监听数据
  434. if (hexStr.substring(0, 6) === "555520") {
  435. $comments = "监听数据";
  436. // 监听佩戴正确, 当s1为 00时 数据有效
  437. $this.device_bg = (hexStr.substring(8, 10) === "00");
  438. LOG_DEBUG("监听佩戴正确:", hexStr.substring(0, 10), $this.device_bg);
  439. //游戏中模块
  440. let $game_status = game_store.getters.getGameStatus();
  441. if ($game_status === 1 || $game_status === 2) {
  442. // 获取蓝牙低功耗设备(脑机)的信号强度
  443. wx.getBLEDeviceRSSI({
  444. deviceId: deviceId,
  445. success(res) {$this.RSSI = res.RSSI;}
  446. });
  447. // 分析实时数据
  448. if($this.$options.name === "StartGames"){
  449. $this.analysisGameData(hexStr);
  450. }
  451. }
  452. }
  453. //todo 接收脑机关机指令
  454. if (hexStr.toUpperCase().indexOf("AADD5A00000000A5") >= 0) {
  455. let $game_status = game_store.getters.getGameStatus();
  456. if ($game_status === 1 || $game_status === 2) {
  457. Notify({
  458. type: 'danger',
  459. duration: 0,
  460. message: '智脑机已关机,训练结束',
  461. onOpened() {
  462. $this.endTheGame();
  463. }
  464. });
  465. }
  466. that.clearStatus($this);
  467. $comments = "脑环关机的应答";
  468. }
  469. }
  470. // 日志DEBUG: 脑机电量 || 教具电量 || 数据
  471. let logFlag = (hexStr.substring(0, 8) === "55550203") || (hexStr.toUpperCase().indexOf("AADD8A") >= 0) || (hexStr.substring(0, 6) === "555520");
  472. if (logFlag) {
  473. LOG_DEBUG($code, "电量及数据应答:", hexStr, $comments);
  474. } else {
  475. // 日志-推送到微信
  476. LOG_WECHAT($code, "指令应答:", hexStr, $comments);
  477. }
  478. });
  479. },
  480. /**
  481. * 监听蓝牙连接状态
  482. * 监听蓝牙低功耗连接状态改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等
  483. */
  484. watchBLEstatus($this) {
  485. let that = this;
  486. if($this && $this.$options.name){
  487. LOG_DEBUG("微信自身监听低功耗蓝牙连接状态:", $this.$options.name);
  488. }
  489. // 微信自身监听低功耗蓝牙连接状态的改变事件
  490. wx.onBLEConnectionStateChange((res) => {
  491. // 该方法回调中可以用于处理连接意外断开等异常情况
  492. ble_store.setters.setBluetoothLinkStatus(res.connected);
  493. LOG_DEBUG("监听脑机连接状态:", res.connected);
  494. if (!res.connected) {
  495. //判断游戏是否游戏中
  496. let $game_status = game_store.getters.getGameStatus();
  497. LOG_DEBUG("智脑机已断开连接,游戏状态:", $game_status);
  498. if ($game_status === 1 || $game_status === 2) {
  499. // if($this && $this.$options.name && $this.$options.name === "StartGames"){
  500. // $this.endTheGame();
  501. // }
  502. if($this && $this.$options.name && $this.$options.name === "StartGames"){
  503. //如果是一代脑则结束游戏
  504. if (isJELLYFISH()) {
  505. $this.endTheGame();
  506. } else {
  507. Notify({
  508. type: 'danger',
  509. duration: 0,
  510. message: '智脑机已断开连接,正在尝试重新连接',
  511. onOpened() {
  512. that.reconnectDevice(res.deviceId, $this);
  513. console.log("智脑机已断开连接deviceId", res.deviceId);
  514. }
  515. });
  516. }
  517. }
  518. } else {
  519. that.clearStatus($this);
  520. }
  521. }
  522. });
  523. },
  524. /**
  525. * 重新连接蓝牙
  526. */
  527. reconnectDevice($deviceId, $this){
  528. let that = this;
  529. let $code = ble_store.getters.getDeviceSn();
  530. //重连的次数
  531. let $connect_count = 0;
  532. let $rec = setInterval(() => {
  533. let $game_status = game_store.getters.getGameStatus();
  534. LOG_DEBUG("正在尝试重新连接,游戏状态:", $game_status);
  535. // 开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索到需要的设备后及时调用 wx.stopBluetoothDevicesDiscovery 停止搜索。
  536. wx.startBluetoothDevicesDiscovery({
  537. allowDuplicatesKey: true,
  538. success: function(res) {
  539. try {
  540. // 监听搜索到新设备的事件
  541. wx.onBluetoothDeviceFound((res) => {
  542. res.devices.forEach((device) => {
  543. if (!device.name && !device.localName) { return; }
  544. if (device.localName && device.localName !== "") {
  545. device.name = device.localName;
  546. }
  547. if (device["name"].toUpperCase() === $code) {
  548. // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
  549. wx.stopBluetoothDevicesDiscovery();
  550. // 连接低功耗蓝牙设备
  551. wx.createBLEConnection({
  552. deviceId: $deviceId,
  553. success() {
  554. clearInterval($rec)
  555. Notify({type: 'success', message: `第${$connect_count}次重新连接成功`});
  556. LOG_WECHAT($code, `第${$connect_count}次重新连接成功`);
  557. // 获取蓝牙设备服务
  558. that.getBLEDeviceServices($deviceId);
  559. // 继续游戏
  560. setTimeout(function(){
  561. $this.startTheGame();
  562. }, 3000);
  563. },
  564. fail(err) {
  565. Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
  566. LOG_WECHAT($code, `第${$connect_count}次重新连接失败`, err.errMsg);
  567. }
  568. })
  569. }
  570. });
  571. });
  572. } catch (e) {
  573. Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
  574. LOG_WECHAT($code, `第${$connect_count}次重新连接失败`, e.errMsg);
  575. }
  576. },
  577. fail(err) {
  578. Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
  579. LOG_WECHAT($code, `第${$connect_count}次重新连接失败`, err.errMsg);
  580. },
  581. });
  582. if ($connect_count >= 3) {
  583. let $game_status = game_store.getters.getGameStatus();
  584. if ($game_status === 1 || $game_status === 2) {
  585. $this.endTheGame();
  586. }
  587. clearInterval($rec);
  588. // 移除搜索到新设备的事件的全部监听函数
  589. wx.offBluetoothDeviceFound();
  590. // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
  591. wx.stopBluetoothDevicesDiscovery();
  592. that.clearStatus($this);
  593. }
  594. $connect_count += 1;
  595. }, 7000);
  596. },
  597. /**
  598. * 关闭脑机蓝牙连接
  599. */
  600. closeConnection($this) {
  601. const that = this;
  602. let $code = ble_store.getters.getDeviceSn();
  603. // 关闭脑控
  604. that.SendOrder("09", "关闭脑控");
  605. ble_store.setters.setBluetoothLinkStatus(false);
  606. game_store.setters.setGameStatus(0);
  607. // todo 清空链接的设备
  608. $this.connect_toy = 0;
  609. $this.device_bg = false;
  610. // 断开教具及蓝牙连接
  611. setTimeout(()=>{
  612. that.SendOrder("31", "断开教具及蓝牙连接");
  613. // 移除搜索到新设备的事件的全部监听函数
  614. wx.offBluetoothDeviceFound();
  615. // 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索。
  616. wx.stopBluetoothDevicesDiscovery();
  617. let deviceId = ble_store.getters.getDeviceId();
  618. //断开蓝牙连接
  619. wx.closeBLEConnection({
  620. deviceId: deviceId,
  621. success() {
  622. Toast.success({
  623. message: "断开蓝牙连接成功",
  624. });
  625. LOG_WECHAT($code, "断开蓝牙连接成功", deviceId);
  626. },
  627. fail(err) {
  628. LOG_WECHAT_ERROR($code, "断开蓝牙连接"+deviceId+"失败error:", JSON.stringify(err));
  629. },
  630. complete() {
  631. // 清除状态
  632. that.clearStatus($this);
  633. },
  634. });
  635. },500);
  636. },
  637. /**
  638. * 清除状态
  639. */
  640. clearStatus($this){
  641. wx.closeBluetoothAdapter();
  642. game_store.setters.setGameStatus(0);
  643. ble_store.setters.clearDeviceToy();
  644. $this.device_bg = false;
  645. $this.device_status = 0;
  646. $this.connect_toy = 0;
  647. $this.$forceUpdate();
  648. },
  649. /**
  650. * 错误信息
  651. */
  652. connectionError(errCode) {
  653. if (errCode === 10000) {
  654. return "未初始化蓝牙适配器";
  655. }
  656. if (errCode === 10001) {
  657. return "当前蓝牙适配器不可用";
  658. }
  659. if (errCode === 10002) {
  660. return "没有找到指定设备";
  661. }
  662. if (errCode === 10003) {
  663. return "连接失败";
  664. }
  665. if (errCode === 10006) {
  666. return "当前连接已断开";
  667. }
  668. return "未知连接错误:"+errCode;
  669. },
  670. };