ZXCar.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. const common = require('../common.js');
  2. const FMBMS = require('./FMBMS.js');
  3. var bluetooth = require('@/common/bluetooth.js');
  4. import permision from "@/js_sdk/wa-permission/permission.js"
  5. const readServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
  6. const readID = '000036F6-0000-1000-8000-00805F9B34FB';
  7. const writeServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
  8. const writeID = '000036F5-0000-1000-8000-00805F9B34FB';
  9. const MTU = 115;
  10. let subIndex = -1
  11. let commands = []; // 升级包指令数组,每个指令是一个 ArrayBuffer
  12. let currentCommandIndex = 1;
  13. var totalLength = 0 //总包长度
  14. var joinPack = []//接收到的数据包
  15. var readRepeatTime = 0 //读到完整数据包的时间戳
  16. var readRepeatTime = 0 //读到完整数据包的时间戳
  17. function acceptDevice(device) {
  18. return device.btid ? true : false;
  19. }
  20. function isSingleBt() {
  21. console.log('是单蓝牙');
  22. return true;
  23. }
  24. function haveBms() {
  25. console.log('是单蓝牙并且带bms');
  26. return true;
  27. }
  28. function isDevice(device, data) {
  29. // console.log(device,data,'device111');
  30. const advertisData = new Uint8Array(data.advertisData);
  31. // console.log(advertisData,'判断返回第几个字段是正常模式还是升级模式');
  32. //打印返回广播 判断返回字段是正常模式还是升级模式
  33. // console.log(advertisData.slice(4, 10).toString(),'device2222');
  34. const mac = device.btid
  35. .split('')
  36. .map((p, i) => parseInt(p + device.btid[i + 1], 16))
  37. .filter((p, i) => i % 2 == 0);
  38. // if ( advertisData.slice(4, 10).toString() == "095A5832") {
  39. // return true;
  40. // }
  41. //判断是否是智寻的蓝牙
  42. const result = data.name.startsWith("ZX");
  43. // const result = data.name.startsWith("ZN");
  44. // if (data.name === "865416038002201") {
  45. // if (data.name === "ZX2503150000000") {
  46. if (result) {
  47. return true
  48. }
  49. return false;
  50. }
  51. //连接蓝牙后 发送登录指令
  52. function alterConnect(device, deviceId) {
  53. const app = getApp();
  54. readRepeatTime=0
  55. // console.log(device,app.globalData.connectionState[deviceId],'deviceliuwei');
  56. //登录 crc[0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00]
  57. //登录 [[0x22,0x22,0x01,0x1F,0x0F,0x5A,0x58,0x32,0x32,0x30,0x32,0x32,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x08,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x67,0xAC,0x53,0xE7,0x08,0x00,crc_data,0xAA,0xAA]]
  58. //时间戳 0x67AC53E7 0x65,0xB3,0xED,0x6F 16:00:05
  59. //切换正常,工厂下发指令 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
  60. //OTA 升级指令 [[0x22,0x22,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,n,0xCB,0xAA,0xAA]]
  61. // const data = [0x1F, 0x0F, ,0x5A,0x58, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
  62. console.log("校检---》")
  63. let data=[ 0x1F, 0x0F]
  64. const device_name=app.globalData.connectionState[device.mac_id].deviceName
  65. const device_sn=stringToHexArray(device_name)
  66. // const car_info = uni.getStorageSync('car_info')
  67. // const device_sn=stringToHexArray(car_info.car_sn)
  68. // const device_sn=stringToHexArray('865416038001109')
  69. data.push(...device_sn)
  70. data.push(0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00)
  71. // const data=[ 0x1F, 0x0F,0x38, 0x36, 0x35, 0x34, 0x31, 0x36, 0x30, 0x33, 0x38, 0x30, 0x30, 0x32, 0x32, 0x30, 0x31,0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00]
  72. // console.log(data,'datatest');
  73. console.log(crc8IEEE8023(data).toString(16).toUpperCase(),'crc---------');
  74. const crc_data = parseInt(crc8IEEE8023(data).toString(16).toUpperCase(),16)
  75. // const crc_data =crc8IEEE8023(data).toString(16).toUpperCase()
  76. data.push(crc_data,0xAA,0xAA)
  77. data.unshift(0x22,0x22,0x01)
  78. // // 从索引 0 开始,删除 3 个元素
  79. const firstPart = data.splice(0, 20);
  80. // // 剩余的元素
  81. const secondPart = data;
  82. // const threePart = data;
  83. // return [data]
  84. return [firstPart,secondPart]
  85. // return [[0x22]]
  86. }
  87. function crc8IEEE8023(data) {
  88. const poly = 0x07; // IEEE 802.3 polynomial x^8 + x^2 + x + 1
  89. let crc = 0x00;
  90. for (let i = 0; i < data.length; i++) {
  91. crc ^= data[i];
  92. for (let j = 0; j < 8; j++) {
  93. if (crc & 0x80) {
  94. crc = ((crc << 1) ^ poly) & 0xFF;
  95. } else {
  96. crc = (crc << 1) & 0xFF;
  97. }
  98. }
  99. }
  100. return crc;
  101. }
  102. function stringToHexArray(str) {
  103. const result = [];
  104. for (let i = 0; i < str.length; i++) {
  105. const charCode = str.charCodeAt(i); // 获取字符的 ASCII 码值
  106. const hexValue=`0x${charCode.toString(16).toUpperCase()}`
  107. const hexDataValue=parseInt(hexValue,16)
  108. result.push(hexDataValue);
  109. }
  110. return result;
  111. }
  112. //收到硬件方向软件方发送的数据
  113. function readData(device, value, data) {
  114. console.log('***********************test');
  115. var test = new Uint8Array(value);
  116. // const bmsData=Array.from(test);
  117. const normalArray=Array.from(test);
  118. // console.log(bmsData,'bmsData-------------');
  119. // const normalArray =packBmsData(bmsData)
  120. if(normalArray){
  121. console.log(normalArray[2],'normalArray---------------');
  122. switch(normalArray[2]){
  123. case 0x60:
  124. //登陆指令
  125. loginCmd(device.mac_id,normalArray)
  126. break;
  127. case 0x61||0x62||0x65:
  128. //开机指令 关机 寻车 //设置灵敏度回复
  129. trunCarCommand(device.mac_id,normalArray)
  130. break;
  131. case 0x66:
  132. //升级指令
  133. checkSendNextCommand(device.mac_id,normalArray)
  134. break;
  135. case 0x7C:
  136. //接近解锁指令
  137. nearCarCmd(device.mac_id,normalArray)
  138. break;
  139. case 0x7E:
  140. //获取车辆接近解锁 是否配对 灵敏度信息
  141. getNearCarCmdInfo(device.mac_id,normalArray)
  142. break;
  143. }
  144. }
  145. // console.log(normalArray,currentCommandIndex-1,commands[currentCommandIndex],commands[currentCommandIndex-1], 'value**************************');
  146. // if((normalArray[0]==0x00) && (normalArray[1]==0x01) && normalArray.length==2){
  147. // switch (normalArray[1]) {
  148. // case 0x01:
  149. // uni.showModal({
  150. // title: '提示',
  151. // confirmText: '开始升级',
  152. // content: '登陆成功,当前处于升级模式是否开始升级',
  153. // success: function(res) {
  154. // if (res.confirm) {
  155. // currentCommandIndex=0
  156. // otaUpgrade().then(()=>{
  157. // //登陆成功 且当前为升级模式可以发送升级文件
  158. // sendNextCommand(device.mac_id)
  159. // })
  160. // } else {}
  161. // }
  162. // });
  163. // return [1,1,2,3]
  164. // break;
  165. // }
  166. // }else if(normalArray[0]==0x00&&normalArray.length==1){
  167. // // common.simpleToast('开机成功', 2000)
  168. // return '操作成功'
  169. // }else{
  170. // switch(normalArray[3]){
  171. // case 0x00:
  172. // sendNextCommand(device.mac_id)
  173. // break;
  174. // case 0x01:
  175. // uni.hideLoading();
  176. // console.log(normalArray,commands.length,currentCommandIndex-1,commands[currentCommandIndex-3],commands[currentCommandIndex-2],commands[currentCommandIndex-1], 'value**************************');
  177. // common.simpleToast('升级文件回复失败', 2000)
  178. // // test() 升级文件回复失败
  179. // break;
  180. // }
  181. // }
  182. return data;
  183. }
  184. function loginCmd(mac_id,data){
  185. const len=data.length-4
  186. if(data[len-1]==0x00 && data[len]==0x01){
  187. uni.showModal({
  188. title: '提示',
  189. confirmText: '开始升级',
  190. content: '登陆成功,当前处于升级模式是否开始升级',
  191. success: function(res) {
  192. if (res.confirm) {
  193. currentCommandIndex=0
  194. otaUpgrade().then(()=>{
  195. //登陆成功 且当前为升级模式可以发送升级文件
  196. sendNextCommand(device.mac_id)
  197. })
  198. } else {}
  199. }
  200. });
  201. }else if(data[4]==0x00 && data[4]==0x00){
  202. // uni.hideLoading();
  203. //正常模式
  204. console.log('登陆成功');
  205. // if('lockType' in app.globalData.nearLockInfo ){
  206. // if(app.globalData.nearLockInfo.lockType==0){
  207. // console.log('获取接近解锁指令为关闭');
  208. // }else{
  209. // uni.hideLoading();
  210. // console.log('获取接近解锁指令为成功');
  211. // }
  212. // }else{
  213. // const getNearUnlockSetCmd=getNearUnlockSet()
  214. // console.log(getNearUnlockSetCmd,'getNearUnlockSetCmd');
  215. // writeData(mac_id,getNearUnlockSetCmd)
  216. // }
  217. checkUnlock(mac_id,'login')
  218. }
  219. }
  220. function checkSendNextCommand(mac_id,data){
  221. const len=data.length-4
  222. if(data[len]==0x00){
  223. sendNextCommand(device.mac_id)
  224. }else if(data[len]==0x01){
  225. uni.hideLoading();
  226. // console.log(normalArray,commands.length,currentCommandIndex-1,commands[currentCommandIndex-3],commands[currentCommandIndex-2],commands[currentCommandIndex-1], 'value**************************');
  227. common.simpleToast('升级文件回复失败')
  228. }
  229. }
  230. function trunCarCommand(mac_id,data){
  231. uni.hideLoading();
  232. const len=data.length-4
  233. if(data[len]==0x00){
  234. common.simpleToast('操作成功')
  235. }else if(data[len]==0x01){
  236. common.simpleToast('操作失败')
  237. }
  238. }
  239. function nearCarCmd(mac_id,data){
  240. const app = getApp();
  241. uni.hideLoading();
  242. //测试
  243. const len=data.length-4
  244. const pData={
  245. lockType:data[4],//接近解锁配置
  246. }
  247. console.log(pData,data,pData.status,'pData');
  248. app.globalData.nearLockInfo=pData
  249. if(data[len]==0x00){
  250. common.simpleToast('操作成功')
  251. // common.simpleToast(`请在系统通知中同意与${mac_id}配对`)
  252. }else if(data[len]==0x01){
  253. common.simpleToast('操作失败')
  254. // common.simpleToast('配对失败,请重新开始配对')
  255. }
  256. }
  257. //处理蓝牙三段回复 综合成一个数组
  258. function packBmsData(value) {
  259. if (value.length!=0) {
  260. console.log(endTime - readRepeatTime);
  261. if (endTime - readRepeatTime > 8000) {//超过8秒,说明数据有问题,数据清空
  262. readRepeatTime = endTime
  263. joinPack = []
  264. }
  265. // console.log((value[0] == 0x22) && (value[1]== 0x22),joinPack,'000000');
  266. if((value[0] == 0x22) && (value[1]== 0x22)){//当开始符为标志符 代表接收包开始
  267. var endTime = new Date().getTime()
  268. totalLength = value[3]//包长度
  269. joinPack=value
  270. // console.log(joinPack,value,'111111');
  271. }else if(joinPack.length!=0 && (joinPack[0] == 0x22) && (joinPack[1]== 0x22)){
  272. const len=joinPack.length-1
  273. const diffJoinLength =joinPack.length-4
  274. readRepeatTime = endTime
  275. // console.log(totalLength,diffJoinLength,value,'2222222');
  276. if(totalLength > diffJoinLength){//内容长度符合为完整包
  277. joinPack.push(...value)
  278. return joinPack
  279. }else if(totalLength <= diffJoinLength){
  280. joinPack = []
  281. }
  282. }
  283. else{
  284. readRepeatTime = endTime
  285. joinPack = []
  286. return joinPack
  287. }
  288. }
  289. }
  290. function mergeUint8Array(arr1, arr2) {
  291. let len1 = arr1 ? arr1.length : 0;
  292. let len2 = arr2.length;
  293. let arr = new Uint8Array(len1 + len2);
  294. for (let i = 0; i < len1; i++) {
  295. arr[i] = arr1[i];
  296. }
  297. for (let i = 0; i < len2; i++) {
  298. arr[len1 + i] = arr2[i];
  299. }
  300. return arr;
  301. }
  302. //发送指令封装
  303. function sendCommand(cmd, data = []) {
  304. readRepeatTime=0
  305. let cmdData = [0x22, 0x22]
  306. // cmdData.push(cmd)
  307. //协议号 cmd
  308. //包长度 data.length
  309. const dataLen=parseInt(data.length.toString(16).toUpperCase(), 16)
  310. //信息内容 cmd
  311. //crc校验
  312. const pData=[dataLen,...data]
  313. const crcData=parseInt(crc8IEEE8023(pData).toString(16).toUpperCase(), 16)
  314. cmdData.push(cmd,dataLen,...data,crcData,0xAA, 0xAA)
  315. // console.log(cmdData,'cmdDatacmdData');
  316. return cmdData
  317. }
  318. function turnOnCar(device, deviceId) {
  319. return [sendCommand(0x02,[0x02])];
  320. }
  321. function turnOffCar(device, deviceId) {
  322. return [sendCommand(0x03,[0x03])];
  323. }
  324. function findCarCmd(device, deviceId) {
  325. return [sendCommand(0x06,[0x06])];
  326. }
  327. function openCarSeat(device, deviceId) {
  328. return [sendCommand(0x07,[0x07])];
  329. }
  330. function openCarTrunk(device, deviceId) {
  331. return [sendCommand(0x08,[0x08])];
  332. }
  333. function getCarPressure(device, deviceId) {
  334. return [sendCommand(0x4A,[0x4A])];
  335. }
  336. function nearUnlock(device, deviceId) {
  337. return [sendCommand(0x4B,[0x02])];
  338. }
  339. function nearCloseUnlock(device, deviceId) {
  340. return [sendCommand(0x4B,[0x00])];
  341. }
  342. function getSensitivity(device, deviceId) {
  343. return [sendCommand(0x4F,[0x4F])];
  344. }
  345. function setSensitivity(device, deviceId,type) {
  346. return [sendCommand(0x4E,['0x4'+type])];
  347. }
  348. function setNearUnlock(device, deviceId,type) {
  349. return [sendCommand(0x4D,[0x4D])];
  350. }
  351. function getNearUnlockSet(device, deviceId,type) {
  352. return [sendCommand(0x4D,[0x4D])];
  353. }
  354. function getNearCarCmdInfo(macid,data){
  355. console.log('getNearCarCmdInfo',macid,data);
  356. if(data[5]==0x02||data[5]==0x01){
  357. uni.hideLoading();
  358. const pData={
  359. lockType:data[4],//接近解锁配置
  360. level:data[5],//感应等级
  361. }
  362. const app = getApp();
  363. app.globalData.nearLockInfo=pData
  364. console.log('已开启配对');
  365. // common.simpleToast('已开启配对',2000)
  366. // common.simpleToast('感应解锁已开启,前往设置灵敏度页面')
  367. // uni.navigateTo({ url: '/pages/bluetoothUnlock/unlockset' })
  368. // if( pData.status == 0x01){
  369. // common.simpleToast('配对成功')
  370. // return
  371. // }else if(pData.status==0x00){
  372. // common.simpleToast('未配对')
  373. // }
  374. setTimeout(()=>{
  375. checkUnlock(macid)
  376. },300)
  377. }else if(data[5]==0x00){
  378. console.log('未开启配对')
  379. const nearUnlockCmd=nearUnlock()
  380. console.log(nearUnlockCmd,'nearUnlockCmd');
  381. writeData(mac_id,nearUnlockCmd)
  382. }
  383. }
  384. function checkUnlock(macid,type='get'){
  385. console.log('test0000000000000');
  386. const res=permision.getBondedDevices()
  387. let app=getApp()
  388. if(res){
  389. app.globalData.nearLockCheck=true
  390. common.simpleToast('感应解锁已开启,前往设置灵敏度页面')
  391. uni.navigateTo({ url: '/pages/bluetoothUnlock/unlockSet' })
  392. console.log('test');
  393. //redirectTo 关闭当前页面 防止用户重复操作
  394. }else{
  395. if(type==='login'){
  396. //下发接近解锁指令
  397. // const nearUnlockCmd=nearUnlock()
  398. // console.log(nearUnlockCmd,'nearUnlockCmd');
  399. // setTimeout(() => {
  400. // writeData(macid,nearUnlockCmd)
  401. // }, 500);
  402. // 获取接近解锁指令信息
  403. const getNearUnlockSetCmd=getNearUnlockSet()
  404. console.log(getNearUnlockSetCmd,'getNearUnlockSetCmd');
  405. setTimeout(() => {
  406. writeData(macid,getNearUnlockSetCmd)
  407. }, 200);
  408. }else{
  409. // uni.showModal({
  410. // title: '蓝牙配对确认',
  411. // content: '请在系统通知栏前往同意与'+macid+'设备配对',
  412. // cancelText: '取消',
  413. // confirmText: '已同意',
  414. // success: function(res) {
  415. // if (res.confirm) {
  416. // checkUnlock(macid)
  417. // }else{
  418. // // uni.redirectTo({ url: '/pages/index/index' })
  419. // }
  420. // },
  421. // fail: function(res) {},
  422. // complete: function(res) {},
  423. // })
  424. }
  425. }
  426. }
  427. function switchFactory(device, deviceId) {
  428. //切换正常,工厂模式指令
  429. //切换工厂模式 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
  430. //切换正常模式 [[0x22,0x22,0x54,0x01,0x00,0x15,0xAA,0xAA]]
  431. return [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
  432. // return [sendCommand([0x54, 0x01, 0x01, 0x12])];
  433. }
  434. //升级按钮
  435. function otaUpgrade(device){
  436. const data = readBinBinarayToCommand()
  437. data.then(result=>{commands=result})
  438. // console.log(data,'datatest111');
  439. return data
  440. }
  441. async function readBinBinarayToCommand() {
  442. let res =await uni.request({
  443. url: 'https://opt.bms16.com/ota.BIN', // 文件的网络地址
  444. method: 'GET',
  445. responseType: 'arraybuffer', // 指定响应类型为 arraybuffer
  446. });
  447. const arrayBuffer=res[1].data
  448. const uint8Array = new Uint8Array(arrayBuffer); // 转换为 Uint8Array
  449. const test = splitArrayIntoChunks(uint8Array, 80); // 分割成长度为 80 的数组
  450. const data =makeArr(test)
  451. return data
  452. }
  453. function sendNextCommand(mac_id) {
  454. const app = getApp();
  455. readRepeatTime=0
  456. // console.log(currentCommandIndex,commands.length,'开始发送指令');
  457. // console.log(commands[currentCommandIndex],'command');
  458. if (currentCommandIndex >= commands.length) {
  459. uni.hideLoading();
  460. common.simpleToast('所有指令发送完成', 2000)
  461. return;
  462. }
  463. const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == mac_id);
  464. if (deviceId == undefined) {
  465. console.log('deviceId == undefined');
  466. return ;
  467. }
  468. const command = [commands[currentCommandIndex]];
  469. if(command.length==0){
  470. return
  471. }
  472. // // 将数据转换为ArrayBuffer类型
  473. var buffer;
  474. buffer = common.toArrayBuffer(command.shift());
  475. // console.log(command,'command');
  476. uni.writeBLECharacteristicValue({
  477. deviceId: deviceId, // 替换为实际的设备 ID
  478. serviceId: writeServiceID, // 替换为实际的服务 ID
  479. characteristicId: writeID, // 替换为可写入的特征值 ID
  480. value: buffer,
  481. success() {
  482. // console.log('指令发送成功,等待设备响应',currentCommandIndex,commands[currentCommandIndex]);
  483. },
  484. fail(err) {
  485. console.error('指令发送失败', err);
  486. }
  487. });
  488. currentCommandIndex++;
  489. }
  490. function splitArrayIntoChunks(array, chunkSize) {
  491. const newArr=array.slice(16383)
  492. const numChunks = Math.ceil(newArr.length / chunkSize);
  493. return Array.from({ length: numChunks }, (_, i) => {
  494. return newArr.slice(i * chunkSize, (i + 1) * chunkSize);
  495. });
  496. }
  497. // 处理分割后的数组
  498. function makeArr(array) {
  499. const result = [];
  500. let endPackage;
  501. for (let i = 0; i < array.length; i ++) {
  502. endPackage = 0x00
  503. if((i + 1) >= array.length){
  504. //当前是最后一次循环
  505. endPackage = 0x01
  506. }
  507. // if(i==2) return
  508. //协议号 30 包长度未固定array.length+8 转16进制 固件类型0x00 升级包大小(总包大小) 125396字节-》0x00,0x01,0xE9,0xD4
  509. let startArray = []
  510. const packageLen=parseInt((array[i].length+8).toString(16).toUpperCase(), 16)
  511. // const totalPackageSize=[0x00,0x00,0x01,0xE9,0xD4]
  512. // const totalPackageSize=[0x00,0x00,0x01,0xeb,0xfc]
  513. const totalPackageSize=[0x00,0x00,0x01,0xAB,0xFC]
  514. startArray.push(packageLen,...totalPackageSize)
  515. //软件包id
  516. const ids=splitNumber(i) // 0x00,0x01
  517. startArray.push(...ids)
  518. //是否为最后一个包
  519. startArray.push(endPackage)
  520. //软件数据包
  521. const formattedChunk = array[i].map(byte => `0x${byte.toString(16).toUpperCase()}`); // 转换为 0xXX 格式
  522. startArray.push(...formattedChunk)
  523. // if(i>95&& i<105){
  524. // console.log(startArray,'startArray-------');
  525. // }
  526. //crc检验
  527. const crcStr='0x'+crc8IEEE8023(startArray).toString(16).toUpperCase()
  528. const testCrc=parseInt(crcStr,16)
  529. startArray.push(crcStr)
  530. startArray.push(0xAA,0xAA)
  531. startArray.unshift(0x22,0x22,0x30)
  532. result.push(startArray);
  533. }
  534. // result.push([0x22,0x22,0x30,0x58,0x00,0x00,0x00,0xE9,0xD4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2C,0xAA,0xAA])
  535. return result;
  536. }
  537. function splitNumber(num) {
  538. let highByte = (num >> 8) & 0xFF; // 对于0-255的数字,结果总是0
  539. // 低字节
  540. let lowByte = num & 0xFF;
  541. // 将每个字节转换为两位的十六进制字符串,并添加'0x'前缀
  542. let highHex = highByte.toString(16).toUpperCase().padStart(2, '0'); // 确保是两位十六进制数
  543. let lowHex = lowByte.toString(16).toUpperCase().padStart(2, '0'); // 确保是两位十六进制数
  544. // 返回结果数组(这里实际上可以返回一个对象或字符串,根据需求调整)
  545. return ['0x' + highHex, '0x' + lowHex];
  546. }
  547. // 定义一个函数,用于向蓝牙设备写入数据
  548. function writeData(mac_id, data, callback = () => {}, fail = () => {}) {
  549. const app = getApp();
  550. const deviceIds = app.globalData.connectionState[mac_id].deviceId
  551. console.log(deviceIds,'deviceIds');
  552. if (deviceIds == undefined) {
  553. return ;
  554. }
  555. // 如果数据长度为0,则直接返回
  556. if (data.length == 0) {
  557. return;
  558. }
  559. // 将数据转换为ArrayBuffer类型
  560. var buffer;
  561. buffer = common.toArrayBuffer(data.shift());
  562. // 调用uni.writeBLECharacteristicValue方法,向蓝牙设备写入数据
  563. uni.writeBLECharacteristicValue({
  564. deviceId: deviceIds,
  565. serviceId: writeServiceID,
  566. characteristicId: writeID,
  567. value: buffer,
  568. // 成功回调函数
  569. success(res) {
  570. // 如果数据长度为0,则调用回调函数
  571. if (data.length == 0) {
  572. callback(res);
  573. } else {
  574. // 否则,延时500毫秒后再次调用writeData函数
  575. setTimeout(() => {
  576. writeData(device, data, callback, fail);
  577. }, 500);
  578. }
  579. },
  580. // 失败回调函数
  581. fail(res) {
  582. console.log(res);
  583. // 调用失败回调函数
  584. fail(res);
  585. }
  586. });
  587. }
  588. module.exports = {
  589. readServiceID: readServiceID,
  590. readID: readID,
  591. writeServiceID: writeServiceID,
  592. writeID: writeID,
  593. MTU: MTU,
  594. acceptDevice: acceptDevice,
  595. isDevice: isDevice,
  596. alterConnect: alterConnect,
  597. readData: readData,
  598. turnOffCar: turnOffCar,
  599. isSingleBt: isSingleBt,
  600. haveBms: haveBms,
  601. switchFactory: switchFactory,
  602. otaUpgrade,
  603. findCarCmd,
  604. turnOffCar,
  605. turnOnCar,
  606. getCarPressure,
  607. nearUnlock,
  608. nearCloseUnlock,
  609. getSensitivity,
  610. setSensitivity,
  611. getNearUnlockSet,
  612. setNearUnlock,
  613. };