#include "kit_time.h"

#include "drv_rtc.h"

#include "bmu_manager.h"
#include "ocv_tables.h"
#include "soc_calculate.h"
#include "fault_manager.h"
#include "signal_manager.h"
#include "eeprom_manager.h"
#include "statistic_manager.h"
#include "run_status.h"
#include "hv_adc_manager.h"

#define SOX_CHG_kEep_SOC            (9900u)     
#define SOX_DIS_kEep_SOC            (100u)  
#define SOX_MAX_SOC_VALUE           (10000u)
#define SOX_MIN_SOC_VALUE           (0u)
#define SOX_MAX_SOH_VALUE           (10000u)
#define SOX_MIN_SOH_VALUE           (0u)
#define SOX_CYCLE_UP_SOC_VALUE      (9000u)
#define SOX_CYCLE_DOWN_SOC_VALUE    (3000u)
#define SOX_MAX_SIGNAL_INTEGRAL     (20000u) 	//单次积分最大值(2000A*10ms)
#define SOX_SIGNAL_ACC_CAP_VALUE    (360000u) 	//1Ams - 0.1Ah
#define SOX_SIGNAL_ACC_ENERGY_VALUE (360000u) 	//1kWms - 0.1kWh

typedef enum
{
    kSocAdjustStep_Wait,
    kSocAdjustStep_Full,
    kSocAdjustStep_Empty,
}SocAdjustStep;

typedef struct
{
	bool soc_kEep_1;
    bool soc_kEep_99;
    bool dis_adjust_flag;
	bool chg_adjust_flag;
    
    bool is_bsu_adjust;
    SocStatus soc_st;
    SocStatus soc_req_st;
    SocAdjustStep adjust_step;
    
    uint8_t cyc_flag;
	  uint8_t dis_adjust_rate;
	  uint8_t chg_adjust_rate;
	  uint8_t stat_day;
    
    uint8_t  soc_run_diff;
    uint8_t  soc_run_min;
    uint16_t req_soc;
    
    uint16_t   show_soc;
    uint32_t   calculate_cap; //积分计算容量(单位Ams)
	  uint32_t rated_cap;     //额定容量(单位Ams)
	  uint32_t soc_1_cap;     //soc 1%对应容量(单位Ams)
	  uint32_t soc_99_cap;    //soc 99%对应容量(单位Ams)
    
	  uint32_t last_tick;
	  uint32_t tmp_dis_cap;   //存储临时放电容量 (单位Ams)
	  uint32_t tmp_chg_cap;   //存储临时充电容量 (单位Ams)
    
    uint32_t tmp_dis_energy;
    uint32_t tmp_chg_energy;
    
    uint16_t soc;
    uint16_t soh;
    uint16_t cycle;
    uint32_t data[kCumulateData_End];
}SoxItem;

SoxItem sox_item;

uint16_t bms_get_show_soc(void)
{
    return sox_item.show_soc;
}

uint16_t bms_get_soc(void)
{
    return sox_item.soc;
}

void bms_set_soc(uint16_t value)
{
    sox_item.req_soc = value;
}

uint16_t bms_get_soh(void)
{
    return sox_item.soh;
}

uint16_t bms_get_cycle(void)
{
    return sox_item.cycle;
}

uint16_t bms_get_cycle_flag(void)
{
    return sox_item.cyc_flag;
}

uint8_t bms_get_stat_day(void)
{
    return sox_item.stat_day;
}

void bms_set_cycle(uint16_t value)
{
    sox_item.cycle = value;
}

SocStatus bms_get_soc_status(void)
{
	return sox_item.soc_st;
}

void bms_set_soc_status(SocStatus st)
{
	sox_item.soc_req_st = st;
}

uint32_t bms_get_cumulate_data(CumulateData idx)
{
    uint32_t tmp = 0;
    if(idx < kCumulateData_End)
    {
        tmp = sox_item.data[idx];
    }
    
    return tmp;
}

void bms_set_cumulate_data(CumulateData idx, uint32_t value)
{
    if(idx < kCumulateData_End)
    {
        sox_item.data[idx] = value;
    }
}

uint16_t soh_init(uint16_t cycle, uint32_t dis_cap, uint32_t charge_cap)
{
    uint16_t soh_loss1 = 0; //充放电次数计算出的SOH损耗百分比
    uint16_t soh_loss2 = 0; //累计放电安时计算出的SOH损耗百分比
    uint32_t rated_cap = get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full);  //2800
    uint16_t cycle_70 = get_eeprom_data(kEep_SOHSeventyCycle, kEepromDataType_Full);//3000
    
    if(cycle <= 10)
    {
        return 10000;
    }
    //单位0.0001/bit
    //公式(0.3 / cycle_70) * cycle * 10000
    soh_loss1 = (uint32_t)cycle * 3000 / cycle_70;
    if (soh_loss1 >= 3000)
    {
        return 7000;
    }
    
    soh_loss2 = (uint16_t)((3000.0 / cycle_70)*(1.0*(dis_cap+charge_cap) / (2*rated_cap)));
    
    if (soh_loss2 >= 3000)
    {
        return 7000;
    }
    if (soh_loss1 > soh_loss2)
    {
        soh_loss1 = SOX_MAX_SOH_VALUE - soh_loss1;
    }
    else
    {
        soh_loss1 = SOX_MAX_SOH_VALUE - soh_loss2;
    }
    return soh_loss1;
}

void cap_data_update(uint16_t base_time)
{
	static uint16_t dly = 0;
    static uint8_t count = 0;
    static uint32_t chg_dly = 0, dis_dly = 0;
    
    uint16_t soc;
    RunStatus run_status;
    int32_t  year, mon, day;
    int16_t cur = bms_get_current();
    
	dly += base_time;
	if(dly >= KIT_SECOND_CONVERT(1))//1S任务
	{
        bms_set_signal(kSignalIdx_SocFull, (SignalStatus)((sox_item.soc_st & kSocStatus_Full) != 0));
        bms_set_signal(kSignalIdx_SocEmpty, (SignalStatus)((sox_item.soc_st & kSocStatus_Empty) != 0));
        
		dly = 0;
        run_status = bms_get_run_status();
        soc = bms_check_run_ocv(KIT_SECOND_CONVERT(1), sox_item.soc);
        if(soc != sox_item.soc)
        {
            bms_set_soc(soc);
        }

		//累计时间更新
		if (run_status == kRunStatus_Chg)
		{
            chg_dly += KIT_SECOND_CONVERT(1);
            if(chg_dly >= KIT_MINUTE_CONVERT(6))//
            {
                chg_dly -= KIT_MINUTE_CONVERT(6);
                
                sox_item.data[kCumulateData_SigChgTime]++;
                sox_item.data[kCumulateData_DayChgTime]++;
                sox_item.data[kCumulateData_AccChgTime]++;
            }
			sox_item.data[kCumulateData_SigDisTime] = 0;
		}
		else if(run_status == kRunStatus_Dis)
		{
            dis_dly += KIT_SECOND_CONVERT(1);
            if(dis_dly >= KIT_MINUTE_CONVERT(6))
            {
                dis_dly -= KIT_MINUTE_CONVERT(6);
                
                sox_item.data[kCumulateData_SigDisTime]++;
                sox_item.data[kCumulateData_DayDisTime]++;
                sox_item.data[kCumulateData_AccDisTime]++;
            }
            sox_item.data[kCumulateData_SigChgTime] = 0;
		}
		//充放电循环次数更新 <30%  >90%
		if ((sox_item.soc <= SOX_CYCLE_DOWN_SOC_VALUE) && (sox_item.cyc_flag == 0))
		{
            sox_item.cycle++;
			sox_item.cyc_flag = 1;
		}
		else if ((sox_item.soc >= SOX_CYCLE_UP_SOC_VALUE) && (sox_item.cyc_flag != 0))
		{
			sox_item.cyc_flag = 0;
		}

        //累计容量更新 0.1Ah 更新一次
        if (sox_item.tmp_dis_cap >= SOX_SIGNAL_ACC_CAP_VALUE)
        {
            sox_item.data[kCumulateData_SigDisCap]++;
            sox_item.data[kCumulateData_AccDisCap]++;
            sox_item.data[kCumulateData_DayDisCap]++;
            sox_item.tmp_dis_cap -= SOX_SIGNAL_ACC_CAP_VALUE;
        }
        
        if (sox_item.tmp_chg_cap >= SOX_SIGNAL_ACC_CAP_VALUE)
        {
            sox_item.data[kCumulateData_SigChgCap]++;
            sox_item.data[kCumulateData_AccChgCap]++;
            sox_item.data[kCumulateData_DayChgCap]++;
            sox_item.tmp_chg_cap -= SOX_SIGNAL_ACC_CAP_VALUE;
        }
        
        drv_rtc_get_date(&year, &mon, &day);
        if(sox_item.stat_day != day)
        {
            if(count++ > 5)
            {
                count = 0;
                sox_item.stat_day = day;
                sox_item.data[kCumulateData_DayDisCap] = sox_item.data[kCumulateData_DayChgCap] = 0;
                sox_item.data[kCumulateData_DayDisTime] = sox_item.data[kCumulateData_DayChgTime] = 0;
                sox_item.data[kCumulateData_DayDisEnergy] = sox_item.data[kCumulateData_DayChgEnergy] = 0;
            }
        }
        else
        {
            count = 0;
        }
        
        //累计能量更新 0.1kWh 更新一次
        while (sox_item.tmp_dis_energy >= SOX_SIGNAL_ACC_ENERGY_VALUE)
        {
            sox_item.data[kCumulateData_SigDisEnergy]++;
            sox_item.data[kCumulateData_AccDisEnergy]++;
            sox_item.data[kCumulateData_DayDisEnergy]++;            
            sox_item.tmp_dis_energy -= SOX_SIGNAL_ACC_ENERGY_VALUE;
        }
        
        while (sox_item.tmp_chg_energy >= SOX_SIGNAL_ACC_ENERGY_VALUE)
        {
            sox_item.data[kCumulateData_SigChgEnergy]++;
            sox_item.data[kCumulateData_AccChgEnergy]++;
            sox_item.data[kCumulateData_DayChgEnergy]++;
            sox_item.tmp_chg_energy -= SOX_SIGNAL_ACC_ENERGY_VALUE;
        }
	}
}

#define SOC_RUN_CALIBRATE_RATE_MAX	200
#define SOC_RUN_CALIBRATE_RATE_DEF	100
#define SOC_RUN_CALIBRATE_RATE_MIN	50

void soc_run_calibrate(int16_t current, uint16_t base_time)
{
	static uint16_t dis_dly = 0;
	static uint16_t chg_dly = 0;
	uint8_t temp = 0;

    //放电
	if((current < 0) && (sox_item.dis_adjust_flag == false) && 
    (bms_get_statistic_data(kStatisticData_MinVolt) <= 3000) && 
    (bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
	{
		chg_dly = 0;
		dis_dly += base_time;
		if(dis_dly >= KIT_SECOND_CONVERT(5))
		{
			sox_item.dis_adjust_flag = true;
			temp = sox_item.soc * 100 / 2000;
			if(temp > SOC_RUN_CALIBRATE_RATE_MAX)
				temp = SOC_RUN_CALIBRATE_RATE_MAX;
			else if(temp < SOC_RUN_CALIBRATE_RATE_MIN)
				temp = SOC_RUN_CALIBRATE_RATE_MIN;
			
			sox_item.dis_adjust_rate = temp;
		}
	}
    //充电
	else if((current > 0) && (sox_item.chg_adjust_flag == false) && 
    (bms_get_statistic_data(kStatisticData_MaxVolt) >= 3450) && 
    (bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
    {
		dis_dly = 0;
		chg_dly += base_time;
		if(chg_dly >= KIT_SECOND_CONVERT(5))
		{
			sox_item.chg_adjust_flag = true;
			temp = 8000 * 100 / sox_item.soc;
			if(temp > SOC_RUN_CALIBRATE_RATE_MAX)
				temp = SOC_RUN_CALIBRATE_RATE_MAX;
			else if(temp < SOC_RUN_CALIBRATE_RATE_MIN)
				temp = SOC_RUN_CALIBRATE_RATE_MIN;
			
			sox_item.chg_adjust_rate = temp;	
		}
	}
	else
	{
		dis_dly = chg_dly = 0;
	}
}

#define SOC_SMOOTH_ADJUST		0
void soc_exterme_calibrate(int16_t current, uint16_t base_time)
{
	static uint16_t full_dly = 0;
    static uint16_t empty_dly = 0;
	uint16_t avg_volt, total_volt;
    uint32_t tmp_soc = sox_item.soc;
    
    if((bms_get_ex_data(kExType_CellVolt) != kExStatus_None)
    || (bms_get_bmu_fault_bit(kBmuFaultBit_Offline) != 0))
    {
        empty_dly = 0;
        full_dly = 0;
        return;
    }
    
	switch(sox_item.adjust_step)
	{
		case kSocAdjustStep_Wait:
            avg_volt = bms_get_statistic_data(kStatisticData_AvgVolt);
            total_volt = bms_get_statistic_data(kStatisticData_AccVolt)/ 100;
			if (((bms_get_statistic_data(kStatisticData_MinVolt) <= get_eeprom_data(kEep_FullDisVolt, kEepromDataType_Full))
			 && (avg_volt <= get_eeprom_data(kEep_FullDisAvgVolt, kEepromDataType_Full))
			 && (bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
             || (total_volt <= get_eeprom_data(kEep_FullDisTotalVolt, kEepromDataType_Full)/100)
             || ((sox_item.soc_req_st == kSocStatus_Empty) && (sox_item.is_bsu_adjust == false)))
			{
                full_dly = 0;
                empty_dly += base_time;
                if (empty_dly >= KIT_SECOND_CONVERT(1))
                {
                    empty_dly = 0;

                    sox_item.soc_st = kSocStatus_Empty;
                    sox_item.calculate_cap = 0;
                    sox_item.soc_kEep_1 = false;
                    sox_item.is_bsu_adjust = true;
                #if (SOC_SMOOTH_ADJUST == 1)
                    sox_item.adjust_step = kSocAdjustStep_Empty;
                #else
                    tmp_soc = SOX_MIN_SOC_VALUE;
                #endif

                }
			}
			else if (((bms_get_statistic_data(kStatisticData_MaxVolt) >= get_eeprom_data(kEep_FullChgVolt, kEepromDataType_Full))
            && (avg_volt >= get_eeprom_data(kEep_FullChgAvgVolt, kEepromDataType_Full))
			&& (bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
            || (total_volt >= get_eeprom_data(kEep_FullChgTotalVolt, kEepromDataType_Full))
            || ((sox_item.soc_req_st == kSocStatus_Full) && (sox_item.is_bsu_adjust == false)))
			{
                empty_dly = 0;
                full_dly += base_time;
                if (full_dly >= KIT_SECOND_CONVERT(1))
                {
                    
                    full_dly = 0;

                    sox_item.soc_st = kSocStatus_Full;
                    sox_item.calculate_cap = sox_item.rated_cap;
                    sox_item.soc_kEep_99 = false;
                    sox_item.is_bsu_adjust = true;                    
                #if (SOC_SMOOTH_ADJUST == 1)
                    sox_item.adjust_step = kSocAdjustStep_Full;
                #else
                    tmp_soc = SOX_MAX_SOC_VALUE;
                #endif

                }
			}
			else
			{
				empty_dly = 0;
				full_dly = 0;
			}
			break;
	#if (SOC_SMOOTH_ADJUST == 1)		
		case kSocAdjustStep_Full:			
			full_dly += base_time;
			if (full_dly >= 1000)
			{
				full_dly = 0;
   
				tmp_soc++ ;
				if(tmp_soc >= SOX_MAX_SOC_VALUE)
					sox_item.adjust_step = kSocAdjustStep_Wait;
			}
			break;
		case kSocAdjustStep_Empty:			
			empty_dly += base_time;
			if (empty_dly >= 1000)
			{
				empty_dly = 0;
				if(tmp_soc > SOX_MIN_SOC_VALUE)
				{   
					tmp_soc-- ;
				}
				else
					sox_item.adjust_step = kSocAdjustStep_Wait;
			}
			break;
	#endif	
		default:
			sox_item.adjust_step = kSocAdjustStep_Wait;
			break;
	}
    sox_item.soc = tmp_soc;
}



void bms_init_soc(void)
{
    uint32_t soc;
    uint64_t tmp_64u;
	 int32_t  year, mon, day;
    
	soc = get_eeprom_data(kEep_SOC, kEepromDataType_Full);
    //soc = bms_check_pwr_on_ocv(soc);
    sox_item.soc_kEep_99 = true;
    sox_item.soc_kEep_1 = true;
	
    if (soc == 0)
    {
		sox_item.soc_kEep_1 = false;
    }
    else if (soc == SOX_MAX_SOC_VALUE)
    {
        sox_item.soc_kEep_99 = false;
    }

    sox_item.req_soc = 0xFFFF;
    sox_item.soc_st = kSocStatus_Normal;
    sox_item.adjust_step = kSocAdjustStep_Wait;
    sox_item.tmp_chg_cap = sox_item.tmp_dis_cap = 0;
    sox_item.tmp_chg_energy = sox_item.tmp_dis_energy = 0;
	sox_item.dis_adjust_flag = sox_item.chg_adjust_flag = false;
	sox_item.dis_adjust_rate = sox_item.chg_adjust_rate = SOC_RUN_CALIBRATE_RATE_DEF;

    sox_item.soc = soc;
    year = get_eeprom_data(kEep_SOCRunMax_Min, kEepromDataType_Low);
    mon = get_eeprom_data(kEep_SOCRunMax_Min, kEepromDataType_High);
    if((year < mon) && (year >= 0) && (mon <= 100))
    {
        sox_item.soc_run_min = year;
        sox_item.soc_run_diff = mon - year;
    }
    else
    {
        sox_item.soc_run_min = 0;
        sox_item.soc_run_diff = 100;
    }
    
    tmp_64u = SOX_CONVERT_AH_TO_AMS(get_eeprom_data(kEep_RatedCapacity, kEepromDataType_Full)) * sox_item.soc_run_diff / 100;
    sox_item.rated_cap = tmp_64u;
    sox_item.soc_1_cap = (SOX_DIS_kEep_SOC * tmp_64u) / SOX_MAX_SOC_VALUE;
	sox_item.soc_99_cap = (SOX_CHG_kEep_SOC * tmp_64u) / SOX_MAX_SOC_VALUE;
	
    sox_item.calculate_cap = (soc * tmp_64u) / SOX_MAX_SOC_VALUE;

    sox_item.cycle = get_eeprom_data(kEep_CycleTimes, kEepromDataType_Full);
    sox_item.cyc_flag = get_eeprom_data(kEep_StatDay_CycleTimesFlag, kEepromDataType_Low);
    sox_item.stat_day = get_eeprom_data(kEep_StatDay_CycleTimesFlag, kEepromDataType_High);

    drv_rtc_get_date(&year, &mon, &day);
    if(sox_item.stat_day == day)
    {
        sox_item.data[kCumulateData_DayDisCap] = get_eeprom_data(kEep_DayDisCapL, kEepromDataType_Double);
        sox_item.data[kCumulateData_DayChgCap] = get_eeprom_data(kEep_DayChgCapL, kEepromDataType_Double);
        sox_item.data[kCumulateData_DayDisTime] = get_eeprom_data(kEep_DayChg_DisTime, kEepromDataType_Low);
        sox_item.data[kCumulateData_DayChgTime] = get_eeprom_data(kEep_DayChg_DisTime, kEepromDataType_High);
        sox_item.data[kCumulateData_DayChgEnergy] = get_eeprom_data(kEep_DayChgEnergyL, kEepromDataType_Double);
        sox_item.data[kCumulateData_DayDisEnergy] = get_eeprom_data(kEep_DayDisEnergyL, kEepromDataType_Double); 
    }
    sox_item.data[kCumulateData_AccChgCap] = get_eeprom_data(kEep_AccChgCapL, kEepromDataType_Double);
    sox_item.data[kCumulateData_AccDisCap] = get_eeprom_data(kEep_AccDisCapL, kEepromDataType_Double);
    sox_item.data[kCumulateData_AccChgTime] = get_eeprom_data(kEep_AccChgTimeL, kEepromDataType_Double);
    sox_item.data[kCumulateData_AccDisTime] = get_eeprom_data(kEep_AccDisTimeL, kEepromDataType_Double);    
    sox_item.data[kCumulateData_AccChgEnergy] = get_eeprom_data(kEep_AccChgEnergyL, kEepromDataType_Double);
    sox_item.data[kCumulateData_AccDisEnergy] = get_eeprom_data(kEep_AccDisEnergyL, kEepromDataType_Double);	
    
  	sox_item.soh = soh_init(sox_item.cycle, sox_item.data[kCumulateData_AccDisCap],sox_item.data[kCumulateData_AccChgCap]);
    
    sox_item.last_tick = kit_time_get_tick();
}

void bms_poll_soh(uint32_t base_time)
{
    static uint16_t dlysoh;

    dlysoh += base_time;
    
    if(dlysoh >= 5000) 
    {
        dlysoh = 0;
        sox_item.soh = soh_init(sox_item.cycle, sox_item.data[kCumulateData_AccDisCap],sox_item.data[kCumulateData_AccChgCap]);
    }
}

/*****************************************************************************
积分电流单位 0.01A/bit
 ******************************************************************************/
void bms_integral_soc(int32_t current, uint16_t base_time)
{
    uint16_t soc = sox_item.soc;
    uint16_t integral_time = 0, total_volt;
    uint32_t tmp_32u = 0;
	
	cap_data_update(base_time);
	soc_exterme_calibrate(current, base_time);
	if(sox_item.adjust_step != kSocAdjustStep_Wait)
		return;

//	/*soc test add 2-19
//	current = 168;
//	soc_run_calibrate(168, base_time);
//	*/
	tmp_32u = kit_time_get_tick();
    integral_time = kit_time_get_interval(sox_item.last_tick, tmp_32u);
    sox_item.last_tick = tmp_32u;
    
    total_volt = bms_get_high_volt(kHvType_Bat);
    
    if(sox_item.soc_req_st == kSocStatus_Normal)
    {
        sox_item.is_bsu_adjust = false;
    }
    
    #if 1
    if((sox_item.soc >= 1000)
    || (bms_get_statistic_data(kStatisticData_MinVolt) >= get_eeprom_data(kEep_ForbidDisRelVolt, kEepromDataType_Full)))
    {
        sox_item.soc_kEep_1 = true;
        sox_item.dis_adjust_flag = false;
        sox_item.dis_adjust_rate = SOC_RUN_CALIBRATE_RATE_DEF;
        
        KIT_CLR_BIT_32(sox_item.soc_st, 1);
    }

    //充电积分
    if(current > 0)
    {
        //单位Ams
        //公式 (current / 100 * integral_time) * (sox_item.chg_adjust_rate / 100)
        tmp_32u = current * integral_time * sox_item.chg_adjust_rate / 10000;
        if (tmp_32u > SOX_MAX_SIGNAL_INTEGRAL)
            tmp_32u = SOX_MAX_SIGNAL_INTEGRAL;

        sox_item.tmp_chg_cap += tmp_32u;	
        //单位 kWms
        sox_item.tmp_chg_energy +=  tmp_32u * total_volt / 10000;
        
        if(sox_item.calculate_cap < sox_item.rated_cap)
        {
            tmp_32u += sox_item.calculate_cap;
            if(tmp_32u > sox_item.soc_99_cap)
            {
                if (sox_item.soc_kEep_99 == true)
                {
                    sox_item.calculate_cap = sox_item.soc_99_cap;
                }
                else if(tmp_32u > sox_item.rated_cap)
                {
                    sox_item.calculate_cap = sox_item.rated_cap;
                }
                else
                {
                    sox_item.calculate_cap = tmp_32u;
                }
            }
            else
            {
                sox_item.calculate_cap = tmp_32u;
            }
        }
    }
    
    
    if((sox_item.soc <= 9500)
    || (bms_get_statistic_data(kStatisticData_MaxVolt) <= get_eeprom_data(kEep_ForbidChgRelVolt, kEepromDataType_Full)))
    {
        sox_item.soc_kEep_99 = true;
        sox_item.chg_adjust_flag = false;
        sox_item.chg_adjust_rate = SOC_RUN_CALIBRATE_RATE_DEF;
        KIT_CLR_BIT_32(sox_item.soc_st, 0);
    }
	
    //放电积分
    if(current < 0)
    {
        tmp_32u = KIT_ABS(current) * integral_time * sox_item.dis_adjust_rate / 10000;
        if (tmp_32u > SOX_MAX_SIGNAL_INTEGRAL)
            tmp_32u = SOX_MAX_SIGNAL_INTEGRAL;

        sox_item.tmp_dis_cap += tmp_32u;
        //单位 kWms--
        sox_item.tmp_dis_energy +=  tmp_32u * total_volt / 10000;
        
        if(sox_item.calculate_cap > 0)
        {
            if (sox_item.calculate_cap < (sox_item.soc_1_cap + tmp_32u))
            {
                if (sox_item.soc_kEep_1 == true)
                {
                    sox_item.calculate_cap = sox_item.soc_1_cap;
                }
                else if(tmp_32u >= sox_item.calculate_cap)
                {
                    sox_item.calculate_cap = 0;
                }
                else
                {
                    sox_item.calculate_cap -= tmp_32u;
                }
            }
            else
            {
                sox_item.calculate_cap -= tmp_32u;
            }
        }
    }
    if (sox_item.req_soc == 0xFFFF)
    {
        soc = (((uint64_t)sox_item.calculate_cap * SOX_MAX_SOC_VALUE * 10 / sox_item.rated_cap + 5)/10); //四舍五入
    }
    else
    {
        if (soc != sox_item.req_soc)
        {
            soc = sox_item.req_soc;
            sox_item.calculate_cap = ((uint64_t)soc * sox_item.rated_cap) / SOX_MAX_SOC_VALUE;
             
            if(sox_item.req_soc == SOX_MAX_SOC_VALUE)
                sox_item.soc_kEep_99 = false;
            else if(sox_item.req_soc == SOX_MIN_SOC_VALUE)
                sox_item.soc_kEep_1 = false;
        }
        sox_item.req_soc = 0xFFFF;
    }
    if(soc > SOX_MAX_SOC_VALUE)
    {
        soc = SOX_MAX_SOC_VALUE;
    }
    sox_item.soc = soc;
	  //计算显示soc
    sox_item.show_soc = (uint32_t)sox_item.soc_run_diff * soc / 100 + sox_item.soc_run_min * 100;
	#endif
}


