123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- 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
- let commands = []; // 升级包指令数组,每个指令是一个 ArrayBuffer
- let currentCommandIndex = 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;
- // }
- //判断是否是智寻的蓝牙
- const result = data.name.startsWith("ZX");
- // if (data.name === "865416038002201") {
- // if (data.name === "ZX2503140000000") {
- if (result) {
- return true
- }
- return false;
- }
- function alterConnect(device, deviceId) {
- // console.log(device,app.globalData.connectionState[deviceId],'deviceliuwei');
- //登录 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 0x65,0xB3,0xED,0x6F 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,
- let data=[ 0x1F, 0x0F]
- const device_name=app.globalData.connectionState[deviceId].deviceName
- const device_sn=stringToHexArray(device_name)
- data.push(...device_sn)
- data.push(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,0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x67, 0xAC, 0x53, 0xE7, 0x08, 0x00]
- // console.log(data,'datatest');
- const crc_data = '0x'+crc8IEEE8023(data).toString(16).toUpperCase()
- data.push(crc_data,0xAA,0xAA)
- data.unshift(0x22,0x22,0x01)
-
- return [data]
- }
- function crc8IEEE8023(data) {
- const poly = 0x07; // IEEE 802.3 polynomial x^8 + x^2 + x + 1
- let crc = 0x00;
- for (let i = 0; i < data.length; i++) {
- crc ^= data[i];
- for (let j = 0; j < 8; j++) {
- if (crc & 0x80) {
- crc = ((crc << 1) ^ poly) & 0xFF;
- } else {
- crc = (crc << 1) & 0xFF;
- }
- }
- }
- return crc;
- }
- function stringToHexArray(str) {
- const result = [];
- for (let i = 0; i < str.length; i++) {
- const charCode = str.charCodeAt(i); // 获取字符的 ASCII 码值
- const hexValue=`0x${charCode.toString(16).toUpperCase()}`
- const hexDataValue=parseInt(hexValue,16)
- result.push(hexDataValue);
- }
- return result;
- }
- //收到硬件方向软件方发送的数据
- function readData(device, value, data) {
- // console.log(value, 'test1111');
- var value = new Uint8Array(value);
- const normalArray = Array.from(value); // 或 [...uint8Array]
- console.log(normalArray,currentCommandIndex-1,commands[currentCommandIndex-1], 'value**************************');
- switch (normalArray[1]) {
- case 0x01:
- uni.showModal({
- title: '提示',
- confirmText: '开始升级',
- content: '登陆成功,当前处于升级模式是否开始升级',
- success: function(res) {
- if (res.confirm) {
- currentCommandIndex=0
- otaUpgrade().then(()=>{
- //登陆成功 且当前为升级模式可以发送升级文件
- sendNextCommand(device.mac_id)
- })
- } else {}
- }
- });
- break;
- }
- switch(normalArray[3]){
- case 0x00:
- sendNextCommand(device.mac_id)
- break;
-
-
- case 0x01:
- uni.hideLoading();
- common.simpleToast('升级文件回复失败', 2000)
- // test() 升级文件回复失败
- break;
- }
-
-
-
- return data;
- }
- //发送指令封装
- function sendCommand(cmd, data = []) {
- let cmdData = [0x02, 0x02]
- // cmdData.push(cmd)
- //协议号 cmd
- //包长度 data.length
- const dataLen=ensureInteger(data.length)
- //信息内容 cmd
- //crc校验
- const pData=[dataLen,cmd]
- const crcData='0x'+crc8IEEE8023(pData).toString(16).toUpperCase()
- cmdData.push(cmd,dataLen,crcData,0xAA, 0xAA)
- return cmdData
- }
- //转成16进制
- function ensureInteger(cmd){
- return parseInt((cmd).toString(16).toUpperCase(), 16)
- }
- function turnOnCar(device, deviceId) {
- return [sendCommand(0x02,[0x02])];
- }
- function turnOffCar(device, deviceId) {
- return [sendCommand(0x03,[0x03])];
- }
- function defenseCmd(device, deviceId) {
- return [sendCommand(0x04,[0x04])];
- }
- 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])];
- }
- //升级按钮
- function otaUpgrade(device){
-
- const data = readBinBinarayToCommand()
- data.then(result=>{commands=result})
-
- // console.log(data,'datatest111');
- return data
- }
- async function readBinBinarayToCommand() {
- let res =await uni.request({
- url: 'https://opt.bms16.com/ota.BIN', // 文件的网络地址
- method: 'GET',
- responseType: 'arraybuffer', // 指定响应类型为 arraybuffer
- });
- const arrayBuffer=res[1].data
- const uint8Array = new Uint8Array(arrayBuffer); // 转换为 Uint8Array
- const test = splitArrayIntoChunks(uint8Array, 80); // 分割成长度为 80 的数组
- const data =makeArr(test)
- // const tests=data.slice(data.length-3)
- // console.log(data.length,tests[0],'testtest数组');
- // console.log(tests,'tests');
- return data
- }
- function sendNextCommand(mac_id) {
- // console.log(commands[currentCommandIndex],'command');
- if (currentCommandIndex >= commands.length) {
- uni.hideLoading();
- common.simpleToast('所有指令发送完成', 2000)
- return;
- }
- const deviceId = Object.keys(app.globalData.connectionState).find((i) => app.globalData.connectionState[i].device.mac_id == mac_id);
- if (deviceId == undefined) {
- console.log('deviceId == undefined');
- return ;
- }
- const command = [commands[currentCommandIndex]];
- console.log(command,'commandtest');
- if(command.length==0){
- return
- }
- // 将数据转换为ArrayBuffer类型
- var buffer;
- buffer = common.toArrayBuffer(command.shift());
- // console.log(command,'command');
- uni.writeBLECharacteristicValue({
- deviceId: deviceId, // 替换为实际的设备 ID
- serviceId: writeServiceID, // 替换为实际的服务 ID
- characteristicId: writeID, // 替换为可写入的特征值 ID
- value: buffer,
- success() {
- // console.log('指令发送成功,等待设备响应');
- },
- fail(err) {
- console.error('指令发送失败', err);
- }
- });
- currentCommandIndex++;
- }
- function splitArrayIntoChunks(array, chunkSize) {
- const numChunks = Math.ceil(array.length / chunkSize);
- return Array.from({ length: numChunks }, (_, i) => {
- return array.slice(i * chunkSize, (i + 1) * chunkSize);
- });
- }
- // 处理分割后的数组
- function makeArr(array) {
- const result = [];
- let endPackage;
- for (let i = 0; i < array.length; i ++) {
-
- endPackage = 0x00
- if((i + 1) >= array.length){
- //当前是最后一次循环
- endPackage = 0x01
- }
- //协议号 30 包长度未固定array.length+8 转16进制 固件类型0x00 升级包大小(总包大小) 125396字节-》0x00,0x01,0xE9,0xD4
- let startArray = []
- const packageLen=parseInt((array[i].length+8).toString(16).toUpperCase(), 16)
-
- // const totalPackageSize=[0x00,0x00,0x01,0xE9,0xD4]
- const totalPackageSize=[0x00,0x00,0x01,0xe8,0x24]
- startArray.push(packageLen,...totalPackageSize)
- //软件包id
- const ids=splitNumber(i) // 0x00,0x01
- startArray.push(...ids)
- //是否为最后一个包
- startArray.push(endPackage)
- //软件数据包
- const formattedChunk = array[i].map(byte => `0x${byte.toString(16).toUpperCase()}`); // 转换为 0xXX 格式
- startArray.push(...formattedChunk)
- // if(i>95&& i<105){
- // console.log(startArray,'startArray-------');
- // }
- //crc检验
- const crcStr='0x'+crc8IEEE8023(startArray).toString(16).toUpperCase()
- const testCrc=parseInt(crcStr,16)
- // if(i>95&& i<105){
- // console.log(testCrc,crcStr,'startArray*******');
- // }
- startArray.push(crcStr)
- startArray.push(0xAA,0xAA)
- startArray.unshift(0x22,0x22,0x30)
- result.push(startArray);
- }
- // 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])
- return result;
- }
- function splitNumber(num) {
- // 将数字转换为字符串
- const numStr = num.toString();
- // 使用正则表达式分割字符串为两位一组
- const parts = numStr.match(/.{1,2}/g) || [];
- // 将字符串数组转换为数字数组
- let result = parts.map(part => parseInt(part, 10));
- // 如果数组长度为 1,前面补一个 0
- if (result.length === 1) {
- result = [0, ...result];
- }
- return result;
- }
- module.exports = {
- readServiceID: readServiceID,
- readID: readID,
- writeServiceID: writeServiceID,
- writeID: writeID,
- MTU: MTU,
- acceptDevice: acceptDevice,
- isDevice: isDevice,
- alterConnect: alterConnect,
- readData: readData,
- turnOnCar: turnOnCar,
- turnOffCar: turnOffCar,
- isSingleBt: isSingleBt,
- haveBms: haveBms,
- switchFactory: switchFactory,
- otaUpgrade
- };
|