devices-update.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <!-- 蓝牙平台限制 todo https://uniapp.dcloud.io/api/system/bluetooth?id=stopbluetoothdevicesdiscovery -->
  2. <template>
  3. <view>
  4. <uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="设备升级" color="#000000" fixed="true" :border="false">
  5. <view slot="left">
  6. <view class=" flex align-center margin-left">
  7. <image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
  8. </view>
  9. </view>
  10. </uni-nav-bar>
  11. <view class="card-view padding-top padding-bottom" v-for="(item,index) in devicesList" :key="index" :class="item.bRatio?'hardware-border':''">
  12. <view class="flex justify-between align-center">
  13. <image style="margin-left: 30rpx; width: 200rpx;height: 120rpx;" :src="item.icon" mode="aspectFit"></image>
  14. <view style="width: 250rpx;">
  15. <view style="font-weight: bold; font-size: 18px; color: #565656; margin: 20rpx 0;">{{item.cname}}</view>
  16. <view v-if="send_index<=0&&item.currentVersion !== ''">
  17. <view style="margin: 20rpx 0; font-size: 12px; color: grey;">固件版本号:{{item.currentVersion}}</view>
  18. <!-- <view style="margin: 20rpx; font-size: 12px;" class="make-text-bPurple">更新版本号:{{item.latestVersion}}</view> -->
  19. </view>
  20. <!-- <view class="flex">
  21. <view style="margin: 20rpx; font-size: 12px; color: grey;">硬件rom:{{item.currentRomVersion}}</view>
  22. <view style="margin: 20rpx; font-size: 12px;" class="make-text-bPurple">更新版本rom:{{item.latestRomVersion}}</view>
  23. </view> -->
  24. <!-- <view class="flex">
  25. <view style="margin: 20rpx; font-size: 12px; color: grey;">Bytes:{{bin_offset}} 总 {{bin_byteLength}}</view>
  26. </view> -->
  27. <view v-if="send_index>0" class="flex justify-between align-center" style="width: 210rpx;">
  28. <view class="cu-progress round" style=" width: 140rpx; height: 15rpx;">
  29. <view class="bg-green" :style="[{ width:percentage+'%'}]"></view>
  30. </view>
  31. <view class="" style=" font-size: 12px; color: grey;">{{percentage}}%</view>
  32. <!-- <view>
  33. <progress :percent="percentage" stroke-width="3" />
  34. </view> -->
  35. <!-- ,total {{bin_total}} send:{{send_index}} -->
  36. <!-- <view style=" font-size: 12px; color: grey;"> {{percentage}}% </view> -->
  37. </view>
  38. </view>
  39. <view v-if = "!bStart" style="width: 180rpx;margin-right: 30rpx;">
  40. <view v-if="send_index<=0&&item.latestVersion !== ''">
  41. <view v-if="bCanUpdate&&downLoadOTA!==''" class="text-11px make-text-bPurple " style="text-decoration:underline"
  42. @click="onSendConnect"> 请更新版本{{item.latestVersion}}
  43. </view>
  44. <view v-else class="text-11px text-grey">最新版本{{item.latestVersion}}</view>
  45. <!-- <button v-else class="text-11px make-bg-bPurple text-white" @click="onCheckDeviceFiles">检查更新</button> -->
  46. <!-- <button v-if="item.currentVersion !== ''" class="text-11px margin" @click="onSendConnect">开始</button> -->
  47. <!-- <button v-if="item.currentVersion !== ''" class="text-11px margin" @click="onStop">停止</button> -->
  48. </view>
  49. <view v-if="send_index<=0&&item.latestVersion === ''" class="text-26px text-grey text-center"><text class="cuIcon-loading2 cuIconfont-spin"></text></view>
  50. </view>
  51. <view v-else style="width: 180rpx;margin-right: 30rpx;">
  52. <view v-if="send_index<=0&&!sending_file" class="text-11px text-grey">{{writeTip}}</view>
  53. <view v-else class="text-11px text-grey">{{writeTip}}</view>
  54. </view>
  55. </view>
  56. <!-- <view class="flex">
  57. <view style="margin: 20rpx; font-size: 12px; color: grey;">发送和接收的次数:send:{{send_index}}</view>
  58. <view style="margin: 20rpx; font-size: 12px;" class="make-text-bPurple">time:{{send_index/100}}</view>
  59. </view> -->
  60. <!-- <scroll-view class="text-box" scroll-y="true">
  61. <scroll-view scroll-x="true">
  62. <text selectable="true">{{text}}</text>
  63. </scroll-view>
  64. </scroll-view> -->
  65. </view>
  66. </view>
  67. </template>
  68. <script>
  69. import config from '@/common/config.js'
  70. import reqUtil from '@/util/util-js/requstUtil.js';
  71. import {
  72. mapState,
  73. mapMutations
  74. } from 'vuex';
  75. export default {
  76. computed: mapState(['bOpenBluetooth', 'bOpenSuccess', 'bListenAdapterStateChange', 'bListenDeviceFound',
  77. 'BLEConnectDevice', 'cIndex'
  78. ]),
  79. data() {
  80. return {
  81. /**
  82. * OTA config
  83. */
  84. UUID_OTA_SERVICE: "f000ffc0-0451-4000-b000-000000000000", //OTA 服务对应的服务的 UUID
  85. UUID_IDENTFY: "f000ffc1-0451-4000-b000-000000000000", //OTA 版本特征值的UUID,读取版本就是写向这个特征值写入:0x00
  86. UUID_BLOCK: "f000ffc2-0451-4000-b000-000000000000", //OTA 写bin文件特征值UUID,发送bin文件就是写这个特征值
  87. /*****/
  88. boxingList: [{
  89. cname: "蓝牙手柄",
  90. ename: "BLEHandle",
  91. icon: "/static/devicesIcon/handle.png",
  92. mIcon: "/static/devicesIcon/handle.png",
  93. bRatio: false,
  94. limitType: 'noRebound', //app处理蓝牙发送的数据
  95. deviceType: 'BLEHandle', //指的是外部蓝牙,目前定义为BLEHandle
  96. deviceName: 'PBox', //连接的设备名称
  97. limitDis: 100, //
  98. primaryUUID: 'f000ffc0', //OTA升级主服务id
  99. currentVersion: '', //当前固件版本
  100. latestVersion: '', //服务器最新固件版本
  101. currentRomVersion: '',
  102. latestRomVersion: '',
  103. UUID_OTA_SERVICE: "f000ffc0-0451-4000-b000-000000000000", //OTA 服务对应的服务的 UUID
  104. UUID_IDENTFY: "f000ffc1-0451-4000-b000-000000000000", //OTA 版本特征值的UUID,读取版本就是写向这个特征值写入:0x00
  105. UUID_BLOCK: "f000ffc2-0451-4000-b000-000000000000", //OTA 写bin文件特征值UUID,发送bin文件就是写这个特征值
  106. }],
  107. devicesList: [],
  108. downLoadOTA: '',
  109. //文件数据
  110. bin_buffer: [],
  111. bin_file_len: 0,
  112. bin_byteLength: 0,
  113. bin_total: 0,
  114. bin_offset: 0,
  115. //当前发送的下标
  116. send_index: 0,
  117. sending_file: false,
  118. // 当前进度
  119. percentage: 0,
  120. //是否可以发送
  121. bSend: true,
  122. //是否可以更新
  123. bCanUpdate: false,
  124. //是否开始
  125. bStart: false,
  126. bListenValueChange: false,
  127. //测试
  128. text: '',
  129. extraLine: [],
  130. //timeout 对象
  131. writeHeadTimeout: null,
  132. backTimeout: null,
  133. sendFileHeaderTimeout: null,
  134. writeTip:'准备写入数据..',
  135. bBacking:false,
  136. }
  137. },
  138. onLoad(option) {
  139. uni.$on('callbackCloseBLE', this.updateCallbackCloseBLE);
  140. this.devicesList = this.boxingList;
  141. //比如现在BLEHandle 对应的 1,
  142. //获得游戏列表
  143. reqUtil
  144. .requestData(config.URL.GETOTA, {
  145. bleType: 1, //目前只有一种设备,就是 BLEHandle,todo 后面如果设备多了需要设备多种ota
  146. })
  147. .then(
  148. res => {
  149. console.log('GETOTA =====', res);
  150. if (res.code == 0) {
  151. //设置对应的下载地址
  152. this.downLoadOTA = res.data.otaDownload;
  153. //读取需要更新的设备,存储在数据库
  154. this.onCheckServerFiles();
  155. this.onCheckDeviceFiles();
  156. uni.showToast({
  157. title: '获取信息...',
  158. icon: 'loading',
  159. duration: 20000
  160. })
  161. }
  162. },
  163. e => {
  164. console.log(e);
  165. }
  166. );
  167. },
  168. onUnload() {
  169. uni.$off('callbackCloseBLE', this.updateCallbackCloseBLE);
  170. //如果是获取版本指令timeout
  171. if (this.writeHeadTimeout) {
  172. clearTimeout(this.writeHeadTimeout);
  173. this.writeHeadTimeout = null;
  174. }
  175. //回退timeout
  176. if (this.backTimeout) {
  177. clearTimeout(this.backTimeout);
  178. this.backTimeout = null;
  179. }
  180. //发送头指令timeout
  181. if (this.sendFileHeaderTimeout) {
  182. clearTimeout(this.sendFileHeaderTimeout);
  183. this.sendFileHeaderTimeout = null;
  184. }
  185. this.onBack();
  186. },
  187. onShow() {
  188. },
  189. onHide() {},
  190. methods: {
  191. ...mapMutations(['initAdapter', 'onCloseBLEConnection',
  192. 'onGetRSSITransDistance'
  193. ]),
  194. updateCallbackCloseBLE() {
  195. this.onBack();
  196. },
  197. onBack() {
  198. // if(this.bStart){
  199. // }
  200. if(this.bBacking)return;
  201. this.bBacking = true;
  202. //停止发送数据
  203. this.onStop();
  204. console.log('onBack:',this.BLEConnectDevice);
  205. //关闭当前的蓝牙连接
  206. this.onCloseBLEConnection({
  207. getSuccess: () => {
  208. console.log("close ble");
  209. this.$store.state.bConnection = false;
  210. }
  211. });
  212. console.log('onBack');
  213. this.$store.state.cIndex = -1;
  214. this.$store.state.BLEConnectDevice = null;
  215. this.$store.state.BLEGetServices = null;
  216. this.$store.state.bOpenBluetooth = false;
  217. uni.navigateBack({
  218. delta: 1
  219. })
  220. },
  221. //获取版本
  222. onCheckDeviceFiles() {
  223. // console.log('onCheckDeviceFiles:', this.BLEConnectDevice);
  224. //直接连接对应服务
  225. this.notifyBLECharacteristicValueChange({
  226. deviceId: this.BLEConnectDevice.deviceId,
  227. serviceId: this.UUID_OTA_SERVICE,
  228. characteristicId: this.UUID_IDENTFY
  229. });
  230. },
  231. //开始写数据
  232. onSendConnect() {
  233. uni.showModal({
  234. title: '更新提示',
  235. content: '设备更新成功后会自动关闭,是否继续更新?',
  236. success: (resValue) => {
  237. if (resValue.confirm) {
  238. //直接连接对应服务
  239. this.notifyBLECharacteristicValueChange({
  240. deviceId: this.BLEConnectDevice.deviceId,
  241. serviceId: this.UUID_OTA_SERVICE,
  242. characteristicId: this.UUID_BLOCK
  243. });
  244. uni.showToast({
  245. title: '请求硬件更新数据...',
  246. icon: 'none',
  247. duration: 3000,
  248. mask:true
  249. })
  250. //发送头指令timeout
  251. if (this.sendFileHeaderTimeout) {
  252. clearTimeout(this.sendFileHeaderTimeout);
  253. this.sendFileHeaderTimeout = null;
  254. }
  255. this.sendFileHeaderTimeout = setTimeout(() => {
  256. this.sendFileHeader();
  257. // this.send_index = -1;
  258. }, 2000)
  259. this.bStart = true;
  260. }
  261. }
  262. })
  263. },
  264. //启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。
  265. //注意:必须设备的特征值支持notify或者indicate才可以成功调用,具体参照 characteristic 的 properties 属性
  266. notifyBLECharacteristicValueChange(context) {
  267. var _self = this;
  268. let {
  269. deviceId,
  270. serviceId,
  271. characteristicId
  272. } = context;
  273. // 启用notify功能
  274. uni.notifyBLECharacteristicValueChange({
  275. state: true,
  276. deviceId: deviceId,
  277. serviceId: serviceId,
  278. characteristicId: characteristicId,
  279. success: function(res) {
  280. if (!_self.bListenValueChange) {
  281. _self.onBLECharacteristicValueChange(); //监听特征值变化
  282. _self.bListenValueChange = true;
  283. }
  284. if (characteristicId == _self.UUID_IDENTFY) {
  285. _self.onGetDeviceVersion(context);
  286. }
  287. },
  288. fail: function(res) {
  289. uni.showToast({
  290. title: 'notify启动失败',
  291. icon: "none",
  292. mask: true
  293. });
  294. }
  295. })
  296. },
  297. onGetDeviceVersion(context){
  298. let _self = this;
  299. let {
  300. deviceId,
  301. serviceId,
  302. characteristicId
  303. } = context;
  304. //如果是获取版本,延迟写一个指令
  305. if (_self.writeHeadTimeout) {
  306. clearTimeout(_self.writeHeadTimeout);
  307. _self.writeHeadTimeout = null;
  308. }
  309. _self.writeHeadTimeout = setTimeout(() => {
  310. // 向蓝牙设备发送一个0x00的16进制数据
  311. let bufferDevice = new ArrayBuffer(1)
  312. let dataViewDevice = new DataView(bufferDevice)
  313. dataViewDevice.setUint8(0, 0)
  314. uni.writeBLECharacteristicValue({
  315. deviceId: deviceId,
  316. serviceId: serviceId,
  317. characteristicId: characteristicId,
  318. value: bufferDevice,
  319. success:(res) => {
  320. console.log('获取版本:writeBLECharacteristicValue success', res.errMsg)
  321. },
  322. fail:(fail)=>{
  323. console.error('获取版本:writeBLECharacteristicValue fail', fail.errMsg)
  324. uni.showModal({
  325. title:'获取固件版本',
  326. content:'获取不成功,是否重新获取',
  327. success: (resValue) => {
  328. if(resValue.confirm){
  329. _self.onGetDeviceVersion(context);
  330. }
  331. }
  332. })
  333. }
  334. })
  335. }, 1500)
  336. },
  337. //监听低功耗蓝牙设备的特征值变化。必须先启用notify接口才能接收到设备推送的notification。
  338. onBLECharacteristicValueChange() {
  339. var _self = this;
  340. // ArrayBuffer转16进制字符串示例
  341. // console.log("onBLECharacteristicValueChange");
  342. uni.onBLECharacteristicValueChange(function(res) {
  343. if (res.characteristicId.toLocaleLowerCase() === _self.UUID_IDENTFY) {
  344. //如果硬件的版本获取版本
  345. var resValue = ab2hext(res.value); //16进制字符串
  346. // console.log("Device 版本:", resValue.substr(0, 4), "Rom 版本号:", resValue.substr(16, 4));
  347. _self.devicesList[0].currentRomVersion = resValue.substr(16, 4);
  348. _self.devicesList[0].currentVersion = resValue.substr(0, 4);
  349. //读取到硬件版本,判断是否需要更新
  350. if (_self.devicesList[0].currentVersion === _self.devicesList[0].latestVersion && _self.devicesList[0].currentRomVersion ===
  351. _self.devicesList[0].latestRomVersion) {
  352. uni.showToast({
  353. title: '版本一致,无需升级',
  354. icon: 'none',
  355. mask: true,
  356. })
  357. _self.bCanUpdate = false;
  358. return;
  359. }
  360. uni.showToast({
  361. title: '获取信息成功',
  362. icon: 'success',
  363. mask: true,
  364. })
  365. //设置状态
  366. _self.bCanUpdate = true;
  367. } else {
  368. uni.hideToast();
  369. //成功发送头文件会走一个回调
  370. let uint8_buf = new DataView(res.value);
  371. _self.send_index = ((uint8_buf.getUint8(1) << 8) | uint8_buf.getUint8(0));
  372. console.log("val===>> data:" + ab2hext(res.value) + ",rv index:" + _self.send_index + _self.sending_file)
  373. if (_self.sending_file == false) {
  374. _self.sending_file = true;
  375. // console.log("SendBlePkg");
  376. _self.writeTip = "正在写入设备...";
  377. _self.SendBlePkg();
  378. }
  379. }
  380. });
  381. },
  382. //下载后读取
  383. onCheckServerFiles() {
  384. this.bin_buffer = [];
  385. this.bin_offset = 0;
  386. this.bin_total = 0;
  387. this.reset();
  388. uni.request({
  389. url: this.downLoadOTA,
  390. method: "GET",
  391. responseType: "arraybuffer",
  392. success: (res) => {
  393. //记录二进制数据
  394. this.bin_buffer = res.data;
  395. let binData = new Uint8Array(this.bin_buffer, 0, 16); //new Uint8Array(this.bin_buffer);
  396. this.bin_file_len = (binData[7] << 8) | binData[6]
  397. this.bin_total = (this.bin_file_len) / 4
  398. this.bin_byteLength = this.bin_buffer.byteLength;
  399. function uint8_to_hex_str(data) {
  400. var v = data.toString(16).slice(-2) + ''
  401. if (v == '0') {
  402. v = '00'
  403. }
  404. if (v.length == 1) {
  405. v = '0' + v
  406. }
  407. return v
  408. }
  409. // console.log("ver2:", uint8_to_hex_str(binData[4]) + uint8_to_hex_str(binData[5]), ",rom:", uint8_to_hex_str(
  410. // binData[14]) +
  411. // uint8_to_hex_str(binData[15]));
  412. //显示信息
  413. this.devicesList[0].latestRomVersion = uint8_to_hex_str(binData[14]) + uint8_to_hex_str(binData[15]); //str.substr(28, 2);
  414. this.devicesList[0].latestVersion = uint8_to_hex_str(binData[4]) + uint8_to_hex_str(binData[5]); //str.substr(8, 2);
  415. },
  416. fail: (fail) => {
  417. uni.showToast({
  418. title: '下载固件失败..',
  419. icon: 'none'
  420. });
  421. }
  422. });
  423. },
  424. //发送文件头信息(配置信息)
  425. sendFileHeader() {
  426. console.log('---------- sendFileHeader --------------')
  427. let _self = this
  428. let buffer = new ArrayBuffer(16)
  429. let dataView = new DataView(buffer)
  430. var b = new Uint8Array(_self.bin_buffer, 0, 16);
  431. for (var i = 0; i < 16; i++) {
  432. dataView.setUint8(i, b[i])
  433. }
  434. console.log('send header:' + ab2hext(buffer))
  435. // return;
  436. uni.writeBLECharacteristicValue({
  437. deviceId: _self.BLEConnectDevice.deviceId,
  438. serviceId: _self.UUID_OTA_SERVICE.toLocaleUpperCase(),
  439. characteristicId: _self.UUID_IDENTFY.toLocaleUpperCase(),
  440. value: buffer,
  441. success: function(res) {
  442. // _self.send_index = -1
  443. // _self.sending_file = false
  444. uni.showToast({
  445. title: '准备更新数据...',
  446. icon: 'none',
  447. duration: 3000,
  448. mask:true
  449. })
  450. console.log('开始发送文件success', _self.sending_file)
  451. // _self.SendBlePkg()
  452. },
  453. fail: function(err) {
  454. console.log('read version fail! ' + JSON.stringify(err))
  455. uni.showModal({
  456. title:'请求更新',
  457. content:'请求更新失败,是否重新尝试继续。',
  458. success: (resValue) => {
  459. if(resValue.confirm){
  460. _self.sendFileHeader();
  461. }else if(resValue.cancel){
  462. _self.bStart = false;
  463. }
  464. }
  465. })
  466. }
  467. })
  468. },
  469. //发送一包数据
  470. SendBlePkg() {
  471. var _self = this;
  472. if (!_self.bSend) return;
  473. if (_self.send_index == -1) {
  474. return
  475. }
  476. if (_self.send_index >= _self.bin_total) {
  477. _self.percentage = 100;
  478. uni.showToast({
  479. title: "更新完成",
  480. duration: 2000,
  481. mask: true
  482. })
  483. //回退timeout
  484. if (this.backTimeout) {
  485. clearTimeout(this.backTimeout);
  486. this.backTimeout = null;
  487. }
  488. this.backTimeout = setTimeout(() => {
  489. //更新成功后设备会断开,此时回退出此页面
  490. uni.hideToast();
  491. _self.onBack();
  492. }, 1500)
  493. return;
  494. }
  495. _self.percentage = parseInt(_self.send_index / _self.bin_total * 100);
  496. //分包长度,16字节有效数据(总数据/16=次数)
  497. let length = 16;
  498. //发送每包数据的结构:2个字节的序号 + 16个字节的有效数据
  499. //设置数据包序号
  500. let lo = getLow8(_self.send_index);
  501. let hi = getHeight8(_self.send_index);
  502. //最要一个18字节的包
  503. let send_ab = new ArrayBuffer(18);
  504. let a = new Uint8Array(send_ab);
  505. //2个字节的序号
  506. a[0] = lo;
  507. a[1] = hi;
  508. if (_self.bin_offset + length > _self.bin_buffer.byteLength) {
  509. length = _self.bin_buffer.byteLength - _self.bin_offset;
  510. }
  511. var b = new Uint8Array(_self.bin_buffer, _self.bin_offset, length);
  512. a.set(b, 2);
  513. uni.writeBLECharacteristicValue({
  514. deviceId: _self.BLEConnectDevice.deviceId,
  515. serviceId: _self.UUID_OTA_SERVICE, // _deviceId,
  516. characteristicId: _self.UUID_BLOCK,
  517. value: send_ab,
  518. fail: function(res) {
  519. console.log('write BLEChar fail')
  520. _self.SendBlePkg();
  521. },
  522. success: function(res) {
  523. _self.send_index++;
  524. //发送的有效字节数
  525. _self.bin_offset += length;
  526. // _self.sending_file = false;
  527. _self.SendBlePkg();
  528. // console.log('success')
  529. },
  530. })
  531. },
  532. reset() {
  533. //发送字节的下标
  534. this.send_index = 0;
  535. //发送的有效字节数
  536. this.bin_offset = 0;
  537. this.percentage = 0;
  538. this.bSend = true;
  539. },
  540. onStop() {
  541. this.bSend = false;
  542. },
  543. onReadFile(url) {
  544. //游戏列表
  545. // firmwareList: [{
  546. // name: "24_LYY_3431Q_H2_S3_bk3435_ble_app_oad.bin",
  547. // downloadUrl: "https://www.yuyekeji.cn/Cocos/bin_version/24_LYY_3431Q_H2_S3_bk3435_ble_app_oad.bin",
  548. // fileName: "bin_version",
  549. // suffix: "bin",
  550. // type: "bin",
  551. // task: null,
  552. // progressVal: 0,
  553. // bFileExists: false,
  554. // bDownload: false,
  555. // }],
  556. // data URIs to buffer
  557. function dataURL2Buffer(dataURI) {
  558. var byteStr
  559. var intArray
  560. var ab
  561. var i
  562. var mimetype
  563. var parts
  564. parts = dataURI.split(',')
  565. parts[1] = parts[1].replace(/\s/g, '')
  566. // console.log(parts);
  567. if (~parts[0].indexOf('base64')) {
  568. byteStr = atob(parts[1])
  569. } else {
  570. byteStr = decodeURIComponent(parts[1])
  571. }
  572. // // ab = new ArrayBuffer(byteStr.length)
  573. // intArray = new Uint8Array(byteStr.length)
  574. // for (i = 0; i < byteStr.length; i++) {
  575. // intArray[i] = byteStr.charCodeAt(i)
  576. // }
  577. // console.log(intArray.length, intArray.byteLength);
  578. return byteStr;
  579. }
  580. let item = this.firmwareList[0];
  581. console.log("url:" + JSON.stringify(url));
  582. plus.io.resolveLocalFileSystemURL(url, function(entry) {
  583. entry.file(function(file) {
  584. var fileReader = new plus.io.FileReader();
  585. fileReader.readAsDataURL(file);
  586. fileReader.onloadend = function(evt) {
  587. // console.log("_buffer1:" + JSON.stringify(evt.target.result));
  588. // let _arrayBuffer = dataURL2Buffer(evt.target.result)
  589. let parts = evt.target.result.split(',')
  590. let _arrayBuffer = parts[1].replace(/\s/g, '')
  591. console.log("_buffer1:" + JSON.stringify(_arrayBuffer));
  592. let _buffer = uni.base64ToArrayBuffer(_arrayBuffer);
  593. console.log("_buffer2:", JSON.stringify(_buffer));
  594. console.log("_buffer:", _buffer.length, _buffer.byteLength, _buffer.byteOffset);
  595. }
  596. });
  597. }, function(e) {
  598. console.log("Resolve file URL failed: " + e.message);
  599. });
  600. },
  601. //下载固件
  602. downLoadBin() {
  603. let _self = this;
  604. let item = this.firmwareList[0];
  605. let downloadUrl = item.downloadUrl;
  606. let _filename = '_doc/' + item.name; //+'/'+item.name
  607. console.log(_filename, downloadUrl);
  608. item.task = plus.downloader.createDownload(downloadUrl, {
  609. filename: _filename
  610. });
  611. item.task.addEventListener("statechanged", (download, status) => {
  612. // console.log("status", status);
  613. //连接服务器后
  614. // no default
  615. switch (download.state) {
  616. case 1:
  617. console.log('开始下载');
  618. // item.bDownload = true;
  619. break;
  620. case 2:
  621. console.log('链接到服务器...');
  622. item.bDownload = true;
  623. break;
  624. case 3:
  625. if (status !== 200) {
  626. uni.showToast({
  627. title: 'status=' + status
  628. })
  629. return;
  630. }
  631. item.progressVal = Math.ceil(download.downloadedSize / download.totalSize * 100);
  632. // _this.precent = progressVal;
  633. console.log(item.progressVal);
  634. break;
  635. case 4:
  636. // 下载完成
  637. console.log("监听下载 success: " + download.getFileName());
  638. setTimeout(() => {
  639. item.bDownload = false;
  640. }, 500)
  641. break;
  642. }
  643. }, false);
  644. item.task.start();
  645. },
  646. add: function(data) {
  647. // console.log(data)
  648. if (this.extraLine.length > 500) {
  649. this.extraLine = [];
  650. this.text = this.extraLine.join('\n');
  651. }
  652. this.extraLine.push(data);
  653. this.text = this.extraLine.join('\n');
  654. },
  655. remove: function(e) {
  656. if (this.extraLine.length > 0) {
  657. // this.extraLine.pop();
  658. this.extraLine = [];
  659. this.text = this.extraLine.join('\n');
  660. }
  661. },
  662. }
  663. }
  664. function ab2hext(buffer) {
  665. var hexArr = Array.prototype.map.call(
  666. new Uint8Array(buffer),
  667. function(bit) {
  668. return ('00' + bit.toString(16)).slice(-2)
  669. }
  670. )
  671. return hexArr.join('');
  672. }
  673. function getHeight8(data) { //获取高8位
  674. let height;
  675. height = (data >> 8);
  676. return height;
  677. }
  678. function getLow8(data) { //获取低8位
  679. let low;
  680. low = (data & 0xFF);
  681. return low;
  682. }
  683. </script>
  684. <style>
  685. .hardware-border {
  686. border: 1rpx solid #9898FF;
  687. box-sizing: border-box;
  688. }
  689. .text-box {
  690. margin: 20rpx;
  691. display: flex;
  692. width: 95%;
  693. min-height: 300rpx;
  694. max-height: 600rpx;
  695. background-color: #EEEEEE;
  696. justify-content: center;
  697. align-items: center;
  698. text-align: center;
  699. font-size: 30upx;
  700. color: #353535;
  701. line-height: 1.8;
  702. border: 1rpx solid #555555;
  703. overflow-y: hidden;
  704. }
  705. </style>