@jiabaida/tools 1.1.0 → 1.1.2
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.
- package/dist/cjs/core/BleApiManager.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdAnalysis.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/BleCmdDD.js +1 -1
- package/dist/cjs/core/BleCmdAnalysis/readAndSetParam.js +1 -1
- package/dist/cjs/core/OtaUpgrade.js +1 -1
- package/dist/cjs/core/mqttServer.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/core/BleApiManager.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdAnalysis.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/BleCmdDD.js +1 -1
- package/dist/esm/core/BleCmdAnalysis/readAndSetParam.js +1 -1
- package/dist/esm/core/OtaUpgrade.js +1 -1
- package/dist/esm/core/mqttServer.js +1 -1
- package/dist/esm/index.js +1 -1
- package/package.json +1 -1
- package/src/core/BleApiManager.js +75 -60
- package/src/core/BleCmdAnalysis/BleCmdAnalysis.js +17 -9
- package/src/core/BleCmdAnalysis/BleCmdDD.js +2 -3
- package/src/core/BleCmdAnalysis/readAndSetParam.js +13 -2
- package/src/core/OtaUpgrade.js +15 -6
- package/src/core/mqttServer.js +8 -4
- package/src/index.js +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{hexArr2string,hex2string,decimalToHex,generateCrc16modbusCheck,hexArr2Assic,generateCrcCheckSum,hexToDecimal,stringToTwoHexArray,decimalToHex0x,sleep,fromBCD,isWithin30Minutes,toBCD}from"../BleDataProcess.js";import{getData}from"./BleCmdAnalysis.js";import{getFFAA80Async}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;){if(content.length<2){console.warn("Content too short to parse, remaining:",content);break}const len=Math.min(content[1]+2,content.length),[v1,v2,...v]=content.splice(0,len);if(v.length===v2){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))}else console.warn(`Data length mismatch for type ${v1}: expected ${v2}, got ${v.length}`)}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,eqCurr: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",decimalToHex0x(_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;try{if(!deviceId)throw new Error("deviceId required");const _ffaa_80=await getFFAA80Async(deviceId,"AT^VERSION?");console.warn("Report-3B3C _ffaa_80 ",{_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,reportData.bmsVersion=_3b3c?.sofewareV;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
|
+
import{hexArr2string,hex2string,decimalToHex,generateCrc16modbusCheck,hexArr2Assic,generateCrcCheckSum,hexToDecimal,stringToTwoHexArray,decimalToHex0x,sleep,fromBCD,isWithin30Minutes,toBCD}from"../BleDataProcess.js";import{getData}from"./BleCmdAnalysis.js";import{getFFAA80Async}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;){if(content.length<2){console.warn("Content too short to parse, remaining:",content);break}const len=Math.min(content[1]+2,content.length),[v1,v2,...v]=content.splice(0,len);if(v.length===v2){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))}else console.warn(`Data length mismatch for type ${v1}: expected ${v2}, got ${v.length}`)}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",decimalToHex0x(_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;try{if(!deviceId)throw new Error("deviceId required");const _ffaa_80=await getFFAA80Async(deviceId,"AT^VERSION?");console.warn("Report-3B3C _ffaa_80 ",{_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,reportData.bmsVersion=_3b3c?.sofewareV;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,decimalToHex0x,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=decimalToHex0x(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.warn("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=Number(paramInfo?.paramValue||paramInfo.newValue)/Number(paramInfo?.divisor||1);console.log("value: ",value),paramInfo.isTemp&&(value=2731+10*Number(paramInfo.newValue)),value=Math.round(value);let valuesHexs=[];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={paramNo:1,oldParamNo:"0x11",values:.8*values,paramLength:2},full={paramNo:112,oldParamNo:"0x10",values:values,paramLength:2},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))},handleCapacityParam=async(paramObj,lowParamNo,highParamNo)=>{const value=Math.round(Number(paramObj.values)/paramInfo.divisor);console.log(`容量参数value (paramNo ${lowParamNo}):`,value);const highValue=value>>16&65535,lowBytes=decimalToTwoByteHexArray(65535&value),lowAddress=decimalToTwoByteHexArray(lowParamNo),hexLength=decimalToHex(1),lowHex=await handleSet(async()=>await setDDA5FAAsync(deviceId,lowAddress,hexLength,lowBytes)),highBytes=decimalToTwoByteHexArray(highValue),highAddress=decimalToTwoByteHexArray(highParamNo),highHex=await handleSet(async()=>await setDDA5FAAsync(deviceId,highAddress,hexLength,highBytes));return lowHex&&highHex};try{let paramInfoHex;await enterFactory(deviceId),paramInfoHex=chipType?await handleCapacityParam(paramInfo,0,155):await handleParam(paramInfo);await handleParam(circular)
|
|
1
|
+
import{decimalToTwoByteHexArray,decimalToHex0x,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=decimalToHex0x(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.warn("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=Number(paramInfo?.paramValue||paramInfo.newValue)/Number(paramInfo?.divisor||1);console.log("value: ",value),paramInfo.isTemp&&(value=2731+10*Number(paramInfo.newValue)),value=Math.round(value);let valuesHexs=[];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={paramNo:1,oldParamNo:"0x11",values:.8*values,paramLength:2},full={paramNo:112,oldParamNo:"0x10",values:values,paramLength:2},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))},handleCapacityParam=async(paramObj,lowParamNo,highParamNo)=>{const value=Math.round(Number(paramObj.values)/paramInfo.divisor);console.log(`容量参数value (paramNo ${lowParamNo}):`,value);const highValue=value>>16&65535,lowBytes=decimalToTwoByteHexArray(65535&value),lowAddress=decimalToTwoByteHexArray(lowParamNo),hexLength=decimalToHex(1),lowHex=await handleSet(async()=>await setDDA5FAAsync(deviceId,lowAddress,hexLength,lowBytes)),highBytes=decimalToTwoByteHexArray(highValue),highAddress=decimalToTwoByteHexArray(highParamNo),highHex=await handleSet(async()=>await setDDA5FAAsync(deviceId,highAddress,hexLength,highBytes));return lowHex&&highHex};try{let paramInfoHex;await enterFactory(deviceId),paramInfoHex=chipType?await handleCapacityParam(paramInfo,0,155):await handleParam(paramInfo);const circularValue=Math.round(Number(circular.values)/paramInfo.divisor);if(0===(circularValue>>16&65535)){await handleParam(circular)}else{await handleParam({...circular,values:655.35})}if(chipType){await handleCapacityParam(full,112,156)}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:()=>{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(){
|
|
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(){if(this.finishedTimes+1>this.totalTimes+1){const pkg=[0];await BLE.sendDelay(this.delay),BLE.transferFirmwareFileCmd(this.deviceId,pkg,!0,this.fail.bind(this)),console.log("[OTA]","=== Send 51 ===",this.finishedTimes,this.totalTimes,pkg)}else if(0===this.finishedTimes){const emptyPkg=[0,0];console.log("[OTA]","=== Send empty package first ==="),await BLE.sendDelay(this.delay),BLE.transferFirmwareFileCmd(this.deviceId,emptyPkg,!1,this.fail.bind(this))}else{const dataIndex=this.finishedTimes-1,pkg=this.fileHexArray.slice(dataIndex*max,(dataIndex+1)*max),index=Transfer.decimalToTwoByteHexArray(this.finishedTimes);console.log("[OTA]",`S50-${this.finishedTimes}/${this.totalTimes}`),await BLE.sendDelay(this.delay),BLE.transferFirmwareFileCmd(this.deviceId,index.concat(pkg),!1,this.fail.bind(this))}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 +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(options={}){const{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}=options;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,this.setPassthroughType=1,this.currentCommand="",this.verify3LevelPasswordFn=async(deviceObj,ciphertext)=>{}}initData(options={}){const{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,verify3LevelPasswordFn:verify3LevelPasswordFn=async()=>{}}=options;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,this.verify3LevelPasswordFn=verify3LevelPasswordFn}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,deviceObj),this.publishInOrder(client,deviceObj).then(()=>this.subscribeInOrder(client))}storeMqttClient(client,deviceObj){this.mqttClient[`${client.options.deviceId}_mqtt`]=client,this.mqttClient[`${client.options.deviceId}_mqtt`].deviceObj=deviceObj,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 deviceObj=this.mqttClient[`${client.options.deviceId}_mqtt`]?.deviceObj||{};await this.verify3LevelPasswordFn(deviceObj,deviceObj.macAddr);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()&&"50"!==resultArray[1]?.toUpperCase()||(this.currentCommand=resultArray.slice(0,4).map(o=>`0x${o}`));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):(console.log("resultArray",resultArray),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?.
|
|
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(options={}){const{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}=options;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,this.setPassthroughType=1,this.currentCommand="",this.verify3LevelPasswordFn=async(deviceObj,ciphertext)=>{}}initData(options={}){const{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,verify3LevelPasswordFn:verify3LevelPasswordFn=async()=>{}}=options;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,this.verify3LevelPasswordFn=verify3LevelPasswordFn}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,deviceObj),this.publishInOrder(client,deviceObj).then(()=>this.subscribeInOrder(client))}storeMqttClient(client,deviceObj){this.mqttClient[`${client.options.deviceId}_mqtt`]=client,this.mqttClient[`${client.options.deviceId}_mqtt`].deviceObj=deviceObj,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 deviceObj=this.mqttClient[`${client.options.deviceId}_mqtt`]?.deviceObj||{};await this.verify3LevelPasswordFn(deviceObj,deviceObj.macAddr);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()&&"50"!==resultArray[1]?.toUpperCase()||(this.currentCommand=resultArray.slice(0,4).map(o=>`0x${o}`));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):(console.log("resultArray",resultArray),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?.setMqttPublish(!1),uni.removeStorageSync&&uni.removeStorageSync(`${deviceId}_mqttPublish`))}catch(error){console.error(error)}}closeMqttByDeviceId(deviceId){const client=this.mqttClient[`${deviceId}_mqtt`];console.log("closeMqttByDeviceId",this.mqttClient,client),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})}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&&(console.log("publishHandle",client,msg,this.publishObj),client.publish(`/${this.publishObj.productKey}/${this.publishObj.clientId}/plat/passthrough/reply`,msg,()=>{console.log("发布回复主题完成",msg)})),this.publishObj.isLast&&(await sleep(300),this.mqttPublish=!1,this.$store?.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?.setMqttPublish(!0),this.mqttCode=values[2];let res=null;this.setPassthroughType=1,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("")),console.log("res",res);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,this.mqttCode),code.toUpperCase()==this.mqttCode.toUpperCase()&&this.publishHandle(res?.dataStr),this.timer=setTimeout(()=>{this.mqttPublish=!1,this.$store?.setMqttPublish(!1)},3e4)}}const mqttServer=new MqttServer;export{MqttServer,mqttServer};
|
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,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";
|
|
1
|
+
export{chunk,unique}from"./core/array.js";export{bluetoothScanHandle,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,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,12 +1,13 @@
|
|
|
1
1
|
import { ref } from 'vue';
|
|
2
2
|
import { ab2decimalArr, hexToDecimal } from './BleDataProcess';
|
|
3
|
-
import { eventBus, getOS } from './commonfun'; // 导入eventBus
|
|
3
|
+
import { eventBus, getOS, getPlatform } from './commonfun'; // 导入eventBus
|
|
4
4
|
// #ifdef MP-WEIXIN
|
|
5
5
|
import { tcpServer } from './tcpServer.js';
|
|
6
6
|
// #endif
|
|
7
7
|
// #ifdef APP-PLUS
|
|
8
8
|
import { mqttServer } from './mqttServer.js';
|
|
9
9
|
// #endif
|
|
10
|
+
|
|
10
11
|
const serviceId = '0000FF00-0000-1000-8000-00805F9B34FB';
|
|
11
12
|
const UUID_READ = '0000FF01-0000-1000-8000-00805F9B34FB';
|
|
12
13
|
const UUID_WRITE = '0000FF02-0000-1000-8000-00805F9B34FB';
|
|
@@ -16,6 +17,19 @@ const bluetoothAdapterState = ref({
|
|
|
16
17
|
discovering: false,
|
|
17
18
|
});
|
|
18
19
|
|
|
20
|
+
const platform = getPlatform();
|
|
21
|
+
|
|
22
|
+
// // 根据平台动态引入
|
|
23
|
+
// let tcpServer, mqttServer;
|
|
24
|
+
// if (platform === 'mp-weixin') {
|
|
25
|
+
// import('./tcpServer.js').then(module => {
|
|
26
|
+
// tcpServer = module.tcpServer;
|
|
27
|
+
// });
|
|
28
|
+
// } else {
|
|
29
|
+
// import('./mqttServer.js').then(module => {
|
|
30
|
+
// mqttServer = module.mqttServer;
|
|
31
|
+
// });
|
|
32
|
+
// }
|
|
19
33
|
|
|
20
34
|
export var isInit = false;
|
|
21
35
|
|
|
@@ -281,13 +295,11 @@ export const onBLEConnectionStateChange = async () => {
|
|
|
281
295
|
// 触发事件总线事件
|
|
282
296
|
eventBus.emit('setBleChangedConnectionState', characteristic);
|
|
283
297
|
if (!characteristic.connected) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
tcpServer.closeTcpSocket(characteristic.deviceId);
|
|
290
|
-
// #endif
|
|
298
|
+
if (platform === 'mp-weixin') {
|
|
299
|
+
tcpServer.closeTcpSocket(characteristic.deviceId);
|
|
300
|
+
} else {
|
|
301
|
+
mqttServer.closeMqttByDeviceId(characteristic.deviceId)
|
|
302
|
+
}
|
|
291
303
|
}
|
|
292
304
|
});
|
|
293
305
|
};
|
|
@@ -460,58 +472,7 @@ export const scanHandle = (historyConnectedList = [], connectFn = (device) => {
|
|
|
460
472
|
scanType: ['barCode', 'qrCode'],
|
|
461
473
|
autoZoom: false,
|
|
462
474
|
success: async ({ result }) => {
|
|
463
|
-
|
|
464
|
-
let searchKey = result;
|
|
465
|
-
try {
|
|
466
|
-
// MAC地址格式化工具函数
|
|
467
|
-
const formatMacAddress = (mac) => {
|
|
468
|
-
return mac
|
|
469
|
-
.replace(/(.{2})/g, '$1:')
|
|
470
|
-
.slice(0, -1)
|
|
471
|
-
.toUpperCase();
|
|
472
|
-
};
|
|
473
|
-
// // 判断result是否为mac地址;
|
|
474
|
-
let isMac = false;
|
|
475
|
-
if (result.includes('?qrCodeInfo=')) {
|
|
476
|
-
searchKey = result.split('?qrCodeInfo=')[1];
|
|
477
|
-
// this.searchKey = result;
|
|
478
|
-
if (searchKey.includes(':')) {
|
|
479
|
-
searchKey = searchKey.slice(-17).toUpperCase();
|
|
480
|
-
isMac = true;
|
|
481
|
-
} else {
|
|
482
|
-
// 截取最后12位,每两位加一个冒号,去掉最后一个冒号
|
|
483
|
-
searchKey = searchKey.slice(-12);
|
|
484
|
-
searchKey = formatMacAddress(searchKey);
|
|
485
|
-
isMac = true;
|
|
486
|
-
}
|
|
487
|
-
} else {
|
|
488
|
-
if (result.length === 17 && result.includes(':')) {
|
|
489
|
-
searchKey = result.toUpperCase();
|
|
490
|
-
isMac = true;
|
|
491
|
-
} else if (result.length === 12) {
|
|
492
|
-
searchKey = formatMacAddress(result);
|
|
493
|
-
isMac = true;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
// 检查历史连接列表是否已包含该设备
|
|
497
|
-
const matchedHistoryDevice = historyConnectedList.find((item) => item.macAddr == searchKey);
|
|
498
|
-
if (matchedHistoryDevice) {
|
|
499
|
-
connectFn(matchedHistoryDevice);
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
502
|
-
// 安卓机且扫码内容是mac地址直连,苹果机广播五秒连接
|
|
503
|
-
if (isAndroid && isMac) {
|
|
504
|
-
connectFn({
|
|
505
|
-
deviceId: searchKey,
|
|
506
|
-
macAddr: searchKey,
|
|
507
|
-
name: searchKey,
|
|
508
|
-
});
|
|
509
|
-
} else {
|
|
510
|
-
foundScanDevice(searchKey, connectFn);
|
|
511
|
-
}
|
|
512
|
-
} catch (error) {
|
|
513
|
-
console.log(error);
|
|
514
|
-
}
|
|
475
|
+
bluetoothScanHandle(result, historyConnectedList, connectFn, failScanFn)
|
|
515
476
|
},
|
|
516
477
|
complete: (err) => {
|
|
517
478
|
},
|
|
@@ -521,6 +482,60 @@ export const scanHandle = (historyConnectedList = [], connectFn = (device) => {
|
|
|
521
482
|
}
|
|
522
483
|
});
|
|
523
484
|
};
|
|
485
|
+
export const bluetoothScanHandle = (retult, historyConnectedList = [], connectFn = (device) => { }, failScanFn = (err) => { }) => {
|
|
486
|
+
console.log('扫描内容: ' + result);
|
|
487
|
+
let searchKey = result;
|
|
488
|
+
try {
|
|
489
|
+
// MAC地址格式化工具函数
|
|
490
|
+
const formatMacAddress = (mac) => {
|
|
491
|
+
return mac
|
|
492
|
+
.replace(/(.{2})/g, '$1:')
|
|
493
|
+
.slice(0, -1)
|
|
494
|
+
.toUpperCase();
|
|
495
|
+
};
|
|
496
|
+
// // 判断result是否为mac地址;
|
|
497
|
+
let isMac = false;
|
|
498
|
+
if (result.includes('?qrCodeInfo=')) {
|
|
499
|
+
searchKey = result.split('?qrCodeInfo=')[1];
|
|
500
|
+
// this.searchKey = result;
|
|
501
|
+
if (searchKey.includes(':')) {
|
|
502
|
+
searchKey = searchKey.slice(-17).toUpperCase();
|
|
503
|
+
isMac = true;
|
|
504
|
+
} else {
|
|
505
|
+
// 截取最后12位,每两位加一个冒号,去掉最后一个冒号
|
|
506
|
+
searchKey = searchKey.slice(-12);
|
|
507
|
+
searchKey = formatMacAddress(searchKey);
|
|
508
|
+
isMac = true;
|
|
509
|
+
}
|
|
510
|
+
} else {
|
|
511
|
+
if (result.length === 17 && result.includes(':')) {
|
|
512
|
+
searchKey = result.toUpperCase();
|
|
513
|
+
isMac = true;
|
|
514
|
+
} else if (result.length === 12) {
|
|
515
|
+
searchKey = formatMacAddress(result);
|
|
516
|
+
isMac = true;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// 检查历史连接列表是否已包含该设备
|
|
520
|
+
const matchedHistoryDevice = historyConnectedList.find((item) => item.macAddr == searchKey);
|
|
521
|
+
if (matchedHistoryDevice) {
|
|
522
|
+
connectFn(matchedHistoryDevice);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
// 安卓机且扫码内容是mac地址直连,苹果机广播五秒连接
|
|
526
|
+
if (isAndroid && isMac) {
|
|
527
|
+
connectFn({
|
|
528
|
+
deviceId: searchKey,
|
|
529
|
+
macAddr: searchKey,
|
|
530
|
+
name: searchKey,
|
|
531
|
+
});
|
|
532
|
+
} else {
|
|
533
|
+
foundScanDevice(searchKey, connectFn);
|
|
534
|
+
}
|
|
535
|
+
} catch (error) {
|
|
536
|
+
console.log(error);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
524
539
|
// #region 广播5秒
|
|
525
540
|
export const foundScanDevice = async (result, connectFn) => {
|
|
526
541
|
const deviceList = [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ab2decimalArr, hexArr2ab, hexArr2string, sleep } from '../BleDataProcess';
|
|
2
2
|
import { eventBus, getOS, getPlatform } from '../commonfun';
|
|
3
3
|
// #ifdef APP-PLUS
|
|
4
|
-
import { mqttServer } from '../mqttServer';
|
|
4
|
+
import { mqttServer } from '../mqttServer.js';
|
|
5
5
|
// #endif
|
|
6
6
|
|
|
7
7
|
const BLE_RESPONSE_TIMEOUT = 300; // 蓝牙指令响应超时
|
|
@@ -13,6 +13,14 @@ const characteristicId = '0000FF02-0000-1000-8000-00805F9B34FB';
|
|
|
13
13
|
// 按设备维度串行执行蓝牙指令,避免并发写入导致回包串线
|
|
14
14
|
const BLE_COMMAND_QUEUE = new Map();
|
|
15
15
|
const BLE_COMMAND_RUNNING = new Set();
|
|
16
|
+
const platform = getPlatform();
|
|
17
|
+
// if (platform === 'mp-weixin') {
|
|
18
|
+
|
|
19
|
+
// } else {
|
|
20
|
+
// import('../mqttServer.js').then(module => {
|
|
21
|
+
// mqttServer = module.mqttServer;
|
|
22
|
+
// });
|
|
23
|
+
// }
|
|
16
24
|
|
|
17
25
|
const runNextBleCommand = async (queueKey) => {
|
|
18
26
|
if (BLE_COMMAND_RUNNING.has(queueKey)) return;
|
|
@@ -181,16 +189,16 @@ export const getData = async (deviceId, {
|
|
|
181
189
|
if (verified) {
|
|
182
190
|
responsed = true;
|
|
183
191
|
cleanup();
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
if (platform !== 'mp-weixin') {
|
|
193
|
+
const value = [...pkg].map((o) => `00${o.toString(16)}`.slice(-2)).join('');
|
|
194
|
+
const cmdCode = mqttServer.currentCommand
|
|
195
|
+
if (value && cmdCode) {
|
|
196
|
+
if (mqttServer.setPassthroughType === 0) {
|
|
197
|
+
mqttServer.publishPassthroughHandle({ value, cmdCode }, deviceId)
|
|
198
|
+
}
|
|
199
|
+
mqttServer.setPassthroughType = 0
|
|
190
200
|
}
|
|
191
|
-
mqttServer.setPassthroughType = 0
|
|
192
201
|
}
|
|
193
|
-
// #endif
|
|
194
202
|
resolve([...pkg]);
|
|
195
203
|
} else {
|
|
196
204
|
// 验证失败,重置状态
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { decimalToHex, fromBCD, generateCrc16modbusCheck, generateCrcCheckSum, hex2string, hexArr2Assic, hexArr2string, hexToDecimal, isWithin30Minutes, sleep, stringToTwoHexArray, toBCD
|
|
1
|
+
import { decimalToHex, decimalToHex0x, fromBCD, generateCrc16modbusCheck, generateCrcCheckSum, hex2string, hexArr2Assic, hexArr2string, hexToDecimal, isWithin30Minutes, sleep, stringToTwoHexArray, toBCD } from '../BleDataProcess';
|
|
2
2
|
import { getData } from './BleCmdAnalysis.js';
|
|
3
|
-
import { getFFAA80Async
|
|
3
|
+
import { getFFAA80Async } from './BleCmdFFAA.js';
|
|
4
4
|
import { controlSwitch } from './readAndSetParam.js';
|
|
5
5
|
|
|
6
6
|
// #region 进出工厂
|
|
@@ -396,7 +396,6 @@ export const resolveDDA503 = (data) => {
|
|
|
396
396
|
heatingState,
|
|
397
397
|
heatingCurrent,
|
|
398
398
|
equilibriumCurrent,
|
|
399
|
-
eqCurr: equilibriumCurrent,
|
|
400
399
|
isFactoryMode,
|
|
401
400
|
protVal,
|
|
402
401
|
alarmsState,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { decimalToHex,
|
|
1
|
+
import { decimalToHex, decimalToHex0x, decimalToTwoByteHexArray } from '../BleDataProcess.js';
|
|
2
2
|
import { enterFactory, existFactory, getDD5AE1Async, getDD5AFBAsync, getDDA5FAAsync, getDDA5OldAsync, readExistFactory, resolveBaseDD, setDDA5FAAsync, setDDA5OldAsync } from './BleCmdDD.js';
|
|
3
3
|
|
|
4
4
|
// #region 发指令读取参数
|
|
@@ -392,7 +392,18 @@ export const setCapacityParamCmd = (chipType, deviceId, paramInfo) => {
|
|
|
392
392
|
// 旧协议:直接写入
|
|
393
393
|
paramInfoHex = await handleParam(paramInfo);
|
|
394
394
|
}
|
|
395
|
-
const
|
|
395
|
+
const circularValue = Math.round(Number(circular.values) / paramInfo.divisor);
|
|
396
|
+
const circularLowValue = circularValue & 0xFFFF; // 低16位
|
|
397
|
+
const circularHighValue = (circularValue >> 16) & 0xFFFF; // 高16位
|
|
398
|
+
// 计算循环容量是否超出2字节的存储空间,若大于,则设置循环容量最大值65536
|
|
399
|
+
if (circularHighValue === 0) {
|
|
400
|
+
const circularHex = await handleParam(circular);
|
|
401
|
+
} else {
|
|
402
|
+
const circularHex = await handleParam({
|
|
403
|
+
...circular,
|
|
404
|
+
values: 655.35
|
|
405
|
+
});
|
|
406
|
+
}
|
|
396
407
|
if (chipType) {
|
|
397
408
|
const fullHex = await handleCapacityParam(full, 112, 156);
|
|
398
409
|
}
|
package/src/core/OtaUpgrade.js
CHANGED
|
@@ -323,18 +323,27 @@ export class OTAUpgrade {
|
|
|
323
323
|
|
|
324
324
|
async transferFirmwareFile() {
|
|
325
325
|
let nextTime = this.finishedTimes + 1;
|
|
326
|
-
const timeFor51 = nextTime > this.totalTimes;
|
|
326
|
+
const timeFor51 = nextTime > this.totalTimes + 1; // 51命令时机:当下一包序号大于总包数时,即所有包都已发送完毕,等待设备回复是否升级成功 此处+1是因为发了个无数据的0包,总次数需要加1出否则会丢包;
|
|
327
327
|
if (timeFor51) {
|
|
328
328
|
const pkg = [0x00];
|
|
329
329
|
await BLE.sendDelay(this.delay);
|
|
330
330
|
BLE.transferFirmwareFileCmd(this.deviceId, pkg, true, this.fail.bind(this));
|
|
331
331
|
console.log('[OTA]', '=== Send 51 ===', this.finishedTimes, this.totalTimes, pkg);
|
|
332
332
|
} else {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
333
|
+
if (this.finishedTimes === 0) {
|
|
334
|
+
// 第一次时先发空包
|
|
335
|
+
const emptyPkg = [0x00, 0x00];
|
|
336
|
+
console.log('[OTA]', '=== Send empty package first ===');
|
|
337
|
+
await BLE.sendDelay(this.delay);
|
|
338
|
+
BLE.transferFirmwareFileCmd(this.deviceId, emptyPkg, false, this.fail.bind(this));
|
|
339
|
+
}else {
|
|
340
|
+
const dataIndex = this.finishedTimes - 1; // 因为第0次发的是空包,所以实际数据从finishedTimes-1开始
|
|
341
|
+
const pkg = this.fileHexArray.slice(dataIndex * max, (dataIndex + 1) * max);
|
|
342
|
+
const index = Transfer.decimalToTwoByteHexArray(this.finishedTimes);
|
|
343
|
+
console.log('[OTA]', `S50-${this.finishedTimes}/${this.totalTimes}`);
|
|
344
|
+
await BLE.sendDelay(this.delay);
|
|
345
|
+
BLE.transferFirmwareFileCmd(this.deviceId, index.concat(pkg), false, this.fail.bind(this));
|
|
346
|
+
}
|
|
338
347
|
}
|
|
339
348
|
this.onProgress && this.onProgress({ type: 'upgrade', percent: Math.floor((this.finishedTimes * 100) / this.totalTimes) });
|
|
340
349
|
}
|