ZXCar.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. const common = require('../common.js');
  2. const FMBMS = require('./FMBMS.js');
  3. const readServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
  4. const readID = '000036F6-0000-1000-8000-00805F9B34FB';
  5. const writeServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB';
  6. const writeID = '000036F5-0000-1000-8000-00805F9B34FB';
  7. const MTU = 115;
  8. const app = getApp();
  9. let subIndex = -1
  10. function acceptDevice(device) {
  11. return device.btid ? true : false;
  12. }
  13. function isSingleBt() {
  14. console.log('是单蓝牙');
  15. return true;
  16. }
  17. function haveBms() {
  18. console.log('是单蓝牙并且带bms');
  19. return true;
  20. }
  21. function isDevice(device, data) {
  22. // console.log(device,data,'device111');
  23. const advertisData = new Uint8Array(data.advertisData);
  24. console.log(advertisData,'判断返回第几个字段是正常模式还是升级模式');
  25. //打印返回广播 判断返回字段是正常模式还是升级模式
  26. // console.log(advertisData.slice(4, 10).toString(),'device2222');
  27. const mac = device.btid
  28. .split('')
  29. .map((p, i) => parseInt(p + device.btid[i + 1], 16))
  30. .filter((p, i) => i % 2 == 0);
  31. // if ( advertisData.slice(4, 10).toString() == "095A5832") {
  32. // return true;
  33. // }
  34. // if (data.name === "ZX2202220000000") {
  35. if (data.name === "865416038002201") {
  36. return true
  37. }
  38. return false;
  39. }
  40. function alterConnect(device, deviceId) {
  41. //登录 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]
  42. //登录 [[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]]
  43. //时间戳 0x67AC53E7 16:00:05
  44. //切换正常,工厂下发指令 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
  45. //OTA 升级指令 [[0x22,0x22,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,n,0xCB,0xAA,0xAA]]
  46. // const data = [0x1F, 0x0F, ,0x5A,0x58, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
  47. // 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00]
  48. const data=[ 0x1F, 0x0F,0x38, 0x36, 0x35, 0x34, 0x31, 0x36, 0x30, 0x33, 0x38, 0x30, 0x30, 0x32, 0x32, 0x30, 0x31]
  49. const crc_data = crc8Ieee8023(data)
  50. console.log(crc_data, 111);
  51. return [
  52. [0x22, 0x22, 0x01, 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,
  53. crc_data, 0xAA, 0xAA
  54. ]
  55. ]
  56. //return [sendCommand(0x01, [0xAB, 0xCD, 0xAB, 0xCD])]
  57. }
  58. function crc8Ieee8023(data) {
  59. let crc = 0x00; // 初始化CRC为0
  60. const polynomial = 0x07; // CRC-8 IEEE 802.3 多项式
  61. // 遍历数据数组中的每个字节
  62. for (let byte of data) {
  63. crc ^= byte; // 将当前字节与CRC寄存器进行异或操作
  64. // 对CRC寄存器的每一位进行8次迭代
  65. for (let i = 0; i < 8; i++) {
  66. if (crc & 0x80) { // 检查最高位是否为1
  67. crc = (crc << 1) ^ polynomial; // 左移一位并与多项式异或
  68. } else {
  69. crc <<= 1; // 仅左移一位
  70. }
  71. }
  72. // 截断CRC到8位(在JavaScript中这一步是多余的,因为位运算会自动处理溢出)
  73. crc &= 0xFF;
  74. }
  75. // 返回CRC校验码的最低8位,并转换为十六进制字符串
  76. return '0x' + crc.toString(16).toUpperCase().padStart(2, '0'); // 使用padStart确保结果始终是两位十六进制数
  77. }
  78. //connectDevice 打开连接 findDevice 查找设备
  79. //收到硬件方向软件方发送的数据
  80. function readData(device, value, data) {
  81. // console.log(value, 'test1111');
  82. var value = new Uint8Array(value);
  83. console.log(value, 'value**************************');
  84. switch (value[0]) {
  85. case 0:
  86. //登陆成功准备
  87. switchFactory(device)
  88. break;
  89. }
  90. // switch(value[2]){
  91. // case 0x66:
  92. // break;
  93. // }
  94. return data;
  95. }
  96. function parseOTAData(){
  97. //解析是否成功&&第几个包
  98. //如果是第一个包成功 发送第二个包的数据 //otaUpgrade
  99. }
  100. function sendCommand(cmd, data = []) {
  101. const startCmd = [0x02, 0x02]
  102. const endCmd = [0xAA, 0xAA]
  103. data = startCmd.concat(cmd).concat(endCmd)
  104. console.log(data,'打印是否切换正常模式');
  105. return data
  106. }
  107. function stateUpdate(device, deviceId) {
  108. return [sendCommand(0x04), sendCommand(0x02, FMBMS
  109. .BMSRead())]; //return [[0x02,0x00,0x15,0x15,0x00,0x4e,0x57,0x00,0x13,0x00,0x00,0x00,0x00,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x01,0x27,0x7b]]
  110. }
  111. function turnOn(device, deviceId) {
  112. return [sendCommand(0x02, FMBMS.BMSTurnOn())];
  113. }
  114. function turnOff(device, deviceId) {
  115. return [sendCommand(0x02, FMBMS.BMSTurnOff())];
  116. }
  117. function switchFactory(device, deviceId) {
  118. //切换正常,工厂模式指令
  119. //切换工厂模式 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
  120. //切换正常模式 [[0x22,0x22,0x54,0x01,0x00,0x15,0xAA,0xAA]]
  121. return [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]]
  122. // return [sendCommand([0x54, 0x01, 0x01, 0x12])];
  123. }
  124. //升级OTA
  125. async function otaUpgrade(device, deviceId) {
  126. //return [sendCommand([0x54,0x01,0x01,0x12])];
  127. //第一步先读取BIN文件的二进制流
  128. const subPackage = await readBinBinarayToCommand()
  129. // console.log(dataRecursion(subPackage,subIndex))
  130. return dataRecursion(subPackage)
  131. // //提取分包数据
  132. // var subPackage = []
  133. // for(var i=0;Math.ceil(fileCommandList.length/80) >i;i++){
  134. // //提取数组的分割数据
  135. // var subCmd = []
  136. // subCmd = [0x22,0x22,]
  137. // //[[0x01,0x02,0x23],[0x04,0x05,0x06]] subPackage
  138. // subPackage.push(subCmd) //提取80个数据 0-80 81-160
  139. // }
  140. // return [subPackage[2]]
  141. }
  142. function dataRecursion(subPackage){
  143. subIndex += 1
  144. let endPackage = 0x00
  145. if(subPackage.groupedArray.length - 1 == subIndex){
  146. endPackage = 0x01
  147. }
  148. let startArray = [0x22,0x22,0x30,0x30,0x00,0x58,0x00]
  149. startArray = startArray.concat(decimalToHexBytes(subPackage.size,4))
  150. console.log(222222)
  151. startArray = startArray.concat(decimalToHexBytes(subIndex + 1,2))
  152. startArray.push(endPackage)
  153. startArray = startArray.concat(subPackage.groupedArray[subIndex])
  154. startArray.push(0xCB)
  155. console.log(subPackage.groupedArray[subIndex])
  156. startArray = startArray.concat([0xAA,0xAA])
  157. console.log(startArray)
  158. return startArray
  159. }
  160. async function readBinBinarayToCommand() {
  161. let res = await uni.request({
  162. url: 'https://opt.bms16.com/ota.BIN', // 文件的网络地址
  163. method: 'GET',
  164. responseType: 'arraybuffer', // 指定响应类型为 arraybuffer
  165. });
  166. return arrayBufferToHexWithPrefix(res[1].data)
  167. }
  168. function arrayBufferToHexWithPrefix(buffer,groupSize = 80) {
  169. const uint8Array = new Uint8Array(buffer);
  170. const groupedArray = [];
  171. const size = uint8Array.length
  172. // 遍历数据,每 groupSize 个字节为一组
  173. for (let i = 0; i < size; i += groupSize) {
  174. const group = Array.from(uint8Array.slice(i, i + groupSize)) // 获取当前分组
  175. // .map(byte => '0x' + byte.toString(16).padStart(2, 0)); // 添加 0x 前缀
  176. groupedArray.push(group); // 将分组添加到结果中
  177. }
  178. return {
  179. size,
  180. groupedArray
  181. };
  182. }
  183. //进制转化
  184. function decimalToHexBytes(decimal,bytes){
  185. const maxValue = Math.pow(2, 8 * bytes) - 1;
  186. // 创建一个数组来存储字节
  187. const byteArray = new Array(bytes);
  188. // 将十进制数分解为字节
  189. for (let i = 0; i < bytes; i++) {
  190. // 每次取最低的8位(一个字节)
  191. byteArray[bytes - 1 - i] = decimal & 0xff;
  192. // 右移8位,处理下一个字节
  193. decimal >>>= 8;
  194. }
  195. return byteArray;
  196. }
  197. module.exports = {
  198. readServiceID: readServiceID,
  199. readID: readID,
  200. writeServiceID: writeServiceID,
  201. writeID: writeID,
  202. MTU: MTU,
  203. acceptDevice: acceptDevice,
  204. isDevice: isDevice,
  205. alterConnect: alterConnect,
  206. readData: readData,
  207. stateUpdate: stateUpdate,
  208. turnOn: turnOn,
  209. turnOff: turnOff,
  210. isSingleBt: isSingleBt,
  211. haveBms: haveBms,
  212. switchFactory: switchFactory,
  213. otaUpgrade
  214. };