const common = require('../common.js'); const FMBMS = require('./FMBMS.js'); const readServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB'; const readID = '000036F6-0000-1000-8000-00805F9B34FB'; const writeServiceID = '0000FEE7-0000-1000-8000-00805F9B34FB'; const writeID = '000036F5-0000-1000-8000-00805F9B34FB'; const MTU = 115; const app = getApp(); let subIndex = -1 function acceptDevice(device) { return device.btid ? true : false; } function isSingleBt() { console.log('是单蓝牙'); return true; } function haveBms() { console.log('是单蓝牙并且带bms'); return true; } function isDevice(device, data) { // console.log(device,data,'device111'); const advertisData = new Uint8Array(data.advertisData); console.log(advertisData,'判断返回第几个字段是正常模式还是升级模式'); //打印返回广播 判断返回字段是正常模式还是升级模式 // console.log(advertisData.slice(4, 10).toString(),'device2222'); const mac = device.btid .split('') .map((p, i) => parseInt(p + device.btid[i + 1], 16)) .filter((p, i) => i % 2 == 0); // if ( advertisData.slice(4, 10).toString() == "095A5832") { // return true; // } // if (data.name === "ZX2202220000000") { if (data.name === "865416038002201") { return true } return false; } function alterConnect(device, deviceId) { //登录 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] //登录 [[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]] //时间戳 0x67AC53E7 16:00:05 //切换正常,工厂下发指令 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]] //OTA 升级指令 [[0x22,0x22,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,n,0xCB,0xAA,0xAA]] // const data = [0x1F, 0x0F, ,0x5A,0x58, 0x35, 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] const data=[ 0x1F, 0x0F,0x38, 0x36, 0x35, 0x34, 0x31, 0x36, 0x30, 0x33, 0x38, 0x30, 0x30, 0x32, 0x32, 0x30, 0x31] const crc_data = crc8Ieee8023(data) console.log(crc_data, 111); return [ [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, crc_data, 0xAA, 0xAA ] ] //return [sendCommand(0x01, [0xAB, 0xCD, 0xAB, 0xCD])] } function crc8Ieee8023(data) { let crc = 0x00; // 初始化CRC为0 const polynomial = 0x07; // CRC-8 IEEE 802.3 多项式 // 遍历数据数组中的每个字节 for (let byte of data) { crc ^= byte; // 将当前字节与CRC寄存器进行异或操作 // 对CRC寄存器的每一位进行8次迭代 for (let i = 0; i < 8; i++) { if (crc & 0x80) { // 检查最高位是否为1 crc = (crc << 1) ^ polynomial; // 左移一位并与多项式异或 } else { crc <<= 1; // 仅左移一位 } } // 截断CRC到8位(在JavaScript中这一步是多余的,因为位运算会自动处理溢出) crc &= 0xFF; } // 返回CRC校验码的最低8位,并转换为十六进制字符串 return '0x' + crc.toString(16).toUpperCase().padStart(2, '0'); // 使用padStart确保结果始终是两位十六进制数 } //connectDevice 打开连接 findDevice 查找设备 //收到硬件方向软件方发送的数据 function readData(device, value, data) { // console.log(value, 'test1111'); var value = new Uint8Array(value); console.log(value, 'value**************************'); switch (value[0]) { case 0: //登陆成功准备 switchFactory(device) break; } // switch(value[2]){ // case 0x66: // break; // } return data; } function parseOTAData(){ //解析是否成功&&第几个包 //如果是第一个包成功 发送第二个包的数据 //otaUpgrade } function sendCommand(cmd, data = []) { const startCmd = [0x02, 0x02] const endCmd = [0xAA, 0xAA] data = startCmd.concat(cmd).concat(endCmd) console.log(data,'打印是否切换正常模式'); return data } function stateUpdate(device, deviceId) { return [sendCommand(0x04), sendCommand(0x02, FMBMS .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]] } function turnOn(device, deviceId) { return [sendCommand(0x02, FMBMS.BMSTurnOn())]; } function turnOff(device, deviceId) { return [sendCommand(0x02, FMBMS.BMSTurnOff())]; } function switchFactory(device, deviceId) { //切换正常,工厂模式指令 //切换工厂模式 [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]] //切换正常模式 [[0x22,0x22,0x54,0x01,0x00,0x15,0xAA,0xAA]] return [[0x22,0x22,0x54,0x01,0x01,0x12,0xAA,0xAA]] // return [sendCommand([0x54, 0x01, 0x01, 0x12])]; } //升级OTA async function otaUpgrade(device, deviceId) { //return [sendCommand([0x54,0x01,0x01,0x12])]; //第一步先读取BIN文件的二进制流 const subPackage = await readBinBinarayToCommand() // console.log(dataRecursion(subPackage,subIndex)) return dataRecursion(subPackage) // //提取分包数据 // var subPackage = [] // for(var i=0;Math.ceil(fileCommandList.length/80) >i;i++){ // //提取数组的分割数据 // var subCmd = [] // subCmd = [0x22,0x22,] // //[[0x01,0x02,0x23],[0x04,0x05,0x06]] subPackage // subPackage.push(subCmd) //提取80个数据 0-80 81-160 // } // return [subPackage[2]] } function dataRecursion(subPackage){ subIndex += 1 let endPackage = 0x00 if(subPackage.groupedArray.length - 1 == subIndex){ endPackage = 0x01 } let startArray = [0x22,0x22,0x30,0x30,0x00,0x58,0x00] startArray = startArray.concat(decimalToHexBytes(subPackage.size,4)) console.log(222222) startArray = startArray.concat(decimalToHexBytes(subIndex + 1,2)) startArray.push(endPackage) startArray = startArray.concat(subPackage.groupedArray[subIndex]) startArray.push(0xCB) console.log(subPackage.groupedArray[subIndex]) startArray = startArray.concat([0xAA,0xAA]) console.log(startArray) return startArray } async function readBinBinarayToCommand() { let res = await uni.request({ url: 'https://opt.bms16.com/ota.BIN', // 文件的网络地址 method: 'GET', responseType: 'arraybuffer', // 指定响应类型为 arraybuffer }); return arrayBufferToHexWithPrefix(res[1].data) } function arrayBufferToHexWithPrefix(buffer,groupSize = 80) { const uint8Array = new Uint8Array(buffer); const groupedArray = []; const size = uint8Array.length // 遍历数据,每 groupSize 个字节为一组 for (let i = 0; i < size; i += groupSize) { const group = Array.from(uint8Array.slice(i, i + groupSize)) // 获取当前分组 // .map(byte => '0x' + byte.toString(16).padStart(2, 0)); // 添加 0x 前缀 groupedArray.push(group); // 将分组添加到结果中 } return { size, groupedArray }; } //进制转化 function decimalToHexBytes(decimal,bytes){ const maxValue = Math.pow(2, 8 * bytes) - 1; // 创建一个数组来存储字节 const byteArray = new Array(bytes); // 将十进制数分解为字节 for (let i = 0; i < bytes; i++) { // 每次取最低的8位(一个字节) byteArray[bytes - 1 - i] = decimal & 0xff; // 右移8位,处理下一个字节 decimal >>>= 8; } return byteArray; } module.exports = { readServiceID: readServiceID, readID: readID, writeServiceID: writeServiceID, writeID: writeID, MTU: MTU, acceptDevice: acceptDevice, isDevice: isDevice, alterConnect: alterConnect, readData: readData, stateUpdate: stateUpdate, turnOn: turnOn, turnOff: turnOff, isSingleBt: isSingleBt, haveBms: haveBms, switchFactory: switchFactory, otaUpgrade };