ZXCar.js 21 KB

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