123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- import ble_store from "../store/bluetooth";
- import game_store from "../store/game";
- import Toast from "../../static/vant/toast/toast";
- import Notify from "../../static/vant/notify/notify";
- import {LOG_DEBUG, LOG_WECHAT, LOG_WECHAT_ERROR} from "./log";
- function getDeviceWriteInfo() {
- let deviceId = ble_store.getters.getDeviceId();
- let serviceId = ble_store.getters.getServiceId();
- let characteristicWriteId = ble_store.getters.getCharacteristicWriteId();
- let characteristicNotifyId = ble_store.getters.getCharacteristicNotifyId();
- return { deviceId, serviceId, characteristicWriteId, characteristicNotifyId};
- }
- function isJELLYFISH() {
- let $code = ble_store.getters.getDeviceSn();
- return $code.indexOf("JELLYFISH") >= 0;
- }
- function ab2hex(buffer) {
- const hexArr = Array.prototype.map.call(
- new Uint8Array(buffer), function (bit) {
- return ("00" + bit.toString(16)).slice(-2);
- }
- );
- return hexArr.join("");
- }
- function doAnalysis(hexStr, count, start = 6) {
- let $result = "";
-
- let $str = hexStr.substring(start);
- let $data = $str.substring(0, count * 2);
- for (let $i = 0; $i < $data.length; $i += 2) {
- let $code = parseInt($data.substring($i, $i+2), 16)
- $result += String.fromCharCode($code)
- }
- return $result;
- }
- export default {
-
- getBLEDeviceServices(deviceId) {
- const that = this;
- wx.getBLEDeviceServices({
- deviceId,
- success: (res) => {
- LOG_DEBUG("获取蓝牙设备服务service:\n", JSON.stringify(res.services));
- for (let i = 0; i < res.services.length; i++) {
- LOG_DEBUG("第" + (i + 1) + "个UUID:" + res.services[i].uuid + "\n");
- if (res.services[i].uuid.indexOf('6E') !== -1 || res.services[i].uuid.indexOf('0000FFF0') !== -1) {
-
- that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid);
- ble_store.setters.setServiceId(res.services[i].uuid);
- LOG_DEBUG("脑机deviceId(mac)", deviceId, "notifyServicesId:" + res.services[i].uuid);
- return;
- }
- }
- },
- fail() {
- let deviceId = wx.getStorageSync('deviceId');
-
- wx.closeBLEConnection({
- deviceId: deviceId
- });
- },
- });
- },
-
- getBLEDeviceCharacteristics(deviceId, serviceId) {
- const that = this;
- wx.getBLEDeviceCharacteristics({
- deviceId,
- serviceId,
- success: (res) => {
- LOG_DEBUG("获取服务", serviceId, "的特征值:\n", JSON.stringify(res));
- for (let i = 0; i < res.characteristics.length; i++) {
- let item = res.characteristics[i]
- if (item.properties.read) {
- LOG_DEBUG("第" + (i + 1) + ",该特征值可读:" + item.uuid);
- }
- if (item.properties.write) {
- LOG_DEBUG("第" + (i + 1) + ",该特征值可写:" + item.uuid);
- if(item.uuid.indexOf("0002") !== -1){
- ble_store.setters.setCharacteristicWriteId(item.uuid);
-
- that.SendOrder("ff", "打开数据帧");
- }
- }
- if (item.properties.notify || item.properties.indicate) {
- LOG_DEBUG("第" + (i + 1) + ",该特征值可监听:" + item.uuid);
- if(item.uuid.indexOf("0003") !== -1){
- ble_store.setters.setCharacteristicNotifyId(item.uuid);
- }
-
- wx.notifyBLECharacteristicValueChange({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: item.uuid,
- state: true,
- success() {
- that.notifyDatas(null);
- LOG_DEBUG("init正在监听特征值:", item.uuid);
- }
- });
- }
- }
- },
- fail() {
- let deviceId = wx.getStorageSync('deviceId');
-
- wx.closeBLEConnection({
- deviceId: deviceId
- });
- },
- });
- },
-
- sendToyConnection(toyItem) {
- let that = this;
- if(toyItem && toyItem["hex"]) {
- let $hex = toyItem["hex"].substr(toyItem["hex"].length - 2, 2);
- if ($hex === "80") {
- wx.setStorageSync("report_mode", 2)
- } else {
- wx.setStorageSync("report_mode", 1)
- }
- LOG_DEBUG("连接教具(获取连接ID):", `03 00 ${$hex} 00 0A`, JSON.stringify(toyItem));
-
- that.sendConnectOneToMore($hex);
- }
- },
-
- sendConnectOneToMore(id) {
- this.WriteBufferInBle(`03 00 ${id} 00 0A`, "一对多教具连接");
- },
-
- sendConnectOneToOne(id) {
- ble_store.setters.setCurrentToyId(id);
- this.WriteBufferInBle(`03 00 ${id} 01 0A`, "连接教具(使用获取的ID)")
- },
-
- sendConnectOneToToy(id) {
- ble_store.setters.setCurrentToyId(id);
- this.WriteBufferInBle(`03 00 ${id} 02 0A`, "连接教具(使用下发的ID)")
- },
-
- SendOrder(id, $comments = "") {
- let $hexStr = `03 00 00 00 ${id}`;
- this.WriteBufferInBle($hexStr, $comments)
- },
-
- SendLedOrder(id) {
- let $hexStr = `03 00 00 ${id} ec`;
- this.WriteBufferInBle($hexStr, "控制脑机LED灯")
- },
-
- SendMotionOrder(id) {
- let $hexStr = `03 00 00 ${id} 34`;
- this.WriteBufferInBle($hexStr, "设置教具为无运动状态")
- },
-
- sendAutoConnectRf(isOn, timeOut) {
- let onVal = isOn ? '01' : '00';
- let mTimeOut = timeOut.toString(16);
- if (mTimeOut.length === 1) {
- mTimeOut = `0${mTimeOut}`;
- }
- let $hexStr = `03 00 ${onVal} ${mTimeOut} d0`;
- this.WriteBufferInBle($hexStr, "RF重连");
- },
-
- sendControl() {
- let that = this;
- wx.showLoading({
- title: "正在启动"
- })
- setTimeout(()=>{
- that.SendOrder("07", "开启脑控");
- },500)
- },
-
- sendControlClose() {
- let that = this
- setTimeout(()=>{
-
- that.SendLedOrder("01");
- },500);
- setTimeout(()=>{
-
- that.SendOrder("09", "关闭脑控");
- ble_store.setters.setCurrentToyId("00");
- },1000);
-
- if (isJELLYFISH()) {
- setTimeout(()=>{
- that.sendConnectOneToMore('00');
- },1500);
- }
- },
-
- WriteBufferInBle($hex, $comments = "", $buffer_len = 8) {
- let { deviceId, serviceId, characteristicWriteId } = getDeviceWriteInfo();
- let $code = ble_store.getters.getDeviceSn();
- if (deviceId && serviceId && characteristicWriteId) {
- let $hex_header = "aa cc ";
- let $hex_sum = 0;
- let $hex_ary = $hex.split(" ");
- $hex_ary.forEach(($val) => {
- $hex_sum += parseInt($val, 16);
- })
- let $checksum = ($hex_sum ^ parseInt("ffffffff", 16)) & parseInt("ff", 16);
- $hex = $hex_header + $hex + " " + ("00" + $checksum.toString(16)).substr(-2, 2);
- let buffer = new ArrayBuffer($buffer_len);
- let dataView = new DataView(buffer);
- $hex_ary = $hex.split(" ");
- $hex_ary.forEach(($val, $index) => {
- dataView.setUint8($index, parseInt($val, 16))
- })
- wx.writeBLECharacteristicValue({
- deviceId: deviceId,
- serviceId: serviceId,
- characteristicId: characteristicWriteId,
- value: buffer,
- success: function () {
- LOG_WECHAT($code, "写入指令:", $hex, $comments);
- },
- fail: function (err) {
- LOG_WECHAT_ERROR($code, "写入指令失败:", $hex, $comments, JSON.stringify(err));
- },
- });
- }
- },
-
- notifyDatas($this) {
- const that = this;
- let deviceId = ble_store.getters.getDeviceId();
- console.log("%c监听脑机数据", "color:red;", deviceId);
-
- wx.onBLECharacteristicValueChange((characteristic) => {
- let hexStr = ab2hex(characteristic.value);
- let $code = ble_store.getters.getDeviceSn();
- let $comments = "";
-
- if (hexStr.toUpperCase().indexOf("AADD07") >= 0) {
- ble_store.setters.setBluetoothLinkStatus(true);
- $comments = "打开脑控的应答";
- }
-
- if (hexStr.toUpperCase().indexOf("AADD8E") >= 0) {
- let $currentToyId = ble_store.getters.getCurrentToyId();
-
- that.sendConnectOneToToy($currentToyId);
- $comments = "连接教具(使用下发的ID)的应答";
- }
- if (hexStr.toUpperCase().indexOf("AAEE87") >= 0) {
- let $currentToyId = ble_store.getters.getCurrentToyId();
-
- if ($currentToyId !== '80') {
- that.SendOrder('87', "获取教具编号")
- }
- $comments = "获取教具编号异常";
- }
-
-
-
- if($this && $this.$options.name){
- LOG_DEBUG("当前页面名称:", $this?$this.$options.name:"");
-
- if (hexStr.substring(0, 8) === "55550203") {
- $comments = "监听脑机电量";
- let $power = parseInt(hexStr.substring(8, 10), 16);
-
-
-
- if ($power) {
- $this.device_power = $power;
- }
- if ($power < 10 && $power > 0) {
- wx.showToast({ title: "脑机电量不足", icon: "none", duration: 2000});
- }
- }
-
- if (hexStr.toUpperCase().indexOf("AADD0A") >= 0) {
- $comments = "连接教具的应答";
-
- if (hexStr.toUpperCase().indexOf("AADD0A0000") >= 0) {
- if(!isJELLYFISH()){
- $this.connect_toy = 3;
- }
- return false;
- }
- let $baseIndex = hexStr.toUpperCase().indexOf("AADD0A");
- let $hex_index = hexStr.substring($baseIndex + 28, 30)
- let $toy_id = hexStr.substring($baseIndex + 8, 10)
- LOG_DEBUG("连接HEX:", $hex_index, "教具ID:", $toy_id)
-
- if (new RegExp("00").test($hex_index) === true) {
- if (isJELLYFISH()){
-
- $this.connect_toy = 2;
- if($this.toy_item && $this.toy_item.name){
- wx.showToast({title: "已连接到" + $this.toy_item.name });
- }
- } else {
- LOG_DEBUG("一对多")
-
- that.sendConnectOneToOne($toy_id);
- ble_store.setters.setCurrentToyId($toy_id);
-
- }
- }
- if (new RegExp("01").test($hex_index) === true) {
- LOG_DEBUG("一对一")
- if($this.toy_item && $this.toy_item.name){
- wx.showToast({title: "已连接到" + $this.toy_item.name });
- }
-
- $this.connect_toy = 2;
-
- if ($toy_id !== "80") {
-
- setTimeout(() => {
- that.SendOrder('87', "获取教具编号")
- }, 3000)
-
- let toy_interval = setInterval(() => {
- let $game_status = game_store.getters.getGameStatus();
- if($game_status === 0 || $game_status === 3){
- clearInterval(toy_interval);
- } else{
- that.SendOrder('8a', "获取教具电量");
- }
- }, 10000);
- }
- }
- }
-
- if (hexStr.toUpperCase().indexOf("AADD87") >= 0) {
- let $currentToyId = ble_store.getters.getCurrentToyId();
- let $mHexStr = hexStr.substring(hexStr.toUpperCase().indexOf("AADD87"))
- let $datas = doAnalysis($mHexStr, 10);
- let $number = $datas.match(/\d+/);
- $number = $number ? $number : "00000000";
- let toy_list_pre = {'00': "", '01': "SW", '02': "KL", '04': "SC", '05': "PP", '06': "SU", '09': "UF", '12': "JM", '13': "QM"}
- let $sn = toy_list_pre[$currentToyId] + $number;
- $this.toy_sn = $sn;
-
- ble_store.setters.setToySn($sn);
- LOG_DEBUG("获取教具名称hexStr:", hexStr, ",获取教具名称$sn", $sn);
- $comments = "获取教具名称";
- }
-
- if (hexStr.toUpperCase().indexOf("AADD8A") >= 0) {
- let $_hexStr = hexStr.substring(hexStr.toUpperCase().indexOf("AADD8A") + 6);
- let $power = parseInt($_hexStr.substring(0, 2), 16)
- if ($power > 0) {
- $this.toy_power = $power
- }
- $comments = "获取教具电量的应答";
- }
-
- if (hexStr.toUpperCase().indexOf("AAEE70") >= 0) {
-
- wx.showModal({
- content: "教具已断开",
- success(res) {
- if (res.confirm) {
- let $game_status = game_store.getters.getGameStatus();
- if ($game_status === 1 || $game_status === 2) {
- $this.endTheGame();
- }
- $this.connect_toy = 3;
- }
- }
- })
- $comments = "连续多次到教具的命令没有响应";
- }
-
- if (hexStr.substring(0, 6) === "555520") {
- $comments = "监听数据";
-
- $this.device_bg = (hexStr.substring(8, 10) === "00");
- LOG_DEBUG("监听佩戴正确:", hexStr.substring(0, 10), $this.device_bg);
-
- let $game_status = game_store.getters.getGameStatus();
- if ($game_status === 1 || $game_status === 2) {
-
- wx.getBLEDeviceRSSI({
- deviceId: deviceId,
- success(res) {$this.RSSI = res.RSSI;}
- });
-
- if($this.$options.name === "StartGames"){
- $this.analysisGameData(hexStr);
- }
- }
- }
-
- if (hexStr.toUpperCase().indexOf("AADD5A00000000A5") >= 0) {
- let $game_status = game_store.getters.getGameStatus();
- if ($game_status === 1 || $game_status === 2) {
- Notify({
- type: 'danger',
- duration: 0,
- message: '智脑机已关机,训练结束',
- onOpened() {
- $this.endTheGame();
- }
- });
- }
- that.clearStatus($this);
- $comments = "脑环关机的应答";
- }
- }
-
- let logFlag = (hexStr.substring(0, 8) === "55550203") || (hexStr.toUpperCase().indexOf("AADD8A") >= 0) || (hexStr.substring(0, 6) === "555520");
- if (logFlag) {
- LOG_DEBUG($code, "电量及数据应答:", hexStr, $comments);
- } else {
-
- LOG_WECHAT($code, "指令应答:", hexStr, $comments);
- }
- });
- },
-
- watchBLEstatus($this) {
- let that = this;
- if($this && $this.$options.name){
- LOG_DEBUG("微信自身监听低功耗蓝牙连接状态:", $this.$options.name);
- }
-
- wx.onBLEConnectionStateChange((res) => {
-
- ble_store.setters.setBluetoothLinkStatus(res.connected);
- LOG_DEBUG("监听脑机连接状态:", res.connected);
- if (!res.connected) {
-
- let $game_status = game_store.getters.getGameStatus();
- LOG_DEBUG("智脑机已断开连接,游戏状态:", $game_status);
- if ($game_status === 1 || $game_status === 2) {
-
-
-
- if($this && $this.$options.name && $this.$options.name === "StartGames"){
-
- if (isJELLYFISH()) {
- $this.endTheGame();
- } else {
- Notify({
- type: 'danger',
- duration: 0,
- message: '智脑机已断开连接,正在尝试重新连接',
- onOpened() {
- that.reconnectDevice(res.deviceId, $this);
- console.log("智脑机已断开连接deviceId", res.deviceId);
- }
- });
- }
- }
- } else {
- that.clearStatus($this);
- }
- }
- });
- },
-
- reconnectDevice($deviceId, $this){
- let that = this;
- let $code = ble_store.getters.getDeviceSn();
-
- let $connect_count = 0;
- let $rec = setInterval(() => {
- let $game_status = game_store.getters.getGameStatus();
- LOG_DEBUG("正在尝试重新连接,游戏状态:", $game_status);
-
- wx.startBluetoothDevicesDiscovery({
- allowDuplicatesKey: true,
- success: function(res) {
- try {
-
- wx.onBluetoothDeviceFound((res) => {
- res.devices.forEach((device) => {
- if (!device.name && !device.localName) { return; }
- if (device.localName && device.localName !== "") {
- device.name = device.localName;
- }
- if (device["name"].toUpperCase() === $code) {
-
- wx.stopBluetoothDevicesDiscovery();
-
- wx.createBLEConnection({
- deviceId: $deviceId,
- success() {
- clearInterval($rec)
- Notify({type: 'success', message: `第${$connect_count}次重新连接成功`});
- LOG_WECHAT($code, `第${$connect_count}次重新连接成功`);
-
- that.getBLEDeviceServices($deviceId);
-
- setTimeout(function(){
- $this.startTheGame();
- }, 3000);
- },
- fail(err) {
- Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
- LOG_WECHAT($code, `第${$connect_count}次重新连接失败`, err.errMsg);
- }
- })
- }
- });
- });
- } catch (e) {
- Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
- LOG_WECHAT($code, `第${$connect_count}次重新连接失败`, e.errMsg);
- }
- },
- fail(err) {
- Notify({type: 'danger', message: `第${$connect_count}次重新连接失败`});
- LOG_WECHAT($code, `第${$connect_count}次重新连接失败`, err.errMsg);
- },
- });
- if ($connect_count >= 3) {
- let $game_status = game_store.getters.getGameStatus();
- if ($game_status === 1 || $game_status === 2) {
- $this.endTheGame();
- }
- clearInterval($rec);
-
- wx.offBluetoothDeviceFound();
-
- wx.stopBluetoothDevicesDiscovery();
- that.clearStatus($this);
- }
- $connect_count += 1;
- }, 7000);
- },
-
- closeConnection($this) {
- const that = this;
- let $code = ble_store.getters.getDeviceSn();
-
- that.SendOrder("09", "关闭脑控");
- ble_store.setters.setBluetoothLinkStatus(false);
- game_store.setters.setGameStatus(0);
-
- $this.connect_toy = 0;
- $this.device_bg = false;
-
- setTimeout(()=>{
- that.SendOrder("31", "断开教具及蓝牙连接");
-
- wx.offBluetoothDeviceFound();
-
- wx.stopBluetoothDevicesDiscovery();
- let deviceId = ble_store.getters.getDeviceId();
-
- wx.closeBLEConnection({
- deviceId: deviceId,
- success() {
- Toast.success({
- message: "断开蓝牙连接成功",
- });
- LOG_WECHAT($code, "断开蓝牙连接成功", deviceId);
- },
- fail(err) {
- LOG_WECHAT_ERROR($code, "断开蓝牙连接"+deviceId+"失败error:", JSON.stringify(err));
- },
- complete() {
-
- that.clearStatus($this);
- },
- });
- },500);
- },
-
- clearStatus($this){
- wx.closeBluetoothAdapter();
- game_store.setters.setGameStatus(0);
- ble_store.setters.clearDeviceToy();
- $this.device_bg = false;
- $this.device_status = 0;
- $this.connect_toy = 0;
- $this.$forceUpdate();
- },
-
- connectionError(errCode) {
- if (errCode === 10000) {
- return "未初始化蓝牙适配器";
- }
- if (errCode === 10001) {
- return "当前蓝牙适配器不可用";
- }
- if (errCode === 10002) {
- return "没有找到指定设备";
- }
- if (errCode === 10003) {
- return "连接失败";
- }
- if (errCode === 10006) {
- return "当前连接已断开";
- }
- return "未知连接错误:"+errCode;
- },
- };
|