定制版本逆变电源通讯程序[增加干节点状态读取和母联开关状态读取以及防雷显示]
V10.640 edit at date 2021-11-03 lijun
1.修复锂电BTS远程修改电池参数与常规BTS电池参数不一致bug
2.修复BTS记录充放电数据时记录一次内阻数据的test_record_count==0bug
12个文件已修改
2个文件已添加
719 ■■■■■ 已修改文件
BattMonitor_FBS9100S_Inverter/log4j2_batt_ms_x64_fbsdev.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/data/BattData_RT_Array.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/dev/DevRealDataPro_Thread.java 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/dev/FBS9100S_DeviceInf.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/sql/Sql_Mysql.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/batttest/BattResStorePro_Thread.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/comm/BattRealDataPro_Thread.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/comm/FBS9100S_SocketClient2.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/comm/FBS9100_Task_Thread_SQL.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/data/FBS9100S_LiBMS_AnalogData.java 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/data/FBS9100_ParamBatt.java 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/data/FBS9100_VCData.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/com/version_inf/version_inf.txt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/src/main/main_MonitorServer_FBS9100S.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
BattMonitor_FBS9100S_Inverter/log4j2_batt_ms_x64_fbsdev.xml
@@ -43,7 +43,7 @@
    </Appenders>
    <Loggers>
        <Root level="trace">
        <Root level="TRACE">
            <AppenderRef ref="Console" />
            <appenderRef ref="INFO" />
            <appenderRef ref="ERROR" />
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/data/BattData_RT_Array.java
@@ -11,6 +11,7 @@
import com.battmonitor.base.AppParam;
import com.battmonitor.base.Com;
import com.battmonitor.data_store.InsertDataToMysql_Task_SQL;
import com.battmonitor.dev.FBS9100S_DeviceInf;
import com.battmonitor.sql.MysqlConnPool;
import com.battmonitor.sql.Sql_Mysql;
import com.config.AppConfig;
@@ -24,6 +25,8 @@
    final public static int DATA_SOURCE_SQLSERVER_AND_C_INTERFACE = 3;
    
    private ArrayList<BattData_RT> Data_Array = new ArrayList<BattData_RT>();
    private ArrayList<FBS9100S_DeviceInf> Device_Array = new ArrayList<>();
    private MysqlConnPool m_Conn_Pool;
    private int Sybase_query_count = 0;
    private Date m_SybaseServerDate = new Date();
@@ -41,6 +44,33 @@
        m_Conn_Pool = pool;
    }
    
    /**
     *     获取当前设备的信息
     * @param dev_id
     * @return
     */
    public FBS9100S_DeviceInf getDeviceInfByDevId(int dev_id) {
        for(int i=0;i<Device_Array.size();i++) {
            if(Device_Array.get(i).getDev_id() == dev_id) {
                return Device_Array.get(i);
            }
        }
        FBS9100S_DeviceInf dev_inf = new FBS9100S_DeviceInf(dev_id);
        Device_Array.add(dev_inf);
        return dev_inf;
    }
    public FBS9100S_DeviceInf getItemDevInf(int index) {
        if(index < Device_Array.size()) {
            return Device_Array.get(index);
        }
        return null;
    }
    public int getDeviceCount() {
        return Device_Array.size();
    }
    public Date getSybaseServerDateTime()
    {
        return m_SybaseServerDate;
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/dev/DevRealDataPro_Thread.java
New file
@@ -0,0 +1,295 @@
package com.battmonitor.dev;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.battmonitor.base.Com;
import com.battmonitor.data.BattData_RT;
import com.battmonitor.data.BattData_RT_Array;
import com.battmonitor.data.BattStatData;
import com.battmonitor.sql.MysqlConnPool;
import com.battmonitor.sql.Sql_Mysql;
import com.config.AppConfig;
import com.dev.btse.comm.FBS9100_Task_Thread_SQL;
import com.dev.btse.data.FBS9100S_LiBMS_AnalogData;
/**
 * 设备历史实时数据记录线程
 * @author LiJun
 *
 */
public class DevRealDataPro_Thread extends Thread{
    public MysqlConnPool con_pool;
    public AppConfig cfg;
    public BattData_RT_Array data;
    public static int MinRecordTimeLong = 60;            //每次记录的最短时间间隔
    public static int MaxRecordTimeLong = 366*3;        //最大记录历史数据时间
    private Logger logger = null;
    public DevRealDataPro_Thread(MysqlConnPool con_pool, AppConfig cfg, BattData_RT_Array data) {
        this.cfg = cfg;
        this.con_pool = con_pool;
        this.data = data;
        logger = LogManager.getFormatterLogger(this.getClass());
        MinRecordTimeLong = cfg.getRealDataRecord_MinTimeLong();
        MaxRecordTimeLong = cfg.getRealDataRecord_MaxSaveTime();
    }
    @Override
    public void run() {
        logger.warn("DevRealDataPro_Thread Started ...");
        Date lastTime = new Date();
        Date lastdelTime = new Date();                    //上一次删除历史实时表检测时间
        //线程启动前休眠60秒                                    //用于甄别还未通讯上的设备
        for(int i =0; i<60; i++) {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                System.err.println( e);
            }
        }
        logger.warn("DevRealDataPro_Thread Start  Record......");
        Date nowTime = null;
        while(true) {
            try {
                sleep(50);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                System.out.println(e1);
            }
            /**********************************************************/
            nowTime = new Date();
            long timelong =(nowTime.getTime()-lastTime.getTime())/1000;
            long deltimelong =(nowTime.getTime()-lastdelTime.getTime())/1000;
            try {
                /**************** lijun add @ 20200906 ***************/
                //获取指定天数之前的时间
                Date critical = getDateBefore(nowTime, MaxRecordTimeLong);
                //删除修改时间超时的数据表
                //FBS9100_Task_Thread_SQL.deleteHistoryData(con_pool, critical);
                //删除修改时间超时的数据表
                if(deltimelong > 60*60*24) {
                    /**
                     * 2021-08-25 @lijun 24小时定期检测删除指定天数之前的历史实时表,该查询占用SQL资源较大,减轻SQL查询负担
                     */
                    deleteHistoryData(con_pool, critical);
                    lastdelTime = nowTime;
                }
                /**********************************************************/
                if(timelong < MinRecordTimeLong) {
                    continue;
                }
                boolean isRecorded = false;
                for(int i=0; i<data.getDeviceCount(); i++) {
                    FBS9100S_DeviceInf dev_inf = data.getItemDevInf(i);
                    if((nowTime.getTime()-dev_inf.getM_liBMS_RecordTime().getTime())>(5*60*1000)) {
                        continue;                //筛除通讯超时电池组信息记录(5分钟)
                    }
                    if(null != dev_inf) {
                        continue;
                    }
                    isRecorded = true;
                    //记录当前电池组的历史实时记录
                    RecordDevReadDataNew(con_pool, dev_inf);                            //记录电池组的放电记录
                    sleep(50);
                }
                if(isRecorded) {
                    lastTime = nowTime;
                }
                /**************** mxpopstar edit @ 20200817 ***************/
                /*sleep(500);*/        //this statement is big bug, because line 59 use "continue" statement;
                /**************** mxpopstar edit @ 20200817 ***************/
            } catch (Exception e) {
                logger.error(e.toString(),e);
            }
        }
    }
    private void RecordDevReadDataNew(MysqlConnPool con_pool2, FBS9100S_DeviceInf dev_inf) {
        Date time = new Date();
        //创建指定电池组的电池组当月历史实时数据记录表
        CreateTb_DevRealDataTable(con_pool, dev_inf.dev_id,time);
        //String sql_str_delete = " DELETE FROM "+ Sql_Mysql.Tb_Batt_RealData+battData.BattGroupId +" WHERE recrod_time < DATE_SUB(NOW(),INTERVAL 1 YEAR) ";                    //删除超过1年的记录
        String sql_str = " INSERT INTO " + Sql_Mysql.Tb_Dev_RealData+dev_inf.dev_id+"_"+Com.getDateTimeFormat(time, Com.DTF_YM)+"(dev_id,record_time,bms_idx,data_flag,pack_pos,monomer_cnt,mon_vol1,mon_vol2,mon_vol3,mon_vol4,mon_vol5,mon_vol6,mon_vol7,mon_vol8,mon_vol9,mon_vol10,mon_vol11,mon_vol12,mon_vol13,mon_vol14,mon_vol15,mon_vol16,tmp_cnt,mon_tmp1,mon_tmp2,mon_tmp3,mon_tmp4,env_temp,mos_temp,current,sum_vol,rest_cap,sum_cap,cycle_times,user_def_cnt)  VALUES" ;
        Date dt_record = new Date();
        for(int i=0;i<dev_inf.m_LiBMS_States.length;i++) {
            if(i > 0){
                sql_str += ",";
            }
            FBS9100S_LiBMS_AnalogData data = dev_inf.m_LiBMS_States[i];
            sql_str+="("
                    + dev_inf.dev_id+","
                    + "'" + Com.getDateTimeFormat(dt_record,Com.DTF_YMDhms ) + "',"
                    + (i+1) +","
                    + data.data_flag + ","
                    + data.pack_pos +","
                    + data.monomer_cnt +","
                    + data.monomer_vol[0] +","
                    + data.monomer_vol[1] +","
                    + data.monomer_vol[2] +","
                    + data.monomer_vol[3] +","
                    + data.monomer_vol[4] +","
                    + data.monomer_vol[5] +","
                    + data.monomer_vol[6] +","
                    + data.monomer_vol[7] +","
                    + data.monomer_vol[8] +","
                    + data.monomer_vol[9] +","
                    + data.monomer_vol[10] +","
                    + data.monomer_vol[11] +","
                    + data.monomer_vol[12] +","
                    + data.monomer_vol[13] +","
                    + data.monomer_vol[14] +","
                    + data.monomer_vol[15] +","
                    + data.temp_cnt +","
                    + data.monomer_temp[0] +","
                    + data.monomer_temp[1] +","
                    + data.monomer_temp[2] +","
                    + data.monomer_temp[3] +","
                    + data.env_temp +","
                    + data.current +","
                    + data.sum_vol +","
                    + data.rest_cap +","
                    + data.sum_cap +","
                    + data.cycle_times +","
                    + data.user_def_cnt
                    +")";
        }
        Sql_Mysql sql = new Sql_Mysql(con_pool.getConn());
        try {
            sql.sqlMysqlExecute(sql_str);
        } catch (SQLException e) {
            logger.error(e.toString(),e);
        } finally {
            sql.close_con();
        }
    }
    /**
     * 创建指定的电池组历史数据记录表
     * @param pool
     * @param BattGroupId    电池组id
     * @param time 记录时间
     */
    private void CreateTb_DevRealDataTable(MysqlConnPool pool, int dev_id, Date time) {
        String  sql_str = "CREATE TABLE IF NOT EXISTS " + Sql_Mysql.Tb_Dev_RealData+dev_id+"_"+Com.getDateTimeFormat(time, Com.DTF_YM) + " (" +
                "  `num` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键'," +
                "  `dev_id` int(11) NOT NULL DEFAULT '0' COMMENT '设备ID'," +
                "  `record_time` datetime NOT NULL DEFAULT '2000-01-01 00:00:00' COMMENT '记录时间'," +
                "  `bms_idx` int(11) NOT NULL DEFAULT '0' COMMENT '信息索引'," +
                "  `op_cmd` int(11) NOT NULL DEFAULT '0' COMMENT '控制'," +
                "  `data_flag` int(11) NOT NULL DEFAULT '0'," +
                "  `pack_pos` int(11) NOT NULL DEFAULT '0' COMMENT '上位机需要获取的pack组位置'," +
                "  `monomer_cnt` int(11) NOT NULL DEFAULT '0' COMMENT '单体电池数量'," +
                "  `mon_vol1` float NOT NULL DEFAULT '0' COMMENT '单体1电压'," +
                "  `mon_vol2` float NOT NULL DEFAULT '0' COMMENT '单体2电压'," +
                "  `mon_vol3` float NOT NULL DEFAULT '0' COMMENT '单体3d'," +
                "  `mon_vol4` float NOT NULL DEFAULT '0' COMMENT '单体4电压'," +
                "  `mon_vol5` float NOT NULL DEFAULT '0' COMMENT '单体5电压'," +
                "  `mon_vol6` float NOT NULL DEFAULT '0' COMMENT '单体6电压'," +
                "  `mon_vol7` float NOT NULL DEFAULT '0' COMMENT '单体7电压'," +
                "  `mon_vol8` float NOT NULL DEFAULT '0' COMMENT '单体8电压'," +
                "  `mon_vol9` float NOT NULL DEFAULT '0' COMMENT '单体9电压'," +
                "  `mon_vol10` float NOT NULL DEFAULT '0' COMMENT '单体10电压'," +
                "  `mon_vol11` float NOT NULL DEFAULT '0' COMMENT '单体11电压'," +
                "  `mon_vol12` float NOT NULL DEFAULT '0' COMMENT '单体12电压'," +
                "  `mon_vol13` float NOT NULL DEFAULT '0' COMMENT '单体13电压'," +
                "  `mon_vol14` float NOT NULL DEFAULT '0' COMMENT '单体14电压'," +
                "  `mon_vol15` float NOT NULL DEFAULT '0' COMMENT '单体15电压'," +
                "  `mon_vol16` float NOT NULL DEFAULT '0' COMMENT '单体16电压'," +
                "  `tmp_cnt` int(11) NOT NULL DEFAULT '0' COMMENT '电芯温度数量'," +
                "  `mon_tmp1` float NOT NULL DEFAULT '0' COMMENT '电芯1温度'," +
                "  `mon_tmp2` float NOT NULL DEFAULT '0' COMMENT '电芯2温度'," +
                "  `mon_tmp3` float NOT NULL DEFAULT '0' COMMENT '电芯3温度'," +
                "  `mon_tmp4` float NOT NULL DEFAULT '0' COMMENT '电芯4温度'," +
                "  `env_temp` int(11) NOT NULL DEFAULT '0' COMMENT '环境温度'," +
                "  `mos_temp` int(11) NOT NULL DEFAULT '0' COMMENT 'MOS管温度'," +
                "  `current` int(11) NOT NULL DEFAULT '0' COMMENT '电流'," +
                "  `sum_vol` int(11) NOT NULL DEFAULT '0' COMMENT '总压'," +
                "  `rest_cap` int(11) NOT NULL DEFAULT '0' COMMENT '剩余容量'," +
                "  `sum_cap` int(11) NOT NULL DEFAULT '0' COMMENT '总容量'," +
                "  `cycle_times` int(11) NOT NULL DEFAULT '0' COMMENT '电池循环次数'," +
                "  `user_def_cnt` int(11) NOT NULL DEFAULT '0' COMMENT '自定义遥测数量'," +
                "  PRIMARY KEY (`num`)," +
                "  KEY `idx_dev_id` (`dev_id`) USING BTREE" +
                ") ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;";
        Sql_Mysql sql = new Sql_Mysql(pool.getConn());
        try {
            sql.sqlMysqlExecute(sql_str);
        } catch (SQLException e) {
            sql.logger.error("CreateTb_DevRealDataTable():" + e.toString(), e);
        } finally {
            sql.close_con();
        }
    }
    /**
     *     获取指定时间之前指定天数的时间
     * @param d
     * @param day
     * @return
     */
    public static Date getDateBefore(Date d,int day){
        Calendar now =Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE,now.get(Calendar.DATE)-day);
        return now.getTime();
    }
    public static void main(String[] args) {
        System.out.println(Com.getDateTimeFormat(getDateBefore(new Date(), 366), Com.DTF_YMDhms));
    }
    /**
     *     删除表创建时间超时的历史数据表[没有修改时间的表不会有应影响]
     */
    public static void deleteHistoryData(MysqlConnPool conn_pool,Date deldate) {
        String sql_select_strs = " select TABLE_NAME,UPDATE_TIME " +
                                 " from information_schema.tables " +
                                 " where table_schema='db_dev_history' " +
                                 " AND TABLE_NAME like 'tb_dev_bms_state__%' " +
                                 " AND CREATE_TIME <= '"+Com.getDateTimeFormat(deldate, Com.DTF_YMDhms)+"';" ;
        String sql_delete_strs = " DROP TABLE IF EXISTS ";
        Sql_Mysql sql = new Sql_Mysql(conn_pool.getConn());
        ResultSet res = null;
        int count = 0;
        res = sql.sqlMysqlQuery(sql_select_strs);
        try {
            while(res.next()) {
                if(count > 0) {
                    sql_delete_strs += ",";
                }
                sql_delete_strs += "db_dev_history." + res.getString("TABLE_NAME");
                System.out.println("删除:"+res.getString("TABLE_NAME")+"\t at "+Com.getDateTimeFormat(new Date(), Com.DTF_YMDhms));
                count++;
            }
            if(count >0) {
                sql.sqlMysqlExecute(sql_delete_strs);
            }
            res.close();
        } catch (SQLException e) {
            sql.logger.error("DevRealDataPro_Thread.deleteHistoryData():" + e.toString(), e);
        } finally {
            sql.close_con();
        }
    }
}
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/dev/FBS9100S_DeviceInf.java
New file
@@ -0,0 +1,59 @@
package com.battmonitor.dev;
import java.util.Date;
import com.dev.btse.data.FBS9100S_LiBMS_AnalogData;
/**
 *     设备对象,方便定期存储设备历史实时信息
 * @author LiJun
 *
 */
public class FBS9100S_DeviceInf {
    public static final int Max_LiBMSCount = 4;
    public int dev_id;
    public Date m_liBMS_RecordTime = new Date(0);
    public FBS9100S_LiBMS_AnalogData[] m_LiBMS_States;
    public FBS9100S_DeviceInf(int dev_id) {
        this.dev_id = dev_id;
        this.m_LiBMS_States = new FBS9100S_LiBMS_AnalogData[Max_LiBMSCount];
        for(int i=0;i<m_LiBMS_States.length;i++) {
            m_LiBMS_States[i] = new FBS9100S_LiBMS_AnalogData();
        }
    }
    public int getDev_id() {
        return dev_id;
    }
    public Date getM_liBMS_RecordTime() {
        return m_liBMS_RecordTime;
    }
    public FBS9100S_LiBMS_AnalogData[] getM_LiBMS_States() {
        return m_LiBMS_States;
    }
    public void setDev_id(int dev_id) {
        this.dev_id = dev_id;
    }
    public void setM_liBMS_RecordTime(Date m_liBMS_RecordTime) {
        this.m_liBMS_RecordTime = m_liBMS_RecordTime;
    }
    public void setM_LiBMS_States(FBS9100S_LiBMS_AnalogData[] m_LiBMS_States) {
        this.m_LiBMS_States = m_LiBMS_States;
    }
}
BattMonitor_FBS9100S_Inverter/src/com/battmonitor/sql/Sql_Mysql.java
@@ -26,6 +26,7 @@
    
    final public static String WEB_Site = "`web_site`";
    final public static String DB_BATT_HISTORY = "`db_batt_history`";
    final public static String DB_DEV_HISTORY = "`db_dev_history`";                                //设备历史实时数据库
    //--------------------------------------------------------------------------------------------//
    public final static String TB_HardDevSmsState = "tb_hard_dev_sms_state";
    //--------------------------------------------------------------------------------------------//
@@ -123,6 +124,8 @@
    public final static String UserPermitGroupTable = DB_USER + ".`tb_user_permitgroup`";
    public final static String UserPermitGroupDataTable = DB_USER + ".`tb_user_permitgroup_data`";
    public final static String UserJieJiaRiTable = DB_USER + ".`tb_user_jiejiari`";
    public final static String Tb_Dev_RealData = DB_DEV_HISTORY + ".tb_dev_bms_state_";                            //电池实时数据记录表
    public final static String Tb_Batt_RealData = DB_BATT_HISTORY + ".tb_batt_realdata_";                            //电池实时数据记录表
    
    public final static String FBS9100s_stemnode_state_Table = DB_RamDB + ".`tb_fbs9100s_stemnode_state`";            //干节点状态表
BattMonitor_FBS9100S_Inverter/src/com/batttest/BattResStorePro_Thread.java
@@ -84,7 +84,12 @@
                sql.sqlMysqlExecute(sql_str);
            }
            
            int mtest_record_count = 0;//sql.getBattTestRecordCountNew(data_rt.BattGroupId, Sql_Mysql.BattResDataInf_Table);
            //int mtest_record_count = 0;//sql.getBattTestRecordCountNew(data_rt.BattGroupId, Sql_Mysql.BattResDataInf_Table);
            /**
             * @lijun 2021-11-03  修复插入内阻测试表钟的test_record_count 都是0的bug
             *
             */
            int mtest_record_count = sql.getBattTestRecordCountNew(data_rt.BattGroupId, Sql_Mysql.BattResDataInf_Table);
            
            for(int c=0; c<3; c++)
            {
@@ -252,7 +257,7 @@
                sql.sqlMysqlExecute(sql_str);
            }
            
            int mtest_record_count = 0;//sql.getBattTestRecordCountNew(data_rt.BattGroupId, Sql_Mysql.BattResDataInf_Table);
            int mtest_record_count = sql.getBattTestRecordCountNew(data_rt.BattGroupId, Sql_Mysql.BattResDataInf_Table);
            
            for(int c=0; c<3; c++)
            {
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/comm/BattRealDataPro_Thread.java
@@ -47,8 +47,8 @@
        logger.warn("BattRealDataPro_Thread Started ...");
        
        Date lastTime = new Date();
        Date lastdelTime = new Date();                //上一次删除历史实时表检测时间
        //线程启动前休眠60秒                            //用于甄别还未通讯上的设备
        Date lastdelTime = new Date();                    //上一次删除历史实时表检测时间
        //线程启动前休眠60秒                                    //用于甄别还未通讯上的设备
        for(int i =0; i<60; i++) {
            try {
                sleep(1000);
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/comm/FBS9100S_SocketClient2.java
@@ -7,8 +7,6 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.time.temporal.JulianFields;
import java.util.Arrays;
import java.util.Date;
import org.apache.logging.log4j.Level;
@@ -19,6 +17,7 @@
import com.battmonitor.data.BattData_RT;
import com.battmonitor.data.BattData_RT_Array;
import com.battmonitor.data.BattData_RT_SQL;
import com.battmonitor.dev.FBS9100S_DeviceInf;
import com.battmonitor.sql.MysqlConnPool;
import com.config.AppConfig;
import com.dev.btse.data.ComFn;
@@ -114,6 +113,8 @@
    private int DevReadCount_Rate = 1;
    
    private boolean DevFBS9100_Encry_en;                //通讯协议是否使用加密版本
    private FBS9100S_DeviceInf dev_inf;
    
    /*********************************************************************************************/
    public FBS9100S_SocketClient2(MysqlConnPool m_cp, BattData_RT_Array AL_RTdata_t, Socket socket,AppConfig config)
@@ -292,8 +293,11 @@
            FBS9100_Task_Thread_SQL.insertFBS9100s_buscouple_state_Table(m_ConnPool, m_StatAndParam.dev_id);
            FBS9100_Task_Thread_SQL.insertFBS61850_jhstate_Table(m_ConnPool, m_StatAndParam.dev_id);
            
            FBS9100_Task_Thread_SQL.insertFBS9100SysParam_Table(m_ConnPool, m_StatAndParam.dev_id);
            //修复客户上一次读取或设置系统参数失败导致通信故障
            FBS9100_ParamSystem tmp_sys_param = new FBS9100_ParamSystem();
            m_StatAndParam.op_cmd_ack = FBS9100_ComBase.CMD_GetSYSSetParamAck;
            FBS9100_Task_Thread_SQL.updateFbs9100SysParamBydev_id(m_ConnPool, m_StatAndParam,tmp_sys_param);
            tmp_sys_param = null;
            
            
            int group_max = FBS9100_ComBase.BattGroupCountMax;
@@ -301,13 +305,15 @@
                m_RTData[n] = null;
            }
            
            dev_inf = AL_RTdata.getDeviceInfByDevId(m_StatAndParam.dev_id);
            m_SX_DCDC_DataList = new FBS9100S_SX_DCDC_Data[FBS9100_ComBase.LIBTS_DCDC_CountMax];
            m_LiBMS_AlarmStates = new FBS9100S_LIBMS_AlarmState[FBS9100_ComBase.LIBTS_DCDC_CountMax];
            m_LiBMS_AnalogDatas = new FBS9100S_LiBMS_AnalogData[FBS9100_ComBase.LIBTS_DCDC_CountMax];
            m_LiBMS_AnalogDatas = dev_inf.getM_LiBMS_States();
            for(int i=0;i<m_SX_DCDC_DataList.length;i++) {
                m_SX_DCDC_DataList[i] = new FBS9100S_SX_DCDC_Data();
                m_LiBMS_AlarmStates[i] = new FBS9100S_LIBMS_AlarmState();
                m_LiBMS_AnalogDatas[i] = new FBS9100S_LiBMS_AnalogData();
                //m_LiBMS_AnalogDatas[i] = new FBS9100S_LiBMS_AnalogData();
            }
            if(m_BTSDevSoftType == FBS9100_ComBase.BTSE_DevType_LIBTS) {
                //锂电BTS默认插入数据
@@ -454,7 +460,7 @@
                            FBS9100_ParamBatt tmp_batt_pm = new FBS9100_ParamBatt();
                            FBS9100_Task_Thread_SQL.queryFbs9100BattParamBydev_id(m_ConnPool, m_StatAndParam, tmp_batt_pm);
                            
                            SocketComm(FBS9100_ComBase.CMD_SetBattParam, tmp_batt_pm.getByteBuffer(), socket);
                            SocketComm(FBS9100_ComBase.CMD_SetBattParam, tmp_batt_pm.getByteBuffer(m_BTSDevSoftType), socket);
                            tmp_batt_pm = null;
                            logger.warn("DevId:" + m_StatAndParam.dev_id + " 设置BTS主机电池参数"
                                        + "\n param:" + tmp_batt_pm);
@@ -667,22 +673,26 @@
                        }
                        
                        /************** 锂电BTS的BMS模块信息读取 ********************************************************/
                        FBS9100_Task_Thread_SQL.queryLi9130_Bms_StateCmdBydev_id(m_ConnPool, m_StatAndParam);
                        if(m_StatAndParam.op_cmd_ack == FBS9100_ComBase.CMD_NULL) {
                            if(m_StatAndParam.op_cmd == FBS9100_ComBase.CMD_GetLiBMSData) {
                                SocketComm(FBS9100_ComBase.CMD_GetLiBMSData, ByteBuffer.allocate(0), socket);
                                logger.warn("DevId:" + m_StatAndParam.dev_id + " 读取锂电BMS状态信息");
                            }
                        //FBS9100_Task_Thread_SQL.queryLi9130_Bms_StateCmdBydev_id(m_ConnPool, m_StatAndParam);
                        //if(m_StatAndParam.op_cmd_ack == FBS9100_ComBase.CMD_NULL) {
                        //    if(m_StatAndParam.op_cmd == FBS9100_ComBase.CMD_GetLiBMSData) {
                        if(0 == (DevReadCount%(16*DevReadCount_Rate))) {
                            SocketComm(FBS9100_ComBase.CMD_GetLiBMSData, ByteBuffer.allocate(0), socket);
                            //logger.warn("DevId:" + m_StatAndParam.dev_id + " 读取锂电BMS状态信息");
                        }
                        //    }
                        //}
                        sleep(10);
                        /************** 锂电BTS的BMS模块告警信息读取 ********************************************************/
                        FBS9100_Task_Thread_SQL.queryLi9130_Bms_AlmCmdBydev_id(m_ConnPool, m_StatAndParam);
                        if(m_StatAndParam.op_cmd_ack == FBS9100_ComBase.CMD_NULL) {
                            if(m_StatAndParam.op_cmd == FBS9100_ComBase.CMD_GetLiBMSState) {
                                logger.warn("DevId:" + m_StatAndParam.dev_id + " 读取锂电BMS状态告警信息");
                                SocketComm(FBS9100_ComBase.CMD_GetLiBMSState, ByteBuffer.allocate(0), socket);
                            }
                        //FBS9100_Task_Thread_SQL.queryLi9130_Bms_AlmCmdBydev_id(m_ConnPool, m_StatAndParam);
                        //if(m_StatAndParam.op_cmd_ack == FBS9100_ComBase.CMD_NULL) {
                        //    if(m_StatAndParam.op_cmd == FBS9100_ComBase.CMD_GetLiBMSState) {
                        if(0 == (DevReadCount%(17*DevReadCount_Rate))) {
                            //logger.warn("DevId:" + m_StatAndParam.dev_id + " 读取锂电BMS状态告警信息");
                            SocketComm(FBS9100_ComBase.CMD_GetLiBMSState, ByteBuffer.allocate(0), socket);
                        }
                        //    }
                        //}
                    }
                    
                    
@@ -775,7 +785,7 @@
                    }else {
                        cipher_tx_t = plain_tx_t;
                    }
                    //System.out.println("发送数据:"+ComFn.bytesToHexString(plain_tx_t, plain_tx_t.length));
                    System.out.println("发送数据:"+ComFn.bytesToHexString(plain_tx_t, plain_tx_t.length));
                }
                
                //=====================================================================//
@@ -841,7 +851,7 @@
                    }
                } else {
                    if(aes_en) {                
                        //System.out.println("接收数据:"+ComFn.bytesToHexString(cipher_buf,cipher_buf.length));
                        System.out.println("接收数据:"+ComFn.bytesToHexString(cipher_buf,cipher_buf.length));
                        my_aes.ecb_decrypt(cipher_buf, plain_buf, cipher_buf.length);
                    }else {
                        plain_buf = cipher_buf;
@@ -1077,7 +1087,7 @@
            else if(FBS9100_ComBase.CMD_GetBattParam == m_FBS_Cmd.CMD)
            {
                FBS9100_ParamBatt tmp_batt_pm = new FBS9100_ParamBatt();
                if(true == tmp_batt_pm.putByteBuffer(bf)) {
                if(true == tmp_batt_pm.putByteBuffer(bf,m_BTSDevSoftType)) {
                    m_StatAndParam.op_cmd_ack = FBS9100_ComBase.CMD_GetBattParamACK;
                    FBS9100_Task_Thread_SQL.updateFbs9100BattParamBydev_id(m_ConnPool, m_StatAndParam, tmp_batt_pm);
                    isSuccess = true;
@@ -1090,7 +1100,7 @@
            //------------------- 设置FBS9100电池参数 -------------------------
            else if(FBS9100_ComBase.CMD_SetBattParam == m_FBS_Cmd.CMD) {
                FBS9100_ParamBatt tmp_batt_pm = new FBS9100_ParamBatt();
                if(true == tmp_batt_pm.putByteBuffer(bf)){
                if(true == tmp_batt_pm.putByteBuffer(bf,m_BTSDevSoftType)){
                    m_StatAndParam.op_cmd_ack = FBS9100_ComBase.CMD_SetBattParamACK;
                    FBS9100_Task_Thread_SQL.updateFbs9100BattParamCmdAckBydev_id(m_ConnPool, m_StatAndParam);
                    isSuccess = true;
@@ -1488,8 +1498,8 @@
    /*********************************************************************************************/
    /*****************   解析锂电DCDC模块信息   ****************************************************************************/
    private void getLiDCDCDataFromCommBuf(ByteBuffer bf){
        System.out.println("开始读取锂电DCDC模块信息"+bf.limit());
        System.err.println(ComFn.bytesToHexString(bf.array(), bf.array().length));
        //System.out.println("开始读取锂电DCDC模块信息"+bf.limit());
        //System.err.println(ComFn.bytesToHexString(bf.array(), bf.array().length));
        for(int i=0;i<m_SX_DCDC_DataList.length;i++){
            if(null != m_SX_DCDC_DataList[i]) {
                m_SX_DCDC_DataList[i].putByteBuffer(bf);
@@ -1511,17 +1521,18 @@
            if(null != m_LiBMS_AnalogDatas[i]) {
                m_LiBMS_AnalogDatas[i].putByteBuffer(bf);
            }            
        }
        }
        dev_inf.setM_liBMS_RecordTime(new Date());
    }
    
    /*****************   解析锂电4个BMS模块告警信息   ****************************************************************************/
    private void getLiBMSAlarmDataFromCommBuf(ByteBuffer bf) {
        System.out.println("开始读取BMS模块告警信息"+bf.limit());
        //System.out.println("开始读取BMS模块告警信息"+bf.limit());
        ByteBuffer tmpbuf = bf;
        int crc0 = tmpbuf.getShort(FBS9100S_LIBMS_AlarmState.TOTAL_BYTE_LEN-2) & 0xFFFF;
        int crc1 = FBS9100_Crc16.CalCRC16(tmpbuf, FBS9100S_LIBMS_AlarmState.TOTAL_BYTE_LEN-2);
        if(crc0 != crc1) {
            System.out.println(crc0+"=="+crc1);
            //System.out.println(crc0+"=="+crc1);
            return;
        }
        for(int i=0;i<m_LiBMS_AlarmStates.length;i++){
@@ -1551,7 +1562,7 @@
                        } else if(FBS9100_ComBase.CMD_GetMonomerTMP == cmd) {
                            //--------------------- 如果软件版本大于35,温度数据在后台减10.0℃ --------------//
                            float temp_t = (float) res_data.m_DATA[mon_index];
                            if(this.getBTSSoftwareVersion() >= 35) {
                            if(this.getBTSSoftwareVersion() >= 35 || (m_BTSDevSoftType != FBS9100_ComBase.BTSE_DevType_TieTa)) {
                                temp_t -= 10.0;
                            }
                            //--------------------------------------------------------------------------//
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/comm/FBS9100_Task_Thread_SQL.java
@@ -1810,6 +1810,10 @@
                    batt_pm.FloatChargeCurr = res.getFloat("FloatChargeCurr");
                    batt_pm.OnlineVolLow = res.getFloat("OnlineVolLow");
                    batt_pm.GroupConnType = res.getInt("GroupConnType");
                    batt_pm.BattGroupCountSum = res.getInt("BattGroupCountSum");
                    batt_pm.LiBattGroupCount = res.getInt("LiBattGroupCount");
                    batt_pm.LiEachGroupBattCount = res.getInt("LiEachGroupBattCount");
                }
            }
        } catch (SQLException e) {
@@ -1842,6 +1846,9 @@
                            + "FloatChargeVol=" + batt_pm.FloatChargeVol + ", "
                            + "FloatChargeCurr=" + batt_pm.FloatChargeCurr + ", "
                            + "OnlineVolLow=" + batt_pm.OnlineVolLow + ", "
                            + "BattGroupCountSum=" + batt_pm.BattGroupCountSum + ", "
                            + "LiBattGroupCount=" + batt_pm.LiBattGroupCount + ", "
                            + "LiEachGroupBattCount=" + batt_pm.LiEachGroupBattCount + ", "
                            + "GroupConnType=" + batt_pm.GroupConnType;
            //String sql_str_update = "UPDATE " + sql_str_base;
            String sql_str_replace = "REPLACE INTO " + sql_str_base;
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/data/FBS9100S_LiBMS_AnalogData.java
@@ -1,6 +1,7 @@
package com.dev.btse.data;
import java.nio.ByteBuffer;
import java.util.Date;
public class FBS9100S_LiBMS_AnalogData {
    
@@ -12,27 +13,28 @@
    public static final int LiBMS_TEMP_MAX = 4;
    
    public int data_flag;
    public int pack_pos;             //上位机需要获取的PACK组位置
    public int pack_pos;                         //上位机需要获取的PACK组位置
    public Date record_time = new Date(0);        //记录时间
    public int monomer_cnt;          //单体电池数量
    public int monomer_cnt;                      //单体电池数量
    public double monomer_vol[] = new double[LiBMS_MONOMER_MAX];
    public int temp_cnt;               //电芯温度数量
    public int temp_cnt;                           //电芯温度数量
    public double monomer_temp[] = new double[LiBMS_TEMP_MAX];
    public int env_temp;               //环境温度
    public int mos_temp;               //MOS管温度
    public double env_temp;                       //环境温度
    public double mos_temp;                       //MOS管温度
    public double current;            //电流
    public double sum_vol;           //总压
    public double current;                        //电流
    public double sum_vol;                       //总压
    public double rest_cap;           //剩余容量
    public double sum_cap;            //总容量
    public double rest_cap;                       //剩余容量
    public double sum_cap;                        //总容量
    public int cycle_times;         //电池循环次数
    public int cycle_times;                     //电池循环次数
    public int user_def_cnt;         //自定义遥测数量
    public int reserved;            //预留
    public int user_def_cnt;                     //自定义遥测数量
    public int reserved;                        //预留
    
    
    /**
@@ -52,7 +54,7 @@
            return false;*/
        
        tmpbuf.position(0);
        record_time = new Date();
        data_flag = FBS9100_ComBase.changeByteToInt(tmpbuf.get());
        pack_pos = FBS9100_ComBase.changeByteToInt(tmpbuf.get());                     //上位机需要获取的PACK组位置
@@ -66,8 +68,8 @@
            monomer_temp[n] = (double)(tmpbuf.getShort()-2731)/10;
        }
        
        env_temp = tmpbuf.getShort();                                               //环境温度
        mos_temp = tmpbuf.getShort();                                               //MOS管温度
        env_temp = (double)tmpbuf.getShort()/100;                                               //环境温度
        mos_temp = (double)tmpbuf.getShort()/100;                                               //MOS管温度
        current = (double)tmpbuf.getShort()/100;                                    //电流
        sum_vol =(double) FBS9100_ComBase.changeShortToInt(tmpbuf.getShort())/100;  //总压
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/data/FBS9100_ParamBatt.java
@@ -5,7 +5,8 @@
public class FBS9100_ParamBatt implements Cloneable
{
    private final int BYTE_LEN = 44;
    private final int BYTE_LEN = 44;                //常规BTS长度
    private final int BYTE_LEN_Li = 46;                //锂电BTS长度
    
    public int op_cmd = 0;
    
@@ -28,6 +29,7 @@
    public int LiBattGroupCount;                 //锂电组数
    public int LiEachGroupBattCount;             //锂电节数
    
    public double bakeup3 = 0;
    public double bakeup4 = 0;
    public double bakeup5 = 0;
    public double bakeup6 = 0;
@@ -86,22 +88,35 @@
        CRC = 0;
    }
    
    public boolean putByteBuffer(final ByteBuffer bf,int BTSE_DevType) {
        if(FBS9100_ComBase.BTSE_DevType_LIBTS == BTSE_DevType) {
            //锂电BTS
            return putLiBTSByteBuffer(bf);
        }else {
            return putBTSByteBuffer(bf);
        }
    }
    /**
     * 将bytebuffer中的数据取出放入该对象的属性中,并返回是否取出成功
     *
     * @param bf
     * @return
     */
    public boolean putByteBuffer(final ByteBuffer bf)
    public boolean putBTSByteBuffer(final ByteBuffer bf)
    {
        if(bf.limit() < BYTE_LEN)
        if(bf.limit() < BYTE_LEN) {
            //System.out.println("长度错误");
            return false;
        }
        ByteBuffer tmpbuf = bf;
        int crc0 = tmpbuf.getShort(BYTE_LEN-2) & 0xFFFF;
        int crc1 = FBS9100_Crc16.CalCRC16(tmpbuf, BYTE_LEN-2);
        if(crc0 != crc1)
        if(crc0 != crc1) {
            //System.out.println("Crc 错误");
            return false;
        }
        tmpbuf.position(0);
        STD_CAP = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort());
        STD_RES = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())*10;//uΩ
@@ -118,6 +133,7 @@
        BattGroupCountSum = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        LiBattGroupCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        LiEachGroupBattCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup4 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup5 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup6 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
@@ -132,6 +148,156 @@
        return true;
    }
    
    /**
     * 将bytebuffer中的数据取出放入该对象的属性中,并返回是否取出成功
     *
     * @param bf
     * @return
     */
    public boolean putLiBTSByteBuffer(final ByteBuffer bf)
    {
        if(bf.limit() < BYTE_LEN_Li) {
            System.out.println("长度错误");
            return false;
        }
        ByteBuffer tmpbuf = bf;
        int crc0 = tmpbuf.getShort(BYTE_LEN_Li-2) & 0xFFFF;
        int crc1 = FBS9100_Crc16.CalCRC16(tmpbuf, BYTE_LEN_Li-2);
        if(crc0 != crc1) {
            //System.out.println("Crc 错误");
            return false;
        }
        tmpbuf.position(0);
        STD_CAP = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort());
        STD_RES = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())*10;//uΩ
        BattGroupCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        EachGroupBattCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        MonomerVol = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        GroupVol = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort());
        BattTemp = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        FloatChargeVol = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        FloatChargeCurr = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        OnlineVolLow = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        GroupConnType = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        BattGroupCountSum = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        LiBattGroupCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        LiEachGroupBattCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup3 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup4 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup5 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup6 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup7 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup8 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup9 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup10 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        tmpbuf.compact();
        tmpbuf.flip();
        return true;
    }
    /**
     * 将bytebuffer中的数据取出放入该对象的属性中,并返回是否取出成功
     *
     * @param bf
     * @return
     */
    public boolean putByteBuffer(final ByteBuffer bf)
    {
        if(bf.limit() < BYTE_LEN) {
            System.out.println("长度错误");
            return false;
        }
        ByteBuffer tmpbuf = bf;
        int crc0 = tmpbuf.getShort(BYTE_LEN-2) & 0xFFFF;
        int crc1 = FBS9100_Crc16.CalCRC16(tmpbuf, BYTE_LEN-2);
        if(crc0 != crc1) {
            System.out.println("Crc 错误");
            return false;
        }
        tmpbuf.position(0);
        STD_CAP = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort());
        STD_RES = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())*10;//uΩ
        BattGroupCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        EachGroupBattCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        MonomerVol = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        GroupVol = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort());
        BattTemp = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        FloatChargeVol = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        FloatChargeCurr = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        OnlineVolLow = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
        GroupConnType = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        BattGroupCountSum = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        LiBattGroupCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        LiEachGroupBattCount = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup4 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup5 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup6 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup7 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup8 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup9 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        bakeup10 = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        tmpbuf.compact();
        tmpbuf.flip();
        return true;
    }
    public ByteBuffer getByteBuffer(int BTSE_DevType) {
        if(FBS9100_ComBase.BTSE_DevType_LIBTS == BTSE_DevType) {
            //锂电BTS
            return getLiByteBuffer();
        }else {
            return getByteBuffer();
        }
    }
    /**
     * 将数据放入bytebuffer中并返回
     * @return
     */
    public ByteBuffer getLiByteBuffer()
    {
        ByteBuffer bytebuffer = ByteBuffer.allocate(BYTE_LEN_Li);
        bytebuffer.order(ByteOrder.LITTLE_ENDIAN);
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(STD_CAP));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(STD_RES/10));//uΩ
        bytebuffer.putShort(FBS9100_ComBase.changeIntToShort(BattGroupCount));
        bytebuffer.putShort(FBS9100_ComBase.changeIntToShort(EachGroupBattCount));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(MonomerVol*10));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(GroupVol));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(BattTemp*10));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(FloatChargeVol*10));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(FloatChargeCurr*10));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(OnlineVolLow*10));
        bytebuffer.putShort(FBS9100_ComBase.changeIntToShort(GroupConnType));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(BattGroupCountSum));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(LiBattGroupCount));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(LiEachGroupBattCount));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup3));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup4));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup5));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup6));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup7));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup8));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup9));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup10));
        CRC = FBS9100_Crc16.CalCRC16(bytebuffer, bytebuffer.position());
        bytebuffer.putShort(FBS9100_ComBase.changeIntToShort(CRC));
        bytebuffer.flip();
        return bytebuffer;
    }
    
    /**
     * 将数据放入bytebuffer中并返回
@@ -156,6 +322,7 @@
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(BattGroupCountSum));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(LiBattGroupCount));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(LiEachGroupBattCount));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup4));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup5));
        bytebuffer.putShort(FBS9100_ComBase.changeDoubleToShort(bakeup6));
@@ -172,13 +339,15 @@
        return bytebuffer;
    }
    @Override
    public String toString() {
        return "FBS9100_ParamBatt [BYTE_LEN=" + BYTE_LEN + ", STD_CAP=" + STD_CAP + ", STD_RES=" + STD_RES
                + ", BattGroupCount=" + BattGroupCount + ", EachGroupBattCount=" + EachGroupBattCount + ", MonomerVol="
                + MonomerVol + ", GroupVol=" + GroupVol + ", BattTemp=" + BattTemp + ", FloatChargeVol="
                + FloatChargeVol + ", FloatChargeCurr=" + FloatChargeCurr + ", OnlineVolLow=" + OnlineVolLow
                + ", GroupConnType=" + GroupConnType + ", bakeup1=" + BattGroupCountSum + ", bakeup2=" + LiBattGroupCount + ", bakeup3="
                + ", GroupConnType=" + GroupConnType + ", BattGroupCountSum=" + BattGroupCountSum + ", LiBattGroupCount=" + LiBattGroupCount + ", LiEachGroupBattCount="
                + LiEachGroupBattCount + ", bakeup4=" + bakeup4 + ", bakeup5=" + bakeup5 + ", bakeup6=" + bakeup6 + ", bakeup7="
                + bakeup7 + ", bakeup8=" + bakeup8 + ", bakeup9=" + bakeup9 + ", bakeup10=" + bakeup10 + ", CRC=" + CRC
                + "]";
BattMonitor_FBS9100S_Inverter/src/com/dev/btse/data/FBS9100_VCData.java
@@ -199,14 +199,14 @@
        /***  2020-12-04 lijun 逆变版本的设备在线电压和组端电压不用/10  ****/
        for(int n=0; n<BATTGROUP_COUNT; n++) {
            double o_v = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
            if(((0x08 == dev_type) || (soft_ver >= 35)) && ((0x06 != dev_type) || (0x06 == dev_type && hard_ver >70 && hard_ver < 80))) {
            if(((0x08 == dev_type) ||(0x05 == dev_type) || (soft_ver >= 35)) && ((0x06 != dev_type) || (0x06 == dev_type && hard_ver >70 && hard_ver < 80))) {
                o_v /= 10;
            }
            onlinevol[n] = o_v;
        }
        for(int n=0; n<BATTGROUP_COUNT; n++) {
            double g_v = FBS9100_ComBase.changeShortToDouble(tmpbuf.getShort())/10;
            if(((0x08 == dev_type) || (soft_ver >= 35)) && ((0x06 != dev_type) || (0x06 == dev_type && hard_ver >70 && hard_ver < 80))) {
            if(((0x08 == dev_type) ||(0x05 == dev_type) || (soft_ver >= 35)) && ((0x06 != dev_type) || (0x06 == dev_type && hard_ver >70 && hard_ver < 80))) {
                g_v /= 10;
            }
            groupvol[n] = g_v;
@@ -228,7 +228,11 @@
            battcap[n] = b_cap;
        }
        for(int n=0; n<BATTGROUP_COUNT; n++)
            batttemp[n] = FBS9100_ComBase.changeShortToDouble((short)(tmpbuf.getShort()-(short)100))/10;
            /**
             * 2021-10-27 @lijun 修复温度<10度时,温度显示bug
             */
            //batttemp[n] = FBS9100_ComBase.changeShortToDouble((short)(tmpbuf.getShort()-(short)100))/10;
            batttemp[n] = FBS9100_ComBase.changeShortToDouble((short)(tmpbuf.getShort()))/10 -10;
        for(int n=0; n<BATTGROUP_COUNT; n++) {
            monMAX_num[n] = FBS9100_ComBase.changeShortToInt(tmpbuf.getShort());
        }
BattMonitor_FBS9100S_Inverter/src/com/version_inf/version_inf.txt
@@ -1,3 +1,10 @@
V10.640 edit at date 2021-11-03 lijun
    1.修复锂电BTS远程修改电池参数与常规BTS电池参数不一致bug
    2.修复BTS记录充放电数据时记录一次内阻数据的test_record_count==0bug
V10.639 edit at date 2021-10-27 lijun
    1.修复设备温度<10摄氏度时温度读取bug
V10.638 edit at date 2021-09-14 lijun
    1.新增锂电BTS设备相关信息读取
        ①设备对接命令接口
BattMonitor_FBS9100S_Inverter/src/main/main_MonitorServer_FBS9100S.java
@@ -6,6 +6,7 @@
import com.battmonitor.base.AppParam;
import com.battmonitor.data.BattData_RT_Array;
import com.battmonitor.dev.DevRealDataPro_Thread;
import com.battmonitor.sql.MysqlConnPool;
import com.battmonitor.sql.Sql_Mysql;
import com.batttest.BattDataTestPro_Thread;
@@ -28,7 +29,7 @@
    /**************************************************************************/
    /**************************************************************************/
    public final static boolean app_debug = false;
    public final static double m_VersionNum = 10.638;
    public final static double m_VersionNum = 10.640;
    public final static String m_Version = "Welcome To Use BattMonitorFBS9100S V" 
                                            + m_VersionNum + " RC_20201110";
    /**************************************************************************/
@@ -232,6 +233,12 @@
            batt_realdata.start();
        }
        
        /********************** 锂电BTS历史实时数据记录线程 ********************************************/
        if(true == m_AppConfig.isRealDataRecord_fn_En())
        {
            DevRealDataPro_Thread dev_realdata = new DevRealDataPro_Thread(GB_MysqlConnPool, m_AppConfig, GB_DataArray);
            dev_realdata.start();
        }
        
        /*
        if(true == m_AppConfig.getBattAutoStoreFnEn())