@jiabaida/tools 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{hexArr2string,hex2string,decimalToHex,generateCrc16modbusCheck,hexArr2Assic,generateCrcCheckSum,hexToDecimal,stringToTwoHexArray,sleep,fromBCD,isWithin30Minutes,toBCD}from"../BleDataProcess.js";import{getData}from"./BleCmdAnalysis.js";import{getFFAA80Async,resolveFFAA80}from"./BleCmdFFAA.js";const enterFactory=async deviceId=>set_PlanCMD_DD(deviceId,"DD5A00025678FF3077"),existFactory=async deviceId=>set_PlanCMD_DD(deviceId,"DD5A01022828ffad77"),readExistFactory=async deviceId=>set_PlanCMD_DD(deviceId,"DD5A01020000FFFD77"),set_PlanCMD_DD=async(deviceId,command)=>{"string"==typeof command&&(command=command.match(/(.{2})/g).map(o=>`0x${o}`));let result=null;try{const data=await getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"PlanCMD_DD");if(data){const dataStr=hexArr2string(data),content=data.slice(4,data.length-3);result={data:data,dataStr:dataStr,status:hex2string(data[2]),len:data[3],content:content}}else result={status:0,content:[]}}catch(error){console.error(error)}return result},set_PlanCMD_3B3C=async(deviceId,command)=>{"string"==typeof command&&(command=command.match(/(.{2})/g).map(o=>`0x${o}`));let result=null;try{const data=await getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:59==hexArr[0]&&60==hexArr[1],pkgLen:hexArr[11]+15}),pkgVerifyHandler:pkg=>({verified:!0})},"PlanCMD_3B3C");if(data){const dataStr=hexArr2string(data),content=data.slice(12,data.length-3);result={dataStr:dataStr,status:128==data[10]?1:0,addr:hexArr2string(data.slice(2,10)),content:content}}}catch(error){console.error(error)}return result},get3B3CAsync=async deviceId=>{const addressCode=["0x00","0x00","0x00","0x00","0x00","0x00","0x00","0x00"],commandCode=["0x01"],data=[],dataLength=[`0x${decimalToHex(data.length,2)}`],check=generateCrc16modbusCheck([...addressCode,...commandCode,...dataLength,...data],!1),command=["0x3b","0x3c",...addressCode,...commandCode,...dataLength,...data,...check,"0x0d"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:59==hexArr[0]&&60==hexArr[1],pkgLen:hexArr[11]+15}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrc16modbusCheck(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"3B3C")},resolve3B3C=data=>{if(!data)return null;let result={dataStr:hexArr2string(data),status:hex2string(data[10]),addr:hexArr2string(data.slice(2,10))};const content=data.slice(12,data.length-3);for(;content.length>0;){const[v1,v2,...v]=content.splice(0,content[1]+2);if(1==v1&&(result.productFlag=hex2string(v1),result.productLen=v2,v)){const[productType,frontType,protocolV,level]=v.map(o=>hex2string(o));Object.assign(result,{productType:productType,frontType:frontType,protocolV:protocolV,level:level})}2==v1&&(result.hardwareFlag=hex2string(v1),result.hardwareLen=v2,result.hardwareV=hexArr2Assic(v)),3==v1&&(result.sofewareFlag=hex2string(v1),result.sofewareLen=v2,result.sofewareV=hexArr2Assic(v)),4==v1&&(result.pcbFlag=hex2string(v1),result.pcbLen=v2,result.pcbContent=hexArr2Assic(v))}return result},getDDA503Async=async deviceId=>{const hex=await getData(deviceId,{command:["0xdd","0xa5","0x03","0x00","0xff","0xfd","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&3==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_03");return hex?resolveDDA503(hex):null},resolveDDA503=data=>{if(!data)return null;const cmdResp03=hexArr2string(data),content=data.slice(4,data.length-3),binArr=data[24].toString(2).padStart(8,"0").split("").reverse(),BC1=(data[16]<<8|data[17]).toString(2).padStart(16,"0").split("").reverse();console.log("BC1: ",BC1);const BC2=(data[18]<<8|data[19]).toString(2).padStart(16,"0").split("").reverse(),balances=BC1.concat(BC2);console.warn("BC: ---------------",balances);const fet=data[24],chargeSwitch=!!Number(binArr[0]),dischargeSwitch=!!Number(binArr[1]),BMSVersion=decimalToHex(data[22]),humidityIndex=2*data[26]+27,humidity=data[humidityIndex],n=Number(binArr[7])||136==humidity?10:100,totalVoltage=Number((((data[4]<<8)+(255&data[5]))/100).toFixed(2));let current=(data[6]<<8)+(255&data[7]);current=current>32768?(current-65536)/n:current/n;const electricity=Number(current.toFixed(2)),power=Number((totalVoltage*electricity).toFixed(2)),soc=data[23]??0,seriesNum=data[25]??0,volumeHex=decimalToHex(data[8])+decimalToHex(data[9]),surplusCapacity=Number((hexToDecimal(volumeHex)/n).toFixed(2)),normCapHex=decimalToHex(data[10])+decimalToHex(data[11]),normCap=Number((hexToDecimal(normCapHex)/n).toFixed(2)),cycleHex=decimalToHex(data[12])+decimalToHex(data[13]),cycleIndex=hexToDecimal(cycleHex),fccHex=decimalToHex(data[humidityIndex+3])+decimalToHex(data[humidityIndex+4]),fullChargeCapacity=Number((hexToDecimal(fccHex)/n).toFixed(2)),SOH=cycleIndex<=100?100:Math.min(100,fullChargeCapacity/normCap*100),heatingState=!!Number(binArr[4])||!!Number(binArr[3]);let heatingCurrent=null;const hasHeatingCurrent=data[3]+7>=humidityIndex+9+4+1,hasEquilCurrent=data[3]+7>=humidityIndex+7+4+1;if(heatingState&&hasHeatingCurrent){const i=humidityIndex+9;heatingCurrent=heatingCurrent=((data[i]<<8|data[i+1])/100).toFixed(2)}let equilibriumCurrent=null;if(hasEquilCurrent){const i=humidityIndex+7;let equilCurrent=(data[i]<<8)+(255&data[i+1]);equilCurrent=equilCurrent>32768?(equilCurrent-65536)/1e3:equilCurrent/1e3,equilibriumCurrent=Number(equilCurrent.toFixed(2))}const isFactoryMode=!!Number(binArr[6]),equilibriumStatus=!(0===data[16]&&0===data[17]),protectStatus=!(0===data[20]&&0===data[21]),protectStateHex=decimalToHex(data[20])+decimalToHex(data[21]),protVal=hexToDecimal(protectStateHex);let alarmIndex=2*data[26]+28,alarmStateHex=decimalToHex(data[alarmIndex])+decimalToHex(data[alarmIndex+1]),alarmsState=hexToDecimal(alarmStateHex);const ntcNums=255&data[26],temperaturesList=Array.from({length:ntcNums},(_,i)=>((256*(255&data[26+2*i+1])+(255&data[26+2*i+2])-2731)/10).toFixed(1)),fahTempList=[];temperaturesList.forEach(el=>{const value=1.8*Number(el)+32;fahTempList.push(value.toFixed(1))});const temperatures=temperaturesList.map((item,index)=>({name:index+1,value:item}));return{cmdResp03:cmdResp03,status:hex2string(data[2]),len:data[3],softwareV:hex2string(content[18]),balances:balances,BMSVersion:BMSVersion,soc:soc,normCap:normCap,surplusCapacity:surplusCapacity,totalVoltage:totalVoltage,electricity:electricity,power:power,cycleIndex:cycleIndex,equilibriumStatus:equilibriumStatus,chargeSwitch:chargeSwitch,dischargeSwitch:dischargeSwitch,temperatures:temperatures,humidity:humidity,protectStatus:protectStatus,fullChargeCapacity:fullChargeCapacity,SOH:SOH,heatingState:heatingState,heatingCurrent:heatingCurrent,equilibriumCurrent:equilibriumCurrent,isFactoryMode:isFactoryMode,protVal:protVal,alarmsState:alarmsState,ntcNums:ntcNums,temperaturesList:temperaturesList,fahTempList:fahTempList,fet:fet,seriesNum:seriesNum}},getDDA504Async=async(deviceId,dataScope)=>{const hex=await getData(deviceId,{command:["0xdd","0xa5","0x04","0x00","0xff","0xfc","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&4==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_04");return hex?resolveDDA504(hex,dataScope):null},resolveDDA504=(data,dataScope)=>{if(console.log("data: ",data),!data)return null;const cmdResp04=hexArr2string(data),voltageList=[];for(let index=4;index<parseInt(data[3])+4;index+=2){let voltageHex=decimalToHex(data[index])+decimalToHex(data[index+1]),voltage=hexToDecimal(voltageHex);voltageList.push(Number(voltage))}let highestVoltage=null,lowestVoltage=null,averageVoltage=null,dropoutVoltage=null;if(voltageList.length>0){highestVoltage=Math.max(...voltageList),lowestVoltage=Math.min(...voltageList);averageVoltage=voltageList.reduce((acc,cur)=>acc+cur,0)/voltageList.length;const dropout=highestVoltage-lowestVoltage,precision=dataScope?3:2;highestVoltage=Number((highestVoltage/1e3).toFixed(precision)),lowestVoltage=Number((lowestVoltage/1e3).toFixed(precision)),averageVoltage=Number((averageVoltage/1e3).toFixed(precision)),dropoutVoltage=Number((dropout/1e3).toFixed(precision))}voltageList.forEach((v,i)=>{let newV=v/1e3;voltageList[i]=Number(newV.toFixed(dataScope?3:2))});const voltageSeries=voltageList.map((item,index)=>({name:index+1,value:item}));return{cmdResp04:cmdResp04,voltageList:voltageList,voltageSeries:voltageSeries,highestVoltage:highestVoltage,lowestVoltage:lowestVoltage,averageVoltage:averageVoltage,dropoutVoltage:dropoutVoltage}},getChipTypeAsync=async deviceId=>{const hex=await getData(deviceId,{command:["0xdd","0xa5","0x00","0x00","0x00","0x00","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&0==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_00");return hex?resolveDDA500(hex):null},resolveDDA500=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3],type:data[5]}},getDD5AE1Async=async(deviceId,value)=>{const _command=["0xE1","0x02","0x00",value],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&225==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_E1")},getDD5AFBAsync=async(deviceId,type,value)=>{const _command=["0xFB","0x02",type,value],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return console.log("command: ",command),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&251==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_FB")},resolveBaseDD=data=>{if(!data)return null;const dataStr=hexArr2string(data),content=data.slice(4,data.length-3);return{dataStr:dataStr,status:hex2string(data[2]),len:data[3],content:content}},getDD5A0AAsync=async(deviceId,value)=>{const _command=["0x0A","0x02",...stringToTwoHexArray(value)],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return console.log("command: ",command),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&10==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},`DD5A_0A_${value}`)},resolveDD5A0A=data=>{if(!data)return null;const dataStr=hexArr2string(data),statusDec=data[2],len=data[3],succeeded=0===statusDec;return{dataStr:dataStr,status:hex2string(statusDec),len:len,succeeded:succeeded,message:succeeded?"CMD_EXEC_SUCCESS":"CMD_EXEC_FAIL"}},getDD5AFAAsync=async(deviceId,value)=>{const hexStr=decimalToHex(100*value,4),_command=["0xFA","0x05","0x00","0x70","0x01",...[`0x${hexStr.slice(0,2)}`,`0x${hexStr.slice(2,4)}`]],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&250==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_FA")},getDDA505Async=async deviceId=>getData(deviceId,{command:["0xdd","0xa5","0x05","0x00","0xff","0xfb","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&5==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_05"),resolveDDA505=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3],hardwareV:hexArr2Assic(data.slice(4,data.length-3))}},getDDA5FAAsync=async(deviceId,paramNo,length)=>{const _values=[...paramNo,length],_command=["0xFA",decimalToHex(_values.length),..._values],checks=generateCrcCheckSum(_command),command=["0xDD","0xA5",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&250==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"READ_DDA5_FA")},setDDA5FAAsync=async(deviceId,paramNo,valueLength,content)=>{const _values=[...paramNo,valueLength,...content],_command=["0xFA",decimalToHex(_values.length),..._values],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&250==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"SET_DDA5_FA")},resolveDDA5FA=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3],type:data[5],value:data.slice(7,-3)}},getDDA5OldAsync=async(deviceId,path)=>{const values=[path,"0x00"],checks=generateCrcCheckSum(values),command=["0xDD","0xa5",...values,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==path,pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_读旧协议读参")},setDDA5OldAsync=async(deviceId,path,value,type="")=>{const values=[path,"0x02",...value],checks=generateCrcCheckSum(values),command=["0xDD","0x5A",...values,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==path,pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DDA5_写旧协议读参"+type)},getDD5AE0Async=async(deviceId,value)=>{const hex=100*value,hexStr=decimalToHex(hex,4),_values=[`0x${hexStr.slice(0,2)}`,`0x${hexStr.slice(2,4)}`],_command=["0xE0","0x02",..._values],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return console.warn("=======CCCCCCC=SET===",{value:value,hex:hex,hexStr:hexStr,_values:_values,_command:_command,checks:checks,command:command}),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&224==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_E0")},getDD5A0EAsync=async deviceId=>getData(deviceId,{command:["0xDD","0x5A","0x0E","0x02","0x81","0x18","0xFF","0x57","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&14==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_0E_复位"),getDD5AE4Async=async deviceId=>getData(deviceId,{command:["0xdd","0x5a","0xe4","0x02","0x18","0x81","0xfe","0x81","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&228==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_E4"),getDD5AAllAsync=async(deviceId,path,lengthHex,values,type)=>{const _command=[path,lengthHex,...values],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==path,pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},`DD5A_${path}_${type}`)},sendBMSAsync=async(deviceId,values)=>{const command=values.match(/[0-9a-fA-F]{2}/g)?.map(item=>`0x${item}`)||[];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==command[2],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},`DD5A_${command[2]}`)},resolveBMSCmd=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3]}},getProtectCountCmd=async deviceId=>{const data=await getData(deviceId,{command:["0xdd","0xa5","0xaa","0x00","0xff","0x56","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&170==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DDA5_AA保护次数"),arr=[];for(let i=4;i<data.length-4;i+=2){const offset=i;console.log("offset",offset);let value=((255&data[offset])<<8)+(255&data[offset+1]);arr.push(value)}return arr},getDD5A17Async=async deviceId=>getData(deviceId,{command:["0xDD","0x5A","0x17","0x02","0x00","0x01","0xFF","0xE6","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&23==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_17-清除电池循环次数"),getDDA507Async=async deviceId=>getData(deviceId,{command:["0xDD","0xA5","0x07","0x00","0xFF","0xF9","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&7==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_07历史运行履历总数"),getDDA508Async=async(deviceId,i=0)=>{const _command=["0x08",`0x${i.toString(16).padStart(2,0)}`],checks=generateCrcCheckSum(_command),command=["0xDD","0xA5",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&8==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_08读取履历详情")},resolveProtections=binary=>{const arr=binary.split("").reverse(),map=["device.0041","device.0042","device.0043","device.0044","device.0045","device.0046","device.0047","device.0048","device.0049","device.0050","device.0051","device.0052","device.0053","device.0054","device.0055","device.00551"];let _arr=[],_indexs=[];for(let i=0;i<arr.length;i++)1==arr[i]&&(_arr.push(map[i]),_indexs.push(i));return{_arr:_arr,_indexs:_indexs}},resolveDDA508=data=>{if(!data)return null;if(!data)return null;const hexArr=data.map(o=>o.toString(16).padStart(2,"0").toUpperCase()),f=s=>parseInt(s,16),fet=data[40].toString(2).padStart(8,"0").split("").reverse(),protection=f(hexArr[23]+hexArr[22]).toString(2).padStart(16,"0"),n=Number(fet[7])?10:100;let current=(hexArr[16]<<8)+(255&hexArr[17]);current=current>32768?(current-65536)/n:current/n;const electricity=Number(current.toFixed(2)),sysTime=65536*data[30]+256*data[31]+data[32];console.log("hexArr[30], hexArr[31], hexArr[32]",hexArr[30],hexArr[31],hexArr[32]),console.warn("sysTime: ",sysTime);const reportTime=65536*data[11]+256*data[12]+data[13];console.log("data[11], data[12], data[13]",data[11],data[12],data[13]),console.warn("reportTime: ",reportTime);const time=60*Math.abs(sysTime-reportTime)*1e3;console.warn("time: ",time);const timestamp=(new Date).getTime()-time;return console.warn("new Date().getTime(): ",(new Date).getTime()),{dataStr:hexArr.join(""),status:hex2string(data[2]),len:data[3],total:f(hexArr[4]+hexArr[5]),page:f(hexArr[6]+hexArr[7]),type:data[8],sysTime:sysTime,timestamp:timestamp,sumV:(f(hexArr[15]+hexArr[14])/100).toFixed(2),sumE:electricity,restC:(f(hexArr[19]+hexArr[18])/n).toFixed(2),designC:(f(hexArr[21]+hexArr[20])/n).toFixed(2),protections:resolveProtections(protection)._arr,protectionIndex:resolveProtections(protection)._indexs,tH:((f(hexArr[27]+hexArr[26])-2731)/10).toFixed(2),tL:((f(hexArr[29]+hexArr[28])-2731)/10).toFixed(2),vH:(f(hexArr[35]+hexArr[34])/1e3).toFixed(3),vL:(f(hexArr[37]+hexArr[36])/1e3).toFixed(3),nH:f(hexArr[38]),nL:f(hexArr[39]),fet:fet.join("")}},get3B3CInfo=({deviceId:deviceId,macAddr:macAddr,moduleType:moduleType,productType:productType})=>new Promise(async(resolve,reject)=>{let reportData={macAddr:macAddr,moduleTypeKey:moduleType,productKey:productType},_3b3c=null,_dda5_03=null,_dda5_05=null,_ffaa_80=null;try{if(!deviceId)throw new Error("deviceId required");const _ffaa_80_hex=await getFFAA80Async(deviceId,"AT^VERSION?");_ffaa_80=resolveFFAA80(_ffaa_80_hex),console.warn("Report-3B3C _ffaa_80 ",{_ffaa_80_hex:_ffaa_80_hex,_ffaa_80:_ffaa_80}),_ffaa_80&&(reportData.moduleVersion=_ffaa_80?.moduleVersion);const _3b3c_hex=await get3B3CAsync(deviceId);if(_3b3c=resolve3B3C(_3b3c_hex),console.warn("Report-3B3C _3b3c ",{_3b3c_hex:_3b3c_hex,_3b3c:_3b3c}),_3b3c)reportData.cmdContent=_3b3c?.dataStr;else{const _dda5_03_hex=await getDDA503Async(deviceId);_dda5_03=resolveDDA503(_dda5_03_hex),console.warn("Report-3B3C _dda5_03 ",{_dda5_03_hex:_dda5_03_hex,_dda5_03:_dda5_03}),_dda5_03&&(reportData.bmsVersion=_dda5_03?.softwareV);const _dda5_05_hex=await getDDA505Async(deviceId);_dda5_05=resolveDDA505(_dda5_05_hex),console.warn("Report-3B3C _dda5_05 ",{_dda5_05_hex:_dda5_05_hex,_dda5_05:_dda5_05}),_dda5_05&&(reportData.bmsSn=_dda5_05?.hardwareV)}resolve({reportData:reportData,_3b3c:_3b3c,_dda5_03:_dda5_03,_dda5_05:_dda5_05,_ffaa_80:_ffaa_80})}catch(error){reject(error)}}),activateAsync=async deviceId=>{const startTime=+new Date,disChargMOSHex=await getDD5AFBAsync(deviceId,"0x00","0x00"),disChargMOSRes=resolveBaseDD(disChargMOSHex)?.dataStr,disChargEndTime=+new Date,activeHex=await getDD5AFBAsync(deviceId,"0x05","0x01"),activeRes=resolveBaseDD(disChargMOSHex)?.dataStr;let baseInfo=null;const endTime=+new Date;await sleep(300),baseInfo=await getDDA503Async(deviceId);return{disChargMOSHex:disChargMOSHex,disChargMOSRes:disChargMOSRes,activeHex:activeHex,activeRes:activeRes,baseInfo:baseInfo,voltageInfo:await getDDA504Async(deviceId),startTime:startTime,disChargEndTime:disChargEndTime,endTime:endTime}},getDDA5DCAsync=deviceId=>{const _command=["0xDE","0x00"],checks=generateCrcCheckSum(_command),command=["0xDD","0xA5",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&222==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_DC")},resolveDDA5DC=data=>{if(!data)return null;const dataStr=hexArr2string(data),status=hex2string(data[2]),len=255&data[3],resistances_milliohm=[];for(let i=4;i<4+len;i+=2){const value=((255&data[i])<<8)+(255&data[i+1]);resistances_milliohm.push(value)}console.log("均衡线电阻(mΩ): ",resistances_milliohm,data);let maxResistance=null,minResistance=null,avgResistance=null;resistances_milliohm.length&&(maxResistance=Math.max(...resistances_milliohm),minResistance=Math.min(...resistances_milliohm),avgResistance=resistances_milliohm.reduce((a,c)=>a+c,0)/resistances_milliohm.length);const resistances_ohm=resistances_milliohm.map(v=>Number((v/1e3).toFixed(3))),resistancesSeries=resistances_ohm.map((v,idx)=>({name:idx+1,value:v}));return{dataStr:dataStr,status:status,len:len,resistances_milliohm:resistances_milliohm,resistances_ohm:resistances_ohm,maxResistance_milliohm:maxResistance,minResistance_milliohm:minResistance,avgResistance_milliohm:avgResistance,maxResistance_ohm:null!=maxResistance?Number((maxResistance/1e3).toFixed(3)):null,minResistance_ohm:null!=minResistance?Number((minResistance/1e3).toFixed(3)):null,avgResistance_ohm:null!=avgResistance?Number((avgResistance/1e3).toFixed(3)):null,resistancesSeries:resistancesSeries}},resetCapacity=deviceId=>getData(deviceId,{command:["0xDD","0x5A","0x0A","0x02","0x01","0x00","0xFF","0xF3","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&10==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_0A"),getDDA506Async=async deviceId=>getData(deviceId,{command:["0xdd","0xa5","0x06","0x00","0xff","0xfa","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&6==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_06"),resolveDDA506=data=>{if(!data)return null;if(6==data[1]&&0==data[2]&&6==data[3]){const seconds=fromBCD(data[4]),minutes=fromBCD(data[5]),hours=fromBCD(data[6]),day=fromBCD(data[7]),month=fromBCD(data[8]),timeStr=`${2e3+fromBCD(data[9])}-${String(month).padStart(2,0)}-${String(day).padStart(2,0)} ${String(hours).padStart(2,0)}:${String(minutes).padStart(2,0)}:${String(seconds).padStart(2,0)}`;return console.log("timeStr: ",timeStr,isWithin30Minutes(timeStr)),isWithin30Minutes(timeStr)}return!1},setDD5AE3sync=async deviceId=>{const now=new Date,year=now.getFullYear(),month=now.getMonth()+1,day=now.getDate(),hours=now.getHours(),minutes=now.getMinutes(),seconds=now.getSeconds(),content=["0xE3","0x07","0x06",...[toBCD(seconds),toBCD(minutes),128|toBCD(hours),toBCD(day),toBCD(month),toBCD(year-2e3)].map(b=>"0x"+b.toString(16).padStart(2,"0"))],checks=generateCrcCheckSum(content),command=["0xDD","0x5A",...content,...checks,"0x77"];return console.log("command: ",command),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&227==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"SET_DDA5_E3")},getDDA4F0Async=async deviceId=>{const command=["0xDD","0xA4","0xF0","0x00"],checks=generateCrcCheckSum(command.slice(2)),fullCommand=[...command,...checks,"0x77"];return getData(deviceId,{command:fullCommand,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&240==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA4_F0")},resolveDDA4F0=data=>{if(!data)return null;if(240==data[1]&&4==data[3]){const runTime=data[4]<<24|data[5]<<16|data[6]<<8|data[7];return{runTime:runTime,runTimeHour:(runTime/3600).toFixed(2),raw:hexArr2string(data)}}return null};export{activateAsync,enterFactory,existFactory,get3B3CAsync,get3B3CInfo,getChipTypeAsync,getDD5A0AAsync,getDD5A0EAsync,getDD5A17Async,getDD5AAllAsync,getDD5AE0Async,getDD5AE1Async,getDD5AE4Async,getDD5AFAAsync,getDD5AFBAsync,getDDA4F0Async,getDDA503Async,getDDA504Async,getDDA505Async,getDDA506Async,getDDA507Async,getDDA508Async,getDDA5DCAsync,getDDA5FAAsync,getDDA5OldAsync,getProtectCountCmd,readExistFactory,resetCapacity,resolve3B3C,resolveBMSCmd,resolveBaseDD,resolveDD5A0A,resolveDDA4F0,resolveDDA500,resolveDDA503,resolveDDA504,resolveDDA505,resolveDDA506,resolveDDA508,resolveDDA5DC,resolveDDA5FA,resolveProtections,sendBMSAsync,setDD5AE3sync,setDDA5FAAsync,setDDA5OldAsync,set_PlanCMD_3B3C,set_PlanCMD_DD};
1
+ import{hexArr2string,hex2string,decimalToHex,generateCrc16modbusCheck,hexArr2Assic,generateCrcCheckSum,hexToDecimal,stringToTwoHexArray,sleep,fromBCD,isWithin30Minutes,toBCD}from"../BleDataProcess.js";import{getData}from"./BleCmdAnalysis.js";import{getFFAA80Async,resolveFFAA80}from"./BleCmdFFAA.js";import{controlSwitch}from"./readAndSetParam.js";const enterFactory=async deviceId=>set_PlanCMD_DD(deviceId,"DD5A00025678FF3077"),existFactory=async deviceId=>set_PlanCMD_DD(deviceId,"DD5A01022828ffad77"),readExistFactory=async deviceId=>set_PlanCMD_DD(deviceId,"DD5A01020000FFFD77"),set_PlanCMD_DD=async(deviceId,command)=>{"string"==typeof command&&(command=command.match(/(.{2})/g).map(o=>`0x${o}`));let result=null;try{const data=await getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"PlanCMD_DD");if(data){const dataStr=hexArr2string(data),content=data.slice(4,data.length-3);result={data:data,dataStr:dataStr,status:hex2string(data[2]),len:data[3],content:content}}else result={status:0,content:[]}}catch(error){console.error(error)}return result},set_PlanCMD_3B3C=async(deviceId,command)=>{"string"==typeof command&&(command=command.match(/(.{2})/g).map(o=>`0x${o}`));let result=null;try{const data=await getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:59==hexArr[0]&&60==hexArr[1],pkgLen:hexArr[11]+15}),pkgVerifyHandler:pkg=>({verified:!0})},"PlanCMD_3B3C");if(data){const dataStr=hexArr2string(data),content=data.slice(12,data.length-3);result={dataStr:dataStr,status:128==data[10]?1:0,addr:hexArr2string(data.slice(2,10)),content:content}}}catch(error){console.error(error)}return result},get3B3CAsync=async deviceId=>{const addressCode=["0x00","0x00","0x00","0x00","0x00","0x00","0x00","0x00"],commandCode=["0x01"],data=[],dataLength=[`0x${decimalToHex(data.length,2)}`],check=generateCrc16modbusCheck([...addressCode,...commandCode,...dataLength,...data],!1),command=["0x3b","0x3c",...addressCode,...commandCode,...dataLength,...data,...check,"0x0d"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:59==hexArr[0]&&60==hexArr[1],pkgLen:hexArr[11]+15}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrc16modbusCheck(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"3B3C")},resolve3B3C=data=>{if(!data)return null;let result={dataStr:hexArr2string(data),status:hex2string(data[10]),addr:hexArr2string(data.slice(2,10))};const content=data.slice(12,data.length-3);for(;content.length>0;){const[v1,v2,...v]=content.splice(0,content[1]+2);if(1==v1&&(result.productFlag=hex2string(v1),result.productLen=v2,v)){const[productType,frontType,protocolV,level]=v.map(o=>hex2string(o));Object.assign(result,{productType:productType,frontType:frontType,protocolV:protocolV,level:level})}2==v1&&(result.hardwareFlag=hex2string(v1),result.hardwareLen=v2,result.hardwareV=hexArr2Assic(v)),3==v1&&(result.sofewareFlag=hex2string(v1),result.sofewareLen=v2,result.sofewareV=hexArr2Assic(v)),4==v1&&(result.pcbFlag=hex2string(v1),result.pcbLen=v2,result.pcbContent=hexArr2Assic(v))}return result},getDDA503Async=async deviceId=>{const hex=await getData(deviceId,{command:["0xdd","0xa5","0x03","0x00","0xff","0xfd","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&3==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_03");return hex?resolveDDA503(hex):null},resolveDDA503=data=>{if(!data)return null;const cmdResp03=hexArr2string(data),content=data.slice(4,data.length-3),binArr=data[24].toString(2).padStart(8,"0").split("").reverse(),BC1=(data[16]<<8|data[17]).toString(2).padStart(16,"0").split("").reverse();console.log("BC1: ",BC1);const BC2=(data[18]<<8|data[19]).toString(2).padStart(16,"0").split("").reverse(),balances=BC1.concat(BC2);console.warn("BC: ---------------",balances);const fet=data[24],chargeSwitch=!!Number(binArr[0]),dischargeSwitch=!!Number(binArr[1]),BMSVersion=decimalToHex(data[22]),humidityIndex=2*data[26]+27,humidity=data[humidityIndex],n=Number(binArr[7])||136==humidity?10:100,totalVoltage=Number((((data[4]<<8)+(255&data[5]))/100).toFixed(2));let current=(data[6]<<8)+(255&data[7]);current=current>32768?(current-65536)/n:current/n;const electricity=Number(current.toFixed(2)),power=Number((totalVoltage*electricity).toFixed(2)),soc=data[23]??0,seriesNum=data[25]??0,volumeHex=decimalToHex(data[8])+decimalToHex(data[9]),surplusCapacity=Number((hexToDecimal(volumeHex)/n).toFixed(2)),normCapHex=decimalToHex(data[10])+decimalToHex(data[11]),normCap=Number((hexToDecimal(normCapHex)/n).toFixed(2)),cycleHex=decimalToHex(data[12])+decimalToHex(data[13]),cycleIndex=hexToDecimal(cycleHex),fccHex=decimalToHex(data[humidityIndex+3])+decimalToHex(data[humidityIndex+4]),fullChargeCapacity=Number((hexToDecimal(fccHex)/n).toFixed(2)),SOH=cycleIndex<=100?100:Math.min(100,fullChargeCapacity/normCap*100),heatingState=!!Number(binArr[4])||!!Number(binArr[3]);let heatingCurrent=null;const hasHeatingCurrent=data[3]+7>=humidityIndex+9+4+1,hasEquilCurrent=data[3]+7>=humidityIndex+7+4+1;if(heatingState&&hasHeatingCurrent){const i=humidityIndex+9;heatingCurrent=heatingCurrent=((data[i]<<8|data[i+1])/100).toFixed(2)}let equilibriumCurrent=null;if(hasEquilCurrent){const i=humidityIndex+7;let equilCurrent=(data[i]<<8)+(255&data[i+1]);equilCurrent=equilCurrent>32768?(equilCurrent-65536)/1e3:equilCurrent/1e3,equilibriumCurrent=Number(equilCurrent.toFixed(2))}const isFactoryMode=!!Number(binArr[6]),equilibriumStatus=!(0===data[16]&&0===data[17]),protectStatus=!(0===data[20]&&0===data[21]),protectStateHex=decimalToHex(data[20])+decimalToHex(data[21]),protVal=hexToDecimal(protectStateHex);let alarmIndex=2*data[26]+28,alarmStateHex=decimalToHex(data[alarmIndex])+decimalToHex(data[alarmIndex+1]),alarmsState=hexToDecimal(alarmStateHex);const ntcNums=255&data[26],temperaturesList=Array.from({length:ntcNums},(_,i)=>((256*(255&data[26+2*i+1])+(255&data[26+2*i+2])-2731)/10).toFixed(1)),fahTempList=[];temperaturesList.forEach(el=>{const value=1.8*Number(el)+32;fahTempList.push(value.toFixed(1))});const temperatures=temperaturesList.map((item,index)=>({name:index+1,value:item})),hasProtocol=data[3]+7>=humidityIndex+11+3+1,protocolVersion=data[humidityIndex+11];return{cmdResp03:cmdResp03,status:hex2string(data[2]),len:data[3],softwareV:hex2string(content[18]),balances:balances,BMSVersion:BMSVersion,soc:soc,normCap:normCap,surplusCapacity:surplusCapacity,totalVoltage:totalVoltage,electricity:electricity,power:power,cycleIndex:cycleIndex,equilibriumStatus:equilibriumStatus,chargeSwitch:chargeSwitch,dischargeSwitch:dischargeSwitch,temperatures:temperatures,humidity:humidity,protectStatus:protectStatus,fullChargeCapacity:fullChargeCapacity,SOH:SOH,heatingState:heatingState,heatingCurrent:heatingCurrent,equilibriumCurrent:equilibriumCurrent,isFactoryMode:isFactoryMode,protVal:protVal,alarmsState:alarmsState,ntcNums:ntcNums,temperaturesList:temperaturesList,fahTempList:fahTempList,fet:fet,seriesNum:seriesNum,hasProtocol:hasProtocol,protocolVersion:protocolVersion}},getDDA504Async=async(deviceId,dataScope)=>{const hex=await getData(deviceId,{command:["0xdd","0xa5","0x04","0x00","0xff","0xfc","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&4==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_04");return hex?resolveDDA504(hex,dataScope):null},resolveDDA504=(data,dataScope)=>{if(console.log("data: ",data),!data)return null;const cmdResp04=hexArr2string(data),voltageList=[];for(let index=4;index<parseInt(data[3])+4;index+=2){let voltageHex=decimalToHex(data[index])+decimalToHex(data[index+1]),voltage=hexToDecimal(voltageHex);voltageList.push(Number(voltage))}let highestVoltage=null,lowestVoltage=null,averageVoltage=null,dropoutVoltage=null;if(voltageList.length>0){highestVoltage=Math.max(...voltageList),lowestVoltage=Math.min(...voltageList);averageVoltage=voltageList.reduce((acc,cur)=>acc+cur,0)/voltageList.length;const dropout=highestVoltage-lowestVoltage,precision=dataScope?3:2;highestVoltage=Number((highestVoltage/1e3).toFixed(precision)),lowestVoltage=Number((lowestVoltage/1e3).toFixed(precision)),averageVoltage=Number((averageVoltage/1e3).toFixed(precision)),dropoutVoltage=Number((dropout/1e3).toFixed(precision))}voltageList.forEach((v,i)=>{let newV=v/1e3;voltageList[i]=Number(newV.toFixed(dataScope?3:2))});const voltageSeries=voltageList.map((item,index)=>({name:index+1,value:item}));return{cmdResp04:cmdResp04,voltageList:voltageList,voltageSeries:voltageSeries,highestVoltage:highestVoltage,lowestVoltage:lowestVoltage,averageVoltage:averageVoltage,dropoutVoltage:dropoutVoltage}},getChipTypeAsync=async deviceId=>{const hex=await getData(deviceId,{command:["0xdd","0xa5","0x00","0x00","0x00","0x00","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&0==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_00");return hex?resolveDDA500(hex):null},resolveDDA500=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3],type:data[5]}},getDD5AE1Async=async(deviceId,value)=>{const _command=["0xE1","0x02","0x00",value],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&225==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_E1")},getDD5AFBAsync=async(deviceId,type,value)=>{const _command=["0xFB","0x02",type,value],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return console.log("command: ",command),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&251==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_FB")},resolveBaseDD=data=>{if(!data)return null;const dataStr=hexArr2string(data),content=data.slice(4,data.length-3);return{dataStr:dataStr,status:hex2string(data[2]),len:data[3],content:content}},getDD5A0AAsync=async(deviceId,value)=>{const _command=["0x0A","0x02",...stringToTwoHexArray(value)],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return console.log("command: ",command),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&10==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},`DD5A_0A_${value}`)},resolveDD5A0A=data=>{if(!data)return null;const dataStr=hexArr2string(data),statusDec=data[2],len=data[3],succeeded=0===statusDec;return{dataStr:dataStr,status:hex2string(statusDec),len:len,succeeded:succeeded,message:succeeded?"CMD_EXEC_SUCCESS":"CMD_EXEC_FAIL"}},getDD5AFAAsync=async(deviceId,value)=>{const hexStr=decimalToHex(100*value,4),_command=["0xFA","0x05","0x00","0x70","0x01",...[`0x${hexStr.slice(0,2)}`,`0x${hexStr.slice(2,4)}`]],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&250==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_FA")},getDDA505Async=async deviceId=>getData(deviceId,{command:["0xdd","0xa5","0x05","0x00","0xff","0xfb","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&5==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_05"),resolveDDA505=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3],hardwareV:hexArr2Assic(data.slice(4,data.length-3))}},getDDA5FAAsync=async(deviceId,paramNo,length)=>{const _values=[...paramNo,length],_command=["0xFA",decimalToHex(_values.length),..._values],checks=generateCrcCheckSum(_command),command=["0xDD","0xA5",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&250==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"READ_DDA5_FA")},setDDA5FAAsync=async(deviceId,paramNo,valueLength,content)=>{const _values=[...paramNo,valueLength,...content],_command=["0xFA",decimalToHex(_values.length),..._values],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&250==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"SET_DDA5_FA")},resolveDDA5FA=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3],type:data[5],value:data.slice(7,-3)}},getDDA5OldAsync=async(deviceId,path)=>{const values=[path,"0x00"],checks=generateCrcCheckSum(values),command=["0xDD","0xa5",...values,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==path,pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_读旧协议读参")},setDDA5OldAsync=async(deviceId,path,value,type="")=>{const values=[path,"0x02",...value],checks=generateCrcCheckSum(values),command=["0xDD","0x5A",...values,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==path,pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DDA5_写旧协议读参"+type)},getDD5AE0Async=async(deviceId,value)=>{const hex=100*value,hexStr=decimalToHex(hex,4),_values=[`0x${hexStr.slice(0,2)}`,`0x${hexStr.slice(2,4)}`],_command=["0xE0","0x02",..._values],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return console.warn("=======CCCCCCC=SET===",{value:value,hex:hex,hexStr:hexStr,_values:_values,_command:_command,checks:checks,command:command}),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&224==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_E0")},getDD5A0EAsync=async deviceId=>getData(deviceId,{command:["0xDD","0x5A","0x0E","0x02","0x81","0x18","0xFF","0x57","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&14==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_0E_复位"),getDD5AE4Async=async deviceId=>getData(deviceId,{command:["0xdd","0x5a","0xe4","0x02","0x18","0x81","0xfe","0x81","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&228==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_E4"),getDD5AAllAsync=async(deviceId,path,lengthHex,values,type)=>{const _command=[path,lengthHex,...values],checks=generateCrcCheckSum(_command),command=["0xDD","0x5A",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==path,pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},`DD5A_${path}_${type}`)},sendBMSAsync=async(deviceId,values)=>{const command=values.match(/[0-9a-fA-F]{2}/g)?.map(item=>`0x${item}`)||[];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&hexArr[1]==command[2],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},`DD5A_${command[2]}`)},resolveBMSCmd=data=>{if(!data)return null;return{dataStr:hexArr2string(data),status:hex2string(data[2]),len:data[3]}},getProtectCountCmd=async deviceId=>{const data=await getData(deviceId,{command:["0xdd","0xa5","0xaa","0x00","0xff","0x56","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&170==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DDA5_AA保护次数"),arr=[];for(let i=4;i<data.length-4;i+=2){const offset=i;console.log("offset",offset);let value=((255&data[offset])<<8)+(255&data[offset+1]);arr.push(value)}return arr},getDD5A17Async=async deviceId=>getData(deviceId,{command:["0xDD","0x5A","0x17","0x02","0x00","0x01","0xFF","0xE6","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&23==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_17-清除电池循环次数"),getDDA507Async=async deviceId=>getData(deviceId,{command:["0xDD","0xA5","0x07","0x00","0xFF","0xF9","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&7==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_07历史运行履历总数"),getDDA508Async=async(deviceId,i=0)=>{const _command=["0x08",`0x${i.toString(16).padStart(2,0)}`],checks=generateCrcCheckSum(_command),command=["0xDD","0xA5",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&8==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_08读取履历详情")},resolveProtections=binary=>{const arr=binary.split("").reverse(),map=["device.0041","device.0042","device.0043","device.0044","device.0045","device.0046","device.0047","device.0048","device.0049","device.0050","device.0051","device.0052","device.0053","device.0054","device.0055","device.00551"];let _arr=[],_indexs=[];for(let i=0;i<arr.length;i++)1==arr[i]&&(_arr.push(map[i]),_indexs.push(i));return{_arr:_arr,_indexs:_indexs}},resolveDDA508=data=>{if(!data)return null;if(!data)return null;const hexArr=data.map(o=>o.toString(16).padStart(2,"0").toUpperCase()),f=s=>parseInt(s,16),fet=data[40].toString(2).padStart(8,"0").split("").reverse(),protection=f(hexArr[23]+hexArr[22]).toString(2).padStart(16,"0"),n=Number(fet[7])?10:100;let current=(hexArr[16]<<8)+(255&hexArr[17]);current=current>32768?(current-65536)/n:current/n;const electricity=Number(current.toFixed(2)),sysTime=65536*data[30]+256*data[31]+data[32];console.log("hexArr[30], hexArr[31], hexArr[32]",hexArr[30],hexArr[31],hexArr[32]),console.warn("sysTime: ",sysTime);const reportTime=65536*data[11]+256*data[12]+data[13];console.log("data[11], data[12], data[13]",data[11],data[12],data[13]),console.warn("reportTime: ",reportTime);const time=60*Math.abs(sysTime-reportTime)*1e3;console.warn("time: ",time);const timestamp=(new Date).getTime()-time;return console.warn("new Date().getTime(): ",(new Date).getTime()),{dataStr:hexArr.join(""),status:hex2string(data[2]),len:data[3],total:f(hexArr[4]+hexArr[5]),page:f(hexArr[6]+hexArr[7]),type:data[8],sysTime:sysTime,timestamp:timestamp,sumV:(f(hexArr[15]+hexArr[14])/100).toFixed(2),sumE:electricity,restC:(f(hexArr[19]+hexArr[18])/n).toFixed(2),designC:(f(hexArr[21]+hexArr[20])/n).toFixed(2),protections:resolveProtections(protection)._arr,protectionIndex:resolveProtections(protection)._indexs,tH:((f(hexArr[27]+hexArr[26])-2731)/10).toFixed(2),tL:((f(hexArr[29]+hexArr[28])-2731)/10).toFixed(2),vH:(f(hexArr[35]+hexArr[34])/1e3).toFixed(3),vL:(f(hexArr[37]+hexArr[36])/1e3).toFixed(3),nH:f(hexArr[38]),nL:f(hexArr[39]),fet:fet.join("")}},get3B3CInfo=({deviceId:deviceId,macAddr:macAddr,moduleType:moduleType,productType:productType})=>new Promise(async(resolve,reject)=>{let reportData={macAddr:macAddr,moduleTypeKey:moduleType,productKey:productType},_3b3c=null,_dda5_03=null,_dda5_05=null,_ffaa_80=null;try{if(!deviceId)throw new Error("deviceId required");const _ffaa_80_hex=await getFFAA80Async(deviceId,"AT^VERSION?");_ffaa_80=resolveFFAA80(_ffaa_80_hex),console.warn("Report-3B3C _ffaa_80 ",{_ffaa_80_hex:_ffaa_80_hex,_ffaa_80:_ffaa_80}),_ffaa_80&&(reportData.moduleVersion=_ffaa_80?.moduleVersion);const _3b3c_hex=await get3B3CAsync(deviceId);if(_3b3c=resolve3B3C(_3b3c_hex),console.warn("Report-3B3C _3b3c ",{_3b3c_hex:_3b3c_hex,_3b3c:_3b3c}),_3b3c)reportData.cmdContent=_3b3c?.dataStr;else{const _dda5_03_hex=await getDDA503Async(deviceId);_dda5_03=resolveDDA503(_dda5_03_hex),console.warn("Report-3B3C _dda5_03 ",{_dda5_03_hex:_dda5_03_hex,_dda5_03:_dda5_03}),_dda5_03&&(reportData.bmsVersion=_dda5_03?.softwareV);const _dda5_05_hex=await getDDA505Async(deviceId);_dda5_05=resolveDDA505(_dda5_05_hex),console.warn("Report-3B3C _dda5_05 ",{_dda5_05_hex:_dda5_05_hex,_dda5_05:_dda5_05}),_dda5_05&&(reportData.bmsSn=_dda5_05?.hardwareV)}resolve({reportData:reportData,_3b3c:_3b3c,_dda5_03:_dda5_03,_dda5_05:_dda5_05,_ffaa_80:_ffaa_80})}catch(error){reject(error)}}),activateAsync=async deviceId=>{try{const startTime=+new Date;let acStatus=!1;const mosRes=await controlSwitch(deviceId,"0x00",!0,!0),disChargMOSRes=mosRes?.dataStr,disChargEndTime=+new Date,activeHex=await getDD5AFBAsync(deviceId,"0x05","0x01"),activeResult=resolveBaseDD(activeHex);console.log("激活指令结果: ",{activeHex:activeHex,activeResult:activeResult});const activeRes=activeResult?.dataStr;let endTime=+new Date,baseInfo=null,voltageInfo=null,steps=[];if("00"==activeResult?.status)steps.push(4),acStatus=!0;else if("81"==activeResult?.status||"84"==activeResult?.status)"00"==mosRes?.status?(acStatus=!0,steps.push(5)):(acStatus=!1,steps.push(10));else if("82"==activeResult?.status||"83"==activeResult?.status)acStatus=!1,steps.push(6);else if(!activeResult||null==activeResult){await sleep(300);const baseInfo=await getDDA503Async(deviceId);baseInfo?.dischargeSwitch?(acStatus=!0,steps.push(7)):(acStatus=!1,steps.push(8)),endTime=+new Date}return{disChargMOSRes:disChargMOSRes,activeHex:activeHex,activeRes:activeRes,baseInfo:baseInfo,voltageInfo:voltageInfo,startTime:startTime,disChargEndTime:disChargEndTime,endTime:endTime,acStatus:acStatus,steps:steps}}catch(error){return console.log("🚀 ~ BleApiManager ~ activateAsync ~ error:",error),null}},getDDA5DCAsync=deviceId=>{const _command=["0xDE","0x00"],checks=generateCrcCheckSum(_command),command=["0xDD","0xA5",..._command,...checks,"0x77"];return getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&222==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_DC")},resolveDDA5DC=data=>{if(!data)return null;const dataStr=hexArr2string(data),status=hex2string(data[2]),len=255&data[3],resistances_milliohm=[];for(let i=4;i<4+len;i+=2){const value=((255&data[i])<<8)+(255&data[i+1]);resistances_milliohm.push(value)}console.log("均衡线电阻(mΩ): ",resistances_milliohm,data);let maxResistance=null,minResistance=null,avgResistance=null;resistances_milliohm.length&&(maxResistance=Math.max(...resistances_milliohm),minResistance=Math.min(...resistances_milliohm),avgResistance=resistances_milliohm.reduce((a,c)=>a+c,0)/resistances_milliohm.length);const resistances_ohm=resistances_milliohm.map(v=>Number((v/1e3).toFixed(3))),resistancesSeries=resistances_ohm.map((v,idx)=>({name:idx+1,value:v}));return{dataStr:dataStr,status:status,len:len,resistances_milliohm:resistances_milliohm,resistances_ohm:resistances_ohm,maxResistance_milliohm:maxResistance,minResistance_milliohm:minResistance,avgResistance_milliohm:avgResistance,maxResistance_ohm:null!=maxResistance?Number((maxResistance/1e3).toFixed(3)):null,minResistance_ohm:null!=minResistance?Number((minResistance/1e3).toFixed(3)):null,avgResistance_ohm:null!=avgResistance?Number((avgResistance/1e3).toFixed(3)):null,resistancesSeries:resistancesSeries}},resetCapacity=deviceId=>getData(deviceId,{command:["0xDD","0x5A","0x0A","0x02","0x01","0x00","0xFF","0xF3","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&10==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"DD5A_0A"),getDDA506Async=async deviceId=>getData(deviceId,{command:["0xdd","0xa5","0x06","0x00","0xff","0xfa","0x77"],commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&6==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA5_06"),resolveDDA506=data=>{if(!data)return null;if(6==data[1]&&0==data[2]&&6==data[3]){const seconds=fromBCD(data[4]),minutes=fromBCD(data[5]),hours=fromBCD(data[6]),day=fromBCD(data[7]),month=fromBCD(data[8]),timeStr=`${2e3+fromBCD(data[9])}-${String(month).padStart(2,0)}-${String(day).padStart(2,0)} ${String(hours).padStart(2,0)}:${String(minutes).padStart(2,0)}:${String(seconds).padStart(2,0)}`;return console.log("timeStr: ",timeStr,isWithin30Minutes(timeStr)),isWithin30Minutes(timeStr)}return!1},setDD5AE3sync=async deviceId=>{const now=new Date,year=now.getFullYear(),month=now.getMonth()+1,day=now.getDate(),hours=now.getHours(),minutes=now.getMinutes(),seconds=now.getSeconds(),content=["0xE3","0x07","0x06",...[toBCD(seconds),toBCD(minutes),128|toBCD(hours),toBCD(day),toBCD(month),toBCD(year-2e3)].map(b=>"0x"+b.toString(16).padStart(2,"0"))],checks=generateCrcCheckSum(content),command=["0xDD","0x5A",...content,...checks,"0x77"];return console.log("command: ",command),getData(deviceId,{command:command,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&227==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>({verified:!0})},"SET_DDA5_E3")},getDDA4F0Async=async deviceId=>{const command=["0xDD","0xA4","0xF0","0x00"],checks=generateCrcCheckSum(command.slice(2)),fullCommand=[...command,...checks,"0x77"];return getData(deviceId,{command:fullCommand,commandVerifyHandler:hexArr=>({verified:221==hexArr[0]&&240==hexArr[1],pkgLen:hexArr[3]+7}),pkgVerifyHandler:pkg=>{const len=pkg.length,[c1,c2]=generateCrcCheckSum(pkg.slice(2,len-3)),[_c1,_c2]=[pkg[len-3],pkg[len-2]];return{verified:c1==_c1&&c2==_c2}}},"DDA4_F0")},resolveDDA4F0=data=>{if(!data)return null;if(240==data[1]&&4==data[3]){const runTime=data[4]<<24|data[5]<<16|data[6]<<8|data[7];return{runTime:runTime,runTimeHour:(runTime/3600).toFixed(2),raw:hexArr2string(data)}}return null};export{activateAsync,enterFactory,existFactory,get3B3CAsync,get3B3CInfo,getChipTypeAsync,getDD5A0AAsync,getDD5A0EAsync,getDD5A17Async,getDD5AAllAsync,getDD5AE0Async,getDD5AE1Async,getDD5AE4Async,getDD5AFAAsync,getDD5AFBAsync,getDDA4F0Async,getDDA503Async,getDDA504Async,getDDA505Async,getDDA506Async,getDDA507Async,getDDA508Async,getDDA5DCAsync,getDDA5FAAsync,getDDA5OldAsync,getProtectCountCmd,readExistFactory,resetCapacity,resolve3B3C,resolveBMSCmd,resolveBaseDD,resolveDD5A0A,resolveDDA4F0,resolveDDA500,resolveDDA503,resolveDDA504,resolveDDA505,resolveDDA506,resolveDDA508,resolveDDA5DC,resolveDDA5FA,resolveProtections,sendBMSAsync,setDD5AE3sync,setDDA5FAAsync,setDDA5OldAsync,set_PlanCMD_3B3C,set_PlanCMD_DD};
@@ -1 +1 @@
1
- import{decimalToTwoByteHexArray,decimalToHex}from"../BleDataProcess.js";import{getDDA5FAAsync,enterFactory,getDDA5OldAsync,setDDA5FAAsync,setDDA5OldAsync,existFactory,readExistFactory}from"./BleCmdDD.js";const readParamCmd=(chipType,deviceId,paramInfo,needFactoryMode=!0)=>(console.log("chipType: ",chipType),new Promise(async(resolve,reject)=>{const{address:address=0,length:length=1,oldAddress:oldAddress="0x1f"}=paramInfo,hexAddress=decimalToTwoByteHexArray(address),hexLength=decimalToHex(length),handleRead=async(readFunction,index)=>{try{const hex=await readFunction();if(4==index&&needFactoryMode&&await readExistFactory(deviceId),!hex)return void resolve(null);const data=hex.slice(index,-3);console.log("data: 读参数",data),resolve(data||null)}catch(error){console.error("读取参数出错: ",error),reject(error)}};try{if(chipType)await handleRead(async()=>await getDDA5FAAsync(deviceId,hexAddress,hexLength),7);else{if(!oldAddress)return resolve(null);needFactoryMode&&await enterFactory(deviceId),await handleRead(async()=>await getDDA5OldAsync(deviceId,oldAddress),4)}}catch(error){console.error("读取参数出错---: ",error),reject(error)}})),getSysParamCmd=async(chipType,deviceId,paramInfo,needFactoryMode=!0)=>{try{console.log("paramInfo: ",paramInfo);const paramObj={address:paramInfo.paramNo,length:paramInfo.paramLength/2,oldAddress:paramInfo.oldParamNo};let data=await readParamCmd(chipType,deviceId,paramObj,needFactoryMode);return data||null}catch(error){throw console.error("error: 读系统参数报错 getSysParamCmd",error),error}},setSysParamCmd=async(chipType,deviceId,paramInfoArray)=>{try{console.log("paramInfoArray: ",paramInfoArray);const paramsToProcess=Array.isArray(paramInfoArray)?paramInfoArray:[paramInfoArray],paramObjs=[];for(const paramInfo of paramsToProcess){let value=Math.round(Number(paramInfo?.paramValue||paramInfo.newValue)/Number(paramInfo?.divisor||1));console.log("value: ",value),paramInfo.isTemp&&(value=2731+10*Number(paramInfo.newValue));const valuesHexs=decimalToTwoByteHexArray(value);console.log("valuesHexs: ",valuesHexs),paramObjs.push({address:paramInfo.paramNo,length:paramInfo.paramLength/2,values:valuesHexs,oldAddress:paramInfo.oldParamNo})}await setParamCmd(chipType,deviceId,paramObjs)}catch(error){throw console.error("error: 写系统参数报错 setSysParamCmd",error),error}},setParamCmd=(chipType,deviceId,paramInfoArray)=>{console.log("chipType: 芯片",chipType);const paramsToProcess=Array.isArray(paramInfoArray)?paramInfoArray:[paramInfoArray];return new Promise(async(resolve,reject)=>{try{await enterFactory(deviceId);const results=[];for(let i=0;i<paramsToProcess.length;i++){const paramInfo=paramsToProcess[i],{address:address,length:length,values:values,oldAddress:oldAddress}=paramInfo,hexAddress=decimalToTwoByteHexArray(address),hexLength=decimalToHex(length);let hex;if(hex=chipType?await setDDA5FAAsync(deviceId,hexAddress,hexLength,values):await setDDA5OldAsync(deviceId,oldAddress,values),console.log(`data: 写入第${i+1}个参数结果`,hex),!hex)throw new Error(`设置第${i+1}个参数失败`);results.push(hex)}await existFactory(deviceId),resolve(results)}catch(error){console.error("设置参数出错: ",error);try{await existFactory(deviceId)}catch(exitError){console.error("退出工厂模式失败: ",exitError)}reject(error)}})},setCapacityParamCmd=(chipType,deviceId,paramInfo)=>(console.log("chipType: 芯片",chipType),new Promise(async(resolve,reject)=>{const{values:values}=paramInfo,circular={address:1,oldAddress:"0x11",values:.8*values,length:1},full={address:112,oldAddress:"0x10",values:values,length:1},handleSet=async(setFunction,index)=>{try{const hex=await setFunction();return console.log("data: 写入参数结果",hex),hex||void reject("设置参数失败")}catch(error){console.error("设置参数出错: ",error),reject(error)}},handleParam=async paramObj=>{const{paramNo:paramNo,oldParamNo:oldParamNo,paramLength:paramLength}=paramObj,value=Math.round(Number(paramObj.values)/paramInfo.divisor);console.log("value: ",value);const hexValues=decimalToTwoByteHexArray(value),hexAddress=decimalToTwoByteHexArray(paramNo),hexLength=decimalToHex(paramLength/2);return chipType?await handleSet(()=>setDDA5FAAsync(deviceId,hexAddress,hexLength,hexValues)):await handleSet(()=>setDDA5OldAsync(deviceId,oldParamNo,hexValues))};try{await enterFactory(deviceId);const paramInfoHex=await handleParam(paramInfo);await handleParam(circular);if(chipType){await handleParam(full)}await existFactory(deviceId),paramInfoHex&&resolve(paramInfoHex)}catch(error){reject(error)}}));export{getSysParamCmd,readParamCmd,setCapacityParamCmd,setParamCmd,setSysParamCmd};
1
+ import{decimalToTwoByteHexArray,decimalToHex}from"../BleDataProcess.js";import{getDDA5FAAsync,enterFactory,getDDA5OldAsync,setDDA5FAAsync,setDDA5OldAsync,existFactory,getDD5AFBAsync,resolveBaseDD,getDD5AE1Async,readExistFactory}from"./BleCmdDD.js";const readParamCmd=(chipType,deviceId,paramInfo,needFactoryMode=!0)=>(console.log("chipType: ",chipType),new Promise(async(resolve,reject)=>{const{address:address=0,length:length=1,oldAddress:oldAddress="0x1f"}=paramInfo,hexAddress=decimalToTwoByteHexArray(address),hexLength=decimalToHex(length),handleRead=async(readFunction,index)=>{try{const hex=await readFunction();if(4==index&&needFactoryMode&&await readExistFactory(deviceId),!hex)return void resolve(null);const data=hex.slice(index,-3);console.log("data: 读参数",data),resolve(data||null)}catch(error){console.error("读取参数出错: ",error),reject(error)}};try{if(chipType)await handleRead(async()=>await getDDA5FAAsync(deviceId,hexAddress,hexLength),7);else{if(!oldAddress)return resolve(null);needFactoryMode&&await enterFactory(deviceId),await handleRead(async()=>await getDDA5OldAsync(deviceId,oldAddress),4)}}catch(error){console.error("读取参数出错---: ",error),reject(error)}})),getSysParamCmd=async(chipType,deviceId,paramInfo,needFactoryMode=!0)=>{try{console.log("paramInfo: ",paramInfo);const paramObj={address:paramInfo.paramNo,length:paramInfo.paramLength/2,oldAddress:paramInfo.oldParamNo};let data=await readParamCmd(chipType,deviceId,paramObj,needFactoryMode);return data||null}catch(error){throw console.error("error: 读系统参数报错 getSysParamCmd",error),error}},setSysParamCmd=async(chipType,deviceId,paramInfoArray,macAddr,blueConnect=!0)=>{try{console.log("paramInfoArray: ",paramInfoArray);const paramsToProcess=Array.isArray(paramInfoArray)?paramInfoArray:[paramInfoArray],paramObjs=[];for(const paramInfo of paramsToProcess){let value=Number(paramInfo?.paramValue||paramInfo.newValue)/Number(paramInfo?.divisor||1);console.log("value: ",value),paramInfo.isTemp&&blueConnect&&(value=2731+10*Number(paramInfo.newValue)),value=Math.round(value);let valuesHexs=[];blueConnect&&(valuesHexs=decimalToTwoByteHexArray(value),console.log("valuesHexs: ",valuesHexs)),paramObjs.push({address:paramInfo.paramNo,length:paramInfo.paramLength/2,values:valuesHexs,oldAddress:paramInfo.oldParamNo,newValue:value})}console.log("chipType: 芯片",chipType),await setParamCmd(chipType,deviceId,paramObjs)}catch(error){throw console.error("error: 写系统参数报错 setSysParamCmd",error),error}},setParamCmd=async(chipType,deviceId,paramInfoArray)=>{console.log("chipType: 芯片",chipType);const paramsToProcess=Array.isArray(paramInfoArray)?paramInfoArray:[paramInfoArray];return new Promise(async(resolve,reject)=>{try{await enterFactory(deviceId);const results=[];for(let i=0;i<paramsToProcess.length;i++){const paramInfo=paramsToProcess[i],{address:address,length:length,values:values,oldAddress:oldAddress}=paramInfo,hexAddress=decimalToTwoByteHexArray(address),hexLength=decimalToHex(length);let hex;if(hex=chipType?await setDDA5FAAsync(deviceId,hexAddress,hexLength,values):await setDDA5OldAsync(deviceId,oldAddress,values),console.log(`data: 写入第${i+1}个参数结果`,hex),!hex)throw new Error(`设置第${i+1}个参数失败`);results.push(hex)}await existFactory(deviceId),resolve(results)}catch(error){console.error("设置参数出错: ",error);try{await existFactory(deviceId)}catch(exitError){console.error("退出工厂模式失败: ",exitError)}reject(error)}})},controlSwitch=async(deviceId,typeCmd,currentSwitch,anotherSwitch)=>{const hex=await getDD5AFBAsync(deviceId,typeCmd,currentSwitch?"0x00":"0x01"),mosRes=resolveBaseDD(hex);console.log("hex: ",hex);let dataRes=mosRes;if(!mosRes||"00"!=mosRes?.status){const cmd=getE1Cmd(typeCmd,currentSwitch,anotherSwitch),e1hex=await getDD5AE1Async(deviceId,cmd);dataRes=resolveBaseDD(e1hex)}return dataRes},getE1Cmd=(typeCmd,currentSwitch,anotherSwitch)=>{let cmd="0x00";return"0x00"===typeCmd?cmd=currentSwitch&&anotherSwitch?"0x00":currentSwitch&&!anotherSwitch?"0x01":!currentSwitch&&anotherSwitch?"0x02":"0x03":"0x01"===typeCmd&&(cmd=currentSwitch&&anotherSwitch?"0x00":!currentSwitch&&anotherSwitch?"0x01":currentSwitch&&!anotherSwitch?"0x02":"0x03"),cmd},setCapacityParamCmd=(chipType,deviceId,paramInfo)=>(console.log("chipType: 芯片",chipType),new Promise(async(resolve,reject)=>{const{values:values}=paramInfo,circular={address:1,oldAddress:"0x11",values:.8*values,length:1},full={address:112,oldAddress:"0x10",values:values,length:1},handleSet=async(setFunction,index)=>{try{const hex=await setFunction();return console.log("data: 写入参数结果",hex),hex||void reject("设置参数失败")}catch(error){console.error("设置参数出错: ",error),reject(error)}},handleParam=async paramObj=>{const{paramNo:paramNo,oldParamNo:oldParamNo,paramLength:paramLength}=paramObj,value=Math.round(Number(paramObj.values)/paramInfo.divisor);console.log("value: ",value);const hexValues=decimalToTwoByteHexArray(value),hexAddress=decimalToTwoByteHexArray(paramNo),hexLength=decimalToHex(paramLength/2);return chipType?await handleSet(()=>setDDA5FAAsync(deviceId,hexAddress,hexLength,hexValues)):await handleSet(()=>setDDA5OldAsync(deviceId,oldParamNo,hexValues))};try{await enterFactory(deviceId);const paramInfoHex=await handleParam(paramInfo);await handleParam(circular);if(chipType){await handleParam(full)}await existFactory(deviceId),paramInfoHex&&resolve(paramInfoHex)}catch(error){reject(error)}}));export{controlSwitch,getE1Cmd,getSysParamCmd,readParamCmd,setCapacityParamCmd,setParamCmd,setSysParamCmd};
@@ -1 +1 @@
1
- import{getOS}from"./commonfun.js";import{TelinkApi}from"./TelinkApi.js";import{BLE,Transfer}from"./Transfer.js";const max=BLE.PACKAGE_MAX_LENGTH,delayDefault=BLE.WRITE_DELAY,{isIOS:isIOS,isAndroid:isAndroid}=getOS();class OTAUpgrade{constructor({deviceId:deviceId,filePath:filePath,otaInfo:otaInfo,otaStart:otaStart,otaReStart:otaReStart,macAddr:macAddr,onProgress:onProgress,onSuccess:onSuccess,onError:onError,delay:delay,platform:platform="APP"}){this.deviceId=deviceId,this.filePath=filePath,this.otaInfo=otaInfo,this.otaStart=otaStart,this.otaReStart=otaReStart,this.macAddr=macAddr,this.platform=platform,this.isTeLink=!!TelinkApi.isTeLink&&TelinkApi.isTeLink({macAddr:macAddr}),this.onProgress=onProgress,this.onSuccess=onSuccess,this.onError=onError,this.delay=delay||delayDefault,this.fileHexArray=[],this.totalTimes=1,this.finishedTimes=0,this.succeed=!1,this.ready=!0,this.timer=null,this.s_progress=0,this.otaStarting=!1,this.progressType="download"}async start(){this.progressType="download";try{await this.download()}catch(e){this.fail("下载失败: "+e.message)}}async download(){const that=this;return new Promise((resolve,reject)=>{const downloadTask=uni.downloadFile({url:that.filePath,success:({tempFilePath:tempFilePath})=>{this.addBLECharValueChangeListener(),that.resolve(tempFilePath).then(resolve).catch(reject)},fail:res=>{that.fail("固件下载失败"),reject(res)}});downloadTask.onProgressUpdate&&downloadTask.onProgressUpdate(({progress:progress})=>{that.onProgress&&that.onProgress({type:"download",percent:progress})})})}async resolve(tempFilePath){const that=this;return new Promise((resolve,reject)=>{uni.saveFile({tempFilePath:tempFilePath,success:({savedFilePath:savedFilePath})=>{if("APP"===this.platform)plus.io.resolveLocalFileSystemURL(savedFilePath,entry=>{entry.file(file=>{var fileReader=new plus.io.FileReader;fileReader.readAsDataURL(file),fileReader.onloadend=e=>{let base64=e.target.result.split(",")[1];const hexArray=Transfer.base64ToHexArray(base64),times=Math.ceil(hexArray.length/(that.isTeLink?16:max));that.fileHexArray=hexArray,that.totalTimes=times,that.finishedTimes=0,that.progressType="upgrade",that.isTeLink?that.telinkUpgrade():that.normalUpgrade(),resolve()},fileReader.onerror=e=>{that.fail("固件解析失败"),reject(e)}})},err=>{that.fail("固件保存失败"),reject(err)});else if("MP"===this.platform){wx.getFileSystemManager().readFile({filePath:savedFilePath,encoding:"base64",success:res=>{let base64=res.data;const hexArray=Transfer.base64ToHexArray(base64),times=Math.ceil(hexArray.length/(that.isTeLink?16:max));that.fileHexArray=hexArray,that.totalTimes=times,that.finishedTimes=0,that.progressType="upgrade",that.isTeLink?that.telinkUpgrade():that.normalUpgrade(),resolve()},fail:err=>{console.error("[OTA] resolve failed:",JSON.stringify(err)),that.failed("文件解析失败")}})}},fail:res=>{that.fail("固件保存失败"),reject(res)}})})}normalUpgrade(){setTimeout(()=>{BLE.writeATCmd(this.otaInfo,this.deviceId,this.fail.bind(this))},2600)}telinkUpgrade(){this.write(["0x00","0xff"],0)}write(pkg,type){const value=function(hexArr){const buffer=new ArrayBuffer(hexArr.length),dataView=new DataView(buffer);return hexArr.forEach((hex,i)=>dataView.setUint8(i,hex)),buffer}(pkg.map(o=>parseInt(o,16))),opt={deviceId:this.deviceId,serviceId:"00010203-0405-0607-0809-0a0b0c0d1912",characteristicId:"00010203-0405-0607-0809-0a0b0c0d2b12",value:value,success:()=>this.onSucceed(type),fail:async()=>{await this.sleep(2*this.delay),uni.writeBLECharacteristicValue({...opt,fail:async()=>{await this.sleep(2*this.delay),uni.writeBLECharacteristicValue({...opt,fail:this.fail.bind(this)})}})}};uni.writeBLECharacteristicValue(opt),isIOS&&setTimeout(()=>this.onSucceed(type),5)}onSucceed(type){0==type?this.write(["0x01","0xff"],1):1==type?this.sendNextOtaPacketCommand():2==type?(this.finishedTimes++,this.sendNextOtaPacketCommand()):3==type?this.sendNextOtaPacketCommand():4==type?this.sendOtaEndCommand():5==type&&(this.finishedTimes++,this.succeed=!0,this.onSuccess&&this.onSuccess()),this.onProgress&&this.onProgress({type:"upgrade",percent:Math.floor(100*this.finishedTimes/this.totalTimes)})}async sendNextOtaPacketCommand(){const i=this.finishedTimes,index=TelinkApi.getIndexHexArr(i);let pkgValue=this.fileHexArray.slice(16*i,16*(i+1));pkgValue.length<16&&(pkgValue=pkgValue.concat([...Array(16-pkgValue.length)].map(()=>"0xFF")));const crc=TelinkApi.genCheck([...index,...pkgValue]),pkg=[...index,...pkgValue,...crc],type=i>=this.totalTimes-1?4:2;await this.sleep(this.delay),this.write(pkg,type)}sendOtaEndCommand(){const pkgValue=function(i,c=65282){return[255&c,c>>8&255,255&i,i>>8&255,255&~i,~i>>8&255].map(o=>`0x${`00${o.toString(16)}`.slice(-2)}`.toUpperCase())}(this.totalTimes-1),crc=TelinkApi.genCheck([...pkgValue]),pkg=[...pkgValue,...crc];this.write(pkg,5)}addBLECharValueChangeListener(){console.log("添加蓝牙特征值变化监听");const that=this;uni.notifyBLECharacteristicValueChange({deviceId:that.deviceId,serviceId:BLE.serviceId,characteristicId:BLE.readUUID,state:!0,success:()=>{},fail:()=>{}}),that.ready=!0,that.readValue=[],that.receiveLength=null,uni.onBLECharacteristicValueChange(({deviceId:deviceId,serviceId:serviceId,characteristicId:characteristicId,value:value})=>{if(that.ready&&deviceId==that.deviceId&&serviceId==BLE.serviceId){const intArr=Array.prototype.map.call(new Uint8Array(value),x=>x);intArr.length>0&&(null==that.receiveLength&&255==intArr[0]&&170==intArr[1]&&(that.receiveLength=intArr[3]+5),that.receiveLength?(that.readValue=that.readValue.concat(intArr),that.readValue.length==that.receiveLength&&(that.doWithResponse([...that.readValue]),that.readValue=[],that.receiveLength=null)):(that.readValue=[],that.receiveLength=null))}})}async doWithResponse(intArr){if(console.log("收到设备响应: ",intArr[2]),128==intArr[2]){let str=String.fromCharCode(...intArr.slice(4,-1));if(console.log("doWithResponse otaStart1",str),str.indexOf(this.otaInfo)>-1&&(this.finishedTimes=0,this.transferFirmwareFile()),str.indexOf(this.otaStart)>-1||this.otaStarting){if(str.indexOf(this.otaStart)>-1&&(this.otaStarting=!0),console.log("doWithResponse otaStart2",str),str.toUpperCase().includes("ERROR"))return void this.fail(str);str.toUpperCase().indexOf("S100")>-1&&(this.succeed=!0,this.onSuccess&&this.onSuccess())}}80==intArr[2]&&(0==intArr[4]?(this.finishedTimes++,this.transferFirmwareFile()):this.transferFirmwareFile()),81==intArr[2]&&(0==intArr[4]?this.startOTA():this.fail("升级失败"))}transferFirmwareFile(){let nextTime=this.finishedTimes+1;if(nextTime>this.totalTimes){const pkg=[0];BLE.transferFirmwareFileCmd(this.deviceId,pkg,!0,this.fail.bind(this)),console.log("[OTA]","=== Send 51 ===",this.finishedTimes,this.totalTimes,pkg)}else{const pkg=this.fileHexArray.slice(this.finishedTimes*max,nextTime*max),index=Transfer.decimalToTwoByteHexArray(this.finishedTimes);BLE.transferFirmwareFileCmd(this.deviceId,index.concat(pkg),!1,this.fail.bind(this)),console.log("[OTA]",`S50-${this.finishedTimes}/${this.totalTimes}`)}this.onProgress&&this.onProgress({type:"upgrade",percent:Math.floor(100*this.finishedTimes/this.totalTimes)})}async startOTA(){BLE.writeATCmd(this.otaStart,this.deviceId,this.fail.bind(this))}fail(msg){this.succeed=!1,this.onError&&this.onError(msg)}sleep(n=50){return new Promise(r=>setTimeout(()=>r(!0),n))}}export{OTAUpgrade,OTAUpgrade as default};
1
+ import{getOS}from"./commonfun.js";import{TelinkApi}from"./TelinkApi.js";import{BLE,Transfer}from"./Transfer.js";const max=BLE.PACKAGE_MAX_LENGTH,delayDefault=BLE.WRITE_DELAY,{isIOS:isIOS,isAndroid:isAndroid}=getOS();class OTAUpgrade{constructor({deviceId:deviceId,filePath:filePath,otaInfo:otaInfo,otaStart:otaStart,otaReStart:otaReStart,macAddr:macAddr,onProgress:onProgress,onSuccess:onSuccess,onError:onError,delay:delay,platform:platform="APP"}){this.deviceId=deviceId,this.filePath=filePath,this.otaInfo=otaInfo,this.otaStart=otaStart,this.otaReStart=otaReStart,this.macAddr=macAddr,this.platform=platform,this.isTeLink=!!TelinkApi.isTeLink&&TelinkApi.isTeLink({macAddr:macAddr}),this.onProgress=onProgress,this.onSuccess=onSuccess,this.onError=onError,this.delay=delay||delayDefault,this.fileHexArray=[],this.totalTimes=1,this.finishedTimes=0,this.succeed=!1,this.ready=!0,this.timer=null,this.s_progress=0,this.otaStarting=!1,this.progressType="download"}async start(){this.progressType="download";try{await this.download()}catch(e){this.fail("下载失败: "+e.message)}}async download(){const that=this;return new Promise((resolve,reject)=>{const downloadTask=uni.downloadFile({url:that.filePath,success:({tempFilePath:tempFilePath})=>{this.addBLECharValueChangeListener(),that.resolve(tempFilePath).then(resolve).catch(reject)},fail:res=>{that.fail("固件下载失败"),reject(res)}});downloadTask.onProgressUpdate&&downloadTask.onProgressUpdate(({progress:progress})=>{that.onProgress&&that.onProgress({type:"download",percent:progress})})})}async resolve(tempFilePath){const that=this;return new Promise((resolve,reject)=>{uni.saveFile({tempFilePath:tempFilePath,success:({savedFilePath:savedFilePath})=>{if("APP"===this.platform)plus.io.resolveLocalFileSystemURL(savedFilePath,entry=>{entry.file(file=>{var fileReader=new plus.io.FileReader;fileReader.readAsDataURL(file),fileReader.onloadend=e=>{let base64=e.target.result.split(",")[1];const hexArray=Transfer.base64ToHexArray(base64),times=Math.ceil(hexArray.length/(that.isTeLink?16:max));that.fileHexArray=hexArray,that.totalTimes=times,that.finishedTimes=0,that.progressType="upgrade",that.isTeLink?that.telinkUpgrade():that.normalUpgrade(),resolve()},fileReader.onerror=e=>{that.fail("固件解析失败"),reject(e)}})},err=>{that.fail("固件保存失败"),reject(err)});else if("MP"===this.platform){wx.getFileSystemManager().readFile({filePath:savedFilePath,encoding:"base64",success:res=>{let base64=res.data;const hexArray=Transfer.base64ToHexArray(base64),times=Math.ceil(hexArray.length/(that.isTeLink?16:max));that.fileHexArray=hexArray,that.totalTimes=times,that.finishedTimes=0,that.progressType="upgrade",that.isTeLink?that.telinkUpgrade():that.normalUpgrade(),resolve()},fail:err=>{console.error("[OTA] resolve failed:",JSON.stringify(err)),that.failed("文件解析失败")}})}},fail:res=>{that.fail("固件保存失败"),reject(res)}})})}normalUpgrade(){setTimeout(()=>{BLE.writeATCmd(this.otaInfo,this.deviceId,this.fail.bind(this))},2600)}telinkUpgrade(){this.write(["0x00","0xff"],0)}write(pkg,type){const value=function(hexArr){const buffer=new ArrayBuffer(hexArr.length),dataView=new DataView(buffer);return hexArr.forEach((hex,i)=>dataView.setUint8(i,hex)),buffer}(pkg.map(o=>parseInt(o,16))),opt={deviceId:this.deviceId,serviceId:"00010203-0405-0607-0809-0a0b0c0d1912",characteristicId:"00010203-0405-0607-0809-0a0b0c0d2b12",value:value,success:()=>this.onSucceed(type),fail:async()=>{await this.sleep(2*this.delay),uni.writeBLECharacteristicValue({...opt,fail:async()=>{await this.sleep(2*this.delay),uni.writeBLECharacteristicValue({...opt,fail:()=>{console.error("写入失败: ",pkg),this.fail("写入失败")}})}})}};uni.writeBLECharacteristicValue(opt),isIOS&&setTimeout(()=>this.onSucceed(type),5)}onSucceed(type){0==type?this.write(["0x01","0xff"],1):1==type?this.sendNextOtaPacketCommand():2==type?(this.finishedTimes++,this.sendNextOtaPacketCommand()):3==type?this.sendNextOtaPacketCommand():4==type?this.sendOtaEndCommand():5==type&&(this.finishedTimes++,this.succeed=!0,this.onSuccess&&this.onSuccess()),this.onProgress&&this.onProgress({type:"upgrade",percent:Math.floor(100*this.finishedTimes/this.totalTimes)})}async sendNextOtaPacketCommand(){const i=this.finishedTimes,index=TelinkApi.getIndexHexArr(i);let pkgValue=this.fileHexArray.slice(16*i,16*(i+1));pkgValue.length<16&&(pkgValue=pkgValue.concat([...Array(16-pkgValue.length)].map(()=>"0xFF")));const crc=TelinkApi.genCheck([...index,...pkgValue]),pkg=[...index,...pkgValue,...crc],type=i>=this.totalTimes-1?4:2;await this.sleep(this.delay),this.write(pkg,type)}sendOtaEndCommand(){const pkgValue=function(i,c=65282){return[255&c,c>>8&255,255&i,i>>8&255,255&~i,~i>>8&255].map(o=>`0x${`00${o.toString(16)}`.slice(-2)}`.toUpperCase())}(this.totalTimes-1),crc=TelinkApi.genCheck([...pkgValue]),pkg=[...pkgValue,...crc];this.write(pkg,5)}addBLECharValueChangeListener(){console.log("添加蓝牙特征值变化监听");const that=this;uni.notifyBLECharacteristicValueChange({deviceId:that.deviceId,serviceId:BLE.serviceId,characteristicId:BLE.readUUID,state:!0,success:()=>{},fail:()=>{}}),that.ready=!0,that.readValue=[],that.receiveLength=null,uni.onBLECharacteristicValueChange(({deviceId:deviceId,serviceId:serviceId,characteristicId:characteristicId,value:value})=>{if(that.ready&&deviceId==that.deviceId&&serviceId==BLE.serviceId){const intArr=Array.prototype.map.call(new Uint8Array(value),x=>x);intArr.length>0&&(null==that.receiveLength&&255==intArr[0]&&170==intArr[1]&&(that.receiveLength=intArr[3]+5),that.receiveLength?(that.readValue=that.readValue.concat(intArr),that.readValue.length==that.receiveLength&&(that.doWithResponse([...that.readValue]),that.readValue=[],that.receiveLength=null)):(that.readValue=[],that.receiveLength=null))}})}async doWithResponse(intArr){if(console.log("收到设备响应: ",intArr[2]),128==intArr[2]){let str=String.fromCharCode(...intArr.slice(4,-1));if(console.log("doWithResponse otaStart1",str),str.indexOf(this.otaInfo)>-1&&(this.finishedTimes=0,this.transferFirmwareFile()),str.indexOf(this.otaStart)>-1||this.otaStarting){if(str.indexOf(this.otaStart)>-1&&(this.otaStarting=!0),console.log("doWithResponse otaStart2",str),str.toUpperCase().includes("ERROR"))return void this.fail(str);str.toUpperCase().indexOf("S100")>-1&&(this.succeed=!0,this.onSuccess&&this.onSuccess())}}80==intArr[2]&&(0==intArr[4]?(this.finishedTimes++,this.transferFirmwareFile()):this.transferFirmwareFile()),81==intArr[2]&&(0==intArr[4]?this.startOTA():this.fail("升级失败"))}async transferFirmwareFile(){let nextTime=this.finishedTimes+1;if(nextTime>this.totalTimes){const pkg=[0];await BLE.sendDelay(20),BLE.transferFirmwareFileCmd(this.deviceId,pkg,!0,this.fail.bind(this)),console.log("[OTA]","=== Send 51 ===",this.finishedTimes,this.totalTimes,pkg)}else{const pkg=this.fileHexArray.slice(this.finishedTimes*max,nextTime*max),index=Transfer.decimalToTwoByteHexArray(this.finishedTimes);await BLE.sendDelay(20),BLE.transferFirmwareFileCmd(this.deviceId,index.concat(pkg),!1,this.fail.bind(this)),console.log("[OTA]",`S50-${this.finishedTimes}/${this.totalTimes}`)}this.onProgress&&this.onProgress({type:"upgrade",percent:Math.floor(100*this.finishedTimes/this.totalTimes)})}async startOTA(){BLE.writeATCmd(this.otaStart,this.deviceId,this.fail.bind(this))}fail(msg){this.succeed=!1,this.onError&&this.onError(msg)}sleep(n=50){return new Promise(r=>setTimeout(()=>r(!0),n))}}export{OTAUpgrade,OTAUpgrade as default};
@@ -0,0 +1 @@
1
+ var Queue$1=class{constructor(){this._items=[]}enqueue(item){this._items.push(item)}dequeue(){return this._items.shift()}head(){return this._items[0]}tail(){return this._items[this._items.length-1]}isEmpty(){return!this._items.length}size(){return this._items.length}clear(){this._items=[]}};export{Queue$1 as default};
@@ -1 +1 @@
1
- import SHA256 from"crypto-js/sha256";import mqtt from"mqtt/dist/mqtt.min.js";import{set_PlanCMD_DD}from"./BleCmdAnalysis/BleCmdDD.js";import{getFFAA80Async,resolveFFAA80,set_PlanCMD_FFAA}from"./BleCmdAnalysis/BleCmdFFAA.js";import{getCMDESInfoAsync}from"./BleCmdAnalysis/BleCmdHVES.js";import{sleep}from"./BleDataProcess.js";import{decrypt}from"./rsaEncrypt.js";import{Transfer}from"./Transfer.js";class MqttServer{constructor({mqttClient:mqttClient={},MQTT_HOST:MQTT_HOST="wxs://mqtt.jiabaida.com/mqtt",DELAY_TIME:DELAY_TIME=300,networkModelUrl:networkModelUrl="https://cloud.jiabaida.com/bluetooth/server/device/networkModel",request:request}){this.timer=null,this.productKey="bms_wifi",this.is0f=!1,this.publishObj={},this.cmdCode="",this.callbackId="",this.mqttCode="",this.mqttPublish=!1,this.mqttClient=mqttClient,this.MQTT_HOST=MQTT_HOST,this.DELAY_TIME=DELAY_TIME,this.networkModelUrl=networkModelUrl,this.request=request}async getParams(item){try{return await this.request({url:`${this.networkModelUrl}?macAddr=${item.macAddr}`,method:"get"})}catch(error){throw console.error("getnetworkModel-error",error),error}}async connectMqtt(deviceObj){try{const modalData=await this.getParams(deviceObj);if(!modalData||200!==modalData.data.code)return;const mqttParam=modalData.data.data,clientId=decrypt(mqttParam.clientId),username=mqttParam.mqttUsername,password=decrypt(mqttParam.mqttSecret);console.log("连接 MQTT...");const options={clean:!0,connectTimeout:4e3,clientId:clientId,username:username,password:SHA256(password).toString(),deviceId:deviceObj.deviceId},client=mqtt.connect(this.MQTT_HOST,options);console.log("MQTT 客户端创建成功:",client),client.on("connect",res=>{console.log("res连接成功",res),client.productKey=this.productKey,this.handleMqttConnect(client,deviceObj)}),client.on("message",(topic,message)=>{this.handleMqttMessage(topic,message,client)}),client.on("reconnect",res=>console.log("MQTT 重连中...",res,client)),client.on("close",res=>this.handleMqttClose(client,res)),client.on("offline",res=>console.log("MQTT 脱机状态",res,client)),client.on("error",res=>console.error("MQTT 连接错误",res,client)),client.on("disconnect",res=>console.log("MQTT 断开连接",res,client))}catch(e){console.error("MQTT 连接异常:",e)}}handleMqttConnect(client,deviceObj){console.log("MQTT 连接成功 client",client),console.log("MQTT 连接成功 deviceObj",deviceObj),this.storeMqttClient(client),this.publishInOrder(client,deviceObj).then(()=>this.subscribeInOrder(client))}storeMqttClient(client){this.mqttClient[`${client.options.deviceId}_mqtt`]=client,console.log("存储的 MQTT 客户端:",this.mqttClient)}getTopicsAndMessages(client,deviceObj){const{productType:productType,soc:soc,moduleType:moduleType,macAddr:macAddr}=deviceObj,message=JSON.stringify({productKey:productType,soc:soc,moduleTypeKey:moduleType,macAddr:macAddr});return[{topic:`/${client.productKey}/${client.options.clientId}/device/login`,message:message}]}async publishInOrder(client,deviceObj){const topicsAndMessages=this.getTopicsAndMessages(client,deviceObj);try{for(const item of topicsAndMessages)await new Promise(resolve=>{client.publish(item.topic,item.message,()=>{resolve()})})}catch(error){console.error(`处理发布时出现错误: ${error}`)}}getSubscribeTopics(client){const{productKey:productKey}=client,clientId=client.options.clientId;return[`/${productKey}/${clientId}/device/login/reply`,`/${productKey}/${clientId}/device/passthrough/reply`,`/${productKey}/${clientId}/plat/cmd`,`/${productKey}/${clientId}/plat/passthrough`]}async subscribeInOrder(client){const subscribeTopics=this.getSubscribeTopics(client);try{for(const topic of subscribeTopics)await new Promise((resolve,reject)=>{client.subscribe(topic,err=>{err?reject(err):resolve()})})}catch(error){console.error(`订阅主题时出现错误: ${error}`)}}handleMqttMessage(topic,message,client){const clientId=topic.split("/")[2];topic!==`/${(client=Object.values(this.mqttClient).find(c=>c?.options?.clientId===clientId)||client).productKey}/${client.options.clientId}/plat/passthrough`&&topic!==`/${client.productKey}/${client.options.clientId}/plat/cmd`||this.processMessageAsync(client,message.toString())}async processMessageAsync(client,message){const msg=JSON.parse(message);this.callbackId=msg.callbackId,this.cmdCode=msg.cmdCode;let resultArray=[],codeValue=[];if("jbdPWD"===this.cmdCode){const cmdContent={2:"FFAA23010125",3:"FFAA1F010121",4:"FFAA20010122",5:"FFAA23010226"}[msg.value];codeValue=cmdContent?cmdContent.split(","):[]}else codeValue=msg.value?msg.value.split(","):[],this.is0f=2===codeValue.length;resultArray=codeValue[0]?codeValue[0].match(/.{1,2}/g):[];try{"FF"===resultArray[0]?.toUpperCase()&&"AA"===resultArray[1]?.toUpperCase()||"78"===resultArray[1]?.toUpperCase()||resultArray[1]?.toUpperCase();const publishObj={deviceId:client.options.deviceId,clientId:client.options.clientId,productKey:client.productKey,callbackId:this.callbackId,cmdCode:this.cmdCode,is0f:this.is0f,isLast:msg.isLast};this.publishObj=publishObj,this.cmdCode.toLowerCase().includes("wifi_")?await this.publishATHandle(msg.value):(this.writePublishInfoCmd(resultArray),await sleep(this.DELAY_TIME))}catch(error){console.error("error: 处理后台发指令错误",error)}}async publishATHandle(ATvalue){const{deviceId:deviceId,cmdCode:cmdCode,callbackId:callbackId,productKey:productKey,clientId:clientId,isLast:isLast}=this.publishObj,client=this.mqttClient[`${deviceId}_mqtt`];try{if(client){const hex=await getFFAA80Async(deviceId,ATvalue),res=resolveFFAA80(hex);if(res&&res.moduleVersion){const value=res.moduleVersion;client.publish(`/${productKey}/${clientId}/plat/cmd/reply`,JSON.stringify({value:value,cmdCode:cmdCode,callbackId:callbackId}),()=>{})}}isLast&&(await sleep(300),this.mqttPublish=!1,uni.removeStorageSync&&uni.removeStorageSync(`${deviceId}_mqttPublish`))}catch(error){console.error(error)}}handleMqttClose(client,res){console.log("MQTT 连接关闭",res,client),client.end(()=>{this.mqttClient[`${client.options.deviceId}_mqtt`]=null})}async publishHandle(value,baseValue,voltageValue){const client=this.mqttClient[`${this.publishObj.deviceId}_mqtt`];this.publishObj.is0f&&(value=baseValue+","+voltageValue);const msg=JSON.stringify({value:value,cmdCode:this.publishObj.cmdCode,callbackId:this.publishObj.callbackId});client&&client.publish(`/${this.publishObj.productKey}/${this.publishObj.clientId}/plat/passthrough/reply`,msg,()=>{}),this.publishObj.isLast&&(await sleep(300),this.mqttPublish=!1,uni.removeStorageSync&&uni.removeStorageSync(`${this.publishObj.deviceId}_mqttPublish`))}publishPassthroughHandle({value:value,cmdCode:cmdCode},deviceId,timeOffset=3e4){const client=this.mqttClient[`${deviceId}_mqtt`];if(client){const clientTime=(new Date).getTime(),{laseCmdCode:laseCmdCode,lastPassthroughTime:lastPassthroughTime,clientId:clientId}=client?.options;if(laseCmdCode!=cmdCode||!(lastPassthroughTime&&clientTime-lastPassthroughTime<timeOffset)){const topic=`/${client?.productKey}/${clientId}/device/passthrough`,payload=JSON.stringify({value:value,cmdCode:cmdCode,clientTime:clientTime});client.publish(topic,payload,()=>{client.options.lastPassthroughTime=clientTime,client.options.laseCmdCode=cmdCode})}}}async writePublishInfoCmd(values){clearTimeout(this.timer),this.mqttPublish=!0,this.mqttCode=values[2];let res=null;res="FF"===values[0]?.toUpperCase()&&"AA"===values[1]?.toUpperCase()?await set_PlanCMD_FFAA(this.publishObj.deviceId,values.join("")):"78"===values[1]?.toUpperCase()||"50"===values[1]?.toUpperCase()?await getCMDESInfoAsync(this.publishObj.deviceId,values.join("")):await set_PlanCMD_DD(this.publishObj.deviceId,values.join(""));const content=res?.data||[];let code=Transfer.decimalToHex(content[1]);255==content[0]&&170==content[1]&&(code=Transfer.decimalToHex(content[2])),console.log("code: 回复的code",code),code.toUpperCase()==this.mqttCode.toUpperCase()&&this.publishHandle(res?.dataStr),this.timer=setTimeout(()=>{this.mqttPublish=!1},3e4)}}export{MqttServer};
1
+ import SHA256 from"crypto-js/sha256";import mqtt from"mqtt/dist/mqtt.min.js";import{set_PlanCMD_DD}from"./BleCmdAnalysis/BleCmdDD.js";import{getFFAA80Async,resolveFFAA80,set_PlanCMD_FFAA}from"./BleCmdAnalysis/BleCmdFFAA.js";import{getCMDESInfoAsync}from"./BleCmdAnalysis/BleCmdHVES.js";import{sleep}from"./BleDataProcess.js";import{decrypt}from"./rsaEncrypt.js";import{Transfer}from"./Transfer.js";class MqttServer{constructor({mqttClient:mqttClient={},MQTT_HOST:MQTT_HOST="wxs://mqtt.jiabaida.com/mqtt",DELAY_TIME:DELAY_TIME=300,networkModelUrl:networkModelUrl="https://cloud.jiabaida.com/bluetooth/server/device/networkModel",request:request,store:store=null}){this.timer=null,this.productKey="bms_wifi",this.is0f=!1,this.publishObj={},this.cmdCode="",this.callbackId="",this.mqttCode="",this.mqttPublish=!1,this.mqttClient=mqttClient,this.MQTT_HOST=MQTT_HOST,this.DELAY_TIME=DELAY_TIME,this.networkModelUrl=networkModelUrl,this.request=request,this.$store=store}async getParams(item){try{return await this.request({url:`${this.networkModelUrl}?macAddr=${item.macAddr}`,method:"get"})}catch(error){throw console.error("getnetworkModel-error",error),error}}async connectMqtt(deviceObj){try{const modalData=await this.getParams(deviceObj);if(!modalData||200!==modalData.data.code)return;const mqttParam=modalData.data.data,clientId=decrypt(mqttParam.clientId),username=mqttParam.mqttUsername,password=decrypt(mqttParam.mqttSecret);console.log("连接 MQTT...");const options={clean:!0,connectTimeout:4e3,clientId:clientId,username:username,password:SHA256(password).toString(),deviceId:deviceObj.deviceId},client=mqtt.connect(this.MQTT_HOST,options);console.log("MQTT 客户端创建成功:",client),client.on("connect",res=>{console.log("res连接成功",res),client.productKey=this.productKey,this.handleMqttConnect(client,deviceObj)}),client.on("message",(topic,message)=>{this.handleMqttMessage(topic,message,client)}),client.on("reconnect",res=>console.log("MQTT 重连中...",res,client)),client.on("close",res=>this.handleMqttClose(client,res)),client.on("offline",res=>console.log("MQTT 脱机状态",res,client)),client.on("error",res=>console.error("MQTT 连接错误",res,client)),client.on("disconnect",res=>console.log("MQTT 断开连接",res,client))}catch(e){console.error("MQTT 连接异常:",e)}}handleMqttConnect(client,deviceObj){console.log("MQTT 连接成功 client",client),console.log("MQTT 连接成功 deviceObj",deviceObj),this.storeMqttClient(client),this.publishInOrder(client,deviceObj).then(()=>this.subscribeInOrder(client))}storeMqttClient(client){this.mqttClient[`${client.options.deviceId}_mqtt`]=client,this.$store?.commit("setMqttClient",this.mqttClient),console.log("存储的 MQTT 客户端:",this.mqttClient)}getTopicsAndMessages(client,deviceObj){const{productType:productType,soc:soc,moduleType:moduleType,macAddr:macAddr}=deviceObj,message=JSON.stringify({productKey:productType,soc:soc,moduleTypeKey:moduleType,macAddr:macAddr});return[{topic:`/${client.productKey}/${client.options.clientId}/device/login`,message:message}]}async publishInOrder(client,deviceObj){const topicsAndMessages=this.getTopicsAndMessages(client,deviceObj);try{for(const item of topicsAndMessages)await new Promise(resolve=>{client.publish(item.topic,item.message,()=>{resolve()})})}catch(error){console.error(`处理发布时出现错误: ${error}`)}}getSubscribeTopics(client){const{productKey:productKey}=client,clientId=client.options.clientId;return[`/${productKey}/${clientId}/device/login/reply`,`/${productKey}/${clientId}/device/passthrough/reply`,`/${productKey}/${clientId}/plat/cmd`,`/${productKey}/${clientId}/plat/passthrough`]}async subscribeInOrder(client){const subscribeTopics=this.getSubscribeTopics(client);try{for(const topic of subscribeTopics)await new Promise((resolve,reject)=>{client.subscribe(topic,err=>{err?reject(err):resolve()})})}catch(error){console.error(`订阅主题时出现错误: ${error}`)}}handleMqttMessage(topic,message,client){const clientId=topic.split("/")[2];topic!==`/${(client=Object.values(this.mqttClient).find(c=>c?.options?.clientId===clientId)||client).productKey}/${client.options.clientId}/plat/passthrough`&&topic!==`/${client.productKey}/${client.options.clientId}/plat/cmd`||this.processMessageAsync(client,message.toString())}async processMessageAsync(client,message){const msg=JSON.parse(message);this.callbackId=msg.callbackId,this.cmdCode=msg.cmdCode;let resultArray=[],codeValue=[];if("jbdPWD"===this.cmdCode){const cmdContent={2:"FFAA23010125",3:"FFAA1F010121",4:"FFAA20010122",5:"FFAA23010226"}[msg.value];codeValue=cmdContent?cmdContent.split(","):[]}else codeValue=msg.value?msg.value.split(","):[],this.is0f=2===codeValue.length;resultArray=codeValue[0]?codeValue[0].match(/.{1,2}/g):[];try{"FF"===resultArray[0]?.toUpperCase()&&"AA"===resultArray[1]?.toUpperCase()||"78"===resultArray[1]?.toUpperCase()||resultArray[1]?.toUpperCase();const publishObj={deviceId:client.options.deviceId,clientId:client.options.clientId,productKey:client.productKey,callbackId:this.callbackId,cmdCode:this.cmdCode,is0f:this.is0f,isLast:msg.isLast};this.publishObj=publishObj,this.cmdCode.toLowerCase().includes("wifi_")?await this.publishATHandle(msg.value):(this.writePublishInfoCmd(resultArray),await sleep(this.DELAY_TIME))}catch(error){console.error("error: 处理后台发指令错误",error)}}async publishATHandle(ATvalue){const{deviceId:deviceId,cmdCode:cmdCode,callbackId:callbackId,productKey:productKey,clientId:clientId,isLast:isLast}=this.publishObj,client=this.mqttClient[`${deviceId}_mqtt`];try{if(client){const hex=await getFFAA80Async(deviceId,ATvalue),res=resolveFFAA80(hex);if(res&&res.moduleVersion){const value=res.moduleVersion;client.publish(`/${productKey}/${clientId}/plat/cmd/reply`,JSON.stringify({value:value,cmdCode:cmdCode,callbackId:callbackId}),()=>{})}}isLast&&(await sleep(300),this.mqttPublish=!1,this.$store?.commit("setMqttPublish",!1),uni.removeStorageSync&&uni.removeStorageSync(`${deviceId}_mqttPublish`))}catch(error){console.error(error)}}closeMqttByDeviceId(deviceId){const client=this.mqttClient[`${deviceId}_mqtt`];client&&client.end(()=>{this.mqttClient[`${deviceId}_mqtt`]=null,console.log(`MQTT 连接已关闭,设备ID: ${deviceId}`)})}handleMqttClose(client,res){console.log("MQTT 连接关闭",res,client),client.end(()=>{this.mqttClient[`${client.options.deviceId}_mqtt`]=null,this.$store?.commit("setMqttClient",this.mqttClient)})}async publishHandle(value,baseValue,voltageValue){const client=this.mqttClient[`${this.publishObj.deviceId}_mqtt`];this.publishObj.is0f&&(value=baseValue+","+voltageValue);const msg=JSON.stringify({value:value,cmdCode:this.publishObj.cmdCode,callbackId:this.publishObj.callbackId});client&&client.publish(`/${this.publishObj.productKey}/${this.publishObj.clientId}/plat/passthrough/reply`,msg,()=>{}),this.publishObj.isLast&&(await sleep(300),this.mqttPublish=!1,this.$store?.commit("setMqttPublish",!1),uni.removeStorageSync&&uni.removeStorageSync(`${this.publishObj.deviceId}_mqttPublish`))}publishPassthroughHandle({value:value,cmdCode:cmdCode},deviceId,timeOffset=3e4){const client=this.mqttClient[`${deviceId}_mqtt`];if(client){const clientTime=(new Date).getTime(),{laseCmdCode:laseCmdCode,lastPassthroughTime:lastPassthroughTime,clientId:clientId}=client?.options;if(laseCmdCode!=cmdCode||!(lastPassthroughTime&&clientTime-lastPassthroughTime<timeOffset)){const topic=`/${client?.productKey}/${clientId}/device/passthrough`,payload=JSON.stringify({value:value,cmdCode:cmdCode,clientTime:clientTime});client.publish(topic,payload,()=>{client.options.lastPassthroughTime=clientTime,client.options.laseCmdCode=cmdCode})}}}async writePublishInfoCmd(values){clearTimeout(this.timer),this.mqttPublish=!0,this.$store?.commit("setMqttPublish",!0),this.mqttCode=values[2];let res=null;res="FF"===values[0]?.toUpperCase()&&"AA"===values[1]?.toUpperCase()?await set_PlanCMD_FFAA(this.publishObj.deviceId,values.join("")):"78"===values[1]?.toUpperCase()||"50"===values[1]?.toUpperCase()?await getCMDESInfoAsync(this.publishObj.deviceId,values.join("")):await set_PlanCMD_DD(this.publishObj.deviceId,values.join(""));const content=res?.data||[];let code=Transfer.decimalToHex(content[1]);255==content[0]&&170==content[1]&&(code=Transfer.decimalToHex(content[2])),console.log("code: 回复的code",code),code.toUpperCase()==this.mqttCode.toUpperCase()&&this.publishHandle(res?.dataStr),this.timer=setTimeout(()=>{this.mqttPublish=!1,this.$store?.commit("setMqttPublish",!1)},3e4)}}export{MqttServer};
@@ -0,0 +1 @@
1
+ import{reactive}from"vue";import{set_PlanCMD_DD}from"./BleCmdAnalysis/BleCmdDD.js";import{set_PlanCMD_FFAA}from"./BleCmdAnalysis/BleCmdFFAA.js";import{getCMDESInfoAsync}from"./BleCmdAnalysis/BleCmdHVES.js";import{sleep}from"./BleDataProcess.js";import Queue from"./Queue.js";import{Transfer}from"./Transfer.js";const tcpSend=reactive({isSending:!1,isLast:!1,code:null,hasHeartbeat:!1,tcpClose:!1,devices:{}}),messageQueue=new Queue;let timer=null;const tcpServer={version:"2.8.2",socketOpen:!1,macAddr:"",txnNo:"",baseDelay:1e3,maxDelay:6e4,retryCount:0,url:{address:"cloud.jiabaida.com",port:10241},url1:{address:"192.168.80.36",port:10240},timers:{},heartBeatTimers:{},tcpSockets:{},isRetryings:{},socketOpens:{},async initTCPConnection(macAddr,deviceId){return console.log("macAddr: init-------tcp",macAddr,deviceId),new Promise((resolve,reject)=>{try{tcpSend.devices[macAddr]={macAddr:macAddr,deviceId:deviceId},this.tcpSockets[`${deviceId}_socket`]=wx.createTCPSocket(),console.log("this.tcpSockets[`${deviceId}_socket`]: ",this.tcpSockets[`${deviceId}_socket`]),this.tcpSockets[`${deviceId}_socket`].connect(this.url),this.tcpSockets[`${deviceId}_socket`].onConnect(()=>{this.listenerConnect(macAddr,deviceId),resolve(!0)}),this.tcpSockets[`${deviceId}_socket`].onMessage(message=>{console.log("接收到消息:",message);const intArr=Array.prototype.map.call(new Uint8Array(message.message),function(bit){return bit});let valueString=String.fromCharCode(...intArr);console.log(valueString,"valueString"),this.processMessageAsync(valueString)}),this.tcpSockets[`${deviceId}_socket`].onError(error=>{this.listenerError(macAddr,deviceId,error),reject(error)}),this.tcpSockets[`${deviceId}_socket`].onClose(this.listenerClose(deviceId))}catch(error){console.error("error: tcp连接失败",error),reject(error)}})},listenerConnect(macAddr,deviceId){this.socketOpens[`open_${deviceId}`]=!0,this.isRetryings[`retry_${deviceId}`]=!1,console.log("TCP 连接已建立"),clearInterval(this.timers[`timer_${deviceId}`]),this.timers[`timer_${deviceId}`]=null,this.sendHeartbeat(macAddr,deviceId)},listenerError(macAddr,deviceId,error){this.socketOpens[`open_${deviceId}`]=!1,console.log("TCP 连接错误:",deviceId,error),this.stopHeartBeat(deviceId),this.isRetryings[`retry_${deviceId}`]||(this.retryCount=0,this.reConnect(macAddr,deviceId,!0))},listenerClose(deviceId){this.socketOpens[`open_${deviceId}`]=!1,console.log("TCP 连接已关闭")},closeTcpSocket(deviceId){try{clearInterval(this.timers[`timer_${deviceId}`]),this.timers[`timer_${deviceId}`]=null,this.tcpSockets[`${deviceId}_socket`]&&(this.socketOpens[`open_${deviceId}`]=!1,this.stopHeartBeat(deviceId),this.tcpSockets[`${deviceId}_socket`].offMessage(),this.tcpSockets[`${deviceId}_socket`].offConnect(),this.tcpSockets[`${deviceId}_socket`].offClose(),this.tcpSockets[`${deviceId}_socket`].offError(),this.tcpSockets[`${deviceId}_socket`].close(),this.tcpSockets[`${deviceId}_socket`]=null)}catch(error){console.error("error: closeTcpSocket",error)}},async reConnect(macAddr,deviceId,closeSocket=!1){console.log("重连 this.macAddr",macAddr),this.isRetryings[`retry_${deviceId}`]=!0,closeSocket&&this.tcpSockets[`${deviceId}_socket`].close(),this.tcpSockets[`${deviceId}_socket`].connect(this.url);const delay=Math.min(this.baseDelay*Math.pow(2,this.retryCount),this.maxDelay);console.log(`准备 ${delay}ms 后重试...`),this.timers[`timer_${deviceId}`]=setTimeout(()=>{this.reConnect(macAddr,deviceId)},delay),this.retryCount++},sendHeartbeat(macAddr,deviceId){const heartbeatMsg={command:96,data:{token:uni.getStorageSync("token").replace("Bearer ",""),appVersion:"xiaoxiang:"+this.version,macAddr:macAddr},txnNo:+new Date,isAnonymous:0};console.log("heartbeatMsg: ",heartbeatMsg),tcpSend.hasHeartbeat=!1,this.tcpSockets[`${deviceId}_socket`].write(JSON.stringify(heartbeatMsg)),this.heartBeatTimers[`heartTimer_${deviceId}`]=setInterval(()=>{heartbeatMsg.txnNo=+new Date,tcpSend.hasHeartbeat=!1,this.tcpSockets[`${deviceId}_socket`].write(JSON.stringify(heartbeatMsg))},3e4)},stopHeartBeat(deviceId){this.heartBeatTimers[`heartTimer_${deviceId}`]&&(clearInterval(this.heartBeatTimers[`heartTimer_${deviceId}`]),this.heartBeatTimers[`heartTimer_${deviceId}`]=null)},sendReportData(data){const reportData={command:999,data:{value:data.value,cmdCode:"jbd0F",bluetoothName:data.bluetoothName},macAddr:data.macAddr,txnNo:+new Date};console.log(reportData,"reportData111上报基础数据"),this.tcpSockets[`${data.deviceId}_socket`].write(JSON.stringify(reportData))},sendWriteReportData(data,deviceId){console.warn("执行后上报数据data: ",data);const reportData={command:121,data:{macAddr:this.macAddr,content:data},txnNo:this.txnNo};this.tcpSockets[`${deviceId}_socket`].write(JSON.stringify(reportData)),tcpSend.isLast&&(tcpSend.isSending=!1)},processQueue(){tcpSend.isSending||this.processNextMessage()},async processNextMessage(){if(messageQueue.isEmpty())await sleep(300),tcpSend.isSending=!1;else{const message=messageQueue.dequeue();this.processMessageAsync(message).then(()=>{this.processNextMessage()})}},async processMessageAsync(message){return clearTimeout(timer),new Promise(async resolve=>{try{console.log("Message processed:",message);let msgObj=JSON.parse(message);if(console.warn("----------msgObj后台下发的指令: -----------",msgObj),120==msgObj.command){let value=msgObj.data.content;if(!value)return;let resultArray=value.match(/.{1,2}/g);console.log("resultArray: ",resultArray),this.macAddr=msgObj.data.macAddr;let deviceId=null;for(let key in tcpSend.devices)tcpSend.devices[key].macAddr==this.macAddr&&(deviceId=tcpSend.devices[key].deviceId);console.log("deviceId: ",deviceId),this.txnNo=msgObj.txnNo,tcpSend.isLast=msgObj.isLast,tcpSend.isSending=!0,tcpSend.code=resultArray[2];let length=resultArray.length;const buffer=new ArrayBuffer(length),dataView=new DataView(buffer);resultArray.forEach((el,index)=>{dataView.setUint8(index,"0x"+el)}),console.log(buffer,"读取指令-----------------------");let res=null;res="FF"===resultArray[0]?.toUpperCase()&&"AA"===resultArray[1]?.toUpperCase()?await set_PlanCMD_FFAA(deviceId,resultArray.join("")):"78"===resultArray[1]?.toUpperCase()||"50"===resultArray[1]?.toUpperCase()?await getCMDESInfoAsync(deviceId,resultArray.join("")):await set_PlanCMD_DD(deviceId,resultArray.join(""));const content=res?.data||[];let code=Transfer.decimalToHex(content[1]);255==content[0]&&170==content[1]&&(code=Transfer.decimalToHex(content[2])),console.log("code: 回复的code",code),code.toUpperCase()==tcpSend?.code?.toUpperCase()&&this.sendWriteReportData(content,deviceId)}else 97==msgObj.command&&(tcpSend.hasHeartbeat=!0);timer=setTimeout(()=>{tcpSend.isSending=!1},3e4),resolve(!0)}catch(error){console.log("error: ",error)}})}};export{tcpSend,tcpServer};
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- export{chunk,unique}from"./core/array.js";export{checkBluetoothStatus,checkLocationStatus,connectAsync,createBLEConnection,disConnect,enhanceDevice,foundScanDevice,getBLEDeviceCharacteristics,getBLEDeviceServices,getBluetoothAdapterState,getBluetoothPermission,initBle,isInit,notify,onBLECharacteristicValueChange,onBLEConnectionStateChange,onBleChangedConnectionState,onBluetoothAdapterStateChange,onBluetoothDeviceFound,onFoundDevice,scanHandle,startDevicesDiscovery,stopBluetoothDevicesDiscovery}from"./core/BleApiManager.js";export{ab2decimalArr,ab2hex,arrayBufferToHexArray,base64ToHexArray,checkSum,crc16modbus,crcCheckSum,decimalToHex,decimalToHex0x,decimalToTwoByteHexArray,extractBits,fromBCD,generateCheckSum,generateCrc16modbusCheck,generateCrcCheckSum,getParamBaseValue,hex2Ascii,hex2Binary,hex2string,hexArr2Assic,hexArr2ab,hexArr2string,hexArrayToModuleArrayBuffer,hexStrAscii,hexStringToBinary,hexToDecimal,isWithin30Minutes,parseDateTime,sleep,string2hexArr,stringToTwoHexArray,toBCD}from"./core/BleDataProcess.js";export{eventBus,formatTimeHHmm,getOS,getPlatform,inArray,isEmpty,isNotEmpty}from"./core/commonfun.js";export{ALLOWED_MAC_PREFIX,APP_KEY_STATUS,extractModuleInfo,getRandomNum,getTypeBuyCmd,handleNewAppKey,handleOldAppKey,sendAppKey,sendEnableOrVerifyKey,sendOldAppKey,sendVerifyPwd,sendWrite1LevelPwd,verify3LevelPassword,verifyMacAddrAndKey}from"./core/keyAndPwdManager.js";export{MqttServer}from"./core/mqttServer.js";export{OTAUpgrade}from"./core/OtaUpgrade.js";export{decrypt,decrypt2,decryptUsername,encrypt}from"./core/rsaEncrypt.js";export{TelinkApi}from"./core/TelinkApi.js";export{BLE,Logger,Observer,Transfer}from"./core/Transfer.js";export{getBaseInfo,getBaseParams,getResistance}from"./core/BleCmdAnalysis/BaseParamProtocol.js";export{getData,setMTUAsync}from"./core/BleCmdAnalysis/BleCmdAnalysis.js";export{activateAsync,enterFactory,existFactory,get3B3CAsync,get3B3CInfo,getChipTypeAsync,getDD5A0AAsync,getDD5A0EAsync,getDD5A17Async,getDD5AAllAsync,getDD5AE0Async,getDD5AE1Async,getDD5AE4Async,getDD5AFAAsync,getDD5AFBAsync,getDDA4F0Async,getDDA503Async,getDDA504Async,getDDA505Async,getDDA506Async,getDDA507Async,getDDA508Async,getDDA5DCAsync,getDDA5FAAsync,getDDA5OldAsync,getProtectCountCmd,readExistFactory,resetCapacity,resolve3B3C,resolveBMSCmd,resolveBaseDD,resolveDD5A0A,resolveDDA4F0,resolveDDA500,resolveDDA503,resolveDDA504,resolveDDA505,resolveDDA506,resolveDDA508,resolveDDA5DC,resolveDDA5FA,resolveProtections,sendBMSAsync,setDD5AE3sync,setDDA5FAAsync,setDDA5OldAsync,set_PlanCMD_3B3C,set_PlanCMD_DD}from"./core/BleCmdAnalysis/BleCmdDD.js";export{getDDA420Async,getDDA421Async,getDDA422Async,getDDA423Async,getDDA425Async,getDDA426Async,getDDA427Async,getDDA429Async,resolveDDA420,resolveDDA421,resolveDDA422,resolveDDA423,resolveDDA425,resolveDDA426,resolveDDA427,resolveDDA429}from"./core/BleCmdAnalysis/BleCmdDDA4.js";export{clearPrimaryKey,getBluetoothName,getBroadcastDataCmd,getFFAA03Async,getFFAA17Async,getFFAA25Async,getFFAA26Async,getFFAA80Async,getFFAAKeyAsync,getWiFiIP,resetFactoryData,resetSecondaryKey,resolveFFAA25,resolveFFAA26,resolveFFAA80,resolveFFAAKey,setBluetoothName,setWiFi,setWiFiSta,set_PlanCMD_FFAA,set_PlanCMD_FFAA80}from"./core/BleCmdAnalysis/BleCmdFFAA.js";export{getCMDESInfoAsync,getHVESInfoAsync,resolveHVESBMUInfo,resolveHVESBaseInfo,resolveHVESCalibrationC1Info,resolveHVESCalibrationC2Info,resolveHVESCalibrationConfigInfo,resolveHVESCalibrationInfo,resolveHVESCtInfo,resolveHVESDisCtInfo,resolveHVESElectrodeHTInfo,resolveHVESEtInfo,resolveHVESInsulationLRInfo,resolveHVESLSocInfo,resolveHVESMonoVolInfo,resolveHVESOeInfo,resolveHVESOtRisingInfo,resolveHVESOtrInfo,resolveHVESOvrInfo,resolveHVESPackInfo,resolveHVESParamsInfo,resolveHVESSumInfo,resolveHVESSumVolInfo,resolveHVESVersionInfo}from"./core/BleCmdAnalysis/BleCmdHVES.js";export{HostProtocol}from"./core/BleCmdAnalysis/ESHostProtocol.js";export{getSysParamCmd,readParamCmd,setCapacityParamCmd,setParamCmd,setSysParamCmd}from"./core/BleCmdAnalysis/readAndSetParam.js";export{batteryInfoJson,capInfoJson,capVolInfoJson,currentInfoJson,equalizerFunJson,funcAndTempFuncJson,funcJson,systemJson,tempFuncJson,tempInfoJson,voltageInfoJson}from"./core/dataJson/baseParamsJson.js";
1
+ export{chunk,unique}from"./core/array.js";export{checkBluetoothStatus,checkLocationStatus,connectAsync,createBLEConnection,disConnect,enhanceDevice,foundScanDevice,getBLEDeviceCharacteristics,getBLEDeviceServices,getBluetoothAdapterState,getBluetoothPermission,initBle,isInit,notify,onBLECharacteristicValueChange,onBLEConnectionStateChange,onBleChangedConnectionState,onBluetoothAdapterStateChange,onBluetoothDeviceFound,onFoundDevice,scanHandle,startDevicesDiscovery,stopBluetoothDevicesDiscovery}from"./core/BleApiManager.js";export{ab2decimalArr,ab2hex,arrayBufferToHexArray,base64ToHexArray,checkSum,crc16modbus,crcCheckSum,decimalToHex,decimalToHex0x,decimalToTwoByteHexArray,extractBits,fromBCD,generateCheckSum,generateCrc16modbusCheck,generateCrcCheckSum,getParamBaseValue,hex2Ascii,hex2Binary,hex2string,hexArr2Assic,hexArr2ab,hexArr2string,hexArrayToModuleArrayBuffer,hexStrAscii,hexStringToBinary,hexToDecimal,isWithin30Minutes,parseDateTime,sleep,string2hexArr,stringToTwoHexArray,toBCD}from"./core/BleDataProcess.js";export{eventBus,formatTimeHHmm,getOS,getPlatform,inArray,isEmpty,isNotEmpty}from"./core/commonfun.js";export{ALLOWED_MAC_PREFIX,APP_KEY_STATUS,extractModuleInfo,getRandomNum,getTypeBuyCmd,handleNewAppKey,handleOldAppKey,sendAppKey,sendEnableOrVerifyKey,sendOldAppKey,sendVerifyPwd,sendWrite1LevelPwd,verify3LevelPassword,verifyMacAddrAndKey}from"./core/keyAndPwdManager.js";export{MqttServer}from"./core/mqttServer.js";export{OTAUpgrade}from"./core/OtaUpgrade.js";export{decrypt,decrypt2,decryptUsername,encrypt}from"./core/rsaEncrypt.js";export{tcpSend,tcpServer}from"./core/tcpServer.js";export{TelinkApi}from"./core/TelinkApi.js";export{BLE,Logger,Observer,Transfer}from"./core/Transfer.js";export{getBaseInfo,getBaseParams,getResistance}from"./core/BleCmdAnalysis/BaseParamProtocol.js";export{getData,setMTUAsync}from"./core/BleCmdAnalysis/BleCmdAnalysis.js";export{activateAsync,enterFactory,existFactory,get3B3CAsync,get3B3CInfo,getChipTypeAsync,getDD5A0AAsync,getDD5A0EAsync,getDD5A17Async,getDD5AAllAsync,getDD5AE0Async,getDD5AE1Async,getDD5AE4Async,getDD5AFAAsync,getDD5AFBAsync,getDDA4F0Async,getDDA503Async,getDDA504Async,getDDA505Async,getDDA506Async,getDDA507Async,getDDA508Async,getDDA5DCAsync,getDDA5FAAsync,getDDA5OldAsync,getProtectCountCmd,readExistFactory,resetCapacity,resolve3B3C,resolveBMSCmd,resolveBaseDD,resolveDD5A0A,resolveDDA4F0,resolveDDA500,resolveDDA503,resolveDDA504,resolveDDA505,resolveDDA506,resolveDDA508,resolveDDA5DC,resolveDDA5FA,resolveProtections,sendBMSAsync,setDD5AE3sync,setDDA5FAAsync,setDDA5OldAsync,set_PlanCMD_3B3C,set_PlanCMD_DD}from"./core/BleCmdAnalysis/BleCmdDD.js";export{getDDA420Async,getDDA421Async,getDDA422Async,getDDA423Async,getDDA425Async,getDDA426Async,getDDA427Async,getDDA429Async,resolveDDA420,resolveDDA421,resolveDDA422,resolveDDA423,resolveDDA425,resolveDDA426,resolveDDA427,resolveDDA429}from"./core/BleCmdAnalysis/BleCmdDDA4.js";export{clearPrimaryKey,getBluetoothName,getBroadcastDataCmd,getFFAA03Async,getFFAA17Async,getFFAA25Async,getFFAA26Async,getFFAA80Async,getFFAAKeyAsync,getWiFiIP,resetFactoryData,resetSecondaryKey,resolveFFAA25,resolveFFAA26,resolveFFAA80,resolveFFAAKey,setBluetoothName,setWiFi,setWiFiSta,set_PlanCMD_FFAA,set_PlanCMD_FFAA80}from"./core/BleCmdAnalysis/BleCmdFFAA.js";export{getCMDESInfoAsync,getHVESInfoAsync,resolveHVESBMUInfo,resolveHVESBaseInfo,resolveHVESCalibrationC1Info,resolveHVESCalibrationC2Info,resolveHVESCalibrationConfigInfo,resolveHVESCalibrationInfo,resolveHVESCtInfo,resolveHVESDisCtInfo,resolveHVESElectrodeHTInfo,resolveHVESEtInfo,resolveHVESInsulationLRInfo,resolveHVESLSocInfo,resolveHVESMonoVolInfo,resolveHVESOeInfo,resolveHVESOtRisingInfo,resolveHVESOtrInfo,resolveHVESOvrInfo,resolveHVESPackInfo,resolveHVESParamsInfo,resolveHVESSumInfo,resolveHVESSumVolInfo,resolveHVESVersionInfo}from"./core/BleCmdAnalysis/BleCmdHVES.js";export{HostProtocol}from"./core/BleCmdAnalysis/ESHostProtocol.js";export{controlSwitch,getE1Cmd,getSysParamCmd,readParamCmd,setCapacityParamCmd,setParamCmd,setSysParamCmd}from"./core/BleCmdAnalysis/readAndSetParam.js";export{batteryInfoJson,capInfoJson,capVolInfoJson,currentInfoJson,equalizerFunJson,funcAndTempFuncJson,funcJson,systemJson,tempFuncJson,tempInfoJson,voltageInfoJson}from"./core/dataJson/baseParamsJson.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jiabaida/tools",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "exports": {
@@ -1,7 +1,7 @@
1
- import { getSysParamCmd } from './readAndSetParam'
2
1
  import { decimalToHex, hexToDecimal } from '../BleDataProcess';
3
- import { batteryInfoJson, capInfoJson, voltageInfoJson,currentInfoJson, tempInfoJson, equalizerFunJson, capVolInfoJson, funcJson, tempFuncJson, systemJson, funcAndTempFuncJson } from '../dataJson/baseParamsJson.js';
4
- import { readExistFactory, getProtectCountCmd, enterFactory } from './BleCmdDD.js'
2
+ import { batteryInfoJson, capInfoJson, capVolInfoJson, currentInfoJson, equalizerFunJson, funcAndTempFuncJson, funcJson, systemJson, tempFuncJson, tempInfoJson, voltageInfoJson } from '../dataJson/baseParamsJson.js';
3
+ import { enterFactory, getProtectCountCmd, readExistFactory } from './BleCmdDD.js';
4
+ import { getSysParamCmd } from './readAndSetParam';
5
5
 
6
6
  /**
7
7
  *
@@ -117,13 +117,22 @@ export const getBaseParams = async (chipType, deviceData, index, paramObj) => {
117
117
  case 2:
118
118
  let datasInfo2 = {}
119
119
  if (chipType) {
120
- /**连续读两个参数 */
121
- const capData = await getSysParamCmd(chipType, deviceId, { ...capInfoJson[0], paramLength: 4 })
122
- console.warn('capData: ', capData);
123
- datasInfo2['normCap'] = capData?.slice(0, 2)
124
- datasInfo2['cycleCap'] = capData?.slice(2, 4)
125
- const capData2 = await getSysParamCmd(chipType, deviceId, capInfoJson[2])
126
- datasInfo2['fullCap'] = capData2?.slice(0, 2)
120
+
121
+ /**读取标称容量:需要读取paramNo 0(低16位)和155(高16位) */
122
+ const normCapLow = await getSysParamCmd(chipType, deviceId, { paramNo: 0, paramLength: 2 })
123
+ const normCapHigh = await getSysParamCmd(chipType, deviceId, { paramNo: 155, paramLength: 2 })
124
+ console.log('normCapLow: ', normCapLow, 'normCapHigh: ', normCapHigh);
125
+ // 合并高低位,每个都只取前2个字节
126
+ datasInfo2['normCap'] = [...(normCapLow?.slice(0, 2) || []), ...(normCapHigh?.slice(0, 2) || [])]
127
+
128
+ const cycleCapData = await getSysParamCmd(chipType, deviceId, capInfoJson[1])
129
+ datasInfo2['cycleCap'] = cycleCapData?.slice(0, 2)
130
+
131
+ /**读取满充容量:需要读取paramNo 112(低16位)和156(高16位) */
132
+ const fullCapLow = await getSysParamCmd(chipType, deviceId, { paramNo: 112, paramLength: 2 })
133
+ const fullCapHigh = await getSysParamCmd(chipType, deviceId, { paramNo: 156, paramLength: 2 })
134
+ console.log('fullCapLow: ', fullCapLow, 'fullCapHigh: ', fullCapHigh);
135
+ datasInfo2['fullCap'] = [...(fullCapLow?.slice(0, 2) || []), ...(fullCapHigh?.slice(0, 2) || [])]
127
136
  } else {
128
137
  await sendCmdSeq(datasInfo2, chipType, deviceId, capInfoJson)
129
138
  }
@@ -378,9 +387,59 @@ function toHexString(arr) {
378
387
  }
379
388
  const getCapInfo = async (datas) => {
380
389
  console.log('datas: ', datas);
381
- const normCap = format(datas.normCap, 0.01, 0, 2)
390
+ // 标称容量:低16位(前2字节)+ 高16位(后2字节),单位是0.01AH
391
+ let normCap = null;
392
+ if (datas.normCap && datas.normCap.length >= 4) {
393
+ console.log('normCap原始数据: ', datas.normCap);
394
+ // 读取低16位(前两个字节)- 大端序
395
+ const lowBytes = datas.normCap.slice(0, 2);
396
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
397
+ console.log('normCap lowValue: ', lowValue);
398
+
399
+ // 读取高16位(后两个字节)- 大端序
400
+ const highBytes = datas.normCap.slice(2, 4);
401
+ const highValue = (highBytes[0] << 8) | highBytes[1];
402
+ console.log('normCap highValue: ', highValue);
403
+
404
+ // 合并高低位:(高位 << 16) | 低位
405
+ const totalValue = (highValue << 16) | lowValue;
406
+ console.log('normCap totalValue: ', totalValue);
407
+ normCap = Number((totalValue * 0.01).toFixed(2));
408
+ console.log('normCap最终值: ', normCap);
409
+ } else if (datas.normCap && datas.normCap.length >= 2) {
410
+ // 兼容旧协议,只有低16位 - 大端序
411
+ const lowBytes = datas.normCap.slice(0, 2);
412
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
413
+ normCap = Number((lowValue * 0.01).toFixed(2));
414
+ }
415
+
382
416
  const cycleCap = format(datas.cycleCap, 0.01, 0, 2)
383
- const fullCap = format(datas.fullCap, 0.01, 0, 2)
417
+
418
+ // 满充容量:低16位(前2字节)+ 高16位(后2字节),单位是0.01AH
419
+ let fullCap = null;
420
+ if (datas.fullCap && datas.fullCap.length >= 4) {
421
+ console.log('fullCap原始数据: ', datas.fullCap);
422
+ // 读取低16位(前两个字节)- 大端序
423
+ const lowBytes = datas.fullCap.slice(0, 2);
424
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
425
+ console.log('fullCap lowValue: ', lowValue);
426
+
427
+ // 读取高16位(后两个字节)- 大端序
428
+ const highBytes = datas.fullCap.slice(2, 4);
429
+ const highValue = (highBytes[0] << 8) | highBytes[1];
430
+ console.log('fullCap highValue: ', highValue);
431
+
432
+ // 合并高低位:(高位 << 16) | 低位
433
+ const totalValue = (highValue << 16) | lowValue;
434
+ console.log('fullCap totalValue: ', totalValue);
435
+ fullCap = Number((totalValue * 0.01).toFixed(2));
436
+ console.log('fullCap最终值: ', fullCap);
437
+ } else if (datas.fullCap && datas.fullCap.length >= 2) {
438
+ // 兼容旧协议,只有低16位 - 大端序
439
+ const lowBytes = datas.fullCap.slice(0, 2);
440
+ const lowValue = (lowBytes[0] << 8) | lowBytes[1];
441
+ fullCap = Number((lowValue * 0.01).toFixed(2));
442
+ }
384
443
  return {
385
444
  normCap,
386
445
  cycleCap,
@@ -1,7 +1,8 @@
1
1
  import { decimalToHex, fromBCD, generateCrc16modbusCheck, generateCrcCheckSum, hex2string, hexArr2Assic, hexArr2string, hexToDecimal, isWithin30Minutes, sleep, stringToTwoHexArray, toBCD } from '../BleDataProcess';
2
2
  import { getData } from './BleCmdAnalysis.js';
3
3
  import { getFFAA80Async, resolveFFAA80 } from './BleCmdFFAA.js';
4
-
4
+ import { controlSwitch } from './readAndSetParam.js';
5
+
5
6
  // #region 进出工厂
6
7
  /**进工厂 */
7
8
  export const enterFactory = async (deviceId) => {
@@ -358,6 +359,9 @@ export const resolveDDA503 = (data) => {
358
359
  name: index + 1,
359
360
  value: item,
360
361
  }));
362
+ const hasProtocol =
363
+ data[3] + 7 >= humidityIndex + 11 + 3 + 1;
364
+ const protocolVersion = data[humidityIndex + 11];
361
365
  return {
362
366
  cmdResp03,
363
367
  status: hex2string(data[2]),
@@ -391,6 +395,8 @@ export const resolveDDA503 = (data) => {
391
395
  fahTempList,
392
396
  fet,
393
397
  seriesNum,
398
+ hasProtocol,
399
+ protocolVersion
394
400
  };
395
401
  }
396
402
 
@@ -1245,18 +1251,71 @@ export const get3B3CInfo = ({ deviceId, macAddr, moduleType, productType }) => {
1245
1251
 
1246
1252
  // #region 发送设备激活指令
1247
1253
  export const activateAsync = async (deviceId) => {
1248
- const startTime = +new Date();
1249
- const disChargMOSHex = await getDD5AFBAsync(deviceId, '0x00', '0x00');
1250
- const disChargMOSRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1251
- const disChargEndTime = +new Date();
1252
- const activeHex = await getDD5AFBAsync(deviceId, '0x05', '0x01');
1253
- const activeRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1254
- let baseInfo = null
1255
- const endTime = +new Date();
1256
- await sleep(300)
1257
- baseInfo = await getDDA503Async(deviceId);
1258
- const voltageInfo = await getDDA504Async(deviceId);
1259
- return { disChargMOSHex, disChargMOSRes, activeHex, activeRes, baseInfo, voltageInfo, startTime, disChargEndTime, endTime };
1254
+ // const startTime = +new Date();
1255
+ // const disChargMOSHex = await getDD5AFBAsync(deviceId, '0x00', '0x00');
1256
+ // const disChargMOSRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1257
+ // const disChargEndTime = +new Date();
1258
+ // const activeHex = await getDD5AFBAsync(deviceId, '0x05', '0x01');
1259
+ // const activeRes = resolveBaseDD(disChargMOSHex)?.dataStr;
1260
+ // let baseInfo = null
1261
+ // const endTime = +new Date();
1262
+ // await sleep(300)
1263
+ // baseInfo = await getDDA503Async(deviceId);
1264
+ // const voltageInfo = await getDDA504Async(deviceId);
1265
+ // return { disChargMOSHex, disChargMOSRes, activeHex, activeRes, baseInfo, voltageInfo, startTime, disChargEndTime, endTime };
1266
+ try {
1267
+ const startTime = +new Date();
1268
+ let acStatus = false // 激活结果
1269
+ // 发送打开放电MOS指令
1270
+ const mosRes = await controlSwitch(
1271
+ deviceId,
1272
+ '0x00',
1273
+ true,
1274
+ true,
1275
+ );
1276
+ const disChargMOSRes = mosRes?.dataStr;
1277
+ const disChargEndTime = +new Date();
1278
+ // 发送激活指令
1279
+ const activeHex = await getDD5AFBAsync(deviceId, '0x05', '0x01');
1280
+ const activeResult = resolveBaseDD(activeHex);
1281
+ console.log('激活指令结果: ', { activeHex, activeResult });
1282
+ const activeRes = activeResult?.dataStr;
1283
+ let endTime = +new Date();
1284
+ let baseInfo = null
1285
+ let voltageInfo = null
1286
+ let steps = []
1287
+ if (activeResult?.status == '00') {
1288
+ steps.push(4)
1289
+ acStatus = true
1290
+ } else if (activeResult?.status == '81' || activeResult?.status == '84') {//不支持激活指令,判断开关执行结果
1291
+ if (mosRes?.status == '00') {
1292
+ acStatus = true
1293
+ steps.push(5)
1294
+ } else {
1295
+ acStatus = false
1296
+ steps.push(10)
1297
+ }
1298
+ } else if (activeResult?.status == '82' || activeResult?.status == '83') { // 激活指令执行失败
1299
+ acStatus = false
1300
+ steps.push(6)
1301
+ } else if (!activeResult || activeResult == null) { //激活无响应
1302
+ await sleep(300)
1303
+ const baseInfo = await getDDA503Async(deviceId);
1304
+ // 读取03指令后判断放电MOS是否打开,若打开则激活成功
1305
+ if (baseInfo?.dischargeSwitch) {
1306
+ acStatus = true
1307
+ steps.push(7)
1308
+ } else {
1309
+ acStatus = false
1310
+ steps.push(8)
1311
+ }
1312
+ endTime = +new Date()
1313
+ }
1314
+ return { disChargMOSRes, activeHex, activeRes, baseInfo, voltageInfo, startTime, disChargEndTime, endTime, acStatus, steps };
1315
+ } catch (error) {
1316
+ console.log("🚀 ~ BleApiManager ~ activateAsync ~ error:", error)
1317
+ return null
1318
+ }
1260
1319
  }
1261
1320
 
1262
1321
  // #region 获取均衡线电阻 DC 指令