|
@@ -1,544 +0,0 @@
|
|
|
-<template>
|
|
|
- <div id="firmwareContainer">
|
|
|
- <div v-if="finished == false">
|
|
|
- <p class="title">
|
|
|
- {{ title }}
|
|
|
- </p>
|
|
|
- <div class="loading" v-if="update_state">
|
|
|
- <van-steps :steps="steps" :active="step_active"/>
|
|
|
- <div class="progress_container">
|
|
|
- <van-progress :percentage="progress" v-if="step_active == 2"/>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <van-divider/>
|
|
|
- <p class="subtitle">
|
|
|
- 更新相关准备
|
|
|
- </p>
|
|
|
- <div class="desc_container">
|
|
|
- <p class="desc" v-for="(desc,index) in desc_list" :key="index">{{ desc }}</p>
|
|
|
- <p class="desc" v-if="step_active>0">请将脑环保持供电
|
|
|
- <van-icon name="checked" color="#07c160" v-if="hasUsb"/>
|
|
|
- <van-icon name="clear" color="#ff2f4f" v-else/>
|
|
|
- </p>
|
|
|
- </div>
|
|
|
-
|
|
|
- <button class="ready_button" @click="ReadyUpdate" v-if="update_state == false">准备好了</button>
|
|
|
-
|
|
|
- </div>
|
|
|
- <div v-else>
|
|
|
- <div class="finished_container">
|
|
|
- <van-icon name="checked" size="60px" color="#46D5A4"/>
|
|
|
- <p class="finsihed_subtitle">升级完成</p>
|
|
|
- <van-button
|
|
|
- class="finished_button"
|
|
|
- round color="#7078FF"
|
|
|
- plain
|
|
|
- custom-style="margin:200px auto 0px;"
|
|
|
- @click="BackIndex"
|
|
|
- >      返回      
|
|
|
- </van-button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- <p class="version_info">-->
|
|
|
- <!-- 当前版本:{{ software_version }}-->
|
|
|
- <!-- </p>-->
|
|
|
-
|
|
|
- <van-toast id="van-toast"/>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-<script>
|
|
|
-import {EditFirmwareVersion, getDeviceBySn} from "../../../requests/game";
|
|
|
-import ble_store from "@/store/bluetooth";
|
|
|
-import Toast from "../../../../static/vant/toast/toast";
|
|
|
-
|
|
|
-var $this;
|
|
|
-var FileSystemManager = wx.getFileSystemManager();
|
|
|
-export default {
|
|
|
- name: "firmwareContainer",
|
|
|
- data() {
|
|
|
- return {
|
|
|
- brain_sn: "",
|
|
|
- result: "",
|
|
|
- updateImageSavePath: "",
|
|
|
- software_version: "",
|
|
|
- model: "",
|
|
|
- //解密行数下标
|
|
|
- dec_index: 0,
|
|
|
- buffers: [],
|
|
|
- payload_len: 0,
|
|
|
- progress: "",
|
|
|
- hasUsb: false,
|
|
|
- title: "固件升级准备",
|
|
|
- //更新状态
|
|
|
- update_state: false,
|
|
|
- desc_list: [
|
|
|
- "1.保持智脑环开机状态,且电量保证50%,或保持充电;",
|
|
|
- "2.保持手机电量充足,网络处于WIFI或畅通状态;",
|
|
|
- "3.手机蓝牙开启状态;",
|
|
|
- "4.升级固件时避免手机关机或智脑环关机;",
|
|
|
- "5.固件升级中大概5-10分钟,中途不能退出水母星球,否则会导致升级失败"
|
|
|
- ],
|
|
|
- step_active: 0,
|
|
|
- steps: [
|
|
|
- {
|
|
|
- text: "环境检查"
|
|
|
- },
|
|
|
- {
|
|
|
- text: "下载固件"
|
|
|
- },
|
|
|
- {
|
|
|
- text: "固件更新"
|
|
|
- },
|
|
|
- {
|
|
|
- text: "更新完成"
|
|
|
- },
|
|
|
- ],
|
|
|
- finished: false
|
|
|
- }
|
|
|
- },
|
|
|
- watch: {
|
|
|
- update_state($new, $old) {
|
|
|
- if ($new == true) {
|
|
|
- $this.title = "固件更新"
|
|
|
- } else {
|
|
|
- $this.title = "固件升级准备"
|
|
|
- }
|
|
|
- },
|
|
|
- step_active($new, $old) {
|
|
|
- //更新完成
|
|
|
- if ($new == $this.steps.length - 1) {
|
|
|
- //提交 脑环和版本到数据库
|
|
|
- let firmware_info = JSON.parse(wx.getStorageSync("firmware_info"))
|
|
|
- EditFirmwareVersion($this.brain_sn, firmware_info.version)
|
|
|
- $this.finished = true;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- /**
|
|
|
- * 扫码连接设备
|
|
|
- * @constructor
|
|
|
- */
|
|
|
- ConnectBrain() {
|
|
|
- // 判断新的标识值
|
|
|
- // $this.brain_sn = $code;
|
|
|
- //打开蓝牙设备
|
|
|
- wx.getSystemInfo({
|
|
|
- success(res) {
|
|
|
- // 判断ios 和 安卓
|
|
|
- if (res.platform == "ios") {
|
|
|
- wx.openBluetoothAdapter({
|
|
|
- //判断主机模式蓝牙是否打开
|
|
|
- mode: "central",
|
|
|
- success(res) {
|
|
|
- //判断已经打开连接了
|
|
|
- if (res["errMsg"] == "openBluetoothAdapter:ok") {
|
|
|
- // $this.startBluetoothDevicesDiscovery();
|
|
|
- wx.openBluetoothAdapter({
|
|
|
- //判断从机模式蓝牙是否打开
|
|
|
- mode: "peripheral",
|
|
|
- success(res) {
|
|
|
- if (res["errMsg"] == "openBluetoothAdapter:ok") {
|
|
|
- $this.startBluetoothDevicesDiscovery();
|
|
|
- }
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- let $msg =
|
|
|
- $this.$connection.connectionError(
|
|
|
- err["errCode"]
|
|
|
- );
|
|
|
- setTimeout(() => {
|
|
|
- Toast.fail({
|
|
|
- message: $msg,
|
|
|
- });
|
|
|
- }, 3000);
|
|
|
- },
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- let $msg = $this.$connection.connectionError(
|
|
|
- err["errCode"]
|
|
|
- );
|
|
|
- setTimeout(() => {
|
|
|
- Toast.fail({
|
|
|
- message: $msg,
|
|
|
- });
|
|
|
- }, 3000);
|
|
|
- },
|
|
|
- });
|
|
|
- } else {
|
|
|
- // 安卓手机
|
|
|
- wx.openBluetoothAdapter({
|
|
|
- mode: "peripheral",
|
|
|
- success(res) {
|
|
|
- //判断已经打开连接了
|
|
|
- if (res["errMsg"] == "openBluetoothAdapter:ok") {
|
|
|
- $this.startBluetoothDevicesDiscovery();
|
|
|
- }
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- let $msg = $this.$connection.connectionError(
|
|
|
- err["errCode"]
|
|
|
- );
|
|
|
- setTimeout(() => {
|
|
|
- Toast.fail({
|
|
|
- message: $msg,
|
|
|
- });
|
|
|
- }, 3000);
|
|
|
- },
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- },
|
|
|
- /**
|
|
|
- * 开始蓝牙被发现
|
|
|
- */
|
|
|
- startBluetoothDevicesDiscovery() {
|
|
|
- wx.startBluetoothDevicesDiscovery({
|
|
|
- allowDuplicatesKey: true,
|
|
|
- success: (res) => {
|
|
|
- //2021年10月21日15:07:57 通过sn 返回deviceId
|
|
|
- getDeviceBySn($this.code).then((res) => {
|
|
|
- let $data = res.data;
|
|
|
- console.log($data.code);
|
|
|
- $data = $data.data;
|
|
|
- wx.getSystemInfo({
|
|
|
- success(res) {
|
|
|
- // 判断ios 和 安卓
|
|
|
- if (res.platform == "ios") {
|
|
|
- $this.onBluetoothDeviceFound();
|
|
|
- } else {
|
|
|
- if ($data.device_id) {
|
|
|
- console.log("finded");
|
|
|
- $this.device_finded = true;
|
|
|
- $this.createBLEConnection($data.device_id);
|
|
|
- } else {
|
|
|
- $this.device_finded = false;
|
|
|
- console.log("unfinded");
|
|
|
- $this.onBluetoothDeviceFound();
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- $this.change_device_status(3);
|
|
|
- },
|
|
|
- });
|
|
|
- },
|
|
|
- onBluetoothDeviceFound() {
|
|
|
- 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() == $this.brain_sn) {
|
|
|
- console.log("搜索设备", device);
|
|
|
- $this.createBLEConnection(device.deviceId);
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- } catch (e) {
|
|
|
- console.log("打开蓝牙error", e);
|
|
|
- }
|
|
|
- },
|
|
|
- /**
|
|
|
- * 连接低功耗蓝牙设备
|
|
|
- * @param deviceId
|
|
|
- */
|
|
|
- createBLEConnection(deviceId) {
|
|
|
- wx.offBluetoothDeviceFound();
|
|
|
- wx.stopBluetoothDevicesDiscovery();
|
|
|
-
|
|
|
- wx.createBLEConnection({
|
|
|
- deviceId: deviceId,
|
|
|
- success: (res) => {
|
|
|
- console.log(deviceId)
|
|
|
- // 设置mtu单位大小
|
|
|
- wx.setBLEMTU({
|
|
|
- deviceId,
|
|
|
- mtu: 250,
|
|
|
- success(res) {
|
|
|
- console.log("设置mtu成功", JSON.stringify(res));
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- console.log(err)
|
|
|
- }
|
|
|
- })
|
|
|
- ble_store.setters.setDeviceId(deviceId);
|
|
|
- $this.$connection.getBLEDeviceServices(deviceId);
|
|
|
- let $checkServices = setInterval(() => {
|
|
|
- let $serviceId = ble_store.getters.getServiceId();
|
|
|
- if ($serviceId) {
|
|
|
- clearInterval($checkServices);
|
|
|
- // $this.$connection.openNotify($this);
|
|
|
- $this.$connection.notifyDatas($this);
|
|
|
- $this.$connection.watchBLEstatus($this);
|
|
|
- }
|
|
|
- // setTimeout(() => {
|
|
|
- // $this.$connection.SendOrder("02");
|
|
|
- // }, 1000);
|
|
|
- }, 1500);
|
|
|
-
|
|
|
- //步骤加一
|
|
|
- $this.step_active += 1;
|
|
|
- $this.downloadUpateFile()
|
|
|
-
|
|
|
- console.log("连接成功")
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- console.log(err);
|
|
|
- },
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- * todo 下载更新文件
|
|
|
- */
|
|
|
- downloadUpateFile() {
|
|
|
- let firmware_info = JSON.parse(wx.getStorageSync("firmware_info"))
|
|
|
-
|
|
|
- wx.downloadFile({
|
|
|
- url: firmware_info.url, //仅为示例,并非真实的资源
|
|
|
- success(res) {
|
|
|
- // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
|
|
|
- if (res.statusCode === 200) {
|
|
|
- // $this.AddContent("下载成功")
|
|
|
- console.log(res)
|
|
|
- //将临时文件保存到用户文件路径下
|
|
|
- FileSystemManager.saveFile({
|
|
|
- tempFilePath: res.tempFilePath,
|
|
|
- filePath: `${wx.env.USER_DATA_PATH}/update.img`,
|
|
|
- success(res) {
|
|
|
- $this.updateImageSavePath = res.savedFilePath
|
|
|
- $this.readUpdateFile()
|
|
|
- }, fail(err) {
|
|
|
- console.log(err)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- /**
|
|
|
- * todo 读取更新文件
|
|
|
- */
|
|
|
- readUpdateFile() {
|
|
|
- FileSystemManager.readFile({
|
|
|
- filePath: $this.updateImageSavePath,
|
|
|
- success(res) {
|
|
|
- console.log(res.data)
|
|
|
- }
|
|
|
- })
|
|
|
- FileSystemManager.readFile({
|
|
|
- filePath: $this.updateImageSavePath,
|
|
|
- success(res) {
|
|
|
- // $this.AddContent("读取文件成功")
|
|
|
- let buffer_len = new Uint8Array(res.data).length
|
|
|
- // 读取信息
|
|
|
- for (let i = 0; i < buffer_len; i += 16) {
|
|
|
- let buffer = new Uint8Array(res.data, i, 16);
|
|
|
- if (i == 0) {
|
|
|
- //读取第一行信息 并返回 文件解密下标
|
|
|
- $this.dec_index = $this.getUpdateHeader0(buffer) / 10
|
|
|
- console.log(`解密指定行:${$this.dec_index}`)
|
|
|
- }
|
|
|
- if (i == 1 * 16) {
|
|
|
- let software_version = "";
|
|
|
- for (let j = 0; j < buffer.length; j++) {
|
|
|
- software_version += String.fromCharCode(buffer[j])
|
|
|
- }
|
|
|
- console.log(`软件版本:${$this.software_version}`)
|
|
|
- }
|
|
|
- if (i == 2 * 16) {
|
|
|
- for (let j = 0; j < buffer.length; j++) {
|
|
|
- $this.model += String.fromCharCode(buffer[j])
|
|
|
- }
|
|
|
- $this.model = $this.model.trim()
|
|
|
- console.log(`模型:${$this.model}`)
|
|
|
- }
|
|
|
- //发送指定行的数据
|
|
|
- if (i >= $this.dec_index * 16) {
|
|
|
- $this.buffers = res.data
|
|
|
- $this.step_active += 1;
|
|
|
- //开始升级
|
|
|
- $this.OpenBleUpdate();
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- fail(err) {
|
|
|
- console.log(err)
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- /**
|
|
|
- * 获取第一行头部信息
|
|
|
- * @param buffer 数据包
|
|
|
- * @returns {number} 返回需要解密的位置信息
|
|
|
- */
|
|
|
- getUpdateHeader0(buffer) {
|
|
|
- //验证升级标志
|
|
|
- let update_tag = [88, 48, 57, 57]
|
|
|
- let update_tag_count = update_tag.length
|
|
|
- for (let i = 0; i < update_tag.length; i++) {
|
|
|
- let _buffer = buffer[i].toString(16);
|
|
|
- //验证升级标志
|
|
|
- if (_buffer == update_tag[i]) {
|
|
|
- update_tag_count -= 1;
|
|
|
- if (update_tag_count == 0) {
|
|
|
- // // $this.AddContent("验证升级标志成功")
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //获取payload长度
|
|
|
- let payload_len = ""
|
|
|
- for (let i = 7; i > 3; i--) {
|
|
|
- let _buffer = ('00' + buffer[i].toString(16)).substr(-2, 2);
|
|
|
- //验证升级标志
|
|
|
- payload_len += `${_buffer}`;
|
|
|
- }
|
|
|
- payload_len = parseInt(payload_len, 16);
|
|
|
- $this.payload_len = payload_len;
|
|
|
-
|
|
|
- //获取升级的offset
|
|
|
- let update_offset = 0
|
|
|
- for (let i = 15; i > 11; i--) {
|
|
|
- let _buffer = buffer[i].toString(16);
|
|
|
- //验证升级标志
|
|
|
- update_offset += parseInt(_buffer);
|
|
|
- }
|
|
|
-
|
|
|
- //文件总长度
|
|
|
- let file_total_size = payload_len + parseInt(update_offset, 16)
|
|
|
- return update_offset;
|
|
|
- },
|
|
|
- /**
|
|
|
- * 打开蓝牙升级通道
|
|
|
- * @constructor
|
|
|
- */
|
|
|
- OpenBleUpdate() {
|
|
|
- let buffer = new Uint8Array($this.buffers, 4, 4)
|
|
|
- let $hexStr = [
|
|
|
- '03',
|
|
|
- '30'
|
|
|
- ]
|
|
|
- for (let i = 0; i < 11; i++) {
|
|
|
- if (i < buffer.length) {
|
|
|
- let $hex = ('00' + buffer[i].toString(16)).substr(-2, 2)
|
|
|
- $hexStr.push($hex)
|
|
|
- } else {
|
|
|
- $hexStr.push('00')
|
|
|
- }
|
|
|
- }
|
|
|
- $this.$connection.WriteBufferInBle($hexStr.join(' '), 16)
|
|
|
- },
|
|
|
- // todo 准备升级
|
|
|
- ReadyUpdate() {
|
|
|
- $this.update_state = true
|
|
|
- this.ConnectBrain()
|
|
|
- // this.downloadUpateFile();
|
|
|
- },
|
|
|
- BackIndex() {
|
|
|
- wx.navigateBack();
|
|
|
- }
|
|
|
- },
|
|
|
- mounted() {
|
|
|
- },
|
|
|
- created() {
|
|
|
- $this = this;
|
|
|
- },
|
|
|
- onLoad(option) {
|
|
|
- this.brain_sn = option.sn
|
|
|
- }
|
|
|
-}
|
|
|
-</script>
|
|
|
-<style>
|
|
|
-.title {
|
|
|
- font-size: 32px;
|
|
|
- font-family: PingFang SC;
|
|
|
- font-weight: bold;
|
|
|
- color: #151515;
|
|
|
- margin: 25px 0px;
|
|
|
-}
|
|
|
-
|
|
|
-#firmwareContainer {
|
|
|
- padding: 0px 30px;
|
|
|
-}
|
|
|
-
|
|
|
-.subtitle {
|
|
|
- font-size: 17px;
|
|
|
- font-family: PingFang SC;
|
|
|
- font-weight: 500;
|
|
|
- color: #151515;
|
|
|
-}
|
|
|
-
|
|
|
-.desc_container {
|
|
|
- margin: 20px 0px;
|
|
|
-}
|
|
|
-
|
|
|
-.desc {
|
|
|
- font-size: 14px;
|
|
|
- font-family: PingFang SC;
|
|
|
- font-weight: 400;
|
|
|
- color: #666666;
|
|
|
- margin: 10px 0px;
|
|
|
-}
|
|
|
-
|
|
|
-.ready_button {
|
|
|
- width: 250px;
|
|
|
- height: 45px;
|
|
|
- background: #7078FF;
|
|
|
- border-radius: 23px;
|
|
|
-
|
|
|
- font-size: 17px;
|
|
|
- font-family: PingFang SC;
|
|
|
- font-weight: bold;
|
|
|
- color: #FFFFFF;
|
|
|
-
|
|
|
- margin: 100px auto;
|
|
|
-}
|
|
|
-
|
|
|
-.progress_container {
|
|
|
- margin: 10px 0px;
|
|
|
-}
|
|
|
-
|
|
|
-.finsihed_subtitle {
|
|
|
- font-size: 17px;
|
|
|
- font-family: PingFang SC;
|
|
|
- font-weight: bold;
|
|
|
- color: #151515;
|
|
|
- text-align: center;
|
|
|
- margin-top: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.finished_container {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
- margin-top: 100px;
|
|
|
-}
|
|
|
-
|
|
|
-.finished_button {
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-.version_info {
|
|
|
- font-size: 13px;
|
|
|
- font-family: PingFang SC;
|
|
|
- font-weight: 400;
|
|
|
- color: #B2B2B2;
|
|
|
- text-align: center;
|
|
|
- position: absolute;
|
|
|
- bottom: 100px;
|
|
|
- margin: 0px auto;
|
|
|
-}
|
|
|
-</style>
|