whycxzp
2022-09-15 5a41b557ac281dec4f81051a86b35d9cdb27cfcf
更新ABE文件解析
19个文件已添加
2个文件已修改
1582 ■■■■■ 已修改文件
src/main/java/com/whyc/abe/ABEChrDataHeadStart.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABECtDataTime.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABECycleDataHeadStart.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABECycleDataHeadStop.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEDataHeadStart.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEDataHeadStop.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEDataParase.java 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEDataParseUtil.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEDataType.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEDisDataHeadStart.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEFBSData.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABETestDataHeadStop.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABETestTime.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEVolCurrData.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/constant/Com.java 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/constant/ComBase.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/constant/ConstantDefined.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/constant/Crc16.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/constant/ParseUtil.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/controller/BattRealdataController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/service/BattRealdataService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/whyc/abe/ABEChrDataHeadStart.java
New file
@@ -0,0 +1,108 @@
package com.whyc.abe;
import com.whyc.constant.ComBase;
import com.whyc.constant.Crc16;
import java.nio.ByteBuffer;
/**
 *     充电数据头结构体
 * @author LiJun
 *
 */
public class ABEChrDataHeadStart  implements ABEDataHeadStart{
    public static final int BYTE_LEN = 44;
    public int hourRate;               //小时率 固定为10
    public float chargeCurr;        //充电电流参数 x/10 A
    public int  chargeCap;          //测试容量    x AH
    public int  chargeTime;            //测试时间
    public float  groupVol_High;      //充电上限    x/1000 V
    public float  monomerVol_High;    //充电上限    x/1000 V
    public int  monomerHighCount;    //上限个数 固定为1
    public int  battGroupNum;        //电池组数 固定为1
    public int  onlineVolLowAction;    //无用
    public int  staticTime;            //无用
    public int  chargeTestCount;       //无用
    public int  battNum;            //电池编号
    public int  battVolStyle;        //无用
    public int  std_CAP;            //标称容量 x AH
    public int  testcap;            //已测容量 x AH 同 ChargeCap
    public int  bakeup5;
    public int  bakeup6;
    public int  bakeup7;
    public int  bakeup8;
    public int  bakeup9;
    public int  bakeup10;
    public int  crc;
    @Override
    public boolean setDataInf(ByteBuffer bf) {
        //System.out.println("头部数据长度异常"+bf.remaining());
        if(bf.limit() < BYTE_LEN) {
            return false;
        }
        int crc0 = bf.getShort(BYTE_LEN-2) & 0xFFFF;
        int crc1 = Crc16.CalCRC16(bf, BYTE_LEN-2);
        if(crc0 != crc1) {
            //校验CRC
            //System.out.println(crc0 + "==" + crc1);
            return false;
        }
        bf.position(0);
        hourRate = ComBase.changeShortToInt(bf.getShort());               //小时率 固定为10
        chargeCurr = ComBase.changeShortToFloat(bf.getShort())/10;        //充电电流参数 x/10 A
        chargeCap = ComBase.changeShortToInt(bf.getShort());          //测试容量    x AH
        chargeTime = ComBase.changeShortToInt(bf.getShort());            //测试时间
        groupVol_High = ComBase.changeShortToFloat(bf.getShort())/1000;      //充电上限    x/1000 V
        monomerVol_High = ComBase.changeShortToFloat(bf.getShort())/1000;    //充电上限    x/1000 V
        monomerHighCount = ComBase.changeShortToInt(bf.getShort());            //上限个数 固定为1
        battGroupNum = ComBase.changeShortToInt(bf.getShort());                //电池组数 固定为1
        onlineVolLowAction = ComBase.changeShortToInt(bf.getShort());        //无用
        staticTime = ComBase.changeShortToInt(bf.getShort());                //无用
        chargeTestCount = ComBase.changeShortToInt(bf.getShort());           //无用
        battNum = ComBase.changeShortToInt(bf.getShort());                    //电池编号
        battVolStyle = ComBase.changeShortToInt(bf.getShort());                //无用
        std_CAP = ComBase.changeShortToInt(bf.getShort());                    //标称容量 x AH
        testcap = ComBase.changeShortToInt(bf.getShort());                    //已测容量 x AH 同 ChargeCap
        bakeup5 = ComBase.changeShortToInt(bf.getShort());
        bakeup6 = ComBase.changeShortToInt(bf.getShort());
        bakeup7 = ComBase.changeShortToInt(bf.getShort());
        bakeup8 = ComBase.changeShortToInt(bf.getShort());
        bakeup9 = ComBase.changeShortToInt(bf.getShort());
        bakeup10 = ComBase.changeShortToInt(bf.getShort());
        crc = ComBase.changeShortToInt(bf.getShort());
        //System.out.println(this);
        bf.compact();
        bf.flip();
        return true;
    }
    @Override
    public int getBattGroupNum() {
        return this.battGroupNum;
    }
    @Override
    public String toString() {
        return "ABEChrDataHeadStart [hourRate=" + hourRate + ", chargeCurr=" + chargeCurr + ", chargeCap=" + chargeCap
                + ", chargeTime=" + chargeTime + ", groupVol_High=" + groupVol_High + ", monomerVol_High="
                + monomerVol_High + ", monomerHighCount=" + monomerHighCount + ", battGroupNum=" + battGroupNum
                + ", onlineVolLowAction=" + onlineVolLowAction + ", staticTime=" + staticTime + ", chargeTestCount="
                + chargeTestCount + ", battNum=" + battNum + ", battVolStyle=" + battVolStyle + ", std_CAP=" + std_CAP
                + ", testcap=" + testcap + ", bakeup5=" + bakeup5 + ", bakeup6=" + bakeup6 + ", bakeup7=" + bakeup7
                + ", bakeup8=" + bakeup8 + ", bakeup9=" + bakeup9 + ", bakeup10=" + bakeup10 + ", crc=" + crc + "]";
    }
}
src/main/java/com/whyc/abe/ABECtDataTime.java
New file
@@ -0,0 +1,20 @@
package com.whyc.abe;
import java.util.Calendar;
import java.util.Date;
public class ABECtDataTime {
    public int year;        //x+2000
    public int month;
    public int day;
    public int hour;
    public int minute;
    public int second;
    public Date getFBSDateTime() {
        Calendar c = Calendar.getInstance();
        c.set(2000+year, month-1, day, hour, minute, second);
        return c.getTime();
        //return Com.get_DT_FromStr(year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second, Com.DTF_YMDhms);
    }
}
src/main/java/com/whyc/abe/ABECycleDataHeadStart.java
New file
@@ -0,0 +1,95 @@
package com.whyc.abe;
import com.whyc.constant.ComBase;
import com.whyc.constant.Crc16;
import java.nio.ByteBuffer;
/**
 *     活化数据头结构体
 * @author LiJun
 *
 */
public class ABECycleDataHeadStart implements ABEDataHeadStart{
    public static final int BYTE_LEN = 45;
    public int battNum;                //电池编号
    public int battVolStyle;        //电池电压 无用
    public int std_CAP;                //标称容量      x AH
    public int disTime;                //放电时间      x Min
    public float disCurr;            //放电电流      x/10 A
    public float monomerVol_LOW;    //放电电压下限   x/1000 V
    public int chargeTime;            //充电时间      x Min
    public float chargeCurr;        //充电电流      x/10 A
    public float monomerVol_High;    //充电电压上限   x/1000 V
    public int cycleTimes;            //充放次数
    public int waitTime;            //静置时间 无用
    public int workFrom;            //测试起点  0放电 1充电
    public int testcap1;               //初测容量  x AH 第一次放电容量
    public int testcap2;               //终测容量  x AH 最后一次放电容量
    public int bakeup3;
    public int bakeup4;
    public int bakeup5;
    public int bakeup6;
    public int bakeup7;
    public int bakeup8;
    public int bakeup9;
    public int bakeup10;
    public int CRC;
    @Override
    public boolean setDataInf(ByteBuffer bf) {
        System.out.println("头部数据长度异常"+bf.remaining());
        if(bf.limit() < BYTE_LEN) {
            return false;
        }
        int crc0 = bf.getShort(BYTE_LEN-2) & 0xFFFF;
        int crc1 = Crc16.CalCRC16(bf, BYTE_LEN-2);
        if(crc0 != crc1) {
            //校验CRC
            //System.out.println(crc0 + "==" + crc1);
            return false;
        }
        bf.position(0);
        battNum = ComBase.changeShortToInt(bf.getShort());                    //电池编号
        battVolStyle = ComBase.changeShortToInt(bf.getShort());                //电池电压 无用
        std_CAP = ComBase.changeShortToInt(bf.getShort());                    //标称容量      x AH
        disTime = ComBase.changeShortToInt(bf.getShort());                    //放电时间      x Min
        disCurr = ComBase.changeShortToFloat(bf.getShort())/10;                //放电电流      x/10 A
        monomerVol_LOW = ComBase.changeShortToFloat(bf.getShort())/1000;    //放电电压下限   x/1000 V
        chargeTime = ComBase.changeShortToInt(bf.getShort());                //充电时间      x Min
        chargeCurr = ComBase.changeShortToFloat(bf.getShort())/10;            //充电电流      x/10 A
        monomerVol_High = ComBase.changeShortToFloat(bf.getShort())/1000;    //充电电压上限   x/1000 V
        cycleTimes = ComBase.changeShortToInt(bf.getShort());                //充放次数
        waitTime = ComBase.changeShortToInt(bf.getShort());                    //静置时间 无用
        workFrom = ComBase.changeByteToInt(bf.get());                        //测试起点  0放电 1充电
        testcap1 = ComBase.changeShortToInt(bf.getShort());                   //初测容量  x AH 第一次放电容量
        testcap2 = ComBase.changeShortToInt(bf.getShort());                   //终测容量  x AH 最后一次放电容量
        bakeup3 = ComBase.changeShortToInt(bf.getShort());
        bakeup4 = ComBase.changeShortToInt(bf.getShort());
        bakeup5 = ComBase.changeShortToInt(bf.getShort());
        bakeup6 = ComBase.changeShortToInt(bf.getShort());
        bakeup7 = ComBase.changeShortToInt(bf.getShort());
        bakeup8 = ComBase.changeShortToInt(bf.getShort());
        bakeup9 = ComBase.changeShortToInt(bf.getShort());
        bakeup10 = ComBase.changeShortToInt(bf.getShort());
        CRC = ComBase.changeShortToInt(bf.getShort());
        //System.out.println(this);
        bf.compact();
        bf.flip();
        return true;
    }
    @Override
    public int getBattGroupNum() {
        return 1;
    }
}
src/main/java/com/whyc/abe/ABECycleDataHeadStop.java
New file
@@ -0,0 +1,59 @@
package com.whyc.abe;
import com.whyc.constant.ComBase;
import java.nio.ByteBuffer;
import java.util.Date;
/**
 *     活化数据尾结构体
 * @author LiJun
 *
 */
public class ABECycleDataHeadStop implements ABEDataHeadStop{
    public static final  int BYTE_LEN = 19;
    public ABECtDataTime startDT;    //启动放电的日期时间
    public ABECtDataTime stopDT;    //终止放电的日期时间
    public int cycleTestEN;            //活化测试标志位1--活化参数进入测试;
    public int cycleTag;            //活化测试标志位2--活化测试已经启动;
    public int start;                //起点标志位:
    public int cycleTimes;            //当前测试次数;
    public int settedActTimes;        //设置的次数;
    public Date testStartTime;        //测试开始时间
    public Date testStopTime;        //测试结束时间
    @Override
    public boolean setDataInf(ByteBuffer bf) {
        if(bf.limit() < BYTE_LEN) {
            return false;
        }
        startDT.year = ComBase.changeByteToInt(bf.get());
        startDT.month = ComBase.changeByteToInt(bf.get());
        startDT.day = ComBase.changeByteToInt(bf.get());
        startDT.hour = ComBase.changeByteToInt(bf.get());
        startDT.minute = ComBase.changeByteToInt(bf.get());
        startDT.second = ComBase.changeByteToInt(bf.get());
        stopDT.year = ComBase.changeByteToInt(bf.get());
        stopDT.month = ComBase.changeByteToInt(bf.get());
        stopDT.day = ComBase.changeByteToInt(bf.get());
        stopDT.hour = ComBase.changeByteToInt(bf.get());
        stopDT.minute = ComBase.changeByteToInt(bf.get());
        stopDT.second = ComBase.changeByteToInt(bf.get());
        cycleTestEN = ComBase.changeByteToInt(bf.get());                //活化测试标志位1--活化参数进入测试;
        cycleTag = ComBase.changeByteToInt(bf.get());                    //活化测试标志位2--活化测试已经启动;
        start = ComBase.changeByteToInt(bf.get());                        //起点标志位:
        cycleTimes = ComBase.changeShortToInt(bf.getShort());            //当前测试次数;
        settedActTimes = ComBase.changeShortToInt(bf.getShort());        //设置的次数;
        testStartTime = startDT.getFBSDateTime();
        testStopTime = stopDT.getFBSDateTime();
        //System.out.println(test_Time.hour+":"+test_Time.minute+":"+test_Time.second);
        //System.out.println(this);
        return true;
    }
}
src/main/java/com/whyc/abe/ABEDataHeadStart.java
New file
@@ -0,0 +1,11 @@
package com.whyc.abe;
import java.nio.ByteBuffer;
public interface ABEDataHeadStart {
    public boolean setDataInf(ByteBuffer bf);
    public int getBattGroupNum();
}
src/main/java/com/whyc/abe/ABEDataHeadStop.java
New file
@@ -0,0 +1,8 @@
package com.whyc.abe;
import java.nio.ByteBuffer;
public interface ABEDataHeadStop {
    public boolean setDataInf(ByteBuffer bf);
}
src/main/java/com/whyc/abe/ABEDataParase.java
New file
@@ -0,0 +1,163 @@
package com.whyc.abe;
import com.whyc.constant.ConstantDefined;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
public class ABEDataParase {
    public List<ABEFBSData> getFbsData() {
        return fbsData;
    }
    public void setFbsData(List<ABEFBSData> fbsData) {
        this.fbsData = fbsData;
    }
    public ABEDataHeadStart getFbsDataStart() {
        return fbsDataStart;
    }
    public void setFbsDataStart(ABEDataHeadStart fbsDataStart) {
        this.fbsDataStart = fbsDataStart;
    }
    public ABEDataHeadStop getFbsDataStop() {
        return fbsDataStop;
    }
    public void setFbsDataStop(ABEDataHeadStop fbsDataStop) {
        this.fbsDataStop = fbsDataStop;
    }
    public int getParse_result() {
        return parse_result;
    }
    public void setParse_result(int parse_result) {
        this.parse_result = parse_result;
    }
    public List<ABEFBSData> fbsData;
    public ABEDataHeadStart fbsDataStart;
    public ABEDataHeadStop fbsDataStop;
    public int parse_result = ConstantDefined.PARSE_RESULT_NULL;
    public void readFBSFile(String filePath)
    {
        //int Data_Type = -1;
        FileInputStream fis = null;
        try {
            File f = new File(filePath);
            if(filePath.toUpperCase().endsWith(".DDF")) {
                //放电数据文件
                fbsDataStart = new ABEDisDataHeadStart();
                fbsDataStop = new ABETestDataHeadStop();
                //Data_Type = ConstantDefined.DATA_TYPE_DIS;
            }else if(filePath.toUpperCase().endsWith(".CCF")) {
                //充电数据文件
                fbsDataStart = new ABEChrDataHeadStart();
                fbsDataStop = new ABETestDataHeadStop();
                //Data_Type = ConstantDefined.DATA_TYPE_DIS;
            }else {
                //非法文件
                parse_result = ConstantDefined.PARSE_RESULT_FILETYPEERR;
                return;
            }
            if(!f.exists()) {
                //文件不存在
                parse_result = ConstantDefined.PARSE_RESULT_NOTFOUNDFILE;
                //System.out.println("文件不存在..........");
                return;
            }
            fis = new FileInputStream(f);
            /*if(ConstantDefined.DATA_TYPE_DIS == Data_Type) {
            }else if(ConstantDefined.DATA_TYPE_CHR == Data_Type) {
                fbsDataStart = new ABEChrDataHeadStart();
                fbsDataStop = new ABETestDataHeadStop();
            }else if(ConstantDefined.DATA_TYPE_RULE == Data_Type){
                fbsDataStart = new ABECycleDataHeadStart();
                fbsDataStop = new ABECycleDataHeadStop();
            }else {
                parse_result = ConstantDefined.PARSE_RESULT_FILETYPEERR;
                return;
            }*/
            byte[] buf = new byte[512];
            //解析文件头
            if(fis.read(buf, 0, buf.length) == 512)
            {
                ByteBuffer bf = ByteBuffer.allocate(buf.length);
                bf.order(ByteOrder.LITTLE_ENDIAN);
                bf.put(buf);
                bf.position(0);
                if(this.fbsDataStart.setDataInf(bf) && this.fbsDataStop.setDataInf(bf)) {
                    parse_result = ConstantDefined.PARSE_RESULT_SUCCESS;
                } else {
                    parse_result = ConstantDefined.PARSE_RESULT_FILEERROR;
                    return;
                }
                fbsData = new ArrayList<>();
                ABEDataType mType = new ABEDataType();
                while(true)
                {
                    int tag = mType.checkDataHead(fis);
                    if((0xFD == tag) || (0xFC == tag) || (0xFB == tag))
                    {
                        //解析每一笔单体数据
                        byte[] databuf = new byte[8 + 80 + 2];
                        if(fis.read(databuf) == databuf.length)
                        {
                            ABEFBSData m_FbsData = new ABEFBSData();
                            m_FbsData.m_DataType = mType;
                            m_FbsData.setData(databuf);
                            fbsData.add(m_FbsData);
                        }
                    }
                    if(tag == 1) {
                        break;
                    }
                }
            }else {
                parse_result = ConstantDefined.PARSE_RESULT_FILEERROR;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(null != fis)
            {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        ABEDataParase fbs = new ABEDataParase();
        //fbo.readFboFile("D:/test/F2022-03-09 11.26.12.FBX");
        //fbo.readFboFile("D:/test/F2022-03-09 16.22.37.FBX");
        //fbo.readFboFile("D:/test/F2022-03-10 11.12.30.FBX");
        fbs.readFBSFile("C:\\Users\\29550\\Documents\\WeChat Files\\wxid_uh2bej4ad4ya22\\FileStorage\\File\\2022-09\\F2022-08-02-094422-1.DDF");
        //fbs.readFBSFile("D:\\桌面文件备份\\公司各种设备资料\\硬件数据文件解析相关\\ABE文件解析相关\\数据文件\\F2022-08-02-094422-1.DDF");
        //fbs.readFBSFile("D:\\桌面文件备份\\公司各种设备资料\\硬件数据文件解析相关\\ABE文件解析相关\\数据文件\\F2022-08-02-094422-1.DDF");
        //fbs.readFBSFile("D:\\桌面文件备份\\公司各种设备资料\\硬件数据文件解析相关\\ABE文件解析相关\\数据文件\\F2022-08-03-165222-7.CCF");
        System.out.println(fbs);
    }
}
src/main/java/com/whyc/abe/ABEDataParseUtil.java
New file
@@ -0,0 +1,135 @@
package com.whyc.abe;
import com.whyc.constant.ConstantDefined;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
public class ABEDataParseUtil {
    /*public List<ABEFBSData> fbsData;
    public ABEDataHeadStart fbsDataStart;
    public ABEDataHeadStop fbsDataStop;
    public int parse_result = ConstantDefined.PARSE_RESULT_NULL;*/
    public static ABEDataParase readFBSFile(MultipartFile multipartFile) throws IOException {
        List<ABEFBSData> fbsData = null;
        ABEDataHeadStart fbsDataStart = null;
        ABEDataHeadStop fbsDataStop = null;
        int parse_result = ConstantDefined.PARSE_RESULT_NULL;
        //int Data_Type = -1;
        FileInputStream fis = null;
        try {
            //File f = new File(filePath);
            multipartFile.getInputStream();
            if(multipartFile.getOriginalFilename().toUpperCase().endsWith(".DDF")) {
                //放电数据文件
                fbsDataStart = new ABEDisDataHeadStart();
                fbsDataStop = new ABETestDataHeadStop();
                //Data_Type = ConstantDefined.DATA_TYPE_DIS;
            }else if(multipartFile.getOriginalFilename().toUpperCase().endsWith(".CCF")) {
                //充电数据文件
                fbsDataStart = new ABEChrDataHeadStart();
                fbsDataStop = new ABETestDataHeadStop();
                //Data_Type = ConstantDefined.DATA_TYPE_DIS;
            }else {
                //非法文件
                parse_result = ConstantDefined.PARSE_RESULT_FILETYPEERR;
            }
            /*if(!f.exists()) {
                //文件不存在
                parse_result = ConstantDefined.PARSE_RESULT_NOTFOUNDFILE;
                //System.out.println("文件不存在..........");
            }
            fis = new FileInputStream(f);*/
            /*if(ConstantDefined.DATA_TYPE_DIS == Data_Type) {
            }else if(ConstantDefined.DATA_TYPE_CHR == Data_Type) {
                fbsDataStart = new ABEChrDataHeadStart();
                fbsDataStop = new ABETestDataHeadStop();
            }else if(ConstantDefined.DATA_TYPE_RULE == Data_Type){
                fbsDataStart = new ABECycleDataHeadStart();
                fbsDataStop = new ABECycleDataHeadStop();
            }else {
                parse_result = ConstantDefined.PARSE_RESULT_FILETYPEERR;
                return;
            }*/
            byte[] buf = new byte[512];
            //解析文件头
            if(fis.read(buf, 0, buf.length) == 512)
            {
                ByteBuffer bf = ByteBuffer.allocate(buf.length);
                bf.order(ByteOrder.LITTLE_ENDIAN);
                bf.put(buf);
                bf.position(0);
                if(fbsDataStart.setDataInf(bf) && fbsDataStop.setDataInf(bf)) {
                    parse_result = ConstantDefined.PARSE_RESULT_SUCCESS;
                } else {
                    parse_result = ConstantDefined.PARSE_RESULT_FILEERROR;
                }
                fbsData = new ArrayList<>();
                ABEDataType mType = new ABEDataType();
                while(true)
                {
                    int tag = mType.checkDataHead(fis);
                    if((0xFD == tag) || (0xFC == tag) || (0xFB == tag))
                    {
                        //解析每一笔单体数据
                        byte[] databuf = new byte[8 + 80 + 2];
                        if(fis.read(databuf) == databuf.length)
                        {
                            ABEFBSData m_FbsData = new ABEFBSData();
                            m_FbsData.m_DataType = mType;
                            m_FbsData.setData(databuf);
                            fbsData.add(m_FbsData);
                        }
                    }
                    if(tag == 1) {
                        break;
                    }
                }
            }else {
                parse_result = ConstantDefined.PARSE_RESULT_FILEERROR;
            }
            ABEDataParase parse = new ABEDataParase();
            parse.setFbsData(fbsData);
            parse.setFbsDataStart(fbsDataStart);
            parse.setFbsDataStop(fbsDataStop);
            parse.setParse_result(parse_result);
            return parse;
        } finally {
            if(null != fis)
            {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /*public static void main(String[] args) throws FileNotFoundException {
        //fbo.readFboFile("D:/test/F2022-03-09 11.26.12.FBX");
        //fbo.readFboFile("D:/test/F2022-03-09 16.22.37.FBX");
        //fbo.readFboFile("D:/test/F2022-03-10 11.12.30.FBX");
        File file = new File("C:\\\\Users\\\\29550\\\\Documents\\\\WeChat Files\\\\wxid_uh2bej4ad4ya22\\\\FileStorage\\\\File\\\\2022-09\\\\F2022-08-02-094422-1.DDF");
        FileInputStream fileInputStream = new FileInputStream(file);
        ABEDataParase abeDataParase = readFBSFile(file);
        //fbs.readFBSFile("D:\\桌面文件备份\\公司各种设备资料\\硬件数据文件解析相关\\ABE文件解析相关\\数据文件\\F2022-08-02-094422-1.DDF");
        //fbs.readFBSFile("D:\\桌面文件备份\\公司各种设备资料\\硬件数据文件解析相关\\ABE文件解析相关\\数据文件\\F2022-08-02-094422-1.DDF");
        //fbs.readFBSFile("D:\\桌面文件备份\\公司各种设备资料\\硬件数据文件解析相关\\ABE文件解析相关\\数据文件\\F2022-08-03-165222-7.CCF");
        System.out.println(abeDataParase);
    }*/
}
src/main/java/com/whyc/abe/ABEDataType.java
New file
@@ -0,0 +1,64 @@
package com.whyc.abe;
import java.io.FileInputStream;
import java.io.IOException;
public class ABEDataType {
    public int typeTag0;
    public int typeTag1;
    public int typeTag2;
    public int typeTag3;
    public int checkDataHead(FileInputStream fis)
    {
        boolean file_end = false;
        byte type_tag = 0;
        byte[] tag = new byte[1];
        try {
            while(true)
            {
                type_tag = 0;
                int n = 0;
                for(n=0; n<4; n++)
                {
                    if(1 != fis.read(tag, 0, 1))
                    {
                        file_end = true;
                        break;
                    }
                    if((0xFD != (tag[0]&0xFF)) && (0xFC != (tag[0]&0xFF)) && (0xFB != (tag[0]&0xFF)))
                    {
                        break;
                    }
                }
                if(n >= 4)
                {
                    type_tag = tag[0];
                    break;
                }
                if(true == file_end)
                {
                    type_tag = 1;
                    break;
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
        }
        setType(type_tag&0xFF);
        return (typeTag0);
    }
    public void setType(int type)
    {
        typeTag0 = type;
        typeTag1 = type;
        typeTag2 = type;
        typeTag3 = type;
    }
}
src/main/java/com/whyc/abe/ABEDisDataHeadStart.java
New file
@@ -0,0 +1,108 @@
package com.whyc.abe;
import com.whyc.constant.ComBase;
import com.whyc.constant.Crc16;
import java.nio.ByteBuffer;
/**
 *     放电数据的数据头
 * @author LiJun
 *
 */
public class ABEDisDataHeadStart implements ABEDataHeadStart{
    public static final int BYTE_LEN = 44;
    public int hourRate;                   //小时率 固定为10
    public float disCurr;                //放电电流参数 x/10 A
    public int  disCap;                 //测试容量    x AH
    public int  disTime;                //测试时间
    public float groupVol_LOW;           //放电下限    x/1000 V
    public float monomerVol_LOW;        //放电下限    x/1000 V
    public int  monomerLowCount;        //下限个数 固定为1
    public int  battGroupNum;           //电池组数 固定为1
    public int  onlineVolLowAction;        //无用
    public int  staticTime;                //无用
    public int  disTestCount;              //无用
    public int  dCVolHighLimit;            //无用
    public int  battNum;                //电池编号
    public int  battVolStyle;            //无用
    public int  std_CAP;                //标称容量 x AH
    public int  testcap;                //已测容量 x AH 同 DisCap
    public int  bakeup6;
    public int  bakeup7;
    public int  bakeup8;
    public int  bakeup9;
    public int  bakeup10;
    public int  CRC;
    @Override
    public boolean  setDataInf(ByteBuffer bf) {
        //System.out.println("头部数据长度异常"+bf.remaining());
        if(bf.limit() < BYTE_LEN) {
            return false;
        }
        int crc0 = bf.getShort(BYTE_LEN-2) & 0xFFFF;
        int crc1 = Crc16.CalCRC16(bf, BYTE_LEN-2);
        if(crc0 != crc1) {
            //校验CRC
            //System.out.println(crc0 + "==" + crc1);
            return false;
        }
        bf.position(0);
        this.hourRate = ComBase.changeShortToInt(bf.getShort());                       //小时率 固定为10
        this.disCurr = ComBase.changeShortToFloat(bf.getShort())/10;                //放电电流参数 x/10 A
        this.disCap = ComBase.changeShortToInt(bf.getShort());                         //测试容量    x AH
        this.disTime = ComBase.changeShortToInt(bf.getShort());                        //测试时间
        this.groupVol_LOW = ComBase.changeShortToFloat(bf.getShort())/1000;           //放电下限    x/1000 V
        this.monomerVol_LOW = ComBase.changeShortToFloat(bf.getShort())/1000;        //放电下限    x/1000 V
        this.monomerLowCount = ComBase.changeShortToInt(bf.getShort());                //下限个数 固定为1
        this.battGroupNum = ComBase.changeShortToInt(bf.getShort());                   //电池组数 固定为1
        this.onlineVolLowAction = ComBase.changeShortToInt(bf.getShort());            //无用
        this.staticTime = ComBase.changeShortToInt(bf.getShort());                    //无用
        this.disTestCount = ComBase.changeShortToInt(bf.getShort());                  //无用
        this.dCVolHighLimit = ComBase.changeShortToInt(bf.getShort());                //无用
        this.battNum = ComBase.changeShortToInt(bf.getShort());                        //电池编号
        this.battVolStyle = ComBase.changeShortToInt(bf.getShort());                //无用
        this.std_CAP = ComBase.changeShortToInt(bf.getShort());                        //标称容量 x AH
        this.testcap = ComBase.changeShortToInt(bf.getShort());                        //已测容量 x AH 同 DisCap
        this.bakeup6 = ComBase.changeShortToInt(bf.getShort());
        this.bakeup7 = ComBase.changeShortToInt(bf.getShort());
        this.bakeup8 = ComBase.changeShortToInt(bf.getShort());
        this.bakeup9 = ComBase.changeShortToInt(bf.getShort());
        this.bakeup10 = ComBase.changeShortToInt(bf.getShort());
        this.CRC = ComBase.changeShortToInt(bf.getShort());
        //System.out.println(this);
        bf.compact();
        bf.flip();
        return true;
    }
    @Override
    public int getBattGroupNum() {
        return this.battGroupNum;
    }
    @Override
    public String toString() {
        return "ABEDisDataHeadStart [HourRate=" + hourRate + ", DisCurr=" + disCurr + ", DisCap=" + disCap
                + ", DisTime=" + disTime + ", GroupVol_LOW=" + groupVol_LOW + ", MonomerVol_LOW=" + monomerVol_LOW
                + ", MonomerLowCount=" + monomerLowCount + ", BattGroupNum=" + battGroupNum + ", OnlineVolLowAction="
                + onlineVolLowAction + ", StaticTime=" + staticTime + ", DisTestCount=" + disTestCount
                + ", DCVolHighLimit=" + dCVolHighLimit + ", BattNum=" + battNum + ", BattVolStyle=" + battVolStyle
                + ", STD_CAP=" + std_CAP + ", testcap=" + testcap + ", bakeup6=" + bakeup6 + ", bakeup7=" + bakeup7
                + ", bakeup8=" + bakeup8 + ", bakeup9=" + bakeup9 + ", bakeup10=" + bakeup10 + ", CRC=" + CRC + "]";
    }
}
src/main/java/com/whyc/abe/ABEFBSData.java
New file
@@ -0,0 +1,75 @@
package com.whyc.abe;
import com.whyc.abe.ABEVolCurrData.ABEMonData;
import com.whyc.constant.ComBase;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
 *    每一笔单体数据
 * @author LiJun
 *
 */
public class ABEFBSData {
    public ABEDataType m_DataType;       //标志位 0xFD放电 0xFC充电
    public int crc16;
    public ABETestTime m_TestTime;       //测试时间
    public int battGroup = 1;              //电池组数 固定为1
    public int battSum = 1;                //单体数   固定为1
    public ABEVolCurrData vcData;        //组端数据
    public ABEMonData mVol;                //单体数据
    public int testTimeLong;            //测试时长
    public ABEFBSData() {
        m_DataType = new ABEDataType();
        m_TestTime = new ABETestTime();
    }
    public void setData(byte[] databuf) {
        ByteBuffer bf = ByteBuffer.allocate(databuf.length);
        bf.order(ByteOrder.LITTLE_ENDIAN);
        bf.put(databuf);
        bf.position(0);
        crc16 = ComBase.changeShortToInt(bf.getShort());
        m_TestTime.hour = ComBase.changeByteToInt(bf.get());
        m_TestTime.minute = ComBase.changeByteToInt(bf.get());
        m_TestTime.second = ComBase.changeByteToInt(bf.get());
        //System.out.println(m_TestTime.hour + ":" + m_TestTime.minute + ":" + m_TestTime.second);
        battGroup = ComBase.changeByteToInt(bf.get());
        battSum = ComBase.changeShortToInt(bf.getShort());
        testTimeLong = m_TestTime.calTestTimeLong();
        bf.compact();
        bf.flip();
        vcData = new ABEVolCurrData(battGroup);
        mVol = vcData.new ABEMonData(battSum);
        vcData.putByteBuffer(bf);
        mVol.putByteBuffer(bf);
        //System.out.println(this);
    }
    @Override
    public String toString() {
        return "ABEFBSData [m_DataType=" + m_DataType + ", crc16=" + crc16 + ", m_TestTime=" + m_TestTime
                + ", battGroup=" + battGroup + ", battSum=" + battSum + ", vcData=" + vcData + ", mVol=" + mVol
                + ", testTimeLong=" + testTimeLong + "]";
    }
}
src/main/java/com/whyc/abe/ABETestDataHeadStop.java
New file
@@ -0,0 +1,83 @@
package com.whyc.abe;
import com.whyc.constant.Com;
import com.whyc.constant.ComBase;
import java.nio.ByteBuffer;
import java.util.Date;
/**
 *     充电/放电结束结构体
 * @author LiJun
 *
 */
public class ABETestDataHeadStop implements ABEDataHeadStop{
    public static final int BYTE_LEN = 18;
    public ABECtDataTime startDT;    //启动放电的日期时间
    public ABECtDataTime stopDT;    //终止放电的日期时间
    public ABETestTime test_Time;    //已测试时间(HMS)
    public int testState;            //测试状态(停止/暂停/放电)
    public int testType;            //测试类型(放电/充电)
    public int testGroupNum;        //被测试电池组编号(1~4)
    public Date testStartTime;        //测试开始时间
    public Date testStopTime;        //测试结束时间
    public long testTimeLong;        //测试时长
    public ABETestDataHeadStop() {
        startDT = new ABECtDataTime();
        stopDT = new ABECtDataTime();
        test_Time = new ABETestTime();
        testStartTime = new Date();
        testStopTime = new Date();
    }
    @Override
    public boolean setDataInf(ByteBuffer bf) {
        //System.out.println("bf.limit"+bf.remaining());
        if(bf.limit() < BYTE_LEN) {
            return false;
        }
        startDT.year = ComBase.changeByteToInt(bf.get());
        startDT.month = ComBase.changeByteToInt(bf.get());
        startDT.day = ComBase.changeByteToInt(bf.get());
        startDT.hour = ComBase.changeByteToInt(bf.get());
        startDT.minute = ComBase.changeByteToInt(bf.get());
        startDT.second = ComBase.changeByteToInt(bf.get());
        stopDT.year = ComBase.changeByteToInt(bf.get());
        stopDT.month = ComBase.changeByteToInt(bf.get());
        stopDT.day = ComBase.changeByteToInt(bf.get());
        stopDT.hour = ComBase.changeByteToInt(bf.get());
        stopDT.minute = ComBase.changeByteToInt(bf.get());
        stopDT.second = ComBase.changeByteToInt(bf.get());
        test_Time.hour = ComBase.changeByteToInt(bf.get());
        test_Time.minute = ComBase.changeByteToInt(bf.get());
        test_Time.second = ComBase.changeByteToInt(bf.get());
        testState = ComBase.changeByteToInt(bf.get());
        testType = ComBase.changeByteToInt(bf.get());
        testGroupNum = ComBase.changeByteToInt(bf.get());
        testTimeLong = test_Time.calTestTimeLong();
        testStartTime = startDT.getFBSDateTime();
        testStopTime = stopDT.getFBSDateTime();
        //System.out.println(test_Time.hour+":"+test_Time.minute+":"+test_Time.second);
        //System.out.println(this);
        return true;
    }
    @Override
    public String toString() {
        return "ABETestDataHeadStop [startDT=" + startDT + ", stopDT=" + stopDT + ", test_Time=" + test_Time
                + ", testState=" + testState + ", testType=" + testType + ", testGroupNum=" + testGroupNum
                + ", testStartTime=" + Com.getDateTimeFormat(testStartTime, Com.DTF_YMDhms) + ", testStopTime=" + Com.getDateTimeFormat(testStopTime, Com.DTF_YMDhms) + ", testTimeLong="
                + testTimeLong + "]";
    }
}
src/main/java/com/whyc/abe/ABETestTime.java
New file
@@ -0,0 +1,16 @@
package com.whyc.abe;
/**
 *     测试时间
 * @author LiJun
 *
 */
public class ABETestTime {
    public int hour;
    public int minute;
    public int second;
    public int calTestTimeLong() {
        return hour*60*60 + minute*60 + second;
    }
}
src/main/java/com/whyc/abe/ABEVolCurrData.java
New file
@@ -0,0 +1,135 @@
package com.whyc.abe;
import com.whyc.constant.ComBase;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
public class ABEVolCurrData {
    public static final int    BATT_MONOMER_COUNT_MAX = 500;
    public static final int    BATT_GROUP_COUNT_MAX = 4;
    public static final int GROUP_BYTE_LEN = 80;
    public float onlinevol[];     //无用
    public float  groupvol[];     //电池电压 x/1000 V
    public int  battstate[];    //无用
    public float  battcurr[];     //测试电流 x/10 A
    public float  battcap[];      //测试容量 x AH
    public float  batttemp[];     //无用
    public int monMAX_num[];         //无用
    public int monMIN_num[];      //无用
    public float  monvolMAX[];    //无用
    public float  monvolMIN[];    //无用
    public ABEVolCurrData(int battGroupCount) {
        if(battGroupCount > BATT_GROUP_COUNT_MAX) {
            battGroupCount = BATT_GROUP_COUNT_MAX;
        }else if(battGroupCount < 1) {
            battGroupCount = 1;
        }
        onlinevol = new float[BATT_GROUP_COUNT_MAX];         //无用
        groupvol = new float[BATT_GROUP_COUNT_MAX];         //电池电压 x/1000 V
        battstate = new int[BATT_GROUP_COUNT_MAX];            //无用
        battcurr = new float[BATT_GROUP_COUNT_MAX];         //测试电流 x/10 A
        battcap = new float[BATT_GROUP_COUNT_MAX];          //测试容量 x AH
        batttemp = new float[BATT_GROUP_COUNT_MAX];         //无用
        monMAX_num = new int[BATT_GROUP_COUNT_MAX];           //无用
        monMIN_num = new int[BATT_GROUP_COUNT_MAX];          //无用
        monvolMAX = new float[BATT_GROUP_COUNT_MAX];        //无用
        monvolMIN = new float[BATT_GROUP_COUNT_MAX];        //无用
    }
    public class ABEMonData{
        public static final int MON_BYTE_LEN = 2;
        public float vol[];
        public ABEMonData(int monCount) {
            if(monCount > BATT_MONOMER_COUNT_MAX) {
                monCount = BATT_MONOMER_COUNT_MAX;
            }else if(monCount < 1) {
                monCount = 1;
            }
            vol = new float[monCount];
        }
        public boolean putByteBuffer(ByteBuffer bf) {
            ByteBuffer buf = ByteBuffer.allocate(bf.limit());
            buf.order(ByteOrder.LITTLE_ENDIAN);
            buf.put(bf);
            buf.position(0);
            //System.out.println(buf.capacity()+"########");
            if(buf.capacity() < (MON_BYTE_LEN * vol.length)) {
                return false;
            }
            for(int i = 0;i < vol.length;i++) {
                vol[i] = ComBase.changeShortToFloat(buf.getShort())/1000;
            }
            //System.out.println(this);
            return true;
        }
        @Override
        public String toString() {
            return "ABEMonData [vol=" + Arrays.toString(vol) + "]";
        }
    }
    public boolean putByteBuffer(ByteBuffer buf) {
        buf.position(0);
        //System.out.println(buf.capacity()+"====");
        if(buf.capacity() < GROUP_BYTE_LEN) {
            return false;
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            onlinevol[i] = ComBase.changeShortToFloat(buf.getShort());        //无用
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            groupvol[i] = ComBase.changeShortToFloat(buf.getShort())/1000;    //电池电压 x/1000 V
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            battstate[i] = ComBase.changeShortToInt(buf.getShort());            //无用
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            battcurr[i] = ComBase.changeShortToFloat(buf.getShort())/10;        //测试电流 x/10 A
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            battcap[i] = ComBase.changeShortToFloat(buf.getShort());            //测试容量 x AH
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            batttemp[i] = ComBase.changeShortToFloat(buf.getShort());        //无用
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            monMAX_num[i] = ComBase.changeShortToInt(buf.getShort());        //无用
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            monMIN_num[i] = ComBase.changeShortToInt(buf.getShort());        //无用
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            monvolMAX[i] = ComBase.changeShortToFloat(buf.getShort());        //无用
        }
        for(int i=0;i<BATT_GROUP_COUNT_MAX;i++) {
            monvolMIN[i] = ComBase.changeShortToFloat(buf.getShort());        //无用
        }
        buf.compact();
        buf.flip();
        //System.out.println(this);
        return true;
    }
    @Override
    public String toString() {
        return "ABEVolCurrData [onlinevol=" + Arrays.toString(onlinevol) + ", groupvol=" + Arrays.toString(groupvol)
                + ", battstate=" + Arrays.toString(battstate) + ", battcurr=" + Arrays.toString(battcurr) + ", battcap="
                + Arrays.toString(battcap) + ", batttemp=" + Arrays.toString(batttemp) + ", monMAX_num="
                + Arrays.toString(monMAX_num) + ", monMIN_num=" + Arrays.toString(monMIN_num) + ", monvolMAX="
                + Arrays.toString(monvolMAX) + ", monvolMIN=" + Arrays.toString(monvolMIN) + "]";
    }
}
src/main/java/com/whyc/constant/Com.java
New file
@@ -0,0 +1,159 @@
package com.whyc.constant;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Com {
    final public static int UploadData_ClientType_BS_CLI = 0;
    final public static int UploadData_ClientType_CS_CLI = 1;
    final public static int UploadData_ClientType_CS_SVR = 2;
    final public static String DTF_YMDhms = "yyyy-MM-dd HH:mm:ss";
    final public static String DTF_YMDhm = "yyyy-MM-dd HH:mm";
    final public static String DTF_YMDh = "yyyy-MM-dd HH";
    final public static String DTF_YMD = "yyyy-MM-dd";
    final public static String DTFYMD = "yyyyMMdd";
    final public static String DTF_hms = "HH:mm:ss";
    final public static String DTF_YMD_h_m_s = "yyyy-MM-dd+HH_mm_ss";
    //final public static DateFormat DateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    /**
     * �������ʱ��ת����ָ���ĵ�ʱ���ʽ������ʱ���ʽ��֮����ַ���
     * @param dt        ��Ҫת����ʱ��
     * @param format    ��ʽ���ַ���
     * @return
     */
    public static String getDateTimeFormat(Date dt, String format){
        DateFormat dtf = new SimpleDateFormat(format);
        return dtf.format(dt);
    }
    /**
     * ��������ַ�����ָ���ĸ�ʽ������ʱ�����Ͳ�����
     * @param dt       ��Ҫ�������ַ���
     * @param format   ָ����ʱ���ʽ
     * @return
     */
    public static Date getDateTimeFromStr(String dt, String format){
        DateFormat dtf = new SimpleDateFormat(format);
        Date date = new Date();
        try {
            date = dtf.parse(dt);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    public static String getNowTimeWithAt() {
        return " @ " + Com.getDateTimeFormat(new Date(), Com.DTF_YMDhms);
    }
    /**
     * �ж�number�����Ƿ�����������ʾ��ʽ
     * @param number
     * @return
     */
    public static boolean isIntegerNumber(String number){
        number = number.trim();
        String intNumRegex = "\\-{0,1}\\d+";    //������������ʽ
        if(number.matches(intNumRegex))
            return true;
        else
            return false;
    }
    /**
     * �ж�number�����Ƿ��Ǹ�������ʾ��ʽ
     * @param numbe
     * @return
     */
    public static boolean isFloatPointNumber(String number){
        number = number.trim();
        String intNumRegex = "\\-{0,1}\\d+";                //������������ʽ
        String pointPrefix = "(\\-|\\+){0,1}\\d*\\.\\d+";    //��������������ʽ-С�������м���ǰ��
        String pointSuffix = "(\\-|\\+){0,1}\\d+\\.";        //��������������ʽ-С�����ں���
        if(number.matches(intNumRegex) || number.matches(pointPrefix) || number.matches(pointSuffix))
            return true;
        else
            return false;
    }
    /**
     * �ж�number�����Ƿ������ڱ�ʾ��ʽ
     * @param str
     * @return
     */
    public static boolean isValidDate(String str, String format) {
        boolean convertSuccess = true;
        try {
            //DateTimeFormat.setLenient(false);
            DateFormat dtf = new SimpleDateFormat(format);
            dtf.parse(str);
         } catch (ParseException e) {
             convertSuccess = false;
         }
         return convertSuccess;
    }
    /**
     * ����ϵͳ������ʱ��
     * @param str
     * @return
     */
    public static void setDateTime(Date ts){
        String osName = System.getProperty("os.name");
        String cmd = "";
        try {
            if (osName.matches("^(?i)Windows.*$")) {// Window ϵͳ
                // ��ʽ HH:mm:ss
                cmd = "cmd /c time " + getDateTimeFormat(ts, Com.DTF_hms);
                Runtime.getRuntime().exec(cmd);
                // ��ʽ��yyyy-MM-dd
                cmd = "cmd /c date " + getDateTimeFormat(ts, Com.DTF_YMD);
                Runtime.getRuntime().exec(cmd);
            } else {// Linux ϵͳ
                // ��ʽ��yyyyMMdd
                cmd = "date -s " + getDateTimeFormat(ts, Com.DTFYMD);
                Runtime.getRuntime().exec(cmd);
                // ��ʽ HH:mm:ss
                cmd = "date -s " + getDateTimeFormat(ts, Com.DTF_hms);
                Runtime.getRuntime().exec(cmd);
            }
        } catch (IOException e) {
              e.printStackTrace();
        }
    }
    /**
     *
     * @param
     * @return
     */
    public static void getIPFromStr(String ipstr, byte ip[])
    {
        try
        {
            for(int n=0; n < 3; n++)
            {
                int index = ipstr.indexOf('.');
                if(index > 0)
                    ip[n] = (byte)Integer.parseInt(ipstr.substring(0, index));
                ipstr = ipstr.substring(index+1);
            }
            ip[3] = (byte)Integer.parseInt(ipstr);
            //System.out.println((ip[0]&0xFF) + ": "+(ip[1]&0xFF) + ": "+(ip[2]&0xFF)+ ": "+(ip[3]&0xFF));
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}
src/main/java/com/whyc/constant/ComBase.java
New file
@@ -0,0 +1,178 @@
package com.whyc.constant;
public class ComBase
{
    public static final byte CapType_Rest = 0;
    public static final byte CapType_Real = 1;
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static byte changeIntToByte(int data)
    {
        return (byte)(data & 0xFF);
    }
    //------------------------------------------------------------------------------
    public static short changeIntToShort(int data)
    {
        return (short)(data & 0xFFFF);
    }
    //------------------------------------------------------------------------------
    public static byte changeShortToByte(short data)
    {
        return (byte)(data & 0xFF);
    }
    //------------------------------------------------------------------------------
    public static int changeByteToInt(byte data)
    {
        int tmp = data;
        return (tmp & 0xFF);
    }
    //------------------------------------------------------------------------------
    public static int changeShortToInt(short data)
    {
        int tmp = data;
        return (tmp & 0xFFFF);
    }
    //------------------------------------------------------------------------------
    public static double changeShortToDouble(short data)
    {
        int tmp = data & 0xFFFF;
        return (double)(tmp);
    }
    public static float changeShortToFloat(short data)
    {
        int tmp = data & 0xFFFF;
        return (float)(tmp);
    }
    //------------------------------------------------------------------------------
    public static short changeDoubleToShort(double data)
    {
        int tmp = (int)data;
        return (short)(tmp & 0xFFFF);
    }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static double GetFDCurrent(double stdcap, int hourrate)
    {
        double res = 0.055;
        switch(hourrate)
        {
            case 1: res = 0.514; break;
            case 2: res = 0.306; break;
            case 3: res = 0.250; break;
            case 4: res = 0.200; break;
            case 5: res = 0.166; break;
            case 6: res = 0.146; break;
            case 7: res = 0.131; break;
            case 8: res = 0.118; break;
            case 9: res = 0.108; break;
            case 10: res = 0.100; break;
            case 20: res = 0.055; break;
            default: res = 0.055; break;
        }
        return (stdcap * res);
    }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static int GetHourRate(double stdah, double current)
    {
        int index = 0;
        double value[]={5.14, 3.06, 2.50, 2.00, 1.66, 1.46, 1.31, 1.18, 1.08, 1.00, 0.55};
        double res;
        if(stdah < 1)
            stdah = 1;
        res = current/(stdah/10);
        if(res >= 5.14) return 1;
        else if(res <= 0.55) return 20;
        else
        {
            for(index=0; index<10; index++)
            {
                if((res<=value[index]) && (res>value[index+1]))    break;
                else continue;
            }
            if((value[index]-res) < (res-value[index+1]))
            {
                return (index+1);
            }
            else
            {
                if(index+2 > 10) return (20);
                else return (index+2);
            }
        }
    }
    //------------------------------------------------------------------------------
    //------------------------------------------------------------------------------
    public static double N_TO_10H(int n_H)
    {
        switch(n_H)
        {
            case  1 : return(1/0.55);
            case  2 : return(1/0.61);
            case  3 : return(1/0.75);
            case  4 : return(1/0.79);
            case  5 : return(1/0.833);
            case  6 : return(1/0.876);
            case  7 : return(1/0.917);
            case  8 : return(1/0.944);
            case  9 : return(1/0.974);
            case  10: return(1/1);
            case  20: return(1/1.1);
        }
        return 1.0;
    }
    //-------------------------------------------------------------------------------
    //-------------------------------------------------------------------------------
    public static double GetMonomerCap(double STDAH, int HourRate, double SumAH, double MaxMonomerVol,
                                        double MonomerVol, double MonomerVolType, byte CapType)
    {
        if(MaxMonomerVol - MonomerVolType*0.9 <= 0)
            return 0;
        if(STDAH < 1)
            STDAH = 1;
        if(SumAH < 0)
            SumAH *= (-1);
        double tmp_cap;
        tmp_cap = MonomerVol - MonomerVolType * 0.9;
        tmp_cap *= (STDAH - SumAH * N_TO_10H(HourRate));
        double dt_vol = MaxMonomerVol - MonomerVolType*0.9;
        if(dt_vol < 0.01)
            dt_vol = 0.01;
        tmp_cap = tmp_cap/dt_vol;
        if(tmp_cap < 0)
            tmp_cap = 0;
        if(CapType == CapType_Rest)
            return tmp_cap;
        else if(CapType == CapType_Real)
            return (tmp_cap + SumAH * N_TO_10H(HourRate));
        else
            return ((tmp_cap + SumAH * N_TO_10H(HourRate))*100 / STDAH);
    }
    //----------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------
    public static int GetRestTimeSecond(double restcap, double curr)
    {
        double tmp_curr = Math.abs(curr);
        if(tmp_curr < 0.1)
            tmp_curr = 0.1;
        int rest_time = (int)((restcap / tmp_curr) * 3600);
        if(rest_time > (99*3600))
            rest_time = (99*3600);
        return rest_time;
    }
    //----------------------------------------------------------------------------------
}
/***************************************************************************************
******************************* end of file (FBS_ComBase)*******************************
***************************************************************************************/
src/main/java/com/whyc/constant/ConstantDefined.java
New file
@@ -0,0 +1,20 @@
package com.whyc.constant;
public class ConstantDefined {
    /************************* 解析失败原因 **************************************/
    public static final int PARSE_RESULT_NULL = 0;            //未知
    public static final int PARSE_RESULT_SUCCESS = 1;        //解析成功
    public static final int PARSE_RESULT_NOTFOUNDFILE = 2;    //文件未找到
    public static final int PARSE_RESULT_FILETYPEERR = 3;    //文件格式错误
    public static final int PARSE_RESULT_FILEERROR = 4;        //文件异常
    /*****************************************************************************/
    /************************* 数据类型 ******************************************/
    public static final int DATA_TYPE_DIS     = 0xFD;            //放电
    public static final int DATA_TYPE_CHR     = 0xFC;            //充电
    public static final int DATA_TYPE_RULE     = 0xFB;            //常规
    /*****************************************************************************/
}
src/main/java/com/whyc/constant/Crc16.java
New file
@@ -0,0 +1,61 @@
package com.whyc.constant;
import java.nio.ByteBuffer;
public class Crc16 {
    private final static int CRC16Table[] =
    {
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
    };
    public static int CalCRC16(final ByteBuffer buf, int count)
    {
        ByteBuffer tmpbuf = buf;
        tmpbuf.position(0);
        int crc = 0xFFFF;    //关键性的初值...
        int tmp;
        for (int i=0; i<count; i++)
        {
                if(!buf.hasRemaining())
                    break;
                tmp = crc;
                crc = CRC16Table[(int)((((tmp&0xFFFF) >> 8) ^ (tmpbuf.get())) & 0xFF)];
                crc = crc ^ ((tmp&0xFFFF) << 8);
        }
        return (crc & 0xFFFF);
    }
}
src/main/java/com/whyc/constant/ParseUtil.java
New file
@@ -0,0 +1,72 @@
package com.whyc.constant;
import java.io.FileInputStream;
public class ParseUtil {
    /**
     *     检查数据的数据类型
     * @param fis
     * @return
     */
    public static int checkFBSDataType(FileInputStream fis) {
        boolean file_end = false;
        byte[] tag = new byte[1];
        int data_type = -1;
        try {
            fis.mark(2060);
            int count = 0;
            while(true)
            {
                count++;
                int n = 0;
                for(n=0; n<4; n++)
                {
                    if(1 != fis.read(tag, 0, 1))
                    {
                        file_end = true;
                        break;
                    }
                    if((ConstantDefined.DATA_TYPE_DIS != (tag[0]&0xFF)) && (ConstantDefined.DATA_TYPE_CHR != (tag[0]&0xFF)) && (ConstantDefined.DATA_TYPE_RULE != (tag[0]&0xFF)))
                    {
                        break;
                    }else {
                        int tmp_tag = tag[0]&0xFF;
                        System.out.println(tmp_tag+"==="+n);
                        if(n > 0 && (data_type != tmp_tag)) {
                            //筛选数据中只出现一个FD的情况
                            break;
                        }
                        data_type = tag[0]&0xFF;
                    }
                }
                if(n >= 4)
                {
                    //提前解析完成
                    break;
                }
                if(true == file_end)
                {
                    //读取完成
                    break;
                }
                System.out.println("=======count:" + count);
            }
            fis.reset();
            //判断是否支持mark标记
            if(fis.markSupported())
            {
                System.out.println("@@@@@@@@@@@@");
                //重置数据流的位置避免重新读取文件
            }
        } catch (Exception e) {
            e.printStackTrace();
            data_type = -1;
        }
        return data_type;
    }
}
src/main/java/com/whyc/controller/BattRealdataController.java
@@ -38,4 +38,10 @@
        return service.excelParse(file);
    }
    @ApiOperation("ABE文件解析")
    @PostMapping("ABEParse")
    public Response aBEParse(@RequestParam MultipartFile file) throws IOException {
        return service.aBEParse(file);
    }
}
src/main/java/com/whyc/service/BattRealdataService.java
@@ -1,6 +1,8 @@
package com.whyc.service;
import com.github.pagehelper.PageInfo;
import com.whyc.abe.ABEDataParase;
import com.whyc.abe.ABEDataParseUtil;
import com.whyc.dto.BattDataDTO;
import com.whyc.dto.BattTestData;
import com.whyc.dto.Response;
@@ -235,4 +237,8 @@
        return new Response().set(1,dataList);
    }
    public Response aBEParse(MultipartFile file) throws IOException {
        ABEDataParase abeDataParase = ABEDataParseUtil.readFBSFile(file);
        return new Response().set(1,abeDataParase);
    }
}